prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Add `x5c` and `x5t`to the `jwks` response
  **Is your feature request related to a problem? Please describe.**
  I am trying to use Authentik as the identity provider for netbird via OAuth2/OIDC
  
  **Describe the solution you'd like**
  netbird expects the JWKS endpoint which is `/application/o/<provider name>/jwks/` to have a property for the `x5c`. The `x5c` (X.509 certificate chain) Header Parameter contains the X.509 public key certificate or certificate chain corresponding to the key used to digitally sign the JWS (JSON Web Signature).
  
  **Describe alternatives you've considered**
  n/a
  
  **Additional context**
  For the OAuth2 Provider, I specified a signing key which populated the `jwks` endpoint response with the following values:
  ```
  {
      "keys": [
          {
              "kty": "RSA",
              "alg": "RS256",
              "use": "sig",
              "kid": "*REDACTED*",
              "n": "*REDACTED*",
              "e": "AQAB"
          }
      ]
  }
  ```
  
  Comparing it to the example here: https://example.eu.auth0.com/.well-known/jwks.json , it is missing the `x5t` and `x5c` properties.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `authentik/providers/oauth2/views/jwks.py`
  Content:
  ```
  1 """authentik OAuth2 JWKS Views"""
  2 from base64 import urlsafe_b64encode
  3 from typing import Optional
  4 
  5 from cryptography.hazmat.primitives.asymmetric.ec import (
  6     EllipticCurvePrivateKey,
  7     EllipticCurvePublicKey,
  8 )
  9 from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey, RSAPublicKey
  10 from django.http import HttpRequest, HttpResponse, JsonResponse
  11 from django.shortcuts import get_object_or_404
  12 from django.views import View
  13 
  14 from authentik.core.models import Application
  15 from authentik.crypto.models import CertificateKeyPair
  16 from authentik.providers.oauth2.models import JWTAlgorithms, OAuth2Provider
  17 
  18 
  19 def b64_enc(number: int) -> str:
  20     """Convert number to base64-encoded octet-value"""
  21     length = ((number).bit_length() + 7) // 8
  22     number_bytes = number.to_bytes(length, "big")
  23     final = urlsafe_b64encode(number_bytes).rstrip(b"=")
  24     return final.decode("ascii")
  25 
  26 
  27 class JWKSView(View):
  28     """Show RSA Key data for Provider"""
  29 
  30     def get_jwk_for_key(self, key: CertificateKeyPair) -> Optional[dict]:
  31         """Convert a certificate-key pair into JWK"""
  32         private_key = key.private_key
  33         if not private_key:
  34             return None
  35         if isinstance(private_key, RSAPrivateKey):
  36             public_key: RSAPublicKey = private_key.public_key()
  37             public_numbers = public_key.public_numbers()
  38             return {
  39                 "kty": "RSA",
  40                 "alg": JWTAlgorithms.RS256,
  41                 "use": "sig",
  42                 "kid": key.kid,
  43                 "n": b64_enc(public_numbers.n),
  44                 "e": b64_enc(public_numbers.e),
  45             }
  46         if isinstance(private_key, EllipticCurvePrivateKey):
  47             public_key: EllipticCurvePublicKey = private_key.public_key()
  48             public_numbers = public_key.public_numbers()
  49             return {
  50                 "kty": "EC",
  51                 "alg": JWTAlgorithms.ES256,
  52                 "use": "sig",
  53                 "kid": key.kid,
  54                 "n": b64_enc(public_numbers.n),
  55                 "e": b64_enc(public_numbers.e),
  56             }
  57         return None
  58 
  59     def get(self, request: HttpRequest, application_slug: str) -> HttpResponse:
  60         """Show JWK Key data for Provider"""
  61         application = get_object_or_404(Application, slug=application_slug)
  62         provider: OAuth2Provider = get_object_or_404(OAuth2Provider, pk=application.provider_id)
  63         signing_key: CertificateKeyPair = provider.signing_key
  64 
  65         response_data = {}
  66 
  67         if signing_key:
  68             jwk = self.get_jwk_for_key(signing_key)
  69             if jwk:
  70                 response_data["keys"] = [jwk]
  71 
  72         response = JsonResponse(response_data)
  73         response["Access-Control-Allow-Origin"] = "*"
  74 
  75         return response
  76
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/authentik/providers/oauth2/views/jwks.py b/authentik/providers/oauth2/views/jwks.py
  --- 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 @@
       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 @@
                   "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 @@
                   "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"""
  
verification_info: {"golden_diff": "diff --git a/authentik/providers/oauth2/views/jwks.py b/authentik/providers/oauth2/views/jwks.py\n--- a/authentik/providers/oauth2/views/jwks.py\n+++ b/authentik/providers/oauth2/views/jwks.py\n@@ -1,12 +1,14 @@\n \"\"\"authentik OAuth2 JWKS Views\"\"\"\n-from base64 import urlsafe_b64encode\n+from base64 import b64encode, urlsafe_b64encode\n from typing import Optional\n \n+from cryptography.hazmat.primitives import hashes\n from cryptography.hazmat.primitives.asymmetric.ec import (\n     EllipticCurvePrivateKey,\n     EllipticCurvePublicKey,\n )\n from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey, RSAPublicKey\n+from cryptography.hazmat.primitives.serialization import Encoding\n from django.http import HttpRequest, HttpResponse, JsonResponse\n from django.shortcuts import get_object_or_404\n from django.views import View\n@@ -30,12 +32,13 @@\n     def get_jwk_for_key(self, key: CertificateKeyPair) -> Optional[dict]:\n         \"\"\"Convert a certificate-key pair into JWK\"\"\"\n         private_key = key.private_key\n+        key_data = None\n         if not private_key:\n-            return None\n+            return key_data\n         if isinstance(private_key, RSAPrivateKey):\n             public_key: RSAPublicKey = private_key.public_key()\n             public_numbers = public_key.public_numbers()\n-            return {\n+            key_data = {\n                 \"kty\": \"RSA\",\n                 \"alg\": JWTAlgorithms.RS256,\n                 \"use\": \"sig\",\n@@ -43,10 +46,10 @@\n                 \"n\": b64_enc(public_numbers.n),\n                 \"e\": b64_enc(public_numbers.e),\n             }\n-        if isinstance(private_key, EllipticCurvePrivateKey):\n+        elif isinstance(private_key, EllipticCurvePrivateKey):\n             public_key: EllipticCurvePublicKey = private_key.public_key()\n             public_numbers = public_key.public_numbers()\n-            return {\n+            key_data = {\n                 \"kty\": \"EC\",\n                 \"alg\": JWTAlgorithms.ES256,\n                 \"use\": \"sig\",\n@@ -54,7 +57,20 @@\n                 \"n\": b64_enc(public_numbers.n),\n                 \"e\": b64_enc(public_numbers.e),\n             }\n-        return None\n+        else:\n+            return key_data\n+        key_data[\"x5c\"] = [b64encode(key.certificate.public_bytes(Encoding.DER)).decode(\"utf-8\")]\n+        key_data[\"x5t\"] = (\n+            urlsafe_b64encode(key.certificate.fingerprint(hashes.SHA1()))  # nosec\n+            .decode(\"utf-8\")\n+            .rstrip(\"=\")\n+        )\n+        key_data[\"x5t#S256\"] = (\n+            urlsafe_b64encode(key.certificate.fingerprint(hashes.SHA256()))\n+            .decode(\"utf-8\")\n+            .rstrip(\"=\")\n+        )\n+        return key_data\n \n     def get(self, request: HttpRequest, application_slug: str) -> HttpResponse:\n         \"\"\"Show JWK Key data for Provider\"\"\"\n", "issue": "Add `x5c` and `x5t`to the `jwks` response\n**Is your feature request related to a problem? Please describe.**\r\nI am trying to use Authentik as the identity provider for netbird via OAuth2/OIDC\r\n\r\n**Describe the solution you'd like**\r\nnetbird expects the JWKS endpoint which is `/application/o/<provider name>/jwks/` to have a property for the `x5c`. The `x5c` (X.509 certificate chain) Header Parameter contains the X.509 public key certificate or certificate chain corresponding to the key used to digitally sign the JWS (JSON Web Signature).\r\n\r\n**Describe alternatives you've considered**\r\nn/a\r\n\r\n**Additional context**\r\nFor the OAuth2 Provider, I specified a signing key which populated the `jwks` endpoint response with the following values:\r\n```\r\n{\r\n    \"keys\": [\r\n        {\r\n            \"kty\": \"RSA\",\r\n            \"alg\": \"RS256\",\r\n            \"use\": \"sig\",\r\n            \"kid\": \"*REDACTED*\",\r\n            \"n\": \"*REDACTED*\",\r\n            \"e\": \"AQAB\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\nComparing it to the example here: https://example.eu.auth0.com/.well-known/jwks.json , it is missing the `x5t` and `x5c` properties.\n", "before_files": [{"content": "\"\"\"authentik OAuth2 JWKS Views\"\"\"\nfrom base64 import urlsafe_b64encode\nfrom typing import Optional\n\nfrom cryptography.hazmat.primitives.asymmetric.ec import (\n    EllipticCurvePrivateKey,\n    EllipticCurvePublicKey,\n)\nfrom cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey, RSAPublicKey\nfrom django.http import HttpRequest, HttpResponse, JsonResponse\nfrom django.shortcuts import get_object_or_404\nfrom django.views import View\n\nfrom authentik.core.models import Application\nfrom authentik.crypto.models import CertificateKeyPair\nfrom authentik.providers.oauth2.models import JWTAlgorithms, OAuth2Provider\n\n\ndef b64_enc(number: int) -> str:\n    \"\"\"Convert number to base64-encoded octet-value\"\"\"\n    length = ((number).bit_length() + 7) // 8\n    number_bytes = number.to_bytes(length, \"big\")\n    final = urlsafe_b64encode(number_bytes).rstrip(b\"=\")\n    return final.decode(\"ascii\")\n\n\nclass JWKSView(View):\n    \"\"\"Show RSA Key data for Provider\"\"\"\n\n    def get_jwk_for_key(self, key: CertificateKeyPair) -> Optional[dict]:\n        \"\"\"Convert a certificate-key pair into JWK\"\"\"\n        private_key = key.private_key\n        if not private_key:\n            return None\n        if isinstance(private_key, RSAPrivateKey):\n            public_key: RSAPublicKey = private_key.public_key()\n            public_numbers = public_key.public_numbers()\n            return {\n                \"kty\": \"RSA\",\n                \"alg\": JWTAlgorithms.RS256,\n                \"use\": \"sig\",\n                \"kid\": key.kid,\n                \"n\": b64_enc(public_numbers.n),\n                \"e\": b64_enc(public_numbers.e),\n            }\n        if isinstance(private_key, EllipticCurvePrivateKey):\n            public_key: EllipticCurvePublicKey = private_key.public_key()\n            public_numbers = public_key.public_numbers()\n            return {\n                \"kty\": \"EC\",\n                \"alg\": JWTAlgorithms.ES256,\n                \"use\": \"sig\",\n                \"kid\": key.kid,\n                \"n\": b64_enc(public_numbers.n),\n                \"e\": b64_enc(public_numbers.e),\n            }\n        return None\n\n    def get(self, request: HttpRequest, application_slug: str) -> HttpResponse:\n        \"\"\"Show JWK Key data for Provider\"\"\"\n        application = get_object_or_404(Application, slug=application_slug)\n        provider: OAuth2Provider = get_object_or_404(OAuth2Provider, pk=application.provider_id)\n        signing_key: CertificateKeyPair = provider.signing_key\n\n        response_data = {}\n\n        if signing_key:\n            jwk = self.get_jwk_for_key(signing_key)\n            if jwk:\n                response_data[\"keys\"] = [jwk]\n\n        response = JsonResponse(response_data)\n        response[\"Access-Control-Allow-Origin\"] = \"*\"\n\n        return response\n", "path": "authentik/providers/oauth2/views/jwks.py"}], "after_files": [{"content": "\"\"\"authentik OAuth2 JWKS Views\"\"\"\nfrom base64 import b64encode, urlsafe_b64encode\nfrom typing import Optional\n\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives.asymmetric.ec import (\n    EllipticCurvePrivateKey,\n    EllipticCurvePublicKey,\n)\nfrom cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey, RSAPublicKey\nfrom cryptography.hazmat.primitives.serialization import Encoding\nfrom django.http import HttpRequest, HttpResponse, JsonResponse\nfrom django.shortcuts import get_object_or_404\nfrom django.views import View\n\nfrom authentik.core.models import Application\nfrom authentik.crypto.models import CertificateKeyPair\nfrom authentik.providers.oauth2.models import JWTAlgorithms, OAuth2Provider\n\n\ndef b64_enc(number: int) -> str:\n    \"\"\"Convert number to base64-encoded octet-value\"\"\"\n    length = ((number).bit_length() + 7) // 8\n    number_bytes = number.to_bytes(length, \"big\")\n    final = urlsafe_b64encode(number_bytes).rstrip(b\"=\")\n    return final.decode(\"ascii\")\n\n\nclass JWKSView(View):\n    \"\"\"Show RSA Key data for Provider\"\"\"\n\n    def get_jwk_for_key(self, key: CertificateKeyPair) -> Optional[dict]:\n        \"\"\"Convert a certificate-key pair into JWK\"\"\"\n        private_key = key.private_key\n        key_data = None\n        if not private_key:\n            return key_data\n        if isinstance(private_key, RSAPrivateKey):\n            public_key: RSAPublicKey = private_key.public_key()\n            public_numbers = public_key.public_numbers()\n            key_data = {\n                \"kty\": \"RSA\",\n                \"alg\": JWTAlgorithms.RS256,\n                \"use\": \"sig\",\n                \"kid\": key.kid,\n                \"n\": b64_enc(public_numbers.n),\n                \"e\": b64_enc(public_numbers.e),\n            }\n        elif isinstance(private_key, EllipticCurvePrivateKey):\n            public_key: EllipticCurvePublicKey = private_key.public_key()\n            public_numbers = public_key.public_numbers()\n            key_data = {\n                \"kty\": \"EC\",\n                \"alg\": JWTAlgorithms.ES256,\n                \"use\": \"sig\",\n                \"kid\": key.kid,\n                \"n\": b64_enc(public_numbers.n),\n                \"e\": b64_enc(public_numbers.e),\n            }\n        else:\n            return key_data\n        key_data[\"x5c\"] = [b64encode(key.certificate.public_bytes(Encoding.DER)).decode(\"utf-8\")]\n        key_data[\"x5t\"] = (\n            urlsafe_b64encode(key.certificate.fingerprint(hashes.SHA1()))  # nosec\n            .decode(\"utf-8\")\n            .rstrip(\"=\")\n        )\n        key_data[\"x5t#S256\"] = (\n            urlsafe_b64encode(key.certificate.fingerprint(hashes.SHA256()))\n            .decode(\"utf-8\")\n            .rstrip(\"=\")\n        )\n        return key_data\n\n    def get(self, request: HttpRequest, application_slug: str) -> HttpResponse:\n        \"\"\"Show JWK Key data for Provider\"\"\"\n        application = get_object_or_404(Application, slug=application_slug)\n        provider: OAuth2Provider = get_object_or_404(OAuth2Provider, pk=application.provider_id)\n        signing_key: CertificateKeyPair = provider.signing_key\n\n        response_data = {}\n\n        if signing_key:\n            jwk = self.get_jwk_for_key(signing_key)\n            if jwk:\n                response_data[\"keys\"] = [jwk]\n\n        response = JsonResponse(response_data)\n        response[\"Access-Control-Allow-Origin\"] = \"*\"\n\n        return response\n", "path": "authentik/providers/oauth2/views/jwks.py"}]}