crypto: prevent creation of duplicate self-signed default certs

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2023-01-06 16:51:07 +01:00
parent 643b36b732
commit 47aba4a996
No known key found for this signature in database
5 changed files with 17 additions and 26 deletions

View file

@ -47,11 +47,11 @@ def create_test_tenant() -> Tenant:
def create_test_cert(use_ec_private_key=False) -> CertificateKeyPair: def create_test_cert(use_ec_private_key=False) -> CertificateKeyPair:
"""Generate a certificate for testing""" """Generate a certificate for testing"""
builder = CertificateBuilder( builder = CertificateBuilder(
name=f"{generate_id()}.self-signed.goauthentik.io",
use_ec_private_key=use_ec_private_key, use_ec_private_key=use_ec_private_key,
) )
builder.common_name = "goauthentik.io"
builder.build( builder.build(
subject_alt_names=["goauthentik.io"], subject_alt_names=[f"{generate_id()}.self-signed.goauthentik.io"],
validity_days=360, validity_days=360,
) )
builder.common_name = generate_id() builder.common_name = generate_id()

View file

@ -236,8 +236,7 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
data = CertificateGenerationSerializer(data=request.data) data = CertificateGenerationSerializer(data=request.data)
if not data.is_valid(): if not data.is_valid():
return Response(data.errors, status=400) return Response(data.errors, status=400)
builder = CertificateBuilder() builder = CertificateBuilder(data.validated_data["common_name"])
builder.common_name = data.validated_data["common_name"]
builder.build( builder.build(
subject_alt_names=data.validated_data.get("subject_alt_name", "").split(","), subject_alt_names=data.validated_data.get("subject_alt_name", "").split(","),
validity_days=int(data.validated_data["validity_days"]), validity_days=int(data.validated_data["validity_days"]),

View file

@ -27,20 +27,16 @@ class AuthentikCryptoConfig(ManagedAppConfig):
from authentik.crypto.builder import CertificateBuilder from authentik.crypto.builder import CertificateBuilder
from authentik.crypto.models import CertificateKeyPair from authentik.crypto.models import CertificateKeyPair
builder = CertificateBuilder() builder = CertificateBuilder("authentik Internal JWT Certificate")
builder.common_name = "goauthentik.io"
builder.build( builder.build(
subject_alt_names=["goauthentik.io"], subject_alt_names=["goauthentik.io"],
validity_days=360, validity_days=360,
) )
if not cert: if not cert:
cert = CertificateKeyPair() cert = CertificateKeyPair()
cert.certificate_data = builder.certificate builder.cert = cert
cert.key_data = builder.private_key builder.cert.managed = MANAGED_KEY
cert.name = "authentik Internal JWT Certificate" builder.save()
cert.managed = MANAGED_KEY
cert.save()
def reconcile_managed_jwt_cert(self): def reconcile_managed_jwt_cert(self):
"""Ensure managed JWT certificate""" """Ensure managed JWT certificate"""
@ -63,10 +59,6 @@ class AuthentikCryptoConfig(ManagedAppConfig):
name = "authentik Self-signed Certificate" name = "authentik Self-signed Certificate"
if CertificateKeyPair.objects.filter(name=name).exists(): if CertificateKeyPair.objects.filter(name=name).exists():
return return
builder = CertificateBuilder() builder = CertificateBuilder(name)
builder.build(subject_alt_names=[f"{generate_id()}.self-signed.goauthentik.io"]) builder.build(subject_alt_names=[f"{generate_id()}.self-signed.goauthentik.io"])
CertificateKeyPair.objects.create( builder.save()
name="authentik Self-signed Certificate",
certificate_data=builder.certificate,
key_data=builder.private_key,
)

View file

@ -21,13 +21,13 @@ class CertificateBuilder:
_use_ec_private_key: bool _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._use_ec_private_key = use_ec_private_key
self.__public_key = None self.__public_key = None
self.__private_key = None self.__private_key = None
self.__builder = None self.__builder = None
self.__certificate = None self.__certificate = None
self.common_name = "authentik Self-signed Certificate" self.common_name = name
self.cert = CertificateKeyPair() self.cert = CertificateKeyPair()
def save(self) -> CertificateKeyPair: def save(self) -> CertificateKeyPair:

View file

@ -14,7 +14,7 @@ from authentik.crypto.builder import CertificateBuilder
from authentik.crypto.models import CertificateKeyPair from authentik.crypto.models import CertificateKeyPair
from authentik.crypto.tasks import MANAGED_DISCOVERED, certificate_discovery from authentik.crypto.tasks import MANAGED_DISCOVERED, certificate_discovery
from authentik.lib.config import CONFIG 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 from authentik.providers.oauth2.models import OAuth2Provider
@ -54,8 +54,8 @@ class TestCrypto(APITestCase):
def test_builder(self): def test_builder(self):
"""Test Builder""" """Test Builder"""
builder = CertificateBuilder() name = generate_id()
builder.common_name = "test-cert" builder = CertificateBuilder(name)
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
builder.save() builder.save()
builder.build( builder.build(
@ -64,7 +64,7 @@ class TestCrypto(APITestCase):
) )
instance = builder.save() instance = builder.save()
now = datetime.datetime.today() 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) self.assertEqual((instance.certificate.not_valid_after - now).days, 2)
def test_builder_api(self): def test_builder_api(self):
@ -193,8 +193,8 @@ class TestCrypto(APITestCase):
def test_discovery(self): def test_discovery(self):
"""Test certificate discovery""" """Test certificate discovery"""
builder = CertificateBuilder() name = generate_id()
builder.common_name = "test-cert" builder = CertificateBuilder(name)
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
builder.save() builder.save()
builder.build( builder.build(