From 6870eb909ec5a92dad79da62b4101d3f7f6a2abb Mon Sep 17 00:00:00 2001 From: Jan Cholasta Date: Jul 30 2014 14:04:21 +0000 Subject: 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 --- diff --git a/ipalib/x509.py b/ipalib/x509.py index ebb6a81..1081c9f 100644 --- a/ipalib/x509.py +++ b/ipalib/x509.py @@ -118,32 +118,34 @@ def load_certificate(data, datatype=PEM, dbdir=None): return nss.Certificate(buffer(data)) -def load_certificate_chain_from_file(filename, dbdir=None): +def load_certificate_from_file(filename, dbdir=None): """ - Load a certificate chain from a PEM file. + Load a certificate from a PEM file. - Returns a list of nss.Certificate objects. + Returns a nss.Certificate type """ 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 load_certificate(data, PEM, dbdir) - return chain +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_from_file(filename, dbdir=None): +def load_certificate_list_from_file(filename, dbdir=None): """ - Load a certificate from a PEM file. + Load a certificate list from a PEM file. - Returns a nss.Certificate type + Returns a list of nss.Certificate objects. """ fd = open(filename, 'r') data = fd.read() fd.close() - return load_certificate(data, PEM, dbdir) + return load_certificate_list(data, dbdir) def get_subject(certificate, datatype=PEM, dbdir=None): """ @@ -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 ab8f11d..6ad7106 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 bf2a55b..bb2af53 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