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))
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))
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)" )
def setUpTestData(cls): cls.root_key = Key().create_key("rsa", 4096) subject = DistinguishedNameFactory( countryName="NL", stateOrProvinceName="Noord Holland", organizationName="Repleo", commonName="BounCA test CA", ) cls.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): cls.root_certificate.save() root_certhandler = Certificate() root_certhandler.create_certificate(cls.root_certificate, cls.root_key.serialize()) keystore = KeyStore(certificate=cls.root_certificate) keystore.crt = root_certhandler.serialize() keystore.key = cls.root_key.serialize() keystore.save() cls.int_key = Key().create_key("rsa", 4096) subject = DistinguishedNameFactory( countryName=cls.root_certificate.dn.countryName, stateOrProvinceName=cls.root_certificate.dn.stateOrProvinceName, organizationName=cls.root_certificate.dn.organizationName, commonName="BounCA test Int CA", ) cls.int_certificate = CertificateFactory( expires_at=arrow.get(timezone.now()).shift(days=+5).date(), name="test_server_intermediate_certificate", type=CertificateTypes.INTERMEDIATE, parent=cls.root_certificate, dn=subject, ) with mute_signals(signals.post_save): cls.int_certificate.save() int_certhandler = Certificate() int_certhandler.create_certificate(cls.int_certificate, cls.int_key.serialize()) keystore = KeyStore(certificate=cls.int_certificate) keystore.crt = int_certhandler.serialize() keystore.key = cls.int_key.serialize() keystore.save() cls.key = Key().create_key("rsa", 4096)
def setUpTestData(cls): cls.root_key = Key().create_key("ed25519", None) subject = DistinguishedNameFactory(countryName="NL", stateOrProvinceName="Noord Holland", organizationName="Repleo") cls.root_certificate = CertificateFactory( dn=subject, name="test client root certificate", expires_at=arrow.get(timezone.now()).shift(days=+30).date()) with mute_signals(signals.post_save): cls.root_certificate.save() root_certhandler = Certificate() root_certhandler.create_certificate(cls.root_certificate, cls.root_key.serialize()) keystore = KeyStore(certificate=cls.root_certificate) keystore.crt = root_certhandler.serialize() keystore.key = cls.root_key.serialize() keystore.save() cls.int_key = Key().create_key("ed25519", None) subject = DistinguishedNameFactory( countryName=cls.root_certificate.dn.countryName, stateOrProvinceName=cls.root_certificate.dn.stateOrProvinceName, organizationName=cls.root_certificate.dn.organizationName, ) cls.int_certificate = CertificateFactory( expires_at=arrow.get(timezone.now()).shift(days=+5).date(), name="test ocsp intermediate certificate", type=CertificateTypes.INTERMEDIATE, parent=cls.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): cls.int_certificate.save() int_certhandler = Certificate() int_certhandler.create_certificate(cls.int_certificate, cls.int_key.serialize()) keystore = KeyStore(certificate=cls.int_certificate) keystore.crt = int_certhandler.serialize() keystore.key = cls.int_key.serialize() keystore.save() cls.key = Key().create_key("ed25519", None)
def test_distinguished_name_to_dn(self): dn = DistinguishedNameFactory( countryName="NL", stateOrProvinceName="Noord-Holland", localityName="Amsterdam", organizationName="Repleo", organizationalUnitName="IT Department", emailAddress="*****@*****.**", commonName="test.bounca.org", subjectAltNames=["demo.bounca.org"], ) self.assertEqual( dn.dn, "CN=test.bounca.org, O=Repleo, OU=IT Department, L=Amsterdam, ST=Noord-Holland, " "[email protected], C=NL", ) self.assertEqual( dn.subj, "/CN=test.bounca.org/O=Repleo/OU=IT Department/L=Amsterdam/ST=Noord-Holland" "/[email protected]/C=NL", ) self.assertEqual(dn.countryName, "NL") self.assertEqual(dn.stateOrProvinceName, "Noord-Holland") self.assertEqual(dn.localityName, "Amsterdam") self.assertEqual(dn.organizationName, "Repleo") self.assertEqual(dn.organizationalUnitName, "IT Department") self.assertEqual(dn.emailAddress, "*****@*****.**") self.assertEqual(dn.commonName, "test.bounca.org") self.assertEqual(dn.subjectAltNames, ["demo.bounca.org"]) self.assertEqual(dn.slug_commonName, "testbouncaorg")
def test_generate_minimal_root_ca(self): dn = DistinguishedNameFactory(organizationalUnitName=None, emailAddress=None, localityName=None) certificate_request = CertificateFactory(dn=dn) 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) # issuer self.assertIsInstance(crt.issuer, x509.Name) self.assert_subject(crt.issuer, certificate_request) self.assert_root_authority(crt) # authorityKeyIdentifier = keyid:always, issuer self.assert_authority_key(crt, self.key) # subjectKeyIdentifier = hash self.assert_hash(crt)
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")
def test_generate_intermediate_certificate_not_matching_countryName(self): subject = DistinguishedNameFactory( countryName="DE", stateOrProvinceName=self.root_certificate.dn.stateOrProvinceName, organizationName=self.root_certificate.dn.organizationName, ) self.root_ca_not_matching_attribute(subject, "countryName")
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)
def test_generate_server_certificate_no_intermediate_ca(self): server_subject = DistinguishedNameFactory(subjectAltNames=None) certificate = CertificateFactory(type=CertificateTypes.SERVER_CERT, parent=self.root_certificate, dn=server_subject) certhandler = Certificate() certhandler.create_certificate(certificate, self.key.serialize()) crt = certhandler.certificate self.assertEqual(crt.serial_number, int(certificate.serial)) self.assertEqual(crt.public_key().public_numbers(), self.key.key.public_key().public_numbers()) # extendedKeyUsage = serverAuth self.assert_extension(crt, ExtensionOID.EXTENDED_KEY_USAGE, [ExtendedKeyUsageOID.SERVER_AUTH]) # subject self.assert_subject(crt.subject, certificate) # issuer self.assert_subject(crt.issuer, self.root_certificate) # authorityKeyIdentifier = keyid:always, issuer self.assert_authority_key(crt, self.root_key, issuer_certificate=self.root_certificate, critical=False) # subjectKeyIdentifier = hash self.assert_hash(crt, critical=False)
def setUpTestData(cls): cls.root_dn = DistinguishedNameFactory( countryName="NL", stateOrProvinceName="Noord-Holland", localityName="Amsterdam", organizationName="Repleo", organizationalUnitName="IT Department", emailAddress="*****@*****.**", commonName="ca.bounca.org", subjectAltNames=["demo.bounca.org"], ) cls.user = UserFactory() cls.ca = Certificate() cls.ca.type = CertificateTypes.ROOT cls.ca.name = "repleo root ca" cls.ca.dn = cls.root_dn cls.ca.expires_at = arrow.get(timezone.now()).shift(years=+10).date() cls.ca.revoked_at = None cls.ca.owner = cls.user cls.ca.save() cls.ca.refresh_from_db() cls.ca = Certificate.objects.get(pk=cls.ca.pk) cls.int_dn = DistinguishedNameFactory( countryName="NL", stateOrProvinceName="Noord-Holland", localityName="Amsterdam", organizationName="Repleo", organizationalUnitName="IT Department", emailAddress="*****@*****.**", commonName="int.bounca.org", subjectAltNames=["demo.bounca.org"], ) cls.int = Certificate(parent=cls.ca) cls.int.type = CertificateTypes.INTERMEDIATE cls.int.name = "repleo int ca" cls.int.dn = cls.int_dn cls.int.crl_distribution_url = "https://ca.demo.repleo.nl/crl/test.crl.pem" cls.int.ocsp_distribution_host = "https://ca.demo.repleo.nl/ocsp" cls.int.expires_at = arrow.get(timezone.now()).shift(years=+5).date() cls.int.revoked_at = None cls.int.owner = cls.user cls.int.save() cls.int.refresh_from_db()
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)
def test_distinguished_name_validation_in_future_not_allowed(self): dn = DistinguishedNameFactory( countryName="NL", stateOrProvinceName="Noord-Holland", localityName="Amsterdam", organizationName="Repleo", organizationalUnitName="IT Department", emailAddress="*****@*****.**", commonName="test.bounca.org", subjectAltNames=["demo.bounca.org"], ) dn = DistinguishedName.objects.get(id=dn.id) dn.commonName = "www.bounca.org" with self.assertRaises(ValidationError) as c: dn.save() self.assertEqual(c.exception.message, "Not allowed to update a DistinguishedName record")
def test_generate_server_certificate(self): server_subject = DistinguishedNameFactory(subjectAltNames=[ "www.repleo.nl", "*.bounca.org", "www.mac-usb-serial.com", "127.0.0.1" ]) certificate = CertificateFactory( type=CertificateTypes.SERVER_CERT, name="test_generate_server_certificate", parent=self.int_certificate, dn=server_subject, ) certhandler = Certificate() certhandler.create_certificate(certificate, self.key.serialize()) crt = certhandler.certificate # basicConstraints = CA:FALSE # keyUsage = critical, digitalSignature, keyEncipherment self.assert_user_certificate(crt) # 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, critical=False) # extendedKeyUsage = serverAuth self.assert_extension(crt, ExtensionOID.EXTENDED_KEY_USAGE, [ExtendedKeyUsageOID.SERVER_AUTH]) # subjectAltName = @alt_names self.assert_extension( crt, ExtensionOID.SUBJECT_ALTERNATIVE_NAME, [ DNSName("www.repleo.nl"), DNSName("*.bounca.org"), DNSName("www.mac-usb-serial.com"), IPAddress(IPv4Address("127.0.0.1")), ], ) # 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)
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))
def test_distinguished_name_factory(self): dn = DistinguishedNameFactory() self.assertIsNotNone(dn.countryName) self.assertIsNotNone(dn.stateOrProvinceName) self.assertIsNotNone(dn.localityName) self.assertIsNotNone(dn.organizationName) self.assertIsNotNone(dn.organizationalUnitName) self.assertIsNotNone(dn.emailAddress) self.assertIsNotNone(dn.commonName) self.assertIsNotNone(dn.subjectAltNames)
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)
def test_generate_server_certificate(self): dn = DistinguishedNameFactory( countryName="NL", stateOrProvinceName="Noord-Holland", localityName="Amsterdam", organizationName="Repleo", organizationalUnitName="IT Department", emailAddress="*****@*****.**", commonName="www.repleo.nl", subjectAltNames=["repleo.nl"], ) cert = Certificate(parent=self.int, dn=dn) cert.type = CertificateTypes.SERVER_CERT cert.name = "www.repleo.nl" cert.dn = dn cert.expires_at = arrow.get(timezone.now()).shift(years=+1).date() cert.revoked_at = None cert.owner = self.user cert.save() cert.refresh_from_db() self.assertEqual( cert.dn.dn, "CN=www.repleo.nl, O=Repleo, OU=IT Department, " "L=Amsterdam, ST=Noord-Holland, [email protected], C=NL", ) self.assertEqual(cert.type, CertificateTypes.SERVER_CERT) self.assertEqual(cert.name, "www.repleo.nl") self.assertEqual(cert.created_at, arrow.get(cert.expires_at).shift(years=-1).date()) self.assertEqual(cert.expires_at, arrow.get(cert.created_at).shift(years=+1).date()) self.assertIsNone(cert.revoked_at) self.assertEqual(cert.owner, self.user) self.assertEqual(cert.revoked_uuid, UUID(int=0)) self.assertNotEqual(cert.serial, 0) self.assertIsNone(cert.slug_revoked_at) self.assertFalse(cert.revoked) self.assertFalse(cert.expired) with self.assertRaises(ObjectDoesNotExist) as c: cert.crlstore self.assertEqual(str(c.exception), "Certificate has no crlstore.") cert.delete() cert.refresh_from_db() self.assertIsNotNone(cert.revoked_at) self.assertIsNotNone(cert.slug_revoked_at) self.assertNotEqual(cert.revoked_uuid, UUID(int=0))
def test_generate_client_certificate(self): client_subject = DistinguishedNameFactory( subjectAltNames=["jeroen", "*****@*****.**"]) certificate = CertificateFactory(type=CertificateTypes.CLIENT_CERT, parent=self.int_certificate, dn=client_subject) 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, critical=False) # extendedKeyUsage = clientAuth, emailProtection self.assert_extension( crt, ExtensionOID.EXTENDED_KEY_USAGE, [ ExtendedKeyUsageOID.CLIENT_AUTH, ExtendedKeyUsageOID.EMAIL_PROTECTION ], ) # subjectAltName = @alt_names self.assert_extension( crt, ExtensionOID.SUBJECT_ALTERNATIVE_NAME, [RFC822Name("jeroen"), RFC822Name("*****@*****.**")]) # 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)
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)
def test_generate_server_certificate_no_parent(self): server_subject = DistinguishedNameFactory() with self.assertRaises(CertificateError) as context: certificate_request = CertificateFactory( type=CertificateTypes.SERVER_CERT, name="test_generate_server_certificate_no_parent", parent=None, dn=server_subject, ) certhandler = Certificate() certhandler.create_certificate(certificate_request, self.key.serialize()) self.assertEqual("A parent certificate is expected", str(context.exception))
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), )
def test_generate_intermediate_certificate(self): dn = DistinguishedNameFactory( countryName="NL", stateOrProvinceName="Noord-Holland", localityName="Amsterdam", organizationName="Repleo", organizationalUnitName="IT Department", emailAddress="*****@*****.**", commonName="test.bounca.org", subjectAltNames=["demo.bounca.org"], ) cert = Certificate(parent=self.ca) cert.type = CertificateTypes.INTERMEDIATE cert.name = "repleo int ca1" cert.dn = dn cert.crl_distribution_url = "https://ca.demo.repleo.nl/crl/test.crl.pem" cert.ocsp_distribution_host = "https://ca.demo.repleo.nl/ocsp" cert.expires_at = arrow.get(timezone.now()).shift(years=+5).date() cert.revoked_at = None cert.owner = self.user cert.save() cert.refresh_from_db() self.assertEqual( cert.dn.dn, "CN=test.bounca.org, O=Repleo, OU=IT Department, " "L=Amsterdam, ST=Noord-Holland, [email protected], C=NL", ) self.assertEqual(cert.type, CertificateTypes.INTERMEDIATE) self.assertEqual(cert.name, "repleo int ca1") self.assertEqual(cert.crl_distribution_url, "https://ca.demo.repleo.nl/crl/test.crl.pem") self.assertEqual(cert.ocsp_distribution_host, "https://ca.demo.repleo.nl/ocsp") self.assertEqual(cert.created_at, arrow.get(cert.expires_at).shift(years=-5).date()) self.assertEqual(cert.expires_at, arrow.get(cert.created_at).shift(years=+5).date()) self.assertIsNone(cert.revoked_at) self.assertEqual(cert.owner, self.user) self.assertEqual(cert.revoked_uuid, UUID(int=0)) self.assertNotEqual(cert.serial, 0) self.assertIsNone(cert.slug_revoked_at) self.assertFalse(cert.revoked) self.assertFalse(cert.expired) self.assertIsNotNone(cert.crlstore.crl)
def test_parent_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, ) certificate = CertificateFactory(type=CertificateTypes.INTERMEDIATE, name="test_parent_object_not_set", parent=None, dn=subject) with self.assertRaises(RuntimeError) as context: certhandler = Certificate() certhandler.create_certificate(certificate, self.key.serialize()) self.assertEqual("Parent certificate is required", str(context.exception))
def test_generate_ocsp_certificate(self): dn = DistinguishedNameFactory( countryName="NL", stateOrProvinceName="Noord-Holland", localityName="Amsterdam", organizationName="Repleo", organizationalUnitName="IT Department", emailAddress="*****@*****.**", commonName="ca.demo.repleo.nl", ) cert = Certificate(parent=self.int, dn=dn) cert.type = CertificateTypes.OCSP cert.name = "ca.demo.repleo.nl" cert.dn = dn cert.expires_at = arrow.get(timezone.now()).shift(years=+1).date() cert.revoked_at = None cert.owner = self.user cert.save() cert.refresh_from_db() self.assertEqual( cert.dn.dn, "CN=https://ca.demo.repleo.nl/ocsp, O=Repleo, OU=IT Department, " "L=Amsterdam, ST=Noord-Holland, [email protected], C=NL", ) self.assertEqual(cert.type, CertificateTypes.OCSP) self.assertEqual(cert.name, "https://ca.demo.repleo.nl/ocsp") self.assertEqual(cert.created_at, arrow.get(cert.expires_at).shift(years=-1).date()) self.assertEqual(cert.expires_at, arrow.get(cert.created_at).shift(years=+1).date()) self.assertIsNone(cert.revoked_at) self.assertEqual(cert.owner, self.user) self.assertEqual(cert.revoked_uuid, UUID(int=0)) self.assertNotEqual(cert.serial, 0) self.assertIsNone(cert.slug_revoked_at) self.assertFalse(cert.revoked) self.assertFalse(cert.expired) with self.assertRaises(ValidationError) as c: cert.generate_crl() self.assertEqual( c.exception.message, "CRL File can only be generated for Intermediate Certificates")
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)
def test_generate_server_certificate_no_subject_altnames(self): server_subject = DistinguishedNameFactory(subjectAltNames=None) certificate = CertificateFactory(type=CertificateTypes.SERVER_CERT, parent=self.int_certificate, dn=server_subject) certhandler = Certificate() certhandler.create_certificate(certificate, self.key.serialize()) crt = certhandler.certificate self.assertEqual(crt.serial_number, int(certificate.serial)) self.assertEqual(crt.public_key().public_numbers(), self.key.key.public_key().public_numbers()) with self.assertRaises(ExtensionNotFound): crt.extensions.get_extension_for_oid( ExtensionOID.SUBJECT_ALTERNATIVE_NAME)
def test_generate_client_certificate_no_intermediate_ca(self): client_subject = DistinguishedNameFactory(subjectAltNames=None) certificate = CertificateFactory(type=CertificateTypes.CLIENT_CERT, parent=self.root_certificate, dn=client_subject) certhandler = Certificate() certhandler.create_certificate(certificate, self.key.serialize()) crt = certhandler.certificate self.assertEqual(crt.serial_number, int(certificate.serial)) self.assertEqual( crt.public_key().public_bytes( encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw), self.key.key.public_key().public_bytes( encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw), ) # extendedKeyUsage = serverAuth self.assert_extension( crt, ExtensionOID.EXTENDED_KEY_USAGE, [ ExtendedKeyUsageOID.CLIENT_AUTH, ExtendedKeyUsageOID.EMAIL_PROTECTION ], ) # subject self.assert_subject(crt.subject, certificate) # issuer self.assert_subject(crt.issuer, self.root_certificate) # authorityKeyIdentifier = keyid:always, issuer self.assert_authority_key(crt, self.root_key, issuer_certificate=self.root_certificate, critical=False) # subjectKeyIdentifier = hash self.assert_hash(crt, critical=False)
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")