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 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_private_key(self): keyhandler = Key() keyhandler.create_key("ed25519", None) data = b"testdata" signature = keyhandler.key.sign(data) pkey = keyhandler.key.public_key() self.assertIsNotNone(pkey) # would throw InvalidSignature if not correct pkey.verify(signature, data) self.assertIsNotNone(keyhandler.key)
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 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 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_store_keys_no_passphrase(self): key = Key() key.create_key("ed25519", None) pem = key.serialize() key = Key() prvkey = key.load(pem) self.assertIsInstance(prvkey.key, ed25519.Ed25519PrivateKey)
def test_store_keys_no_passphrase(self): key = Key() key.create_key("rsa", 2048) pem = key.serialize() key = Key() prvkey = key.load(pem) self.assertIsInstance(prvkey.key, rsa.RSAPrivateKey) self.assertEqual(prvkey.key.key_size, 2048)
def test_store_keys_wrong_passphrase(self): key = Key() key.create_key("rsa", 2048) pem = key.serialize("test_store_keys_wrong_passphrase") with self.assertRaisesMessage(ValueError, "Bad decrypt. Incorrect password?"): key.load(pem, "test_store_keys_passphrase")
def _get_issuer_key(cert_request, passphrase_issuer): issuer_key = None try: if cert_request.parent: issuer_key = Key().load(cert_request.parent.keystore.key, passphrase_issuer) except ValueError: raise PassPhraseError( "Bad passphrase, could not decode issuer key") return issuer_key
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_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", )
def setUpTestData(cls): with mute_signals(signals.post_save): cls.root_key = Key().create_key("rsa", 4096) subject = DistinguishedNameFactory( countryName="NL", stateOrProvinceName="Noord Holland", organizationName="Repleo") cls.root_certificate = CertificateFactory( dn=subject, expires_at=arrow.get(timezone.now()).shift(days=+3).date()) cls.root_certificate.save() certificate = Certificate() key = cls.root_key.serialize() certificate.create_certificate(cls.root_certificate, key) keystore = KeyStore(certificate=cls.root_certificate) keystore.crt = certificate.serialize() keystore.key = key keystore.save() cls.key = Key().create_key("rsa", 4096)
def test_serialize_keys_passphrase(self): key = Key() key.create_key("rsa", 4096) pem = key.serialize("test_store_keys_passphrase") prvkey = key.load(pem, "test_store_keys_passphrase") self.assertIsInstance(prvkey.key, rsa.RSAPrivateKey) self.assertEqual(prvkey.key.key_size, 4096)
def generate_certificate(sender, instance, created, **kwargs): if created: keystore = KeyStore(certificate=instance) key_size = None if settings.KEY_ALGORITHM == "rsa": key_size = 4096 if instance.type in [ CertificateTypes.ROOT, CertificateTypes.INTERMEDIATE ] else 2048 key = KeyGenerator().create_key(settings.KEY_ALGORITHM, key_size) keystore.key = key.serialize(instance.passphrase_out) certhandler = CertificateGenerator() certhandler.create_certificate(instance, keystore.key, instance.passphrase_out, instance.passphrase_issuer) keystore.crt = certhandler.serialize() if instance.type not in [ CertificateTypes.ROOT, CertificateTypes.INTERMEDIATE ]: root_certificate = CertificateGenerator().load( instance.parent.keystore.crt).certificate int_certificate = CertificateGenerator().load( instance.parent.keystore.crt).certificate keystore.p12 = key.serialize_pkcs12( instance.name, certhandler.certificate, instance.passphrase_out, cas=[int_certificate, root_certificate]) keystore.save() if instance.type in [ CertificateTypes.ROOT, CertificateTypes.INTERMEDIATE ]: crl = revocation_list_builder([], instance, instance.passphrase_out) crlstore = CrlStore(certificate=instance) crlstore.crl = serialize(crl) crlstore.save()
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))
def revocation_list_builder( certificates: List[Tuple[str, datetime.datetime]], issuer_cert: CertificateType, passphrase: str = None, last_update: datetime.datetime = None, next_update: datetime.datetime = None, ) -> CertificateRevocationList: """ Create certificate revocation list Arguments: certificates - The certificates in tuples with revocation date ca - The authority certificate (pem bytes) key - The authority private key (pem bytes) passphrase - The passphrase of the key of the certificate Returns: The certificate revocation list object """ try: ca_key = Key().load(issuer_cert.keystore.key, passphrase) except ValueError: raise PassPhraseError("Bad passphrase, could not decode private key") one_day = datetime.timedelta(1, 0, 0) builder = x509.CertificateRevocationListBuilder() builder = builder.issuer_name(Certificate.build_subject_names(issuer_cert)) last_update = datetime.datetime.now( tz=pytz.UTC) if not last_update else last_update next_update = datetime.datetime.now( tz=pytz.UTC) + one_day if not next_update else next_update builder = builder.last_update(last_update) builder = builder.next_update(next_update) for pem, timestamp in certificates: revoked_cert = revocation_builder(pem, timestamp) builder = builder.add_revoked_certificate(revoked_cert) algorithm = None if isinstance( ca_key.key, (ed25519.Ed25519PrivateKey, ed448.Ed448PrivateKey)) else hashes.SHA256() crl = builder.sign( private_key=ca_key.key, algorithm=algorithm, ) return crl
def test_serialize_pkcs12_nopassphrase(self): subject = DistinguishedNameFactory( localityName="Amsterdam", organizationalUnitName="BounCA Root", ) key = Key() key.create_key("rsa", 4096) certificate_request = CertificateFactory(dn=subject) certhandler = Certificate() certhandler.create_certificate(certificate_request, key.serialize()) crt = certhandler.certificate pkcs12 = key.serialize_pkcs12("test_pkcs12", crt) pkcs12_obj = load_pkcs12(pkcs12, None) self.assertEqual(pkcs12_obj.key.key_size, 4096) self.assertEqual(pkcs12_obj.cert.friendly_name.decode("utf-8"), "test_pkcs12") self.assertEqual(pkcs12_obj.cert.certificate.serial_number, crt.serial_number)
def test_generate_private_key_2048(self): keyhandler = Key() keyhandler.create_key("rsa", 2048) self.assertEqual(keyhandler.key.key_size, 2048) pkey = keyhandler.key.public_key() self.assertIsInstance(pkey.public_numbers(), rsa.RSAPublicNumbers)
def test_serialize_pkcs12_no_certificate(self): key = Key() key.create_key("rsa", 4096) with self.assertRaisesMessage(ValueError, "No certificate provided"): key.serialize_pkcs12("test_pkcs12", None)
def test_serialize_pkcs12_no_key(self): key = Key() with self.assertRaisesMessage(RuntimeError, "No key object"): key.serialize_pkcs12("test_pkcs12", None)
def test_check_passphrase_invalid(self): key = Key() key.create_key("rsa", 2048) pem = key.serialize("test_check_passphrase_invalid") self.assertFalse(key.check_passphrase(pem, "check_passphrase"))
def test_check_passphrase_invalid(self): key = Key() key.create_key("ed25519", None) pem = key.serialize("test_check_passphrase_invalid") self.assertFalse(key.check_passphrase(pem, "check_passphrase"))
def test_store_keys_no_object(self): key = Key() with self.assertRaisesMessage(RuntimeError, "No key object"): key.serialize("test_store_keys_passphrase")
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)
def _get_key(key, passphrase): try: return Key().load(key, passphrase) except ValueError: raise PassPhraseError( "Bad passphrase, could not decode private key")
def test_generate_private_key_4096(self): prvkey = Key().create_key("rsa", 4096) self.assertEqual(prvkey.key.key_size, 4096) pkey = prvkey.key.public_key() self.assertIsInstance(pkey.public_numbers(), rsa.RSAPublicNumbers)
def setUpTestData(cls): cls.key = Key().create_key("rsa", 8192)