Example #1
0
    def install(self):
        print("Installing CA certificate, please wait")

        options = self.options
        cert_filename = self.args[1]

        try:
            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, ValueError) as e:
            raise admintool.ScriptError("Not a valid certificate: %s" % e)

        nickname = options.nickname or str(DN(cert.subject))

        ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2,
                                              api.env.basedn, api.env.realm,
                                              False)

        with certs.NSSDatabase() as tmpdb:
            tmpdb.create_db()
            tmpdb.add_cert(cert, nickname, EXTERNAL_CA_TRUST_FLAGS)
            for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
                tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)

            try:
                tmpdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

        trust_flags = options.trust_flags.split(',')
        if (set(options.trust_flags) - set(',CPTcgpuw')
                or len(trust_flags) not in [3, 4]):
            raise admintool.ScriptError("Invalid trust flags")

        extra_flags = trust_flags[3:]
        extra_usages = set()
        if extra_flags:
            if 'C' in extra_flags[0]:
                extra_usages.add(x509.EKU_PKINIT_KDC)
            if 'T' in extra_flags[0]:
                extra_usages.add(x509.EKU_PKINIT_CLIENT_AUTH)

        trust_flags = parse_trust_flags(','.join(trust_flags[:3]))
        trust_flags = TrustFlags(trust_flags.has_key, trust_flags.trusted,
                                 trust_flags.ca,
                                 trust_flags.usages | extra_usages)

        try:
            certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert,
                                      nickname, trust_flags)
        except ValueError as e:
            raise admintool.ScriptError(
                "Failed to install the certificate: %s" % e)

        print("CA certificate successfully installed")
Example #2
0
def load_external_cert(files, subject_base):
    """
    Load and verify external CA certificate chain from multiple files.

    The files are accepted in PEM and DER certificate and PKCS#7 certificate
    chain formats.

    :param files: Names of files to import
    :param subject_base: Subject name base for IPA certificates
    :returns: Temporary file with the IPA CA certificate and temporary file
        with the external CA certificate chain
    """
    with certs.NSSDatabase() as nssdb:
        db_password = ipautil.ipa_generate_password()
        db_pwdfile = ipautil.write_tmp_file(db_password)
        nssdb.create_db(db_pwdfile.name)

        try:
            nssdb.import_files(files, db_pwdfile.name)
        except RuntimeError as e:
            raise ScriptError(str(e))

        ca_subject = DN(('CN', 'Certificate Authority'), subject_base)
        ca_nickname = None
        cache = {}
        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

            cache[nickname] = (cert, subject, issuer)
            if subject == ca_subject:
                ca_nickname = nickname
            nssdb.trust_root_cert(nickname)

        if ca_nickname is None:
            raise ScriptError("IPA CA certificate not found in %s" %
                              (", ".join(files)))

        trust_chain = reversed(nssdb.get_trust_chain(ca_nickname))
        ca_cert_chain = []
        for nickname in trust_chain:
            cert, subject, issuer = cache[nickname]
            ca_cert_chain.append(cert)
            if subject == issuer:
                break
        else:
            raise ScriptError("CA certificate chain in %s is incomplete" %
                              (", ".join(files)))

        for nickname in trust_chain:
            try:
                nssdb.verify_ca_cert_validity(nickname)
            except ValueError, e:
                raise ScriptError("CA certificate %s in %s is not valid: %s" %
                                  (subject, ", ".join(files), e))
Example #3
0
    def delete(self):
        options = self.options
        nickname = self.args[1]
        conn = api.Backend.ldap2

        ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2,
                                              api.env.basedn, api.env.realm,
                                              False)

        ipa_ca_nickname = get_ca_nickname(api.env.realm)

        found = False
        for _ca_cert, ca_nickname, _ca_trust_flags in ca_certs:
            if ca_nickname == nickname:
                if ca_nickname == ipa_ca_nickname:
                    raise admintool.ScriptError(
                        'The IPA CA cannot be removed with this tool')
                else:
                    found = True
                    break

        if not found:
            raise admintool.ScriptError('Unknown CA \'{}\''.format(nickname))

        with certs.NSSDatabase() as tmpdb:
            tmpdb.create_db()
            for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
                tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)
            loaded = tmpdb.list_certs()
            logger.debug("loaded raw certs '%s'", loaded)

            tmpdb.delete_cert(nickname)

            for ca_nickname, _trust_flags in loaded:
                if ca_nickname == nickname:
                    continue
                elif ipa_ca_nickname == nickname:
                    raise admintool.ScriptError("The IPA CA cannot be removed")
                logger.debug("Verifying %s", ca_nickname)
                try:
                    tmpdb.verify_ca_cert_validity(ca_nickname)
                except ValueError as e:
                    msg = "Verifying \'%s\' failed. Removing part of the " \
                          "chain? %s" % (nickname, e)
                    if options.force:
                        print(msg)
                        continue
                    raise admintool.ScriptError(msg)
                else:
                    logger.debug("Verified %s", ca_nickname)

        for _ca_cert, ca_nickname, _ca_trust_flags in ca_certs:
            if ca_nickname == nickname:
                container_dn = DN(('cn', 'certificates'), ('cn', 'ipa'),
                                  ('cn', 'etc'), api.env.basedn)
                dn = DN(('cn', nickname), container_dn)
                logger.debug("Deleting %s", ca_nickname)
                conn.delete_entry(dn)
                return
Example #4
0
    def install(self):
        print("Installing CA certificate, please wait")

        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

        nickname = options.nickname or str(subject)

        ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2,
                                              api.env.basedn, api.env.realm,
                                              False)

        with certs.NSSDatabase() as tmpdb:
            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
            tmpdb.create_db(pw.name)
            tmpdb.add_cert(cert, nickname, 'C,,')
            for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
                tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)

            try:
                tmpdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

        trust_flags = options.trust_flags
        if ((set(trust_flags) - set(',CPTcgpuw'))
                or len(trust_flags.split(',')) != 3):
            raise admintool.ScriptError("Invalid trust flags")

        try:
            certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert,
                                      nickname, trust_flags)
        except ValueError as e:
            raise admintool.ScriptError(
                "Failed to install the certificate: %s" % e)

        print("CA certificate successfully installed")
Example #5
0
    def install(self):
        print("Installing CA certificate, please wait")

        options = self.options
        cert_filename = self.args[1]

        try:
            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(DN(cert_obj.subject))

        ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2,
                                              api.env.basedn,
                                              api.env.realm,
                                              False)

        with certs.NSSDatabase() as tmpdb:
            tmpdb.create_db()
            tmpdb.add_cert(cert, nickname, 'C,,')
            for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
                tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)

            try:
                tmpdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

        trust_flags = options.trust_flags
        if ((set(trust_flags) - set(',CPTcgpuw')) or
            len(trust_flags.split(',')) != 3):
            raise admintool.ScriptError("Invalid trust flags")

        try:
            certstore.put_ca_cert_nss(
                api.Backend.ldap2, api.env.basedn, cert, nickname, trust_flags)
        except ValueError as e:
            raise admintool.ScriptError(
                "Failed to install the certificate: %s" % e)

        print("CA certificate successfully installed")
Example #6
0
    def renew_external_step_2(self, ca, old_cert_der):
        print("Importing the renewed CA certificate, please wait")

        options = self.options
        conn = api.Backend.ldap2

        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
        )

        cert_file, ca_file = installutils.load_external_cert(
            options.external_cert_files, DN(old_cert_obj.subject))

        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:
            tmpdb.create_db()
            tmpdb.add_cert(old_cert_der, 'IPA CA', 'C,,')

            try:
                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:
                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')
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

            trust_chain = tmpdb.get_trust_chain('IPA CA')[:-1]
            for nickname in trust_chain:
                try:
                    ca_cert = tmpdb.get_cert(nickname)
                except RuntimeError:
                    break
                certstore.put_ca_cert_nss(
                    conn, api.env.basedn, ca_cert, nickname, ',,')

        dn = DN(('cn', self.cert_nickname), ('cn', 'ca_renewal'),
                ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
        try:
            entry = conn.get_entry(dn, ['usercertificate'])
            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=[new_cert_der])
            conn.add_entry(entry)
        except errors.EmptyModlist:
            pass

        try:
            ca.set_renewal_master()
        except errors.NotFound:
            raise admintool.ScriptError("CA renewal master not found")

        self.resubmit_request(ca, 'ipaRetrieval')

        print("CA certificate successfully renewed")
Example #7
0
def load_external_cert(files, ca_subject):
    """
    Load and verify external CA certificate chain from multiple files.

    The files are accepted in PEM and DER certificate and PKCS#7 certificate
    chain formats.

    :param files: Names of files to import
    :param ca_subject: IPA CA subject DN
    :returns: Temporary file with the IPA CA certificate and temporary file
        with the external CA certificate chain
    """
    with certs.NSSDatabase() as nssdb:
        nssdb.create_db()

        try:
            nssdb.import_files(files)
        except RuntimeError as e:
            raise ScriptError(str(e))

        ca_subject = DN(ca_subject)
        ca_nickname = None
        cache = {}
        for nickname, _trust_flags in nssdb.list_certs():
            cert = nssdb.get_cert(nickname)
            subject = DN(cert.subject)
            issuer = DN(cert.issuer)

            cache[nickname] = (cert, subject, issuer)
            if subject == ca_subject:
                ca_nickname = nickname
            nssdb.trust_root_cert(nickname, EXTERNAL_CA_TRUST_FLAGS)

        if ca_nickname is None:
            raise ScriptError(
                "IPA CA certificate with subject '%s' "
                "was not found in %s." % (ca_subject, (",".join(files))))

        trust_chain = list(reversed(nssdb.get_trust_chain(ca_nickname)))
        ca_cert_chain = []
        for nickname in trust_chain:
            cert, subject, issuer = cache[nickname]
            ca_cert_chain.append(cert)
            if subject == issuer:
                break
        else:
            raise ScriptError(
                "CA certificate chain in %s is incomplete: "
                "missing certificate with subject '%s'" %
                (", ".join(files), issuer))

        for nickname in trust_chain:
            try:
                nssdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                cert, subject, issuer = cache[nickname]
                raise ScriptError(
                    "CA certificate %s in %s is not valid: %s" %
                    (subject, ", ".join(files), e))

    cert_file = tempfile.NamedTemporaryFile()
    cert_file.write(ca_cert_chain[0].public_bytes(x509.Encoding.PEM) + b'\n')
    cert_file.flush()

    ca_file = tempfile.NamedTemporaryFile()
    x509.write_certificate_list(
        ca_cert_chain[1:],
        ca_file.name,
        mode=0o644
    )
    ca_file.flush()

    return cert_file, ca_file
Example #8
0
def load_pkcs12(cert_files, key_password, key_nickname, ca_cert_files,
                host_name=None, realm_name=None):
    """
    Load and verify server certificate and private key from multiple files

    The files are accepted in PEM and DER certificate, PKCS#7 certificate
    chain, PKCS#8 and raw private key and PKCS#12 formats.

    :param cert_files: Names of server certificate and private key files to
        import
    :param key_password: Password to decrypt private keys
    :param key_nickname: Nickname of the private key to import from PKCS#12
        files
    :param ca_cert_files: Names of CA certificate files to import
    :param host_name: Host name of the server
    :returns: Temporary PKCS#12 file with the server certificate, private key
        and CA certificate chain, password to unlock the PKCS#12 file and
        the CA certificate of the CA that issued the server certificate
    """
    with certs.NSSDatabase() as nssdb:
        nssdb.create_db()

        try:
            nssdb.import_files(cert_files, True, key_password, key_nickname)
        except RuntimeError as e:
            raise ScriptError(str(e))

        if ca_cert_files:
            try:
                nssdb.import_files(ca_cert_files)
            except RuntimeError as e:
                raise ScriptError(str(e))

        for nickname, trust_flags in nssdb.list_certs():
            if trust_flags.has_key:
                key_nickname = nickname
                continue
            nssdb.trust_root_cert(nickname, EXTERNAL_CA_TRUST_FLAGS)

        # Check we have the whole cert chain & the CA is in it
        trust_chain = list(reversed(nssdb.get_trust_chain(key_nickname)))
        ca_cert = None
        for nickname in trust_chain[1:]:
            cert = nssdb.get_cert(nickname)
            if ca_cert is None:
                ca_cert = cert

            subject = DN(cert.subject)
            issuer = DN(cert.issuer)

            if subject == issuer:
                break
        else:
            raise ScriptError(
                "The full certificate chain is not present in %s" %
                (", ".join(cert_files)))

        for nickname in trust_chain[1:]:
            try:
                nssdb.verify_ca_cert_validity(nickname)
            except ValueError as e:
                raise ScriptError(
                    "CA certificate %s in %s is not valid: %s" %
                    (subject, ", ".join(cert_files), e))

        if host_name is not None:
            try:
                nssdb.verify_server_cert_validity(key_nickname, host_name)
            except ValueError as e:
                raise ScriptError(
                    "The server certificate in %s is not valid: %s" %
                    (", ".join(cert_files), e))

        if realm_name is not None:
            try:
                nssdb.verify_kdc_cert_validity(key_nickname, realm_name)
            except ValueError as e:
                raise ScriptError(
                    "The KDC certificate in %s is not valid: %s" %
                    (", ".join(cert_files), e))

        out_file = tempfile.NamedTemporaryFile()
        out_password = ipautil.ipa_generate_password()
        out_pwdfile = ipautil.write_tmp_file(out_password)
        args = [
            paths.PK12UTIL,
            '-o', out_file.name,
            '-n', key_nickname,
            '-d', nssdb.secdir,
            '-k', nssdb.pwd_file,
            '-w', out_pwdfile.name,
        ]
        ipautil.run(args)

    return out_file, out_password, ca_cert
Example #9
0
    def renew_external_step_2(self, ca, old_cert):
        print("Importing the renewed CA certificate, please wait")

        options = self.options
        conn = api.Backend.ldap2
        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()

        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,,')

            try:
                tmpdb.add_cert(cert, '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

            try:
                tmpdb.verify_ca_cert_validity('IPA CA')
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

            trust_chain = tmpdb.get_trust_chain('IPA CA')[:-1]
            for nickname in trust_chain:
                try:
                    ca_cert = tmpdb.get_cert(nickname)
                except RuntimeError:
                    break
                certstore.put_ca_cert_nss(conn, api.env.basedn, ca_cert,
                                          nickname, ',,')

        dn = DN(('cn', self.cert_nickname), ('cn', 'ca_renewal'),
                ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
        try:
            entry = conn.get_entry(dn, ['usercertificate'])
            entry['usercertificate'] = [cert]
            conn.update_entry(entry)
        except errors.NotFound:
            entry = conn.make_entry(
                dn,
                objectclass=['top', 'pkiuser', 'nscontainer'],
                cn=[self.cert_nickname],
                usercertificate=[cert])
            conn.add_entry(entry)
        except errors.EmptyModlist:
            pass

        try:
            ca.set_renewal_master()
        except errors.NotFound:
            raise admintool.ScriptError("CA renewal master not found")

        self.resubmit_request(ca, 'ipaRetrieval')

        print("CA certificate successfully renewed")
Example #10
0
    def install(self):
        print("Installing CA certificate, please wait")

        options = self.options

        ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2,
                                              api.env.basedn, api.env.realm,
                                              False)

        with certs.NSSDatabase() as tmpdb:
            tmpdb.create_db()
            tmpdb.import_files(self.args[1:])
            imported = tmpdb.list_certs()
            logger.debug("loaded raw certs '%s'", imported)

            if len(imported) > 1 and options.nickname:
                raise admintool.ScriptError(
                    "Nickname can only be used if only a single "
                    "certificate is loaded")

            # If a nickname was provided re-import the cert
            if options.nickname:
                (nickname, trust_flags) = imported[0]
                cert = tmpdb.get_cert(nickname)
                tmpdb.delete_cert(nickname)
                tmpdb.add_cert(cert, options.nickname, EXTERNAL_CA_TRUST_FLAGS)
                imported = tmpdb.list_certs()

            for ca_cert, ca_nickname, ca_trust_flags in ca_certs:
                tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags)

            for nickname, trust_flags in imported:
                if trust_flags.has_key:
                    continue
                tmpdb.trust_root_cert(nickname, EXTERNAL_CA_TRUST_FLAGS)

            for nickname, trust_flags in imported:
                try:
                    tmpdb.verify_ca_cert_validity(nickname)
                except ValueError as e:
                    raise admintool.ScriptError(
                        "Not a valid CA certificate: %s (visit "
                        "http://www.freeipa.org/page/Troubleshooting for "
                        "troubleshooting guide)" % e)
                else:
                    print("Verified %s" % nickname)

            trust_flags = options.trust_flags.split(',')
            if (set(options.trust_flags) - set(',CPTcgpuw')
                    or len(trust_flags) not in [3, 4]):
                raise admintool.ScriptError("Invalid trust flags")

            extra_flags = trust_flags[3:]
            extra_usages = set()
            if extra_flags:
                if 'C' in extra_flags[0]:
                    extra_usages.add(x509.EKU_PKINIT_KDC)
                if 'T' in extra_flags[0]:
                    extra_usages.add(x509.EKU_PKINIT_CLIENT_AUTH)

            trust_flags = parse_trust_flags(','.join(trust_flags[:3]))
            trust_flags = TrustFlags(trust_flags.has_key, trust_flags.trusted,
                                     trust_flags.ca,
                                     trust_flags.usages | extra_usages)

            for nickname, _trust_flags in imported:
                try:
                    cert = tmpdb.get_cert(nickname)
                    certstore.put_ca_cert_nss(api.Backend.ldap2,
                                              api.env.basedn, cert, nickname,
                                              trust_flags)
                except ValueError as e:
                    raise admintool.ScriptError(
                        "Failed to install the certificate: %s" % e)

        print("CA certificate successfully installed")
Example #11
0
    def renew_external_step_2(self, ca, old_cert):
        print("Importing the renewed CA certificate, please wait")

        options = self.options
        conn = api.Backend.ldap2

        old_spki = old_cert.public_key_info_bytes

        cert_file, ca_file = installutils.load_external_cert(
            options.external_cert_files, DN(old_cert.subject))

        with open(cert_file.name, 'rb') as f:
            new_cert_data = f.read()
        new_cert = x509.load_pem_x509_certificate(new_cert_data)
        new_spki = new_cert.public_key_info_bytes

        if new_cert.subject != old_cert.subject:
            raise admintool.ScriptError(
                "Subject name mismatch (visit "
                "http://www.freeipa.org/page/Troubleshooting for "
                "troubleshooting guide)")
        if new_cert.subject_bytes != old_cert.subject_bytes:
            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:
            tmpdb.create_db()
            tmpdb.add_cert(old_cert, 'IPA CA', EXTERNAL_CA_TRUST_FLAGS)

            try:
                tmpdb.add_cert(new_cert, 'IPA CA', EXTERNAL_CA_TRUST_FLAGS)
            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, str(DN(ca_cert.subject)),
                               EXTERNAL_CA_TRUST_FLAGS)

            try:
                tmpdb.verify_ca_cert_validity('IPA CA')
            except ValueError as e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

            trust_chain = tmpdb.get_trust_chain('IPA CA')[:-1]
            for nickname in trust_chain:
                try:
                    ca_cert = tmpdb.get_cert(nickname)
                except RuntimeError:
                    break
                certstore.put_ca_cert_nss(conn, api.env.basedn, ca_cert,
                                          nickname, EMPTY_TRUST_FLAGS)

        dn = DN(('cn', self.cert_nickname), ('cn', 'ca_renewal'),
                ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)

        try:
            entry = conn.get_entry(dn, ['usercertificate'])
            entry['usercertificate'] = [new_cert]
            conn.update_entry(entry)
        except errors.NotFound:
            entry = conn.make_entry(
                dn,
                objectclass=['top', 'pkiuser', 'nscontainer'],
                cn=[self.cert_nickname],
                usercertificate=[new_cert])
            conn.add_entry(entry)
        except errors.EmptyModlist:
            pass

        update_ipa_ca_entry(api, new_cert)

        try:
            ca.set_renewal_master()
        except errors.NotFound:
            raise admintool.ScriptError("CA renewal master not found")

        self.resubmit_request(RENEWAL_REUSE_CA_NAME)

        print("CA certificate successfully renewed")
Example #12
0
    def renew_external_step_2(self, ca, old_cert):
        print "Importing the renewed CA certificate, please wait"

        options = self.options
        cert_file, ca_file = installutils.load_external_cert(
            options.external_cert_files, x509.subject_base())

        nss_cert = None
        nss.nss_init(ca.dogtag_constants.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()

        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,,')

            try:
                tmpdb.add_cert(cert, 'IPA CA', 'C,,')
            except ipautil.CalledProcessError, 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

            try:
                tmpdb.verify_ca_cert_validity('IPA CA')
            except ValueError, e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)
Example #13
0
        try:
            try:
                nss_cert = x509.load_certificate_from_file(cert_filename)
            except IOError, e:
                raise admintool.ScriptError("Can't open \"%s\": %s" %
                                            (cert_filename, e))
            except (TypeError, NSPRError), e:
                raise admintool.ScriptError("Not a valid certificate: %s" % e)
            subject = nss_cert.subject
            cert = nss_cert.der_data
        finally:
            del nss_cert

        nickname = options.nickname or str(subject)

        with certs.NSSDatabase() as tmpdb:
            pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
            tmpdb.create_db(pw.name)
            tmpdb.add_cert(cert, nickname, 'C,,')

            try:
                tmpdb.verify_ca_cert_validity(nickname)
            except ValueError, e:
                raise admintool.ScriptError(
                    "Not a valid CA certificate: %s (visit "
                    "http://www.freeipa.org/page/Troubleshooting for "
                    "troubleshooting guide)" % e)

        trust_flags = options.trust_flags
        if ((set(trust_flags) - set(',CPTcgpuw'))
                or len(trust_flags.split(',')) != 3):