Exemple #1
0
def load_pem_certificate(cert):
    """Abstract load PEM certificate by IPA version"""
    if version.NUM_VERSION < 40600:
        return x509.load_certificate(cert, x509.PEM)
    elif version.NUM_VERSION < 40700:
        return x509.load_pem_x509_certificate(cert)
    else:
        return x509.load_pem_x509_certificate(bytes(cert, 'utf-8'))
 def test_cert_rsa4096(self):
     ca_pem = self.master.get_file_contents(
         paths.IPA_CA_CRT, encoding=None
     )
     cert = load_pem_x509_certificate(ca_pem)
     assert cert.public_key().key_size == 4096
     assert cert.signature_hash_algorithm.name == hashes.SHA512.name
Exemple #3
0
    def test_switch_to_external_ca(self):

        result = self.master.run_command(
            [paths.IPA_CACERT_MANAGE, 'renew', '--external-ca'])
        assert result.returncode == 0

        # Sign CA, transport it to the host and get ipa a root ca paths.
        root_ca_fname, ipa_ca_fname = tasks.sign_ca_and_transport(
            self.master, paths.IPA_CA_CSR, ROOT_CA, IPA_CA)

        # renew CA with externally signed one
        result = self.master.run_command([
            paths.IPA_CACERT_MANAGE, 'renew',
            '--external-cert-file={}'.format(ipa_ca_fname),
            '--external-cert-file={}'.format(root_ca_fname)
        ])
        assert result.returncode == 0

        # update IPA certificate databases
        result = self.master.run_command([paths.IPA_CERTUPDATE])
        assert result.returncode == 0

        # Check if external CA have "C" flag after the switch
        result = check_CA_flag(self.master)
        assert bool(result), ('External CA does not have "C" flag')

        # Check that ldap entries for the CA have been updated
        remote_cacrt = self.master.get_file_contents(ipa_ca_fname)
        cacrt = ipa_x509.load_pem_x509_certificate(remote_cacrt)
        verify_caentry(self.master, cacrt)
Exemple #4
0
    def _get_vaultconfig(self, force_refresh=False):
        config = None
        if not force_refresh:
            config = _kra_config_cache.load(self.api.env.domain)
        if config is None:
            # vaultconfig_show also caches data
            response = self.api.Command.vaultconfig_show()
            config = response['result']
            transport_cert = x509.load_der_x509_certificate(
                config['transport_cert'])
        else:
            # cached JSON uses PEM-encoded ASCII string
            transport_cert = x509.load_pem_x509_certificate(
                config['transport_cert'].encode('ascii'))

        default_algo = config.get('wrapping_default_algorithm')
        if default_algo is None:
            # old server
            wrapping_algo = constants.VAULT_WRAPPING_AES128_CBC
        elif default_algo in constants.VAULT_WRAPPING_SUPPORTED_ALGOS:
            # try to use server default
            wrapping_algo = default_algo
        else:
            # prefer server's sorting order
            for algo in config['wrapping_supported_algorithms']:
                if algo in constants.VAULT_WRAPPING_SUPPORTED_ALGOS:
                    wrapping_algo = algo
                    break
            else:
                raise errors.ValidationError(
                    "No overlapping wrapping algorithm between server and "
                    "client.")
        return transport_cert, wrapping_algo
Exemple #5
0
    def test_install_master(self):
        result = tasks.install_master(self.master)
        assert result.returncode == 0

        # Check the content of the ldap entries for the CA
        remote_cacrt = self.master.get_file_contents(paths.IPA_CA_CRT)
        cacrt = ipa_x509.load_pem_x509_certificate(remote_cacrt)
        verify_caentry(self.master, cacrt)
Exemple #6
0
 def get_cert_from_db(self, nickname):
     """
     Retrieve a certificate from the current NSS database for nickname.
     """
     try:
         args = ["-L", "-n", nickname, "-a"]
         result = self.run_certutil(args, capture_output=True)
         return x509.load_pem_x509_certificate(result.raw_output)
     except ipautil.CalledProcessError:
         return None
def check_pkinit_cert_issuer(host, issuer):
    """Ensures that the PKINIT cert is signed by the expected issuer"""
    data = host.get_file_contents(paths.KDC_CERT)
    pkinit_cert = x509.load_pem_x509_certificate(data)
    # Make sure that the issuer is the expected one
    assert DN(pkinit_cert.issuer) == DN(issuer)
    # KDC cert must have SAN for KDC hostname
    assert host.hostname in pkinit_cert.san_a_label_dns_names
    # at least three SANs, profile adds UPN and KRB principal name
    assert len(pkinit_cert.san_general_names) >= 3
Exemple #8
0
 def get_cert_from_db(self, nickname):
     """
     Retrieve a certificate from the current NSS database for nickname.
     """
     try:
         args = ["-L", "-n", nickname, "-a"]
         result = self.run_certutil(args, capture_output=True)
         return x509.load_pem_x509_certificate(result.raw_output)
     except ipautil.CalledProcessError:
         return None
    def test_http_cert(self):
        """
        Test that HTTP certificate contains ipa-ca.$DOMAIN
        DNS name.

        """
        data = self.master.get_file_contents(paths.HTTPD_CERT_FILE)
        cert = x509.load_pem_x509_certificate(data)
        name = f'ipa-ca.{self.master.domain.name}'
        assert crypto_x509.DNSName(name) in cert.san_general_names
def load_cert_from_str(cert):
    cert = cert.strip()
    if not cert.startswith("-----BEGIN CERTIFICATE-----"):
        cert = "-----BEGIN CERTIFICATE-----\n" + cert
    if not cert.endswith("-----END CERTIFICATE-----"):
        cert += "\n-----END CERTIFICATE-----"

    if load_pem_x509_certificate is not None:
        cert = load_pem_x509_certificate(cert.encode('utf-8'))
    else:
        cert = load_certificate(cert.encode('utf-8'))
    return cert
Exemple #11
0
    def test_long_oid(self):
        """
        Test cerificate with very long OID. In this case we are using a
        certificate from an opened case where one of X509v3 Certificate`s
        Policies OID is longer then 80 chars.
        """
        cert = x509.load_pem_x509_certificate(long_oid_cert)
        ext = cert.extensions.get_extension_for_class(
            crypto_x509.CertificatePolicies)

        assert len(ext.value) == 1
        assert ext.value[0].policy_identifier.dotted_string == (
            u'1.3.6.1.4.1.311.21.8.8950086.10656446.2706058.12775672.480128.'
            '147.13466065.13029902')
Exemple #12
0
    def test_3_cert_contents(self):
        """
        Test the contents of a certificate
        """
        # Verify certificate contents. This exercises python-cryptography
        # more than anything but confirms our usage of it.

        not_before = datetime.datetime(2010, 6, 25, 13, 0, 42)
        not_after = datetime.datetime(2015, 6, 25, 13, 0, 42)
        cert = x509.load_pem_x509_certificate(goodcert_headers)

        assert DN(cert.subject) == DN(('CN', 'ipa.example.com'), ('O', 'IPA'))
        assert DN(cert.issuer) == DN(('CN', 'IPA Test Certificate Authority'))
        assert cert.serial_number == 1093
        assert cert.not_valid_before == not_before
        assert cert.not_valid_after == not_after
Exemple #13
0
    def test_3_cert_contents(self):
        """
        Test the contents of a certificate
        """
        # Verify certificate contents. This exercises python-cryptography
        # more than anything but confirms our usage of it.

        not_before = datetime.datetime(2010, 6, 25, 13, 0, 42)
        not_after = datetime.datetime(2015, 6, 25, 13, 0, 42)
        cert = x509.load_pem_x509_certificate(goodcert_headers)

        assert DN(cert.subject) == DN(('CN', 'ipa.example.com'), ('O', 'IPA'))
        assert DN(cert.issuer) == DN(('CN', 'IPA Test Certificate Authority'))
        assert cert.serial_number == 1093
        assert cert.not_valid_before == not_before
        assert cert.not_valid_after == not_after
Exemple #14
0
 def test_ipa_demo_letsencrypt(self):
     cert = x509.load_pem_x509_certificate(ipa_demo_crt)
     assert DN(cert.subject) == DN('CN=ipa.demo1.freeipa.org')
     assert DN(cert.issuer) == DN(
         "CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US")
     assert cert.serial_number == 0x03ad42a2a5ada59a131327cb0979623cb605
     not_before = datetime.datetime(2018, 7, 25, 5, 36, 59)
     not_after = datetime.datetime(2018, 10, 23, 5, 36, 59)
     assert cert.not_valid_before == not_before
     assert cert.not_valid_after == not_after
     assert cert.san_general_names == [DNSName('ipa.demo1.freeipa.org')]
     assert cert.san_a_label_dns_names == ['ipa.demo1.freeipa.org']
     assert cert.extended_key_usage == {
         '1.3.6.1.5.5.7.3.1', '1.3.6.1.5.5.7.3.2'
     }
     assert cert.extended_key_usage_bytes == (
         b'0 \x06\x03U\x1d%\x01\x01\xff\x04\x160\x14\x06\x08+\x06\x01'
         b'\x05\x05\x07\x03\x01\x06\x08+\x06\x01\x05\x05\x07\x03\x02')
Exemple #15
0
    def test_1_load_base64_cert(self):
        """
        Test loading a base64-encoded certificate.
        """

        # Load a good cert
        x509.load_pem_x509_certificate(goodcert_headers)

        # Load a good cert with headers and leading text
        newcert = (b'leading text\n' + goodcert_headers)
        x509.load_pem_x509_certificate(newcert)

        # Load a good cert with bad headers
        newcert = b'-----BEGIN CERTIFICATE-----' + goodcert_headers
        with pytest.raises((TypeError, ValueError)):
            x509.load_pem_x509_certificate(newcert)

        # Load a bad cert
        with pytest.raises(ValueError):
            x509.load_pem_x509_certificate(badcert)
Exemple #16
0
    def test_1_load_base64_cert(self):
        """
        Test loading a base64-encoded certificate.
        """

        # Load a good cert
        x509.load_pem_x509_certificate(goodcert_headers)

        # Load a good cert with headers and leading text
        newcert = (
            b'leading text\n' + goodcert_headers)
        x509.load_pem_x509_certificate(newcert)

        # Load a good cert with bad headers
        newcert = b'-----BEGIN CERTIFICATE-----' + goodcert_headers
        with pytest.raises((TypeError, ValueError)):
            x509.load_pem_x509_certificate(newcert)

        # Load a bad cert
        with pytest.raises(ValueError):
            x509.load_pem_x509_certificate(badcert)
def decode_certificate(cert):
    """
    Decode a certificate using base64.

    It also takes FreeIPA versions into account and returns a IPACertificate
    for newer IPA versions.
    """
    if hasattr(x509, "IPACertificate"):
        cert = cert.strip()
        if not cert.startswith("-----BEGIN CERTIFICATE-----"):
            cert = "-----BEGIN CERTIFICATE-----\n" + cert
        if not cert.endswith("-----END CERTIFICATE-----"):
            cert += "\n-----END CERTIFICATE-----"

        if load_pem_x509_certificate is not None:
            cert = load_pem_x509_certificate(cert.encode('utf-8'))
        else:
            cert = load_certificate(cert.encode('utf-8'))
    else:
        cert = base64.b64decode(cert)
    return cert
Exemple #18
0
    def test_3_cert_contents(self):
        """
        Test the contents of a certificate
        """
        # Verify certificate contents. This exercises python-cryptography
        # more than anything but confirms our usage of it.

        not_before = datetime.datetime(2010, 6, 25, 13, 0, 42)
        not_after = datetime.datetime(2015, 6, 25, 13, 0, 42)
        cert = x509.load_pem_x509_certificate(goodcert_headers)

        assert DN(cert.subject) == DN(('CN', 'ipa.example.com'), ('O', 'IPA'))
        assert DN(cert.issuer) == DN(('CN', 'IPA Test Certificate Authority'))
        assert cert.serial_number == 1093
        assert cert.not_valid_before == not_before
        assert cert.not_valid_after == not_after
        assert cert.san_general_names == []
        assert cert.san_a_label_dns_names == []
        assert cert.extended_key_usage == {'1.3.6.1.5.5.7.3.1'}
        assert cert.extended_key_usage_bytes == (
            b'0\x16\x06\x03U\x1d%\x01\x01\xff\x04\x0c0\n\x06\x08'
            b'+\x06\x01\x05\x05\x07\x03\x01')
Exemple #19
0
 def test_cert_rsa4096(self):
     ca_pem = self.master.get_file_contents(paths.IPA_CA_CRT, encoding=None)
     cert = load_pem_x509_certificate(ca_pem)
     assert cert.public_key().key_size == 4096
def check_pkinit_cert_issuer(host, issuer):
    """Ensures that the PKINIT cert is signed by the expected issuer"""
    data = host.get_file_contents(paths.KDC_CERT)
    pkinit_cert = x509.load_pem_x509_certificate(data)
    # Make sure that the issuer is the expected one
    assert DN(pkinit_cert.issuer) == DN(issuer)
Exemple #21
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")
Exemple #22
0
 def test_cert_rsa4096(self):
     ca_pem = self.master.get_file_contents(paths.IPA_CA_CRT, encoding=None)
     cert = load_pem_x509_certificate(ca_pem)
     assert cert.public_key().key_size == 4096
     assert cert.signature_hash_algorithm.name == hashes.SHA512.name
Exemple #23
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")
Exemple #24
0
 def test_x509_v1_cert(self):
     with pytest.raises(ValueError):
         x509.load_pem_x509_certificate(v1_cert)