From 7517d612d02612082ca4f262fd41adf7bbf91cef Mon Sep 17 00:00:00 2001 From: Jens L Date: Thu, 8 Sep 2022 23:30:05 +0200 Subject: [PATCH] providers/oauth2: add x5c (#3556) * add x5c, x5t and x5t#S256 Signed-off-by: Jens Langhammer * strip trailing = to fix encoding issues Signed-off-by: Jens Langhammer Signed-off-by: Jens Langhammer --- authentik/providers/oauth2/views/jwks.py | 28 +++++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/authentik/providers/oauth2/views/jwks.py b/authentik/providers/oauth2/views/jwks.py index a0b406ab3..e996bc8fe 100644 --- a/authentik/providers/oauth2/views/jwks.py +++ b/authentik/providers/oauth2/views/jwks.py @@ -1,12 +1,14 @@ """authentik OAuth2 JWKS Views""" -from base64 import urlsafe_b64encode +from base64 import b64encode, urlsafe_b64encode from typing import Optional +from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric.ec import ( EllipticCurvePrivateKey, EllipticCurvePublicKey, ) from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey, RSAPublicKey +from cryptography.hazmat.primitives.serialization import Encoding from django.http import HttpRequest, HttpResponse, JsonResponse from django.shortcuts import get_object_or_404 from django.views import View @@ -30,12 +32,13 @@ class JWKSView(View): def get_jwk_for_key(self, key: CertificateKeyPair) -> Optional[dict]: """Convert a certificate-key pair into JWK""" private_key = key.private_key + key_data = None if not private_key: - return None + return key_data if isinstance(private_key, RSAPrivateKey): public_key: RSAPublicKey = private_key.public_key() public_numbers = public_key.public_numbers() - return { + key_data = { "kty": "RSA", "alg": JWTAlgorithms.RS256, "use": "sig", @@ -43,10 +46,10 @@ class JWKSView(View): "n": b64_enc(public_numbers.n), "e": b64_enc(public_numbers.e), } - if isinstance(private_key, EllipticCurvePrivateKey): + elif isinstance(private_key, EllipticCurvePrivateKey): public_key: EllipticCurvePublicKey = private_key.public_key() public_numbers = public_key.public_numbers() - return { + key_data = { "kty": "EC", "alg": JWTAlgorithms.ES256, "use": "sig", @@ -54,7 +57,20 @@ class JWKSView(View): "n": b64_enc(public_numbers.n), "e": b64_enc(public_numbers.e), } - return None + else: + return key_data + key_data["x5c"] = [b64encode(key.certificate.public_bytes(Encoding.DER)).decode("utf-8")] + key_data["x5t"] = ( + urlsafe_b64encode(key.certificate.fingerprint(hashes.SHA1())) # nosec + .decode("utf-8") + .rstrip("=") + ) + key_data["x5t#S256"] = ( + urlsafe_b64encode(key.certificate.fingerprint(hashes.SHA256())) + .decode("utf-8") + .rstrip("=") + ) + return key_data def get(self, request: HttpRequest, application_slug: str) -> HttpResponse: """Show JWK Key data for Provider"""