diff options
| author | Fraser Tweedale <ftweedal@redhat.com> | 2016-10-13 17:12:31 +1000 |
|---|---|---|
| committer | David Kupka <dkupka@redhat.com> | 2016-11-10 10:21:47 +0100 |
| commit | db116f73fe5fc199bb2e28103cf5e3e2a24eab4c (patch) | |
| tree | ff1a043b376ec4d98b6399040a868e8b45725ee0 /ipaserver/install | |
| parent | c57dc890b2bf447ab575f2e91249179bce3f05d5 (diff) | |
x509: use python-cryptography to process certs
Update x509.load_certificate and related functions to return
python-cryptography ``Certificate`` objects. Update the call sites
accordingly, including removal of NSS initialisation code.
Also update GeneralName parsing code to return python-cryptography
GeneralName values, for consistency with other code that processes
GeneralNames. The new function, `get_san_general_names`, and
associated helper functions, can be removed when python-cryptography
provides a way to deal with unrecognised critical extensions.
Part of: https://fedorahosted.org/freeipa/ticket/6398
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
Diffstat (limited to 'ipaserver/install')
| -rw-r--r-- | ipaserver/install/ca.py | 2 | ||||
| -rw-r--r-- | ipaserver/install/cainstance.py | 25 | ||||
| -rw-r--r-- | ipaserver/install/certs.py | 9 | ||||
| -rw-r--r-- | ipaserver/install/installutils.py | 14 | ||||
| -rw-r--r-- | ipaserver/install/ipa_cacert_manage.py | 103 | ||||
| -rw-r--r-- | ipaserver/install/krainstance.py | 2 |
6 files changed, 74 insertions, 81 deletions
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py index 88ec6277f..921e49495 100644 --- a/ipaserver/install/ca.py +++ b/ipaserver/install/ca.py @@ -102,7 +102,7 @@ def install_check(standalone, replica_config, options): cert = db.get_cert_from_db(nickname) if not cert: continue - subject = DN(str(x509.get_subject(cert))) + subject = DN(x509.load_certificate(cert).subject) if subject in (DN('CN=Certificate Authority', subject_base), DN('CN=IPA RA', subject_base)): raise ScriptError( diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index 1b7acef70..7b26e749e 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -554,9 +554,9 @@ class CAInstance(DogtagInstance): config.set("CA", "pki_req_ext_data", "1E0A00530075006200430041") elif self.external == 2: - cert = x509.load_certificate_from_file(self.cert_file) cert_file = tempfile.NamedTemporaryFile() - x509.write_certificate(cert.der_data, cert_file.name) + with open(self.cert_file) as f: + x509.write_certificate(f.read(), cert_file.name) cert_file.flush() result = ipautil.run( @@ -778,7 +778,7 @@ class CAInstance(DogtagInstance): userstate=["1"], userCertificate=[cert_data], description=['2;%s;%s;%s' % ( - cert.serial_number, + cert.serial, DN(('CN', 'Certificate Authority'), self.subject_base), DN(('CN', 'IPA RA'), self.subject_base))]) conn.add_entry(entry) @@ -1674,8 +1674,9 @@ def update_people_entry(dercert): is needed when a certificate is renewed. """ def make_filter(dercert): - subject = x509.get_subject(dercert, datatype=x509.DER) - issuer = x509.get_issuer(dercert, datatype=x509.DER) + cert = x509.load_certificate(dercert, datatype=x509.DER) + subject = DN(cert.subject) + issuer = DN(cert.issuer) return ldap2.ldap2.combine_filters( [ ldap2.ldap2.make_filter({'objectClass': 'inetOrgPerson'}), @@ -1686,9 +1687,10 @@ def update_people_entry(dercert): ldap2.ldap2.MATCH_ALL) def make_entry(dercert, entry): - serial_number = x509.get_serial_number(dercert, datatype=x509.DER) - subject = x509.get_subject(dercert, datatype=x509.DER) - issuer = x509.get_issuer(dercert, datatype=x509.DER) + cert = x509.load_certificate(dercert, datatype=x509.DER) + serial_number = cert.serial + subject = DN(cert.subject) + issuer = DN(cert.issuer) entry['usercertificate'].append(dercert) entry['description'] = '2;%d;%s;%s' % (serial_number, issuer, subject) return entry @@ -1702,15 +1704,16 @@ def update_authority_entry(dercert): serial number to match the given cert. """ def make_filter(dercert): - subject = x509.get_subject(dercert, datatype=x509.DER) + cert = x509.load_certificate(dercert, datatype=x509.DER) + subject = str(DN(cert.subject)) return ldap2.ldap2.make_filter( dict(objectclass='authority', authoritydn=subject), rules=ldap2.ldap2.MATCH_ALL, ) def make_entry(dercert, entry): - serial_number = x509.get_serial_number(dercert, datatype=x509.DER) - entry['authoritySerial'] = serial_number + cert = x509.load_certificate(dercert, datatype=x509.DER) + entry['authoritySerial'] = cert.serial return entry return __update_entry_from_cert(make_filter, make_entry, dercert) diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py index 31fd36cc3..a73025099 100644 --- a/ipaserver/install/certs.py +++ b/ipaserver/install/certs.py @@ -60,9 +60,8 @@ def get_cert_nickname(cert): representation of the first RDN in the subject and subject_dn is a DN object. """ - nsscert = x509.load_certificate(cert) - subject = str(nsscert.subject) - dn = DN(subject) + cert_obj = x509.load_certificate(cert) + dn = DN(cert_obj.subject) return (str(dn[0]), dn) @@ -304,8 +303,8 @@ class CertDB(object): return cert = self.get_cert_from_db(nickname) - nsscert = x509.load_certificate(cert, dbdir=self.secdir) - subject = str(nsscert.subject) + cert_obj = x509.load_certificate(cert) + subject = str(DN(cert_obj.subject)) certmonger.add_principal(request_id, principal) certmonger.add_subject(request_id, subject) diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index fb9579a07..bee501a6e 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -921,10 +921,9 @@ def load_pkcs12(cert_files, key_password, key_nickname, ca_cert_files, if ca_cert is None: ca_cert = cert - nss_cert = x509.load_certificate(cert, x509.DER) - subject = DN(str(nss_cert.subject)) - issuer = DN(str(nss_cert.issuer)) - del nss_cert + cert_obj = x509.load_certificate(cert, x509.DER) + subject = DN(cert_obj.subject) + issuer = DN(cert_obj.issuer) if subject == issuer: break @@ -1046,10 +1045,9 @@ def load_external_cert(files, subject_base): for nickname, _trust_flags in nssdb.list_certs(): cert = nssdb.get_cert(nickname, pem=True) - nss_cert = x509.load_certificate(cert) - subject = DN(str(nss_cert.subject)) - issuer = DN(str(nss_cert.issuer)) - del nss_cert + cert_obj = x509.load_certificate(cert) + subject = DN(cert_obj.subject) + issuer = DN(cert_obj.issuer) cache[nickname] = (cert, subject, issuer) if subject == ca_subject: diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py index af08ba68c..0dcb70fea 100644 --- a/ipaserver/install/ipa_cacert_manage.py +++ b/ipaserver/install/ipa_cacert_manage.py @@ -21,8 +21,7 @@ from __future__ import print_function import os from optparse import OptionGroup -from nss import nss -from nss.error import NSPRError +from cryptography.hazmat.primitives import serialization import gssapi from ipapython import admintool, certmonger, ipautil @@ -187,7 +186,7 @@ class CACertManage(admintool.AdminTool): "--external-cert-file=/path/to/signed_certificate " "--external-cert-file=/path/to/external_ca_certificate") - def renew_external_step_2(self, ca, old_cert): + def renew_external_step_2(self, ca, old_cert_der): print("Importing the renewed CA certificate, please wait") options = self.options @@ -195,55 +194,54 @@ class CACertManage(admintool.AdminTool): cert_file, ca_file = installutils.load_external_cert( options.external_cert_files, x509.subject_base()) - nss_cert = None - nss.nss_init(paths.PKI_TOMCAT_ALIAS_DIR) - try: - nss_cert = x509.load_certificate(old_cert, x509.DER) - subject = nss_cert.subject - der_subject = x509.get_der_subject(old_cert, x509.DER) - #pylint: disable=E1101 - pkinfo = nss_cert.subject_public_key_info.format() - #pylint: enable=E1101 - - nss_cert = x509.load_certificate_from_file(cert_file.name) - cert = nss_cert.der_data - if nss_cert.subject != subject: - raise admintool.ScriptError( - "Subject name mismatch (visit " - "http://www.freeipa.org/page/Troubleshooting for " - "troubleshooting guide)") - if x509.get_der_subject(cert, x509.DER) != der_subject: - raise admintool.ScriptError( - "Subject name encoding mismatch (visit " - "http://www.freeipa.org/page/Troubleshooting for " - "troubleshooting guide)") - #pylint: disable=E1101 - if nss_cert.subject_public_key_info.format() != pkinfo: - raise admintool.ScriptError( - "Subject public key info mismatch (visit " - "http://www.freeipa.org/page/Troubleshooting for " - "troubleshooting guide)") - #pylint: enable=E1101 - finally: - del nss_cert - nss.nss_shutdown() + old_cert_obj = x509.load_certificate(old_cert_der, x509.DER) + old_der_subject = x509.get_der_subject(old_cert_der, x509.DER) + old_spki = old_cert_obj.public_key().public_bytes( + serialization.Encoding.DER, + serialization.PublicFormat.SubjectPublicKeyInfo + ) + + with open(cert_file.name) as f: + new_cert_data = f.read() + new_cert_der = x509.normalize_certificate(new_cert_data) + new_cert_obj = x509.load_certificate(new_cert_der, x509.DER) + new_der_subject = x509.get_der_subject(new_cert_der, x509.DER) + new_spki = new_cert_obj.public_key().public_bytes( + serialization.Encoding.DER, + serialization.PublicFormat.SubjectPublicKeyInfo + ) + + if new_cert_obj.subject != old_cert_obj.subject: + raise admintool.ScriptError( + "Subject name mismatch (visit " + "http://www.freeipa.org/page/Troubleshooting for " + "troubleshooting guide)") + if new_der_subject != old_der_subject: + raise admintool.ScriptError( + "Subject name encoding mismatch (visit " + "http://www.freeipa.org/page/Troubleshooting for " + "troubleshooting guide)") + if new_spki != old_spki: + raise admintool.ScriptError( + "Subject public key info mismatch (visit " + "http://www.freeipa.org/page/Troubleshooting for " + "troubleshooting guide)") with certs.NSSDatabase() as tmpdb: pw = ipautil.write_tmp_file(ipautil.ipa_generate_password()) tmpdb.create_db(pw.name) - tmpdb.add_cert(old_cert, 'IPA CA', 'C,,') + tmpdb.add_cert(old_cert_der, 'IPA CA', 'C,,') try: - tmpdb.add_cert(cert, 'IPA CA', 'C,,') + tmpdb.add_cert(new_cert_der, 'IPA CA', 'C,,') except ipautil.CalledProcessError as e: raise admintool.ScriptError( "Not compatible with the current CA certificate: %s" % e) ca_certs = x509.load_certificate_list_from_file(ca_file.name) for ca_cert in ca_certs: - tmpdb.add_cert(ca_cert.der_data, str(ca_cert.subject), 'C,,') - del ca_certs - del ca_cert + data = ca_cert.public_bytes(serialization.Encoding.DER) + tmpdb.add_cert(data, str(DN(ca_cert.subject)), 'C,,') try: tmpdb.verify_ca_cert_validity('IPA CA') @@ -266,14 +264,14 @@ class CACertManage(admintool.AdminTool): ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn) try: entry = conn.get_entry(dn, ['usercertificate']) - entry['usercertificate'] = [cert] + entry['usercertificate'] = [new_cert_der] conn.update_entry(entry) except errors.NotFound: entry = conn.make_entry( dn, objectclass=['top', 'pkiuser', 'nscontainer'], cn=[self.cert_nickname], - usercertificate=[cert]) + usercertificate=[new_cert_der]) conn.add_entry(entry) except errors.EmptyModlist: pass @@ -313,21 +311,16 @@ class CACertManage(admintool.AdminTool): options = self.options cert_filename = self.args[1] - nss_cert = None try: - try: - nss_cert = x509.load_certificate_from_file(cert_filename) - except IOError as e: - raise admintool.ScriptError( - "Can't open \"%s\": %s" % (cert_filename, e)) - except (TypeError, NSPRError, ValueError) as e: - raise admintool.ScriptError("Not a valid certificate: %s" % e) - subject = nss_cert.subject - cert = nss_cert.der_data - finally: - del nss_cert + cert_obj = x509.load_certificate_from_file(cert_filename) + except IOError as e: + raise admintool.ScriptError( + "Can't open \"%s\": %s" % (cert_filename, e)) + except (TypeError, ValueError) as e: + raise admintool.ScriptError("Not a valid certificate: %s" % e) + cert = cert_obj.public_bytes(serialization.Encoding.DER) - nickname = options.nickname or str(subject) + nickname = options.nickname or str(DN(cert_obj.subject)) ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, api.env.basedn, diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py index 315057808..77f23c1c3 100644 --- a/ipaserver/install/krainstance.py +++ b/ipaserver/install/krainstance.py @@ -297,7 +297,7 @@ class KRAInstance(DogtagInstance): usertype=["undefined"], userCertificate=[cert_data], description=['2;%s;%s;%s' % ( - cert.serial_number, + cert.serial, DN(('CN', 'Certificate Authority'), self.subject_base), DN(('CN', 'IPA RA'), self.subject_base))]) conn.add_entry(entry) |
