#!/usr/bin/python # ***** BEGIN LICENSE BLOCK ***** # Version: MPL 1.1/GPL 2.0/LGPL 2.1 # # The contents of this file are subject to the Mozilla Public License Version # 1.1 (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # http://www.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS IS" basis, # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License # for the specific language governing rights and limitations under the # License. # # The Original Code is a Python binding for Network Security Services (NSS). # # The Initial Developer of the Original Code is Red Hat, Inc. # (Author: John Dennis ) # # Portions created by the Initial Developer are Copyright (C) 2008,2009 # the Initial Developer. All Rights Reserved. # # Contributor(s): # # Alternatively, the contents of this file may be used under the terms of # either the GNU General Public License Version 2 or later (the "GPL"), or # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), # in which case the provisions of the GPL or the LGPL are applicable instead # of those above. If you wish to allow use of your version of this file only # under the terms of either the GPL or the LGPL, and not to allow others to # use your version of this file under the terms of the MPL, indicate your # decision by deleting the provisions above and replace them with the notice # and other provisions required by the GPL or the LGPL. If you do not delete # the provisions above, a recipient may use your version of this file under # the terms of any one of the MPL, the GPL or the LGPL. # # ***** END LICENSE BLOCK ***** ''' This example will pretty print the contents of a certificate loaded from a file. This is not the easiest or best way to print a certificate, the nss module has internal code to do that, all you need to invoke the str() method of the certificate, or it's format, or format_lines() method. Something as simple as the following will work: print cert print "Certificate is %s" % cert What this example really aims to do is illustrate how to access the various components of a cert. ''' import os import sys import getopt import getpass from nss.error import NSPRError import nss.io as io import nss.nss as nss # ----------------------------------------------------------------------------- def print_extension(level, extension): print nss.indented_format([(level, 'Name: %s' % extension.name), (level, 'Critical: %s' % extension.critical)]) oid_tag = extension.oid_tag if oid_tag == nss.SEC_OID_PKCS12_KEY_USAGE: print nss.indented_format([(level, 'Usages:')]) print nss.indented_format(nss.make_line_pairs(level+1, nss.x509_key_usage(extension.value))) elif oid_tag == nss.SEC_OID_X509_SUBJECT_KEY_ID: print nss.indented_format([(level, 'Data:')]) print nss.indented_format(nss.make_line_pairs(level+1, extension.value.der_to_hex(nss.OCTETS_PER_LINE_DEFAULT))) elif oid_tag == nss.SEC_OID_X509_CRL_DIST_POINTS: pts = nss.CRLDistributionPts(extension.value) i = 1 print nss.indented_format([(level, 'CRL Distribution Points: [%d total]' % len(pts))]) for pt in pts: print nss.indented_format([(level+1, 'Point[%d]:' % i)]) names = pt.get_general_names() print nss.indented_format([(level+2, 'General Names: [%d total]' % len(names))]) for name in names: print nss.indented_format([(level+3, '%s:' % name)]) print nss.indented_format([(level+2, 'Reasons: %s' % (pt.get_reasons(),))]) print nss.indented_format([(level+2, 'Issuer: %s' % pt.issuer)]) elif oid_tag == nss.SEC_OID_X509_AUTH_KEY_ID: auth_key_id = nss.AuthKeyID(extension.value) print nss.indented_format([(level+1, 'Key ID:')]) print nss.indented_format(nss.make_line_pairs(level+2, auth_key_id.key_id.to_hex(nss.OCTETS_PER_LINE_DEFAULT))) print nss.indented_format([(level+1, 'Serial Number: %s' % (auth_key_id.serial_number))]) print nss.indented_format([(level+1, 'Issuer:' % auth_key_id.get_general_names())]) elif oid_tag == nss.SEC_OID_X509_BASIC_CONSTRAINTS: bc = nss.BasicConstraints(extension.value) print nss.indented_format([(level, '%s' % str(bc))]) elif oid_tag == nss.SEC_OID_X509_EXT_KEY_USAGE: print nss.indented_format([(level, 'Usages:')]) print nss.indented_format(nss.make_line_pairs(level+1, nss.x509_ext_key_usage(extension.value))) elif oid_tag in (nss.SEC_OID_X509_SUBJECT_ALT_NAME, nss.SEC_OID_X509_ISSUER_ALT_NAME): names = nss.x509_alt_name(extension.value) print nss.indented_format([(level+2, 'Alternate Names: [%d total]' % len(names))]) for name in names: print nss.indented_format([(level+3, '%s:' % name)]) print # ----------------------------------------------------------------------------- usage_str = ''' -p --pem read the certifcate in PEM ascii format (default) -d --der read the certifcate in DER binary format ''' def usage(): print usage_str try: opts, args = getopt.getopt(sys.argv[1:], "hpd", ["help", "pem", "der"]) except getopt.GetoptError: # print help information and exit: usage() sys.exit(2) filename = 'cert.der' is_pem_format = True for o, a in opts: if o in ("-H", "--help"): usage() sys.exit() elif o in ("-p", "--pem"): is_pem_format = True elif o in ("-d", "--der"): is_pem_format = False filename = sys.argv[1] # Perform basic configuration and setup nss.nss_init_nodb() if len(args): filename = args[0] print "certificate filename=%s" % (filename) # Read the certificate as DER encoded data si = nss.read_der_from_file(filename, is_pem_format) # Parse the DER encoded data returning a Certificate object cert = nss.Certificate(si) # Get the extension list from the certificate extensions = cert.extensions print nss.indented_format([(0, 'Certificate:'), (1, 'Data:')]) print nss.indented_format([(2, 'Version: %d (%#x)' % (cert.version+1, cert.version))]) print nss.indented_format([(2, 'Serial Number: %d (%#x)' % (cert.serial_number, cert.serial_number))]) print nss.indented_format([(2, 'Signature Algorithm: %s' % cert.signature_algorithm)]) print nss.indented_format([(2, 'Issuer: "%s"' % cert.issuer)]) print nss.indented_format([(2, 'Validity:'), (3, 'Not Before: %s' % cert.valid_not_before_str), (3, 'Not After: %s' % cert.valid_not_after_str)]) print nss.indented_format([(2, 'Subject: "%s"' % cert.subject)]) print nss.indented_format([(2, 'Subject Public Key Info:')]) print nss.indented_format(cert.subject_public_key_info.format_lines(3)) if len(extensions) > 0: print nss.indented_format([(1, 'Signed Extensions: (%d)' % len(extensions))]) for extension in extensions: print_extension(2, extension) print nss.indented_format(cert.signed_data.format_lines(1)) print nss.indented_format([(1, 'Fingerprint (MD5):')]) print nss.indented_format(nss.make_line_pairs(2, nss.data_to_hex(nss.md5_digest(cert.der_data), nss.OCTETS_PER_LINE_DEFAULT))) print nss.indented_format([(1, 'Fingerprint (SHA1):')]) print nss.indented_format(nss.make_line_pairs(2, nss.data_to_hex(nss.sha1_digest(cert.der_data), nss.OCTETS_PER_LINE_DEFAULT)))