def get_pin(server, algo): first_cmd = [ 'openssl', 's_client', '-connect', server+":443", '-showcerts', ] second_cmd = ['sed', '-n', "/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p"] p = subprocess.Popen( first_cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) q = subprocess.Popen(second_cmd, stdin=p.stdout, stdout=subprocess.PIPE) p.stdin.close() p.stderr.close() output = q.communicate()[0] output = output.split('-----END') inter = output[1] server = output[0] issuer = inter.split('CERTIFICATE-----')[2] cert_issuer = BEGIN + issuer + END cert = server + END x509_issuer = get_X509_from_string_pem(cert_issuer) x509 = get_X509_from_string_pem(cert) cert = nss.Certificate(x509.as_der(), nssconfig.certdb) spki = get_spki_from_cert(x509_issuer.as_der()) spki_h = hash_with_algorithm_and_data(algo, spki) spki_b64 = base64.b64encode(spki_h) print "[+] PIN\n\t _id: %s" % cert.subject_common_name print "\t issuer : %s" % cert.issuer.common_name print "\t\t Base64 of SPKI with %s: %s" % (algo, spki_b64) return (cert.subject_common_name, cert.issuer.common_name, spki_b64)
def load_certificate(data, datatype=PEM, dbdir=None): """ Given a base64-encoded certificate, with or without the header/footer, return a request object. Returns a nss.Certificate type """ if type(data) in (tuple, list): data = data[0] if (datatype == PEM): data = strip_header(data) data = base64.b64decode(data) if not nss.nss_is_initialized(): if dbdir is None: if 'in_tree' in api.env: if api.env.in_tree: dbdir = api.env.dot_ipa + os.sep + 'alias' else: dbdir = "/etc/httpd/alias" nss.nss_init(dbdir) else: nss.nss_init_nodb() else: nss.nss_init(dbdir) return nss.Certificate(buffer(data))
def __init__(self, certs): self._certs_der = certs self._certs_nss = list() for i in xrange(0, len(self._certs_der)): try: self._certs_nss.append( nss.Certificate(self._certs_der[i], nssconfig.certdb)) except: break
def load_certificate(data, datatype=PEM, dbdir=None): """ Given a base64-encoded certificate, with or without the header/footer, return a request object. Returns a nss.Certificate type """ if type(data) in (tuple, list): data = data[0] if (datatype == PEM): data = strip_header(data) data = base64.b64decode(data) initialize_nss_database(dbdir=dbdir) if six.PY2: return nss.Certificate(buffer(data)) # pylint: disable=buffer-builtin else: # In python 3 , `bytes` has the buffer interface return nss.Certificate(data)
def get_key(server, algorithm): certificate = ssl.get_server_certificate((server, 443)) x509 = get_X509_from_string_pem(certificate) der_cert = x509.as_der() cert = nss.Certificate(der_cert, nssconfig.certdb) spki = get_spki_from_cert(der_cert) fingerprint = hash_with_algorithm_and_data(algorithm, spki) id = cert.subject_public_key_info.algorithm.id_str print "[+] KEYCONTINUITY\n\t %s of SPKI " % algorithm print "\t %s : %s " % (cert.subject_common_name, fingerprint) print "\t Key of type: %s" % id
def get_public_key(transport_cert): """ This function returns public key of the transport cert which will be used to wrap the session key """ # First convert from PEM to DER Format #transport_cert_der = nss.base64_to_binary(transport_cert) # Read the contents of the file certItem = nss.read_der_from_file(transport_cert, ascii=True) # We need to have an Object of nss.Certificate CertObject = nss.Certificate(certItem) # Get the public Key from the cert public_key = CertObject.subject_public_key_info.public_key return public_key
def get_key_from_file(file, algo): import os f = os.path.expanduser(file) f = os.path.abspath(f) x509 = M2Crypto.X509.load_cert(f, FORMAT_PEM) cert_der = x509.as_der() cert = nss.Certificate(cert_der, nssconfig.certdb) spki = get_spki_from_cert(cert_der) fingerprint = hash_with_algorithm_and_data(algo, spki) id = cert.subject_public_key_info.algorithm.id_str print "[+] KEYCONTINUITY\n\t %s of SPKI " % algo print "\t %s : %s " % (cert.subject_common_name, fingerprint) print "\t Key of type: %s" % id
def add_issuer_name(self, conn, entry): dn, attrs = entry if self.verbose: print('Fixing certificate record %s' % dn) attr_cert = attrs.get('userCertificate;binary') if not attr_cert: return # shouldn't happen, but nothing we can do if it does cert = nss.Certificate(bytearray(attr_cert[0])) issuer_name = str(cert.issuer) try: conn.ldap.modify_s(dn, [(ldap.MOD_REPLACE, 'issuerName', issuer_name)]) except ldap.LDAPError as e: print('Failed to add issuerName to certificate {}: {}'.format( attrs.get('cn', ['<unknown>'])[0], e))
def main(): global options parser = argparse.ArgumentParser( description='certificate validation example') # === NSS Database Group === group = parser.add_argument_group('NSS Database', 'Specify & control the NSS Database') group.add_argument('-d', '--db-name', help='NSS database name (e.g. "sql:pki")') group.add_argument('-P', '--db-passwd', help='NSS database password') # === Certificate Group === group = parser.add_argument_group('Certificate', 'Specify how the certificate is loaded') group.add_argument('-f', '--file', dest='cert_filename', help='read cert from file') group.add_argument('-F', '--input-format', choices=['pem', 'der'], help='format of input cert') group.add_argument( '-n', '--nickname', dest='cert_nickname', help='load cert from NSS database by looking it up under this nickname' ) # === Validation Group === group = parser.add_argument_group('Validation', 'Control the validation') group.add_argument( '-u', '--usage', dest='cert_usage', action='append', choices=list(cert_usage_map.keys()), help='certificate usage flags, may be specified multiple times') group.add_argument('-c', '--check-sig', action='store_true', dest='check_sig', help='check signature') group.add_argument('-C', '--no-check-sig', action='store_false', dest='check_sig', help='do not check signature') group.add_argument('-l', '--log', action='store_true', dest='with_log', help='use verify log') group.add_argument('-L', '--no-log', action='store_false', dest='with_log', help='do not use verify log') group.add_argument('-a', '--check-ca', action='store_true', dest='check_ca', help='check if cert is CA') group.add_argument('-A', '--no-check-ca', action='store_false', dest='check_ca', help='do not check if cert is CA') # === Miscellaneous Group === group = parser.add_argument_group('Miscellaneous', 'Miscellaneous options') group.add_argument('-p', '--print-cert', action='store_true', dest='print_cert', help='print the certificate in a friendly fashion') parser.set_defaults( db_name='sql:pki', db_passwd='db_passwd', input_format='pem', check_sig=True, with_log=True, check_ca=True, print_cert=False, ) options = parser.parse_args() # Process the command line arguments # Get usage bitmask if options.cert_usage: intended_usage = 0 for usage in options.cert_usage: try: flag = cert_usage_map[usage] except KeyError: print("Unknown usage '%s', valid values: %s" % (usage, ', '.join(sorted(cert_usage_map.keys())))) return 1 else: intended_usage |= flag else: # We can't use nss.certificateUsageCheckAllUsages here because # it's a special value of zero instead of being the bitwise OR # of all the certificateUsage* flags (go figure!) intended_usage = 0 for usage in list(cert_usage_map.values()): intended_usage |= usage if options.cert_filename and options.cert_nickname: print( "You may not specify both a cert filename and a nickname, only one or the other", file=sys.stderr) return 1 if not options.cert_filename and not options.cert_nickname: print("You must specify either a cert filename or a nickname to load", file=sys.stderr) return 1 # Initialize NSS. print(indented_output('NSS Database', options.db_name)) print() nss.nss_init(options.db_name) certdb = nss.get_default_certdb() nss.set_password_callback(password_callback) # Load the cert if options.cert_filename: # Read the certificate as DER encoded data then initialize a Certificate from the DER data filename = options.cert_filename si = nss.read_der_from_file(filename, options.input_format.lower() == 'pem') # Parse the DER encoded data returning a Certificate object cert = nss.Certificate(si) else: try: cert = nss.find_cert_from_nickname(options.cert_nickname) except Exception as e: print(e) print('Unable to load cert nickname "%s" from database "%s"' % \ (options.cert_nickname, options.db_name), file=sys.stderr) return 1 # Dump the cert if the user wants to see it if options.print_cert: print(cert) else: print(indented_output('cert subject', cert.subject)) print() # Dump the usages attached to the cert print( indented_output('cert has these usages', nss.cert_type_flags(cert.cert_type))) # Should we check if the cert is a CA cert? if options.check_ca: # CA Cert? is_ca, cert_type = cert.is_ca_cert(True) print() print(indented_output('is CA cert boolean', is_ca)) print( indented_output('is CA cert returned usages', nss.cert_type_flags(cert_type))) print() print( indented_output('verifying usages for', nss.cert_usage_flags(intended_usage))) print() # Use the log or non-log variant to verify the cert # # Note: Anytime a NSPR or NSS function returns an error in python-nss it # raises a NSPRError exception. When an exception is raised the normal # return values are discarded because the flow of control continues at # the first except block prepared to catch the exception. Normally this # is what is desired because the return values would be invalid due to # the error. However the certificate verification functions are an # exception (no pun intended). An error might be returned indicating the # cert failed verification but you may still need access to the returned # usage bitmask and the log (if using the log variant). To handle this a # special error exception `CertVerifyError` (derived from `NSPRError`) # is defined which in addition to the normal NSPRError fields will also # contain the returned usages and optionally the CertVerifyLog # object. If no exception is raised these are returned as normal return # values. approved_usage = 0 if options.with_log: try: approved_usage, log = cert.verify_with_log(certdb, options.check_sig, intended_usage, None) except nss_error.CertVerifyError as e: # approved_usage and log available in CertVerifyError exception on failure. print(e) print() print(indented_obj('log', e.log)) print() print( indented_output('approved usages from exception', nss.cert_usage_flags(e.usages))) approved_usage = e.usages # Get the returned usage bitmask from the exception except Exception as e: print(e) else: print( indented_output('approved usages', nss.cert_usage_flags(approved_usage))) if log.count: print() print(indented_obj('log', log)) else: try: approved_usage = cert.verify(certdb, options.check_sig, intended_usage, None) except nss_error.CertVerifyError as e: # approved_usage available in CertVerifyError exception on failure. print(e) print( indented_output('approved usages from exception', nss.cert_usage_flags(e.usages))) approved_usage = e.usages # Get the returned usage bitmask from the exception except Exception as e: print(e) else: print( indented_output('approved usages', nss.cert_usage_flags(approved_usage))) # The cert is valid if all the intended usages are in the approved usages valid = (intended_usage & approved_usage) == intended_usage print() if valid: print( indented_output('SUCCESS: cert is approved for', nss.cert_usage_flags(intended_usage))) return 0 else: print( indented_output( 'FAIL: cert not approved for', nss.cert_usage_flags(intended_usage ^ approved_usage))) return 1
def main(): # Command line argument processing parser = optparse.OptionParser() parser.set_defaults(dbdir = '/etc/pki/nssdb', db_passwd = 'db_passwd', input_format = 'pem', check_sig = True, print_cert = False, with_log = True, check_ca = True, ) param_group = optparse.OptionGroup(parser, 'NSS Database', 'Specify & control the NSS Database') param_group.add_option('-d', '--dbdir', dest='dbdir', help='NSS database directory, default="%default"') param_group.add_option('-P', '--db-passwd', dest='db_passwd', help='NSS database password, default="%default"') parser.add_option_group(param_group) param_group = optparse.OptionGroup(parser, 'Certificate', 'Specify how the certificate is loaded') param_group.add_option('-f', '--file', dest='cert_filename', help='read cert from file') param_group.add_option('--format', dest='input_format', choices=['pem', 'der'], help='import format for certificate (der|pem) default="%default"') param_group.add_option('-n', '--nickname', dest='cert_nickname', help='load cert from NSS database by looking it up under this nickname') parser.add_option_group(param_group) param_group = optparse.OptionGroup(parser, 'Validation', 'Control the validation') param_group.add_option('-u', '--usage', dest='cert_usage', action='append', choices=cert_usage_map.keys(), help='may be specified multiple times, default="CheckAllUsages", may be one of: %s' % ', '.join(sorted(cert_usage_map.keys()))) param_group.add_option('-c', '--check-sig', action='store_true', dest='check_sig', help='check signature default=%default') param_group.add_option('-C', '--no-check-sig', action='store_false', dest='check_sig', help='check signature') param_group.add_option('-l', '--log', action='store_true', dest='with_log', help='use verify log, default=%default') param_group.add_option('-L', '--no-log', action='store_false', dest='with_log', help='use verify log, default=%default') param_group.add_option('-a', '--check-ca', action='store_true', dest='check_ca', help='check if cert is CA, default=%default') param_group.add_option('-A', '--no-check-ca', action='store_false', dest='check_ca', help='check if cert is CA, default=%default') parser.add_option_group(param_group) param_group = optparse.OptionGroup(parser, 'Miscellaneous', 'Miscellaneous options') param_group.add_option('-p', '--print-cert', action='store_true', dest='print_cert', help='print the certificate in a friendly fashion, default=%default') parser.add_option_group(param_group) options, args = parser.parse_args() # Process the command line arguments # Get usage bitmask if options.cert_usage: intended_usage = 0 for usage in options.cert_usage: try: flag = cert_usage_map[usage] except KeyError: print "Unknown usage '%s', valid values: %s" % (usage, ', '.join(sorted(cert_usage_map.keys()))) return 1 else: intended_usage |= flag else: # We can't use nss.certificateUsageCheckAllUsages here because # it's a special value of zero instead of being the bitwise OR # of all the certificateUsage* flags (go figure!) intended_usage = 0 for usage in cert_usage_map.values(): intended_usage |= usage if options.cert_filename and options.cert_nickname: print >>sys.stderr, "You may not specify both a cert filename and a nickname, only one or the other" return 1 if not options.cert_filename and not options.cert_nickname: print >>sys.stderr, "You must specify either a cert filename or a nickname to load" return 1 # Initialize NSS. print indented_output('NSS Database', options.dbdir) print nss.nss_init(options.dbdir) certdb = nss.get_default_certdb() nss.set_password_callback(password_callback) # Load the cert if options.cert_filename: # Read the certificate as DER encoded data then initialize a Certificate from the DER data filename = options.cert_filename si = nss.read_der_from_file(filename, options.input_format.lower() == 'pem') # Parse the DER encoded data returning a Certificate object cert = nss.Certificate(si) else: try: cert = nss.find_cert_from_nickname(options.cert_nickname) except Exception, e: print e print >>sys.stderr, 'Unable to load cert nickname "%s" from database "%s"' % \ (options.cert_nickname, options.dbdir) return 1
parser.add_argument('cert_file', nargs=1, help='input cert file to process') parser.set_defaults(cert_format='pem', print_cert=False) options = parser.parse_args() # Perform basic configuration and setup nss.nss_init_nodb() filename = options.cert_file[0] print("certificate filename=%s" % (filename)) # Read the certificate as DER encoded data si = nss.read_der_from_file(filename, options.cert_format == 'pem') # Parse the DER encoded data returning a Certificate object cert = nss.Certificate(si) # Useful for comparing the internal cert rendering to what this script generates. if options.print_cert: print(cert) # 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([
def forward(self, *args, **options): output_file = options.get('out') password = options.get('password') password_file = options.get('password_file') private_key = options.get('private_key') private_key_file = options.get('private_key_file') # don't send these parameters to server if 'out' in options: del options['out'] if 'password' in options: del options['password'] if 'password_file' in options: del options['password_file'] if 'private_key' in options: del options['private_key'] if 'private_key_file' in options: del options['private_key_file'] if self.api.env.in_server: backend = self.api.Backend.ldap2 else: backend = self.api.Backend.rpcclient if not backend.isconnected(): backend.connect() # retrieve vault info vault = self.api.Command.vault_show(*args, **options)['result'] vault_type = vault['ipavaulttype'][0] # initialize NSS database nss.nss_init(api.env.nss_dir) # retrieve transport certificate config = self.api.Command.vaultconfig_show()['result'] transport_cert_der = config['transport_cert'] nss_transport_cert = nss.Certificate(transport_cert_der) # generate session key mechanism = nss.CKM_DES3_CBC_PAD slot = nss.get_best_slot(mechanism) key_length = slot.get_best_key_length(mechanism) session_key = slot.key_gen(mechanism, None, key_length) # wrap session key with transport certificate # pylint: disable=no-member public_key = nss_transport_cert.subject_public_key_info.public_key # pylint: enable=no-member wrapped_session_key = nss.pub_wrap_sym_key(mechanism, public_key, session_key) # send retrieval request to server options['session_key'] = wrapped_session_key.data response = self.api.Command.vault_retrieve_internal(*args, **options) result = response['result'] nonce = result['nonce'] # unwrap data with session key wrapped_vault_data = result['vault_data'] iv_si = nss.SecItem(nonce) iv_param = nss.param_from_iv(mechanism, iv_si) decoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT, session_key, iv_param) json_vault_data = decoding_ctx.cipher_op(wrapped_vault_data)\ + decoding_ctx.digest_final() vault_data = json.loads(json_vault_data.decode('utf-8')) data = base64.b64decode(vault_data[u'data'].encode('utf-8')) encrypted_key = None if 'encrypted_key' in vault_data: encrypted_key = base64.b64decode(vault_data[u'encrypted_key'] .encode('utf-8')) if vault_type == u'standard': pass elif vault_type == u'symmetric': salt = vault['ipavaultsalt'][0] # get encryption key from vault password if password and password_file: raise errors.MutuallyExclusiveError( reason=_('Password specified multiple times')) elif password: pass elif password_file: password = validated_read('password-file', password_file, encoding='utf-8') password = password.rstrip('\n') else: password = get_existing_password() # generate encryption key from password encryption_key = generate_symmetric_key(password, salt) # decrypt data with encryption key data = decrypt(data, symmetric_key=encryption_key) elif vault_type == u'asymmetric': # get encryption key with vault private key if private_key and private_key_file: raise errors.MutuallyExclusiveError( reason=_('Private key specified multiple times')) elif private_key: pass elif private_key_file: private_key = validated_read('private-key-file', private_key_file, mode='rb') else: raise errors.ValidationError( name='private_key', error=_('Missing vault private key')) # decrypt encryption key with private key encryption_key = decrypt(encrypted_key, private_key=private_key) # decrypt data with encryption key data = decrypt(data, symmetric_key=encryption_key) else: raise errors.ValidationError( name='vault_type', error=_('Invalid vault type')) if output_file: with open(output_file, 'w') as f: f.write(data) else: response['result'] = {'data': data} return response
def forward(self, *args, **options): data = options.get('data') input_file = options.get('in') password = options.get('password') password_file = options.get('password_file') override_password = options.pop('override_password', False) # don't send these parameters to server if 'data' in options: del options['data'] if 'in' in options: del options['in'] if 'password' in options: del options['password'] if 'password_file' in options: del options['password_file'] # get data if data and input_file: raise errors.MutuallyExclusiveError( reason=_('Input data specified multiple times')) elif data: if len(data) > MAX_VAULT_DATA_SIZE: raise errors.ValidationError(name="data", error=_( "Size of data exceeds the limit. Current vault data size " "limit is %(limit)d B") % {'limit': MAX_VAULT_DATA_SIZE}) elif input_file: try: stat = os.stat(input_file) except OSError as exc: raise errors.ValidationError(name="in", error=_( "Cannot read file '%(filename)s': %(exc)s") % {'filename': input_file, 'exc': exc.args[1]}) if stat.st_size > MAX_VAULT_DATA_SIZE: raise errors.ValidationError(name="in", error=_( "Size of data exceeds the limit. Current vault data size " "limit is %(limit)d B") % {'limit': MAX_VAULT_DATA_SIZE}) data = validated_read('in', input_file, mode='rb') else: data = '' if self.api.env.in_server: backend = self.api.Backend.ldap2 else: backend = self.api.Backend.rpcclient if not backend.isconnected(): backend.connect() # retrieve vault info vault = self.api.Command.vault_show(*args, **options)['result'] vault_type = vault['ipavaulttype'][0] if vault_type == u'standard': encrypted_key = None elif vault_type == u'symmetric': # get password if password and password_file: raise errors.MutuallyExclusiveError( reason=_('Password specified multiple times')) elif password: pass elif password_file: password = validated_read('password-file', password_file, encoding='utf-8') password = password.rstrip('\n') else: if override_password: password = get_new_password() else: password = get_existing_password() if not override_password: # verify password by retrieving existing data opts = options.copy() opts['password'] = password try: self.api.Command.vault_retrieve(*args, **opts) except errors.NotFound: pass salt = vault['ipavaultsalt'][0] # generate encryption key from vault password encryption_key = generate_symmetric_key(password, salt) # encrypt data with encryption key data = encrypt(data, symmetric_key=encryption_key) encrypted_key = None elif vault_type == u'asymmetric': public_key = vault['ipavaultpublickey'][0].encode('utf-8') # generate encryption key encryption_key = base64.b64encode(os.urandom(32)) # encrypt data with encryption key data = encrypt(data, symmetric_key=encryption_key) # encrypt encryption key with public key encrypted_key = encrypt(encryption_key, public_key=public_key) else: raise errors.ValidationError( name='vault_type', error=_('Invalid vault type')) # initialize NSS database nss.nss_init(api.env.nss_dir) # retrieve transport certificate config = self.api.Command.vaultconfig_show()['result'] transport_cert_der = config['transport_cert'] nss_transport_cert = nss.Certificate(transport_cert_der) # generate session key mechanism = nss.CKM_DES3_CBC_PAD slot = nss.get_best_slot(mechanism) key_length = slot.get_best_key_length(mechanism) session_key = slot.key_gen(mechanism, None, key_length) # wrap session key with transport certificate # pylint: disable=no-member public_key = nss_transport_cert.subject_public_key_info.public_key # pylint: enable=no-member wrapped_session_key = nss.pub_wrap_sym_key(mechanism, public_key, session_key) options['session_key'] = wrapped_session_key.data nonce_length = nss.get_iv_length(mechanism) nonce = nss.generate_random(nonce_length) options['nonce'] = nonce vault_data = {} vault_data[u'data'] = base64.b64encode(data).decode('utf-8') if encrypted_key: vault_data[u'encrypted_key'] = base64.b64encode(encrypted_key)\ .decode('utf-8') json_vault_data = json.dumps(vault_data) # wrap vault_data with session key iv_si = nss.SecItem(nonce) iv_param = nss.param_from_iv(mechanism, iv_si) encoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT, session_key, iv_param) wrapped_vault_data = encoding_ctx.cipher_op(json_vault_data)\ + encoding_ctx.digest_final() options['vault_data'] = wrapped_vault_data return self.api.Command.vault_archive_internal(*args, **options)
if os.path.isfile(file): # f = open(file).readlines() # f = ''.join(f) try: a = M2Crypto.X509.load_cert(file, format=FORMAT_DER) except: # we should transform PEM encoding to DER cmdstr = [ "openssl", "x509", "-in", file, "-inform", "PEM", "-out", file, "-outform", "DER" ] subprocess.call(cmdstr) a = M2Crypto.X509.load_cert(file, format=FORMAT_DER) der = a.as_der() cert = nss.Certificate(der, certdb) s = hashlib.new("sha256") cert_dec = DerSequence() cert_dec.decode(der) tbsCertificate = DerSequence() try: tbsCertificate.decode(cert_dec[0]) except: continue try: spki = tbsCertificate[6] except: # FIXME observing some outcomes with the certificates given the # len(tbs)-1 is spki I don't know why due to spki in the rfc is in # the 7th position. BTW maybe you have to research in this and
def main(): global options parser = argparse.ArgumentParser(description='certificate trust example') # === NSS Database Group === group = parser.add_argument_group('NSS Database', 'Specify & control the NSS Database') group.add_argument('-d', '--db-name', help='NSS database name (e.g. "sql:pki")') group.add_argument('-P', '--db-passwd', help='NSS database password') # === Certificate Group === group = parser.add_argument_group('Certificate', 'Specify how the certificate is loaded') group.add_argument('-f', '--file', dest='cert_filename', help='read cert from file') group.add_argument('-F', '--input-format', choices=['pem', 'der'], help='format of input cert') group.add_argument('-n', '--nickname', dest='cert_nickname', help='load cert from NSS database by looking it up under this nickname') group.add_argument('-t', '--trust', dest='cert_trust', help='set the cert trust flags, see certutil for format') group.add_argument('-i', '--install-cert', action='store_true', dest='cert_perm', help='check signature') group.add_argument('-p', '--print-cert', action='store_true', dest='print_cert', help='print the certificate in a friendly fashion') parser.set_defaults(db_name = 'sql:pki', db_passwd = 'db_passwd', input_format = 'pem', install_cert = False, print_cert = False, ) options = parser.parse_args() # Process the command line arguments if options.cert_perm: if not options.cert_filename: print("You must specify a cert filename to install a cert in the database", file=sys.stderr) return 1 if not options.cert_nickname: print("You must specify a cert nickname to install a cert in the database", file=sys.stderr) return 1 else: if options.cert_filename and options.cert_nickname: print("You may not specify both a cert filename and a nickname, only one or the other", file=sys.stderr) return 1 if not options.cert_filename and not options.cert_nickname: print("You must specify either a cert filename or a nickname to load", file=sys.stderr) return 1 # Initialize NSS. print('NSS Database: %s' % (options.db_name)) print() # Initialize the database as read/write, otherwise we would not # be able to import a cert nss.nss_init_read_write(options.db_name) certdb = nss.get_default_certdb() # Since we may update the cert make sure we're using the key slot # and not just the internal slot slot = nss.get_internal_key_slot() # If we're importing or modifying a cert we'll need to authenticate # to the database, the password callback supplies the password during # authentication. nss.set_password_callback(password_callback) # Load the cert if options.cert_filename: # Read the certificate as DER encoded data then initialize a Certificate from the DER data filename = options.cert_filename si = nss.read_der_from_file(filename, options.input_format.lower() == 'pem') # Parse the DER encoded data returning a Certificate object. # # If we've been asked to install the cert in the database the # options.cert_perm flag will be True and we'll need to supply # the nickname (which is used to locate the cert in the database). cert = nss.Certificate(si, certdb, options.cert_perm, options.cert_nickname) else: try: cert = nss.find_cert_from_nickname(options.cert_nickname) except Exception as e: print(e) print('Unable to load cert nickname "%s" from database "%s"' % \ (options.cert_nickname, options.db_name), file=sys.stderr) return 1 # Dump the cert if the user wants to see it if options.print_cert: print(cert) else: print('cert subject: %s' % (cert.subject)) print() # Change the cert trust if specified if options.cert_trust: cert.set_trust_attributes(options.cert_trust, certdb, slot) illustrate_ssl_trust(cert) return 0