From 6870eb909ec5a92dad79da62b4101d3f7f6a2abb Mon Sep 17 00:00:00 2001 From: Jan Cholasta Date: Thu, 12 Jun 2014 13:26:34 +0200 Subject: [PATCH] Add function for writing list of certificates to a PEM file to ipalib.x509. Also rename load_certificate_chain_from_file to load_certificate_list_from_file. Part of https://fedorahosted.org/freeipa/ticket/3259 Part of https://fedorahosted.org/freeipa/ticket/3520 Reviewed-By: Rob Crittenden --- ipalib/x509.py | 50 ++++++++++++++++++-------- ipaserver/install/installutils.py | 2 +- ipaserver/install/ipa_cacert_manage.py | 2 +- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/ipalib/x509.py b/ipalib/x509.py index ebb6a81d5..1081c9ff7 100644 --- a/ipalib/x509.py +++ b/ipalib/x509.py @@ -118,21 +118,6 @@ def load_certificate(data, datatype=PEM, dbdir=None): return nss.Certificate(buffer(data)) -def load_certificate_chain_from_file(filename, dbdir=None): - """ - Load a certificate chain from a PEM file. - - Returns a list of nss.Certificate objects. - """ - fd = open(filename, 'r') - data = fd.read() - fd.close() - - chain = PEM_REGEX.findall(data) - chain = [load_certificate(cert, PEM, dbdir) for cert in chain] - - return chain - def load_certificate_from_file(filename, dbdir=None): """ Load a certificate from a PEM file. @@ -145,6 +130,23 @@ def load_certificate_from_file(filename, dbdir=None): return load_certificate(data, PEM, dbdir) +def load_certificate_list(data, dbdir=None): + certs = PEM_REGEX.findall(data) + certs = [load_certificate(cert, PEM, dbdir) for cert in certs] + return certs + +def load_certificate_list_from_file(filename, dbdir=None): + """ + Load a certificate list from a PEM file. + + Returns a list of nss.Certificate objects. + """ + fd = open(filename, 'r') + data = fd.read() + fd.close() + + return load_certificate_list(data, dbdir) + def get_subject(certificate, datatype=PEM, dbdir=None): """ Load an X509.3 certificate and get the subject. @@ -310,6 +312,24 @@ def write_certificate(rawcert, filename): except (IOError, OSError), e: raise errors.FileError(reason=str(e)) +def write_certificate_list(rawcerts, filename): + """ + Write a list of certificates to a file in PEM format. + + The cert values can be either DER or PEM-encoded, they will be normalized + to DER regardless, then back out to PEM. + """ + dercerts = [normalize_certificate(rawcert) for rawcert in rawcerts] + + try: + with open(filename, 'w') as f: + for cert in dercerts: + cert = base64.b64encode(cert) + cert = make_pem(cert) + f.write(cert + '\n') + except (IOError, OSError), e: + raise errors.FileError(reason=str(e)) + def verify_cert_subject(ldap, hostname, dercert): """ Verify that the certificate issuer we're adding matches the issuer diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index ab8f11d67..6ad7106b5 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -889,7 +889,7 @@ def validate_external_cert(cert_file, ca_file, subject_base): extchain = None try: - extchain = x509.load_certificate_chain_from_file(ca_file) + extchain = x509.load_certificate_list_from_file(ca_file) certdict = dict((DN(str(cert.subject)), DN(str(cert.issuer))) for cert in extchain) except IOError, e: diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py index bf2a55b0d..bb2af5375 100644 --- a/ipaserver/install/ipa_cacert_manage.py +++ b/ipaserver/install/ipa_cacert_manage.py @@ -224,7 +224,7 @@ class CACertManage(admintool.AdminTool): raise admintool.ScriptError( "Not compatible with the current CA certificate: %s", e) - ca_certs = x509.load_certificate_chain_from_file(ca_filename) + ca_certs = x509.load_certificate_list_from_file(ca_filename) for ca_cert in ca_certs: tmpdb.add_cert(ca_cert.der_data, str(ca_cert.subject), 'C,,') del ca_certs