Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-joserfc for openSUSE:Factory 
checked in at 2026-09-02 17:00:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-joserfc (Old)
 and      /work/SRC/openSUSE:Factory/.python-joserfc.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-joserfc"

Wed Sep  2 17:00:53 2026 rev:15 rq:1375236 version:1.7.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-joserfc/python-joserfc.changes    
2026-08-01 18:37:09.435997647 +0200
+++ /work/SRC/openSUSE:Factory/.python-joserfc.new.1265/python-joserfc.changes  
2026-09-02 17:01:03.899835628 +0200
@@ -1,0 +2,8 @@
+Tue Sep  1 21:37:09 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 1.7.5:
+  * JWK: Ignore keys with unknown kty values when importing a key
+    set.
+  * JWE: Add max_recipients to JWERegistry.
+
+-------------------------------------------------------------------

Old:
----
  joserfc-1.7.4.tar.gz

New:
----
  joserfc-1.7.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-joserfc.spec ++++++
--- /var/tmp/diff_new_pack.O9a94T/_old  2026-09-02 17:01:04.501856309 +0200
+++ /var/tmp/diff_new_pack.O9a94T/_new  2026-09-02 17:01:04.502856343 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-joserfc
-Version:        1.7.4
+Version:        1.7.5
 Release:        0
 Summary:        The ultimate Python library for JOSE RFCs
 License:        BSD-3-Clause

++++++ joserfc-1.7.4.tar.gz -> joserfc-1.7.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/joserfc-1.7.4/PKG-INFO new/joserfc-1.7.5/PKG-INFO
--- old/joserfc-1.7.4/PKG-INFO  2026-07-19 17:42:30.915866400 +0200
+++ new/joserfc-1.7.5/PKG-INFO  2026-08-29 15:05:19.208686000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: joserfc
-Version: 1.7.4
+Version: 1.7.5
 Summary: The ultimate Python library for JOSE RFCs, including JWS, JWE, JWK, 
JWA, JWT
 Author-email: Hsiaoming Yang <[email protected]>
 License: BSD-3-Clause
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/joserfc-1.7.4/docs/changelog.rst 
new/joserfc-1.7.5/docs/changelog.rst
--- old/joserfc-1.7.4/docs/changelog.rst        2026-07-19 17:42:25.000000000 
+0200
+++ new/joserfc-1.7.5/docs/changelog.rst        2026-08-29 15:05:08.757169700 
+0200
@@ -12,6 +12,14 @@
 .. module:: joserfc
     :noindex:
 
+1.7.5
+-----
+
+**Released on August 29, 2026**
+
+- **JWK**: Ignore keys with unknown ``kty`` values when importing a key set.
+- **JWE**: Add ``max_recipients`` to ``JWERegistry``.
+
 1.7.4
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/joserfc-1.7.4/docs/conf.py 
new/joserfc-1.7.5/docs/conf.py
--- old/joserfc-1.7.4/docs/conf.py      2026-07-19 17:42:25.000000000 +0200
+++ new/joserfc-1.7.5/docs/conf.py      2026-08-29 15:05:08.757169700 +0200
@@ -33,7 +33,7 @@
 ]
 
 iconify_script_url = ""
-sponsors_json_url = "https://cdn.jsdelivr.net/gh/lepture/lepture/sponsors.json";
+sponsors_json_url = "https://cdn.jsdelivr.net/gh/authlib/assets/sponsors.json";
 
 extlinks = {
     "user": ("https://github.com/%s";, "@%s"),
@@ -69,7 +69,11 @@
                 },
             ],
         },
-        {"title": "Support us", "url": "/en/sponsors"},
+        {
+            "title": "Sponsors",
+            "url": "https://authlib.org/sponsors/";,
+            "external": True,
+        },
     ],
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/joserfc-1.7.4/src/joserfc/__init__.py 
new/joserfc-1.7.5/src/joserfc/__init__.py
--- old/joserfc-1.7.4/src/joserfc/__init__.py   2026-07-19 17:42:25.000000000 
+0200
+++ new/joserfc-1.7.5/src/joserfc/__init__.py   2026-08-29 15:05:08.759605600 
+0200
@@ -1,4 +1,4 @@
-__version__ = "1.7.4"
+__version__ = "1.7.5"
 __homepage__ = "https://jose.authlib.org/en/";
 __author__ = "Hsiaoming Yang <[email protected]>"
 __license__ = "BSD-3-Clause"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/joserfc-1.7.4/src/joserfc/_keys.py 
new/joserfc-1.7.5/src/joserfc/_keys.py
--- old/joserfc-1.7.4/src/joserfc/_keys.py      2026-07-19 17:42:25.000000000 
+0200
+++ new/joserfc-1.7.5/src/joserfc/_keys.py      2026-08-29 15:05:08.759626900 
+0200
@@ -167,7 +167,13 @@
         keys: list[Key] = []
 
         for data in value["keys"]:
-            keys.append(cls.registry_cls.import_key(data, 
parameters=parameters))
+            # RFC 7517, Section 5: ignore a key whose "kty" is not understood
+            # rather than failing the whole set (for example a post-quantum key
+            # published alongside classical ones).
+            try:
+                keys.append(cls.registry_cls.import_key(data, 
parameters=parameters))
+            except InvalidKeyTypeError:
+                continue
 
         if not keys:
             raise MissingKeyError("No keys to import")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/joserfc-1.7.4/src/joserfc/_rfc7516/json.py 
new/joserfc-1.7.5/src/joserfc/_rfc7516/json.py
--- old/joserfc-1.7.4/src/joserfc/_rfc7516/json.py      2026-07-19 
17:42:25.000000000 +0200
+++ new/joserfc-1.7.5/src/joserfc/_rfc7516/json.py      2026-08-29 
15:05:08.759827400 +0200
@@ -76,12 +76,14 @@
     protected = json_b64decode(protected_segment)
 
     unprotected = data.get("unprotected")
+    recipients = data["recipients"]
+    registry.validate_recipient_count(recipients)
     base64_segments, bytes_segments, aad = __extract_segments(data, registry)
 
     obj = GeneralJSONEncryption(protected, None, unprotected, aad)
     obj.base64_segments = base64_segments
     obj.bytes_segments = bytes_segments
-    for item in data["recipients"]:
+    for item in recipients:
         recipient = __extract_recipient(obj, item, registry)
         obj.recipients.append(recipient)
     return obj
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/joserfc-1.7.4/src/joserfc/_rfc7516/message.py 
new/joserfc-1.7.5/src/joserfc/_rfc7516/message.py
--- old/joserfc-1.7.4/src/joserfc/_rfc7516/message.py   2026-07-19 
17:42:25.000000000 +0200
+++ new/joserfc-1.7.5/src/joserfc/_rfc7516/message.py   2026-08-29 
15:05:08.759827400 +0200
@@ -102,17 +102,20 @@
 
     cek_set = set()
     for recipient in obj.recipients:
-        headers = recipient.headers()
-        registry.check_header(headers, True)
-        # Step 6, Determine the Key Management Mode employed by the algorithm
-        # specified by the "alg" (algorithm) Header Parameter.
-        alg = registry.get_alg(headers["alg"])
         try:
+            headers = recipient.headers()
+            registry.check_header(headers, True)
+            # Step 6, Determine the Key Management Mode employed by the 
algorithm
+            # specified by the "alg" (algorithm) Header Parameter.
+            alg = registry.get_alg(headers["alg"])
             cek = decrypt_recipient(alg, enc, recipient, tag)
             cek_set.add(cek)
         except (AssertionError, JoseError) as error:
             if registry.verify_all_recipients:
                 raise error
+        else:
+            if not registry.verify_all_recipients:
+                break
 
     if not cek_set:
         raise DecodeError("Invalid recipients")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/joserfc-1.7.4/src/joserfc/_rfc7516/registry.py 
new/joserfc-1.7.5/src/joserfc/_rfc7516/registry.py
--- old/joserfc-1.7.4/src/joserfc/_rfc7516/registry.py  2026-07-19 
17:42:25.000000000 +0200
+++ new/joserfc-1.7.5/src/joserfc/_rfc7516/registry.py  2026-08-29 
15:05:08.759827400 +0200
@@ -43,6 +43,7 @@
     :param algorithms: allowed algorithms to be used
     :param verify_all_recipients: validating all recipients in a JSON 
serialization
     :param strict_check_header: only allow header key in the registry to be 
used
+    :param max_recipients: max number of recipients in JWE General JSON 
Serialization
     """
 
     algorithms: AlgorithmsDict = {
@@ -62,6 +63,8 @@
     max_ciphertext_length: int = 65536  # 64KB
     #: max auth tag's size in bytes
     max_auth_tag_length: int = 64
+    #: max number of recipients in JWE General JSON Serialization
+    max_recipients: int = 16
 
     def __init__(
         self,
@@ -69,6 +72,7 @@
         algorithms: Collection[str] | None = None,
         verify_all_recipients: bool = True,
         strict_check_header: bool = True,
+        max_recipients: int | None = None,
     ):
         self.header_registry: HeaderRegistryDict = {}
         self.header_registry.update(JWE_HEADER_REGISTRY)
@@ -77,6 +81,8 @@
         self.allowed = algorithms
         self.verify_all_recipients = verify_all_recipients
         self.strict_check_header = strict_check_header
+        if max_recipients is not None:
+            self.max_recipients = max_recipients
 
     @classmethod
     def register(cls, model: JWEAlgorithm) -> None:
@@ -122,6 +128,10 @@
         if tag and len(tag) > self.max_auth_tag_length:
             raise ExceededSizeError(f"Auth tag size exceeds 
{self.max_auth_tag_length} bytes.")
 
+    def validate_recipient_count(self, recipients: Collection[t.Any]) -> None:
+        if len(recipients) > self.max_recipients:
+            raise ExceededSizeError(f"Recipient count exceeds 
{self.max_recipients}.")
+
     def get_alg(self, name: str) -> JWEAlgModel:
         """Get the allowed ("alg") algorithm instance of the given name.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/joserfc-1.7.4/src/joserfc.egg-info/PKG-INFO 
new/joserfc-1.7.5/src/joserfc.egg-info/PKG-INFO
--- old/joserfc-1.7.4/src/joserfc.egg-info/PKG-INFO     2026-07-19 
17:42:30.000000000 +0200
+++ new/joserfc-1.7.5/src/joserfc.egg-info/PKG-INFO     2026-08-29 
15:05:19.177635200 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: joserfc
-Version: 1.7.4
+Version: 1.7.5
 Summary: The ultimate Python library for JOSE RFCs, including JWS, JWE, JWK, 
JWA, JWT
 Author-email: Hsiaoming Yang <[email protected]>
 License: BSD-3-Clause
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/joserfc-1.7.4/tests/jwe/test_json.py 
new/joserfc-1.7.5/tests/jwe/test_json.py
--- old/joserfc-1.7.4/tests/jwe/test_json.py    2026-07-19 17:42:25.000000000 
+0200
+++ new/joserfc-1.7.5/tests/jwe/test_json.py    2026-08-29 15:05:08.761375000 
+0200
@@ -1,14 +1,33 @@
 from unittest import TestCase
 from joserfc import jwe
 from joserfc.jwe import GeneralJSONEncryption, FlattenedJSONEncryption
+from joserfc.jwa import JWEKeyEncryption
 from joserfc.jwk import KeySet, RSAKey, ECKey, OctKey
 from joserfc.errors import (
     DecodeError,
     ConflictAlgorithmError,
     InvalidKeyTypeError,
+    ExceededSizeError,
 )
 
 
+class CountingKeyEncryption(JWEKeyEncryption):
+    name = "TEST-COUNT"
+    description = "Counting test key encryption"
+    key_types = ["oct"]
+
+    def __init__(self):
+        self.decrypt_count = 0
+
+    def encrypt_cek(self, cek, recipient):
+        return cek
+
+    def decrypt_cek(self, recipient):
+        self.decrypt_count += 1
+        assert recipient.encrypted_key is not None
+        return recipient.encrypted_key
+
+
 class TestJWEJSON(TestCase):
     rsa_key = RSAKey.generate_key()
     ec_key = ECKey.generate_key()
@@ -87,6 +106,41 @@
         del value["recipients"][0]["encrypted_key"]
         self.assertRaises(DecodeError, jwe.decrypt_json, value, self.rsa_key)
 
+    def test_general_json_recipients_exceeded_size_error(self):
+        key = OctKey.generate_key(128)
+        limit = jwe.JWERegistry.max_recipients
+        obj = GeneralJSONEncryption({"enc": "A128CBC-HS256"}, b"i")
+        for _ in range(limit + 1):
+            obj.add_recipient({"alg": "A128KW"}, key)
+
+        value = jwe.encrypt_json(obj, None)
+        self.assertRaises(ExceededSizeError, jwe.decrypt_json, value, key)
+
+        registry = jwe.JWERegistry(max_recipients=limit + 1)
+        obj1 = jwe.decrypt_json(value, key, registry=registry)
+        self.assertEqual(obj1.plaintext, b"i")
+
+    def test_verify_one_recipient_stops_after_success(self):
+        key = OctKey.generate_key(128)
+        alg = CountingKeyEncryption()
+        jwe.JWERegistry.register(alg)
+        try:
+            registry = jwe.JWERegistry(
+                algorithms=[alg.name, "A128GCM"],
+                verify_all_recipients=False,
+            )
+            obj = GeneralJSONEncryption({"enc": "A128GCM"}, b"i")
+            obj.add_recipient({"alg": alg.name}, key)
+            obj.add_recipient({"alg": alg.name}, key)
+            value = jwe.encrypt_json(obj, None, registry=registry)
+            alg.decrypt_count = 0
+            obj1 = jwe.decrypt_json(value, key, registry=registry)
+        finally:
+            del jwe.JWERegistry.algorithms["alg"][alg.name]
+
+        self.assertEqual(obj1.plaintext, b"i")
+        self.assertEqual(alg.decrypt_count, 1)
+
     def test_flattened_encryption(self):
         key = OctKey.generate_key(128)
         protected = {"enc": "A128CBC-HS256"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/joserfc-1.7.4/tests/jwk/test_jwk_set.py 
new/joserfc-1.7.5/tests/jwk/test_jwk_set.py
--- old/joserfc-1.7.4/tests/jwk/test_jwk_set.py 2026-07-19 17:42:25.000000000 
+0200
+++ new/joserfc-1.7.5/tests/jwk/test_jwk_set.py 2026-08-29 15:05:08.761608600 
+0200
@@ -11,6 +11,16 @@
     def test_import_empty_key_set(self):
         self.assertRaises(MissingKeyError, KeySet.import_key_set, {"keys": []})
 
+    def test_import_key_set_ignores_unknown_kty(self):
+        # RFC 7517 Section 5: a key with an unrecognised "kty" is ignored, not 
fatal.
+        jwks = {"keys": [
+            {"kty": "unknown", "alg": "X", "kid": "unknown"},
+            {"kty": "oct", "k": "MDEyMzQ1Njc4OWFiY2RlZg", "kid": "classical"},
+        ]}
+        key_set = KeySet.import_key_set(jwks)
+        self.assertEqual(len(key_set.keys), 1)
+        self.assertEqual(key_set.keys[0].kid, "classical")
+
     def test_generate_and_import_key_set(self):
         jwks1 = KeySet.generate_key_set("RSA", 2048)
         self.assertEqual(len(jwks1.keys), 4)

Reply via email to