Skip to content

Commit

Permalink
providers/oauth2: properly support P-384 and P-521 keys (#13317)
Browse files Browse the repository at this point in the history
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
  • Loading branch information
rissson authored Feb 28, 2025
1 parent d0d4629 commit 7e7fc75
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 10 deletions.
29 changes: 23 additions & 6 deletions authentik/providers/oauth2/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
from typing import Any
from urllib.parse import urlparse, urlunparse

from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
from cryptography.hazmat.primitives.asymmetric.ec import (
SECP256R1,
SECP384R1,
SECP521R1,
EllipticCurvePrivateKey,
)
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes
from dacite import Config
Expand Down Expand Up @@ -114,6 +119,22 @@ class JWTAlgorithms(models.TextChoices):
HS256 = "HS256", _("HS256 (Symmetric Encryption)")
RS256 = "RS256", _("RS256 (Asymmetric Encryption)")
ES256 = "ES256", _("ES256 (Asymmetric Encryption)")
ES384 = "ES384", _("ES384 (Asymmetric Encryption)")
ES512 = "ES512", _("ES512 (Asymmetric Encryption)")

@classmethod
def from_private_key(cls, private_key: PrivateKeyTypes | None) -> str:
if isinstance(private_key, RSAPrivateKey):
return cls.RS256
if isinstance(private_key, EllipticCurvePrivateKey):
curve = private_key.curve
if isinstance(curve, SECP256R1):
return cls.ES256
if isinstance(curve, SECP384R1):
return cls.ES384
if isinstance(curve, SECP521R1):
return cls.ES512
raise ValueError(f"Invalid private key type: {type(private_key)}")


class ScopeMapping(PropertyMapping):
Expand Down Expand Up @@ -263,11 +284,7 @@ def jwt_key(self) -> tuple[str | PrivateKeyTypes, str]:
return self.client_secret, JWTAlgorithms.HS256
key: CertificateKeyPair = self.signing_key
private_key = key.private_key
if isinstance(private_key, RSAPrivateKey):
return private_key, JWTAlgorithms.RS256
if isinstance(private_key, EllipticCurvePrivateKey):
return private_key, JWTAlgorithms.ES256
raise ValueError(f"Invalid private key type: {type(private_key)}")
return private_key, JWTAlgorithms.from_private_key(private_key)

def get_issuer(self, request: HttpRequest) -> str | None:
"""Get issuer, based on request"""
Expand Down
5 changes: 1 addition & 4 deletions authentik/providers/oauth2/views/jwks.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,7 @@ def get_jwk_for_key(key: CertificateKeyPair, use: str) -> dict | None:
key_data = {}

if use == "sig":
if isinstance(private_key, RSAPrivateKey):
key_data["alg"] = JWTAlgorithms.RS256
elif isinstance(private_key, EllipticCurvePrivateKey):
key_data["alg"] = JWTAlgorithms.ES256
key_data["alg"] = JWTAlgorithms.from_private_key(private_key)
elif use == "enc":
key_data["alg"] = "RSA-OAEP-256"
key_data["enc"] = "A256CBC-HS512"
Expand Down

0 comments on commit 7e7fc75

Please sign in to comment.