From 47aba4a996d8f44c58a2e738b28ddacabc78afd9 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 6 Jan 2023 16:51:07 +0100 Subject: [PATCH] crypto: prevent creation of duplicate self-signed default certs Signed-off-by: Jens Langhammer --- authentik/core/tests/utils.py | 4 ++-- authentik/crypto/api.py | 3 +-- authentik/crypto/apps.py | 20 ++++++-------------- authentik/crypto/builder.py | 4 ++-- authentik/crypto/tests.py | 12 ++++++------ 5 files changed, 17 insertions(+), 26 deletions(-) diff --git a/authentik/core/tests/utils.py b/authentik/core/tests/utils.py index 3da47f87b..ad6942d80 100644 --- a/authentik/core/tests/utils.py +++ b/authentik/core/tests/utils.py @@ -47,11 +47,11 @@ def create_test_tenant() -> Tenant: def create_test_cert(use_ec_private_key=False) -> CertificateKeyPair: """Generate a certificate for testing""" builder = CertificateBuilder( + name=f"{generate_id()}.self-signed.goauthentik.io", use_ec_private_key=use_ec_private_key, ) - builder.common_name = "goauthentik.io" builder.build( - subject_alt_names=["goauthentik.io"], + subject_alt_names=[f"{generate_id()}.self-signed.goauthentik.io"], validity_days=360, ) builder.common_name = generate_id() diff --git a/authentik/crypto/api.py b/authentik/crypto/api.py index 88fe2153e..6ffc517d2 100644 --- a/authentik/crypto/api.py +++ b/authentik/crypto/api.py @@ -236,8 +236,7 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet): data = CertificateGenerationSerializer(data=request.data) if not data.is_valid(): return Response(data.errors, status=400) - builder = CertificateBuilder() - builder.common_name = data.validated_data["common_name"] + builder = CertificateBuilder(data.validated_data["common_name"]) builder.build( subject_alt_names=data.validated_data.get("subject_alt_name", "").split(","), validity_days=int(data.validated_data["validity_days"]), diff --git a/authentik/crypto/apps.py b/authentik/crypto/apps.py index 44449773d..559ca3db5 100644 --- a/authentik/crypto/apps.py +++ b/authentik/crypto/apps.py @@ -27,20 +27,16 @@ class AuthentikCryptoConfig(ManagedAppConfig): from authentik.crypto.builder import CertificateBuilder from authentik.crypto.models import CertificateKeyPair - builder = CertificateBuilder() - builder.common_name = "goauthentik.io" + builder = CertificateBuilder("authentik Internal JWT Certificate") builder.build( subject_alt_names=["goauthentik.io"], validity_days=360, ) if not cert: - cert = CertificateKeyPair() - cert.certificate_data = builder.certificate - cert.key_data = builder.private_key - cert.name = "authentik Internal JWT Certificate" - cert.managed = MANAGED_KEY - cert.save() + builder.cert = cert + builder.cert.managed = MANAGED_KEY + builder.save() def reconcile_managed_jwt_cert(self): """Ensure managed JWT certificate""" @@ -63,10 +59,6 @@ class AuthentikCryptoConfig(ManagedAppConfig): name = "authentik Self-signed Certificate" if CertificateKeyPair.objects.filter(name=name).exists(): return - builder = CertificateBuilder() + builder = CertificateBuilder(name) builder.build(subject_alt_names=[f"{generate_id()}.self-signed.goauthentik.io"]) - CertificateKeyPair.objects.create( - name="authentik Self-signed Certificate", - certificate_data=builder.certificate, - key_data=builder.private_key, - ) + builder.save() diff --git a/authentik/crypto/builder.py b/authentik/crypto/builder.py index 98d391412..ecdc68df1 100644 --- a/authentik/crypto/builder.py +++ b/authentik/crypto/builder.py @@ -21,13 +21,13 @@ class CertificateBuilder: _use_ec_private_key: bool - def __init__(self, use_ec_private_key=False): + def __init__(self, name: str, use_ec_private_key=False): self._use_ec_private_key = use_ec_private_key self.__public_key = None self.__private_key = None self.__builder = None self.__certificate = None - self.common_name = "authentik Self-signed Certificate" + self.common_name = name self.cert = CertificateKeyPair() def save(self) -> CertificateKeyPair: diff --git a/authentik/crypto/tests.py b/authentik/crypto/tests.py index 3231f277b..2e537bca4 100644 --- a/authentik/crypto/tests.py +++ b/authentik/crypto/tests.py @@ -14,7 +14,7 @@ from authentik.crypto.builder import CertificateBuilder from authentik.crypto.models import CertificateKeyPair from authentik.crypto.tasks import MANAGED_DISCOVERED, certificate_discovery from authentik.lib.config import CONFIG -from authentik.lib.generators import generate_key +from authentik.lib.generators import generate_id, generate_key from authentik.providers.oauth2.models import OAuth2Provider @@ -54,8 +54,8 @@ class TestCrypto(APITestCase): def test_builder(self): """Test Builder""" - builder = CertificateBuilder() - builder.common_name = "test-cert" + name = generate_id() + builder = CertificateBuilder(name) with self.assertRaises(ValueError): builder.save() builder.build( @@ -64,7 +64,7 @@ class TestCrypto(APITestCase): ) instance = builder.save() now = datetime.datetime.today() - self.assertEqual(instance.name, "test-cert") + self.assertEqual(instance.name, name) self.assertEqual((instance.certificate.not_valid_after - now).days, 2) def test_builder_api(self): @@ -193,8 +193,8 @@ class TestCrypto(APITestCase): def test_discovery(self): """Test certificate discovery""" - builder = CertificateBuilder() - builder.common_name = "test-cert" + name = generate_id() + builder = CertificateBuilder(name) with self.assertRaises(ValueError): builder.save() builder.build(