Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion authlib/consts.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name = "Authlib"
version = "1.6.6"
version = "1.6.10"
author = "Hsiaoming Yang <[email protected]>"
homepage = "https://authlib.org"
default_user_agent = f"{name}/{version} (+{homepage})"
Expand Down
10 changes: 6 additions & 4 deletions authlib/jose/rfc7515/jws.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,16 +261,18 @@ def _prepare_algorithm_key(self, header, payload, key):
raise MissingAlgorithmError()

alg = header["alg"]
if self._algorithms is not None and alg not in self._algorithms:
raise UnsupportedAlgorithmError()
if alg not in self.ALGORITHMS_REGISTRY:
raise UnsupportedAlgorithmError()

algorithm = self.ALGORITHMS_REGISTRY[alg]
if self._algorithms is None:
if algorithm.deprecated:
raise UnsupportedAlgorithmError()
elif alg not in self._algorithms:
raise UnsupportedAlgorithmError()

if callable(key):
key = key(header, payload)
elif key is None and "jwk" in header:
key = header["jwk"]
key = algorithm.prepare_key(key)
return algorithm, key

Expand Down
1 change: 1 addition & 0 deletions authlib/jose/rfc7515/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class JWSAlgorithm:

name = None
description = None
deprecated = False
algorithm_type = "JWS"
algorithm_location = "alg"

Expand Down
16 changes: 11 additions & 5 deletions authlib/jose/rfc7516/jwe.py
Original file line number Diff line number Diff line change
Expand Up @@ -697,11 +697,19 @@ def get_header_alg(self, header):
raise MissingAlgorithmError()

alg = header["alg"]
if self._algorithms is not None and alg not in self._algorithms:
raise UnsupportedAlgorithmError()
if alg not in self.ALG_REGISTRY:
raise UnsupportedAlgorithmError()
return self.ALG_REGISTRY[alg]

instance = self.ALG_REGISTRY[alg]

# use all ALG_REGISTRY algorithms
if self._algorithms is None:
# do not use deprecated algorithms
if instance.deprecated:
raise UnsupportedAlgorithmError()
elif alg not in self._algorithms:
raise UnsupportedAlgorithmError()
return instance

def get_header_enc(self, header):
if "enc" not in header:
Expand Down Expand Up @@ -754,6 +762,4 @@ def _validate_private_headers(self, header, alg):
def prepare_key(alg, header, key):
if callable(key):
key = key(header, None)
elif key is None and "jwk" in header:
key = header["jwk"]
return alg.prepare_key(key)
1 change: 1 addition & 0 deletions authlib/jose/rfc7516/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class JWEAlgorithmBase(metaclass=ABCMeta): # noqa: B024

name = None
description = None
deprecated = False
algorithm_type = "JWE"
algorithm_location = "alg"

Expand Down
14 changes: 7 additions & 7 deletions authlib/jose/rfc7518/jwe_algs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import os
import secrets
import struct

from cryptography.hazmat.backends import default_backend
Expand Down Expand Up @@ -41,7 +41,7 @@
def unwrap(self, enc_alg, ek, headers, key):
cek = key.get_op_key("decrypt")
if len(cek) * 8 != enc_alg.CEK_SIZE:
raise ValueError('Invalid "cek" length')
cek = secrets.token_bytes(enc_alg.CEK_SIZE // 8)
return cek


Expand All @@ -52,6 +52,7 @@

def __init__(self, name, description, pad_fn):
self.name = name
self.deprecated = name == "RSA1_5"
self.description = description
self.padding = pad_fn

Expand All @@ -75,11 +76,10 @@
return {"ek": ek, "cek": cek}

def unwrap(self, enc_alg, ek, headers, key):
# it will raise ValueError if failed
op_key = key.get_op_key("unwrapKey")
cek = op_key.decrypt(ek, self.padding)
if len(cek) * 8 != enc_alg.CEK_SIZE:
raise ValueError('Invalid "cek" length')
cek = secrets.token_bytes(enc_alg.CEK_SIZE // 8)

Check warning on line 82 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.14)

Missing Coverage

Line 82 missing coverage

Check warning on line 82 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.12)

Missing Coverage

Line 82 missing coverage

Check warning on line 82 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.11)

Missing Coverage

Line 82 missing coverage

Check warning on line 82 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build ([email protected])

Missing Coverage

Line 82 missing coverage

Check warning on line 82 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.10)

Missing Coverage

Line 82 missing coverage

Check warning on line 82 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.13)

Missing Coverage

Line 82 missing coverage
return cek


Expand Down Expand Up @@ -118,7 +118,7 @@
self._check_key(op_key)
cek = aes_key_unwrap(op_key, ek, default_backend())
if len(cek) * 8 != enc_alg.CEK_SIZE:
raise ValueError('Invalid "cek" length')
cek = secrets.token_bytes(enc_alg.CEK_SIZE // 8)

Check warning on line 121 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.14)

Missing Coverage

Line 121 missing coverage

Check warning on line 121 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.12)

Missing Coverage

Line 121 missing coverage

Check warning on line 121 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.11)

Missing Coverage

Line 121 missing coverage

Check warning on line 121 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build ([email protected])

Missing Coverage

Line 121 missing coverage

Check warning on line 121 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.10)

Missing Coverage

Line 121 missing coverage

Check warning on line 121 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.13)

Missing Coverage

Line 121 missing coverage
return cek


Expand Down Expand Up @@ -154,7 +154,7 @@
#: The "iv" (initialization vector) Header Parameter value is the
#: base64url-encoded representation of the 96-bit IV value
iv_size = 96
iv = os.urandom(iv_size // 8)
iv = secrets.token_bytes(iv_size // 8)

cipher = Cipher(AES(op_key), GCM(iv), backend=default_backend())
enc = cipher.encryptor()
Expand Down Expand Up @@ -185,7 +185,7 @@
d = cipher.decryptor()
cek = d.update(ek) + d.finalize()
if len(cek) * 8 != enc_alg.CEK_SIZE:
raise ValueError('Invalid "cek" length')
cek = secrets.token_bytes(enc_alg.CEK_SIZE // 8)

Check warning on line 188 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.14)

Missing Coverage

Line 188 missing coverage

Check warning on line 188 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.12)

Missing Coverage

Line 188 missing coverage

Check warning on line 188 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.11)

Missing Coverage

Line 188 missing coverage

Check warning on line 188 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build ([email protected])

Missing Coverage

Line 188 missing coverage

Check warning on line 188 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.10)

Missing Coverage

Line 188 missing coverage

Check warning on line 188 in authlib/jose/rfc7518/jwe_algs.py

View workflow job for this annotation

GitHub Actions / build (3.13)

Missing Coverage

Line 188 missing coverage
return cek


Expand Down
1 change: 1 addition & 0 deletions authlib/jose/rfc7518/jws_algs.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
class NoneAlgorithm(JWSAlgorithm):
name = "none"
description = "No digital signature or MAC performed"
deprecated = True

def prepare_key(self, raw_data):
return None
Expand Down
13 changes: 12 additions & 1 deletion authlib/oauth2/rfc6749/authorization_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,21 @@
if grant_cls.check_authorization_endpoint(request):
return _create_grant(grant_cls, extensions, request, self)

# Per RFC 6749 §4.1.2.1, only redirect with the error if the client
# exists and the redirect_uri has been validated against it.
redirect_uri = None
if client_id := request.payload.client_id:
if client := self.query_client(client_id):
if requested_uri := request.payload.redirect_uri:
if client.check_redirect_uri(requested_uri):
redirect_uri = requested_uri
else:
redirect_uri = client.get_default_redirect_uri()

Check warning on line 255 in authlib/oauth2/rfc6749/authorization_server.py

View workflow job for this annotation

GitHub Actions / build (3.14)

Missing Coverage

Line 255 missing coverage

Check warning on line 255 in authlib/oauth2/rfc6749/authorization_server.py

View workflow job for this annotation

GitHub Actions / build (3.12)

Missing Coverage

Line 255 missing coverage

Check warning on line 255 in authlib/oauth2/rfc6749/authorization_server.py

View workflow job for this annotation

GitHub Actions / build (3.11)

Missing Coverage

Line 255 missing coverage

Check warning on line 255 in authlib/oauth2/rfc6749/authorization_server.py

View workflow job for this annotation

GitHub Actions / build ([email protected])

Missing Coverage

Line 255 missing coverage

Check warning on line 255 in authlib/oauth2/rfc6749/authorization_server.py

View workflow job for this annotation

GitHub Actions / build (3.10)

Missing Coverage

Line 255 missing coverage

Check warning on line 255 in authlib/oauth2/rfc6749/authorization_server.py

View workflow job for this annotation

GitHub Actions / build (3.13)

Missing Coverage

Line 255 missing coverage

raise UnsupportedResponseTypeError(
f"The response type '{request.payload.response_type}' is not supported by the server.",
request.payload.response_type,
redirect_uri=request.payload.redirect_uri,
redirect_uri=redirect_uri,
)

def get_consent_grant(self, request=None, end_user=None):
Expand Down
4 changes: 2 additions & 2 deletions authlib/oidc/core/claims.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,6 @@ def get_claim_cls_by_response_type(response_type):

def _verify_hash(signature, s, alg):
hash_value = create_half_hash(s, alg)
if not hash_value:
return True
if hash_value is None:
return False
return hmac.compare_digest(hash_value, to_bytes(signature))
10 changes: 6 additions & 4 deletions tests/core/test_oidc/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ def test_validate_at_hash():
)
claims.params = {"access_token": "a"}

# invalid alg won't raise
# invalid alg will raise too
claims.header = {"alg": "HS222"}
claims.validate(1000)
with pytest.raises(InvalidClaimError):
claims.validate(1000)

claims.header = {"alg": "HS256"}
with pytest.raises(InvalidClaimError):
Expand Down Expand Up @@ -143,10 +144,11 @@ def test_hybrid_id_token():
with pytest.raises(MissingClaimError):
claims.validate(1000)

# invalid alg won't raise
# invalid alg will raise too
claims.header = {"alg": "HS222"}
claims["c_hash"] = "a"
claims.validate(1000)
with pytest.raises(InvalidClaimError):
claims.validate(1000)

claims.header = {"alg": "HS256"}
with pytest.raises(InvalidClaimError):
Expand Down
3 changes: 2 additions & 1 deletion tests/jose/test_chacha20.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
from cryptography.exceptions import InvalidTag

from authlib.jose import JsonWebEncryption
from authlib.jose import OctKey
Expand All @@ -16,7 +17,7 @@ def test_dir_alg_c20p():
assert rv["payload"] == b"hello"

key2 = OctKey.generate_key(128, is_private=True)
with pytest.raises(ValueError):
with pytest.raises(InvalidTag):
jwe.deserialize_compact(data, key2)

with pytest.raises(ValueError):
Expand Down
2 changes: 1 addition & 1 deletion tests/jose/test_jwe.py
Original file line number Diff line number Diff line change
Expand Up @@ -1143,7 +1143,7 @@ def test_dir_alg():
assert rv["payload"] == b"hello"

key2 = OctKey.generate_key(256, is_private=True)
with pytest.raises(ValueError):
with pytest.raises(InvalidTag):
jwe.deserialize_compact(data, key2)

with pytest.raises(ValueError):
Expand Down
Loading