Exemple #1
0
    def make_intermediate_certificate(self):
        int_key = Key().create_key("rsa", 4096)
        subject = DistinguishedNameFactory(
            countryName=self.root_certificate.dn.countryName,
            stateOrProvinceName=self.root_certificate.dn.stateOrProvinceName,
            organizationName=self.root_certificate.dn.organizationName,
            commonName="BounCA test Int CA",
        )
        int_certificate = CertificateFactory(
            expires_at=arrow.get(timezone.now()).shift(days=+5).date(),
            name="test_server_intermediate_certificate",
            type=CertificateTypes.INTERMEDIATE,
            parent=self.root_certificate,
            dn=subject,
        )

        int_certificate.save()

        int_certhandler = Certificate()
        int_certhandler.create_certificate(int_certificate,
                                           int_key.serialize())

        crt = int_certhandler.certificate
        return crt, crt.public_bytes(
            encoding=serialization.Encoding.PEM).decode("utf8")
Exemple #2
0
 def test_intermediate_dn_organization_difference(self):
     dn_ca = DistinguishedNameFactory(
         countryName="NL",
         stateOrProvinceName="Noord-Holland",
         localityName="Amsterdam",
         organizationName="Repleo",
         organizationalUnitName="IT Department",
         emailAddress="*****@*****.**",
         commonName="test.bounca.org",
         subjectAltNames=["demo.bounca.org"],
     )
     dn_im = DistinguishedNameFactory(
         countryName="NL",
         stateOrProvinceName="Noord-Holland",
         localityName="Amsterdam",
         organizationName="BJA Electronics",
         organizationalUnitName="IT Department",
         emailAddress="*****@*****.**",
         commonName="test.bounca.org",
         subjectAltNames=["demo.bounca.org"],
     )
     ca = CertificateFactory(type=CertificateTypes.ROOT, dn=dn_ca)
     ca.save()
     cert = CertificateFactory(type=CertificateTypes.INTERMEDIATE,
                               parent=ca,
                               dn=dn_im)
     with self.assertRaises(ValidationError) as c:
         cert.save()
     self.assertEqual(
         c.exception.message,
         "Organization Name of Intermediate CA and Root CA should match (policy strict)"
     )
Exemple #3
0
    def test_generate_server_certificate_parent_server_cert(self):
        server_subject = DistinguishedNameFactory(subjectAltNames=None)
        certificate = CertificateFactory(
            type=CertificateTypes.SERVER_CERT,
            name="test_generate_server_certificate_parent_server_cert_1",
            parent=self.int_certificate,
            dn=server_subject,
            crl_distribution_url=None,
            ocsp_distribution_host=None,
        )
        with mute_signals(signals.post_save):
            certificate.save()
        certhandler = Certificate()
        certhandler.create_certificate(certificate, self.key.serialize())

        keystore = KeyStore(certificate=certificate)
        keystore.crt = certhandler.serialize()
        keystore.key = self.key.serialize()
        keystore.save()

        server_subject = DistinguishedNameFactory()
        with self.assertRaises(CertificateError) as context:
            certificate_request = CertificateFactory(
                type=CertificateTypes.SERVER_CERT,
                name="test_generate_server_certificate_parent_server_cert_2",
                parent=certificate,
                dn=server_subject,
            )
            certhandler = Certificate()
            certhandler.create_certificate(certificate_request,
                                           self.key.serialize())

        self.assertEqual("A root or intermediate parent is expected",
                         str(context.exception))
Exemple #4
0
    def test_generate_ocsp_certificate_parent_client_cert(self):
        ocsp_subject = DistinguishedNameFactory(subjectAltNames=None)
        certificate = CertificateFactory(
            type=CertificateTypes.OCSP,
            name="test_generate_client_certificate_parent_ocsp_cert_1",
            parent=self.int_certificate,
            dn=ocsp_subject,
            crl_distribution_url=None,
            ocsp_distribution_host=None,
        )
        certificate.save()
        certhandler = Certificate()
        certhandler.create_certificate(certificate, self.key.serialize())

        client_subject = DistinguishedNameFactory()
        with self.assertRaises(CertificateError) as context:
            certificate_request = CertificateFactory(
                type=CertificateTypes.OCSP,
                name="test_generate_client_certificate_parent_ocsp_cert_2",
                parent=certificate,
                dn=client_subject,
            )
            certhandler = Certificate()
            certhandler.create_certificate(certificate_request,
                                           self.key.serialize())

        self.assertEqual("A root or intermediate parent is expected",
                         str(context.exception))
Exemple #5
0
    def test_revocation_list_builder_one_cert_passphrase(self):
        subject = DistinguishedNameFactory(
            countryName=self.root_certificate.dn.countryName,
            stateOrProvinceName=self.root_certificate.dn.stateOrProvinceName,
            organizationName=self.root_certificate.dn.organizationName,
            commonName="BounCA test Int passphrase CA",
        )
        int_certificate = CertificateFactory(
            expires_at=arrow.get(timezone.now()).shift(days=+5).date(),
            name="test_server_intermediate_certificate_pass",
            type=CertificateTypes.INTERMEDIATE,
            parent=self.root_certificate,
            dn=subject,
        )

        with mute_signals(signals.post_save):
            int_certificate.save()
        int_key = Key().create_key("rsa", 4096)
        int_certhandler = Certificate()
        int_certhandler.create_certificate(int_certificate,
                                           int_key.serialize())

        keystore = KeyStore(certificate=int_certificate)
        keystore.crt = int_certhandler.serialize()
        keystore.key = int_key.serialize(passphrase="testphrase")
        keystore.save()

        crl = revocation_list_builder([], int_certificate, "testphrase")
        self.assert_subject(crl.issuer, int_certificate)
Exemple #6
0
    def test_generate_client_certificate_minimal(self):
        client_subject = DistinguishedNameFactory(
            countryName=None,
            stateOrProvinceName=None,
            localityName=None,
            organizationName=None,
            organizationalUnitName=None,
            emailAddress=None,
            subjectAltNames=None,
            commonName="client cert",
        )
        certificate = CertificateFactory(
            type=CertificateTypes.CLIENT_CERT,
            name="test_generate_client_certificate_minimal",
            parent=self.int_certificate,
            dn=client_subject,
            crl_distribution_url=None,
            ocsp_distribution_host=None,
        )
        certificate.save()
        certhandler = Certificate()
        certhandler.create_certificate(certificate, self.key.serialize())

        crt = certhandler.certificate

        # basicConstraints = CA:FALSE
        # keyUsage = critical, digitalSignature, keyEncipherment
        self.assert_user_certificate(crt, content_commitment=True)

        # authorityKeyIdentifier = keyid:always, issuer
        self.assert_authority_key(crt,
                                  self.int_key,
                                  issuer_certificate=self.int_certificate,
                                  critical=False)

        # subjectKeyIdentifier = hash
        self.assert_hash(crt)

        # extendedKeyUsage = serverAuth
        self.assert_extension(
            crt,
            ExtensionOID.EXTENDED_KEY_USAGE,
            [
                ExtendedKeyUsageOID.CLIENT_AUTH,
                ExtendedKeyUsageOID.EMAIL_PROTECTION
            ],
        )

        # crlDistributionPoints
        self.assert_crl_distribution(crt, self.int_certificate)

        # OCSP
        # authorityInfoAccess = OCSP;URI:{{cert.ocsp_distribution_host}}
        self.assert_oscp(crt, self.int_certificate)

        # subject
        self.assert_subject(crt.subject, certificate)
        # issuer
        self.assert_subject(crt.issuer, self.int_certificate)
Exemple #7
0
    def test_passphrase_out_not_matching(self):
        cert = CertificateFactory(type=CertificateTypes.ROOT)
        cert.passphrase_out = "test"
        cert.passphrase_out_confirmation = "test2"

        with self.assertRaises(ValidationError) as c:
            cert.save()
        self.assertEqual(c.exception.message,
                         "The two passphrase fields didn't match.")
Exemple #8
0
 def test_generate_root_certificate_unique_violate_name(self):
     cert = CertificateFactory()
     cert.type = CertificateTypes.ROOT
     cert.name = "repleo root ca 1"
     cert.save()
     cert = CertificateFactory()
     cert.type = CertificateTypes.ROOT
     cert.name = "repleo root ca 1"
     with self.assertRaises(ValidationError):
         cert.save()
Exemple #9
0
 def test_parent_not_allowed_for_root_certificate(self):
     ca = CertificateFactory(type=CertificateTypes.ROOT)
     ca.save()
     cert = CertificateFactory(type=CertificateTypes.ROOT, parent=ca)
     cert.type = CertificateTypes.ROOT
     cert.name = "repleo root ca 1"
     with self.assertRaises(ValidationError) as c:
         cert.save()
     self.assertEqual(
         c.exception.message,
         "Not allowed to have a parent certificate for a Root CA certificate"
     )
Exemple #10
0
 def test_ocsp_cert_parent_is_not_intermediate_parent(self):
     ca = CertificateFactory(type=CertificateTypes.ROOT)
     ca.save()
     cert = CertificateFactory(type=CertificateTypes.OCSP,
                               parent=ca,
                               crl_distribution_url=None,
                               ocsp_distribution_host=None)
     with self.assertRaises(ValidationError) as c:
         cert.save()
     self.assertEqual(
         c.exception.message,
         "OCSP certificate can only be generated for intermediate CA parent"
     )
Exemple #11
0
    def test_generate_intermediate_certificate_passphrase(self):
        root_key = Key().create_key("ed25519", None)
        root_certificate = CertificateFactory(
            expires_at=arrow.get(timezone.now()).shift(days=+3).date(),
            name="root_test_generate_intermediate_certificate_passphrase",
        )
        with mute_signals(signals.post_save):
            root_certificate.save()
        root_certhandler = Certificate()
        root_certhandler.create_certificate(
            root_certificate,
            root_key.serialize(passphrase="SecretRootPP"),
            passphrase="SecretRootPP")
        keystore = KeyStore(certificate=root_certificate)
        keystore.crt = root_certhandler.serialize()
        keystore.key = root_key.serialize(passphrase="SecretRootPP")
        keystore.save()

        subject = DistinguishedNameFactory(
            countryName=root_certificate.dn.countryName,
            stateOrProvinceName=root_certificate.dn.stateOrProvinceName,
            organizationName=root_certificate.dn.organizationName,
            localityName=root_certificate.dn.localityName,
        )

        certificate_request = CertificateFactory(
            type=CertificateTypes.INTERMEDIATE,
            name="test_generate_intermediate_certificate_passphrase",
            parent=root_certificate,
            dn=subject,
        )
        certhandler = Certificate()
        certhandler.create_certificate(
            certificate_request,
            self.key.serialize(passphrase="SecretPP"),
            passphrase="SecretPP",
            passphrase_issuer="SecretRootPP",
        )

        crt = certhandler.certificate
        # subject
        self.assert_subject(crt.subject, certificate_request)
        self.assertEqual(
            subject.localityName,
            crt.subject.get_attributes_for_oid(NameOID.LOCALITY_NAME)[0].value)

        # issuer
        self.assert_subject(crt.issuer, root_certificate)
        self.assertEqual(
            subject.localityName,
            crt.subject.get_attributes_for_oid(NameOID.LOCALITY_NAME)[0].value)
Exemple #12
0
    def test_generate_intermediate_certificate(self):
        subject = DistinguishedNameFactory(
            countryName=self.root_certificate.dn.countryName,
            stateOrProvinceName=self.root_certificate.dn.stateOrProvinceName,
            organizationName=self.root_certificate.dn.organizationName,
            localityName="Amsterdam",
        )

        certificate_request = CertificateFactory(
            type=CertificateTypes.INTERMEDIATE,
            name="test_generate_intermediate_certificate",
            parent=self.root_certificate,
            dn=subject,
            crl_distribution_url="https://example.com/crl/cert.crl.pem",
            ocsp_distribution_host="https://example.com/ocsp/",
        )
        certificate_request.save()
        certhandler = Certificate()
        certhandler.create_certificate(certificate_request,
                                       self.key.serialize())
        crt = certhandler.certificate

        self.assert_basic_information(crt, certificate_request)

        # subject
        self.assert_subject(crt.subject, certificate_request)
        self.assertEqual(
            "Amsterdam",
            crt.subject.get_attributes_for_oid(NameOID.LOCALITY_NAME)[0].value)

        # issuer
        self.assert_subject(crt.issuer, self.root_certificate)
        self.assertEqual(
            "Amsterdam",
            crt.subject.get_attributes_for_oid(NameOID.LOCALITY_NAME)[0].value)

        self.assert_intermediate_authority(crt)

        # authorityKeyIdentifier = keyid:always, issuer
        self.assert_authority_key(crt, self.root_key, None, critical=False)

        # subjectKeyIdentifier = hash
        self.assert_hash(crt)

        # crlDistributionspoints
        self.assert_crl_distribution(crt, self.root_certificate)

        # OCSP
        # authorityInfoAccess = OCSP;URI:{{cert.ocsp_distribution_host}}
        self.assert_oscp(crt, self.root_certificate)
Exemple #13
0
 def test_days_valid(self):
     dn_ca = DistinguishedNameFactory(
         countryName="NL",
         stateOrProvinceName="Noord-Holland",
         localityName="Amsterdam",
         organizationName="Repleo",
         organizationalUnitName="IT Department",
         emailAddress="*****@*****.**",
         commonName="test.bounca.org",
         subjectAltNames=["demo.bounca.org"],
     )
     cert = CertificateFactory(dn=dn_ca, type=CertificateTypes.ROOT)
     cert.expires_at = arrow.get(timezone.now()).shift(years=+10).date()
     self.assertEqual(cert.days_valid, 3652)
     cert.save()
     cert.refresh_from_db()
     self.assertEqual(cert.days_valid, 3652)
Exemple #14
0
 def test_set_name_to_common_name(self):
     dn_ca = DistinguishedNameFactory(
         countryName="NL",
         stateOrProvinceName="Noord-Holland",
         localityName="Amsterdam",
         organizationName="Repleo",
         organizationalUnitName="IT Department",
         emailAddress="*****@*****.**",
         commonName="test.bounca.org",
         subjectAltNames=["demo.bounca.org"],
     )
     cert = CertificateFactory(name="",
                               dn=dn_ca,
                               type=CertificateTypes.ROOT)
     cert.save()
     cert.refresh_from_db()
     self.assertEqual(cert.name, cert.dn.commonName)
     self.assertEqual(cert.slug_name, "testbouncaorg")
Exemple #15
0
    def test_parent_object_not_set(self):
        subject = DistinguishedNameFactory(
            countryName=self.root_certificate.dn.countryName,
            stateOrProvinceName=self.root_certificate.dn.stateOrProvinceName,
            organizationName=self.root_certificate.dn.organizationName,
            localityName=self.root_certificate.dn.localityName,
            commonName="ca test repleo",
        )
        root_certificate = CertificateFactory(
            expires_at=arrow.get(timezone.now()).shift(days=+3).date(),
            name="root_test_parent_object_not_set",
            dn=subject,
        )
        with mute_signals(signals.post_save):
            root_certificate.save()
        certificate = Certificate()
        certificate.create_certificate(root_certificate,
                                       self.root_key.serialize())

        keystore = KeyStore(certificate=root_certificate)
        keystore.crt = ""
        keystore.key = self.root_key.serialize()
        keystore.save(full_clean=False)

        key = Key().create_key("ed25519", None)
        subject_int = DistinguishedNameFactory(
            countryName=self.root_certificate.dn.countryName,
            stateOrProvinceName=self.root_certificate.dn.stateOrProvinceName,
            organizationName=self.root_certificate.dn.organizationName,
            localityName=self.root_certificate.dn.localityName,
            commonName="ca int test repleo",
        )
        certificate = CertificateFactory(
            type=CertificateTypes.INTERMEDIATE,
            name="test_parent_object_not_set",
            parent=root_certificate,
            dn=subject_int,
        )
        with self.assertRaises(RuntimeError) as context:
            certhandler = Certificate()
            certhandler.create_certificate(certificate, key.serialize())
        self.assertEqual("Parent certificate object has not been set",
                         str(context.exception))
Exemple #16
0
    def test_generate_intermediate_certificate_passphrase_wrong_issuer_passphrase(
            self):
        root_key = Key().create_key("ed25519", None)
        root_certificate = CertificateFactory(
            expires_at=arrow.get(timezone.now()).shift(days=+3).date(),
            name="root_test_certificate_passphrase_wrong_issuer_passphrase",
        )
        with mute_signals(signals.post_save):
            root_certificate.save()
        root_certhandler = Certificate()
        root_certhandler.create_certificate(
            root_certificate,
            root_key.serialize(passphrase="SecretRootPP"),
            passphrase="SecretRootPP")

        keystore = KeyStore(certificate=root_certificate)
        keystore.crt = root_certhandler.serialize()
        keystore.key = root_key.serialize(passphrase="SecretRootPP")
        keystore.save()

        subject = DistinguishedNameFactory(
            countryName=root_certificate.dn.countryName,
            stateOrProvinceName=root_certificate.dn.stateOrProvinceName,
            organizationName=root_certificate.dn.organizationName,
        )

        certificate = CertificateFactory(
            type=CertificateTypes.INTERMEDIATE,
            name="test_certificate_passphrase_wrong_issuer_passphrase",
            parent=root_certificate,
            dn=subject,
        )
        certhandler = Certificate()
        with self.assertRaisesMessage(
                PassPhraseError,
                "Bad passphrase, could not decode issuer key"):
            certhandler.create_certificate(
                certificate,
                self.key.serialize(passphrase="SecretPP"),
                passphrase="SecretPP",
                passphrase_issuer="SecretRootPPInvalid",
            )
Exemple #17
0
 def test_generate_root_certificate_unique_violate_dn(self):
     dn_ca = DistinguishedNameFactory(
         countryName="NL",
         stateOrProvinceName="Noord-Holland",
         localityName="Amsterdam",
         organizationName="Repleo",
         organizationalUnitName="IT Department",
         emailAddress="*****@*****.**",
         commonName="test.bounca.org",
         subjectAltNames=["demo.bounca.org"],
     )
     cert = CertificateFactory()
     cert.dn = dn_ca
     cert.type = CertificateTypes.ROOT
     cert.name = "repleo root ca 1"
     cert.save()
     cert = CertificateFactory()
     cert.dn = dn_ca
     cert.type = CertificateTypes.ROOT
     cert.name = "repleo root ca 2"
     with self.assertRaises(ValidationError):
         cert.save()
Exemple #18
0
    def test_generate_intermediate_certificate_minimal(self):
        key = Key().create_key("rsa", 4096)

        subject = DistinguishedNameFactory(
            organizationalUnitName=None,
            emailAddress=None,
            localityName=None,
            countryName=self.root_certificate.dn.countryName,
            stateOrProvinceName=self.root_certificate.dn.stateOrProvinceName,
            organizationName=self.root_certificate.dn.organizationName,
        )

        certificate_request = CertificateFactory(
            type=CertificateTypes.INTERMEDIATE,
            name="test_generate_intermediate_certificate_minimal",
            parent=self.root_certificate,
            dn=subject,
        )
        certificate_request.save()
        certhandler = Certificate()
        certhandler.create_certificate(certificate_request, key.serialize())
        crt = certhandler.certificate
        self.assertEqual(crt.public_key().public_numbers(),
                         key.key.public_key().public_numbers())

        # subject
        self.assert_subject(crt.subject, certificate_request)
        self.assertListEqual([],
                             crt.subject.get_attributes_for_oid(
                                 NameOID.LOCALITY_NAME))

        # issuer
        self.assert_subject(crt.issuer, self.root_certificate)
        self.assertListEqual([],
                             crt.subject.get_attributes_for_oid(
                                 NameOID.LOCALITY_NAME))
Exemple #19
0
 def test_child_expire_date_exceeds_parent_expire_date(self):
     dn_ca = DistinguishedNameFactory(
         countryName="NL",
         stateOrProvinceName="Noord-Holland",
         localityName="Amsterdam",
         organizationName="Repleo",
         organizationalUnitName="IT Department",
         emailAddress="*****@*****.**",
         commonName="test.bounca.org",
         subjectAltNames=["demo.bounca.org"],
     )
     dn_im = DistinguishedNameFactory(
         countryName="NL",
         stateOrProvinceName="Noord-Holland",
         localityName="Amsterdam",
         organizationName="Repleo",
         organizationalUnitName="IT Department",
         emailAddress="*****@*****.**",
         commonName="test.bounca.org",
         subjectAltNames=["demo.bounca.org"],
     )
     ca = CertificateFactory(type=CertificateTypes.ROOT, dn=dn_ca)
     ca.expires_at = arrow.get(timezone.now()).shift(years=+10).date()
     ca.save()
     cert = CertificateFactory(type=CertificateTypes.INTERMEDIATE,
                               parent=ca,
                               dn=dn_im)
     cert.expires_at = arrow.get(timezone.now()).shift(years=+20).date()
     with self.assertRaises(ValidationError) as c:
         cert.save()
     self.assertEqual(
         c.exception.message,
         "Child Certificate (expire date: {}) should not "
         "expire later than parent CA (expire date: {})".format(
             cert.expires_at, ca.expires_at),
     )
Exemple #20
0
 def test_parent_intermediate_has_no_root_parent(self):
     cert = CertificateFactory(type=CertificateTypes.INTERMEDIATE)
     with self.assertRaises(ValidationError) as c:
         cert.save()
     self.assertEqual(c.exception.message,
                      "Non Root certificate should have a parent")
Exemple #21
0
    def test_serialize_pkcs12_cas_nopassphrase(self):
        root_key = Key().create_key("ed25519", None)
        subject = DistinguishedNameFactory(countryName="NL",
                                           stateOrProvinceName="Noord Holland",
                                           organizationName="Repleo")

        root_certificate = CertificateFactory(
            dn=subject,
            name="test_server_root_certificate",
            expires_at=arrow.get(timezone.now()).shift(days=+30).date())

        with mute_signals(signals.post_save):
            root_certificate.save()
        root_certhandler = Certificate()
        root_certhandler.create_certificate(root_certificate,
                                            root_key.serialize())
        keystore = KeyStore(certificate=root_certificate)
        keystore.crt = root_certhandler.serialize()
        keystore.key = root_key.serialize()
        keystore.save()

        int_key = Key().create_key("rsa", 2048)
        subject = DistinguishedNameFactory(
            countryName=root_certificate.dn.countryName,
            stateOrProvinceName=root_certificate.dn.stateOrProvinceName,
            organizationName=root_certificate.dn.organizationName,
        )
        int_certificate = CertificateFactory(
            expires_at=arrow.get(timezone.now()).shift(days=+5).date(),
            name="test_server_intermediate_certificate",
            type=CertificateTypes.INTERMEDIATE,
            parent=root_certificate,
            dn=subject,
            crl_distribution_url="https://example.com/crl/cert.crl.pem",
            ocsp_distribution_host="https://example.com/ocsp/",
        )

        with mute_signals(signals.post_save):
            int_certificate.save()

        int_certhandler = Certificate()
        int_certhandler.create_certificate(int_certificate,
                                           int_key.serialize())

        keystore = KeyStore(certificate=int_certificate)
        keystore.crt = int_certhandler.serialize()
        keystore.key = int_key.serialize()
        keystore.save()

        pkcs12 = int_key.serialize_pkcs12("test_pkcs12_cas",
                                          int_certhandler.certificate,
                                          cas=[root_certhandler.certificate])
        pkcs12_obj = load_pkcs12(pkcs12, None)

        self.assertEqual(pkcs12_obj.key.key_size, 2048)
        self.assertEqual(pkcs12_obj.cert.friendly_name.decode("utf-8"),
                         "test_pkcs12_cas")
        self.assertEqual(pkcs12_obj.cert.certificate.serial_number,
                         int_certhandler.certificate.serial_number)
        self.assertEqual(
            pkcs12_obj.additional_certs[0].certificate.serial_number,
            root_certhandler.certificate.serial_number)