Skip to content

Commit

Permalink
Do not fail when an unusable key occurs (#762)
Browse files Browse the repository at this point in the history
* Do not fail when a unusable key occurs

There may be more than keys in the store which may be (still usable).
Therefore we do not want to fail on any key that is not usable by pyjwt,
but rather skip when appending to the KeySet

* Add test cases with unusable 'alg' keys

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add 'skip keys' to changelog

* Update CHANGELOG.rst

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
DaGuich and pre-commit-ci[bot] committed May 31, 2022
1 parent 5a39319 commit 599aba9
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Expand Up @@ -9,6 +9,7 @@ This project adheres to `Semantic Versioning <https://semver.org/>`__.

Changed
~~~~~~~
- Skip keys with incompatible alg when loading JWKSet by @DaGuich in https://github.com/jpadilla/pyjwt/pull/762

Fixed
~~~~~
Expand Down
9 changes: 8 additions & 1 deletion jwt/api_jwk.py
Expand Up @@ -84,7 +84,14 @@ def __init__(self, keys):
raise PyJWKSetError("The JWK Set did not contain any keys")

for key in keys:
self.keys.append(PyJWK(key))
try:
self.keys.append(PyJWK(key))
except PyJWKError:
# skip unusable keys
continue

if len(self.keys) == 0:
raise PyJWKSetError("The JWK Set did not contain any usable keys")

@staticmethod
def from_dict(obj):
Expand Down
1 change: 1 addition & 0 deletions tests/keys/jwk_keyset_only_unknown_alg.json
@@ -0,0 +1 @@
{"keys":[{"kid":"lYXxnemSzWNBUoPug_h0hZnjPi5oKCmQ9awQJaZCWWM","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"k75Ghd4r8h_fdydTAXyMjrGYNnuiG7yevoW1ZIIuegEUK3LLGY0Z3Q8PhCrkmi6LpkPwwR1C8ck9plvSs4vZ9GqmUoi5YcQEile6HjPG3NBwQ-cHWY4ZH_D-ItdzcZUKDxjHYaY-GW1yLeJ1RAh8wMPM7cenA2v0eNIq4HaIXzZJ2Hgxh4Ei-CSYcD0f_TYEySqUEb8jd0dC8frpkYDkOUCVizRBDUEg_hkPSpVqfLP8ekxIHxkC9wcfL-d2FhptxBQYN8NFnIuG9NFXbZ5mdzdmIuN6WPr_CECcgL9qXsph9U-L829dU67ufeBvzEejJ8qwiswslRdx4ZcYjtaBdQ","e":"AQAB","x5c":["MIICnTCCAYUCBgGAUN05KzANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0aW5nMB4XDTIyMDQyMjEwNDAxN1oXDTMyMDQyMjEwNDE1N1owEjEQMA4GA1UEAwwHVGVzdGluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJO+RoXeK/If33cnUwF8jI6xmDZ7ohu8nr6FtWSCLnoBFCtyyxmNGd0PD4Qq5Joui6ZD8MEdQvHJPaZb0rOL2fRqplKIuWHEBIpXuh4zxtzQcEPnB1mOGR/w/iLXc3GVCg8Yx2GmPhltci3idUQIfMDDzO3HpwNr9HjSKuB2iF82Sdh4MYeBIvgkmHA9H/02BMkqlBG/I3dHQvH66ZGA5DlAlYs0QQ1BIP4ZD0qVanyz/HpMSB8ZAvcHHy/ndhYabcQUGDfDRZyLhvTRV22eZnc3ZiLjelj6/whAnIC/al7KYfVPi/NvXVOu7n3gb8xHoyfKsIrMLJUXceGXGI7WgXUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAeMUFrCX4eAfF8i6wILOP5dDJOBN10nPP63VNliQ7+YHu1ZI0VGB7TNrImRE9riH2IWenSXD21DxK31qBlZKNEgaH7rVwwvOZ22qCyWacv1+QdanxAiljD03rU7HOR/tyqcvjl6U2Yadxcq6OWlKKVaa0fNtbPigqAwQ3iVpg9N+OthANYyKHxlmzJKGeEaDA69/uJ6UwektHlv/9BnNFh8We6EwJxYG7/rejI02EgbJFxGO1RlcmigTxRc5l3Dw4WldBIRxWiJgSEkKSfUy5S7sQdFQokZjTyqy6h1ldb/tgrWLIE0srGQ2u/fQeSgPTbAzihaeOf+WKq5RDXoq5bw=="],"x5t":"FaWinuPZQiDMljn3x9DMAuepBYQ","x5t#S256":"_0B--Hh1KgNtdyZqAp1NWUAikRPvlt2HGm__xXpjTi0"}]}
1 change: 1 addition & 0 deletions tests/keys/jwk_keyset_with_unknown_alg.json
@@ -0,0 +1 @@
{"keys":[{"kid":"U1MayerhVuRj8xtFR8hyMH9lCfVMKlb3TG7mbQAS19M","kty":"RSA","alg":"RS256","use":"sig","n":"omef3NkXf4--6BtUPKjhlV7pf6Vv7HMg-VL-ITX8KQZTD4LTzWO3x9RPwVepKjgfvJe_IiZFaJX78-a7zpcG9mpZG8czp3C8nZSvAJKphvYLd9s9qYrGMFW9t1eHyGwmIQN02VXwHeZ0JDd5X4i7sO4XPkNycfzSoxaQbv7wANYBTcvcWcjYVxIj4ZpYkSsQqrrOTm69G7FyurtfExGc7jlSRcv-Gubq_K3IQLHGHTlil20wqZmis1dLJwpAjgTxY7uQSwEdqJHCJR3q76bsDelIBZpbR07kqIOXqYu52w0wkC_1W7_HcVPLNp6T_ML09P8jGsOWfMO95_zchkseQw","e":"AQAB","x5c":["MIICnTCCAYUCBgGAUN03JTANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0aW5nMB4XDTIyMDQyMjEwNDAxNloXDTMyMDQyMjEwNDE1NlowEjEQMA4GA1UEAwwHVGVzdGluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKJnn9zZF3+PvugbVDyo4ZVe6X+lb+xzIPlS/iE1/CkGUw+C081jt8fUT8FXqSo4H7yXvyImRWiV+/Pmu86XBvZqWRvHM6dwvJ2UrwCSqYb2C3fbPamKxjBVvbdXh8hsJiEDdNlV8B3mdCQ3eV+Iu7DuFz5DcnH80qMWkG7+8ADWAU3L3FnI2FcSI+GaWJErEKq6zk5uvRuxcrq7XxMRnO45UkXL/hrm6vytyECxxh05YpdtMKmZorNXSycKQI4E8WO7kEsBHaiRwiUd6u+m7A3pSAWaW0dO5KiDl6mLudsNMJAv9Vu/x3FTyzaek/zC9PT/IxrDlnzDvef83IZLHkMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAi7ZppYbkpt0ALn5NXIIPgA04svRwAmsUJWKLBS5iKVXq6HOJPsz0GAB9oKpjar83rUomwK2UE0XFJLMDvrB0nTZJBjm2DCANLL1GtTKUd+mdvhyHCIMrUApkhAYzv2Rk1c4+Jt7f5/h8FnM8jdl9FGc5TBy5ixS0OxnyW1JOakClYQz8vNS7LrC4hmLWwy7GAmUdemNLEefQcECaNzaLN5gGk1ht5lJyNCsHu9STZeYM2UXdDAtMtu9HAepfzh2CAOscSDtZr89SmFSwxKaOfbJyXH4PivMgWK4zO0P6ofuv8d8gRbUAUgnysKHQc0isTVWOxgmzI69EUe/iVXJHig=="],"x5t":"0C94xr3ayzaC9OUcSSLyrwDGdmI","x5t#S256":"O6ntIrYkVK0hX-_AwnrwJW1CO97lP3D2_aKnELuNLSo"},{"kid":"lYXxnemSzWNBUoPug_h0hZnjPi5oKCmQ9awQJaZCWWM","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"k75Ghd4r8h_fdydTAXyMjrGYNnuiG7yevoW1ZIIuegEUK3LLGY0Z3Q8PhCrkmi6LpkPwwR1C8ck9plvSs4vZ9GqmUoi5YcQEile6HjPG3NBwQ-cHWY4ZH_D-ItdzcZUKDxjHYaY-GW1yLeJ1RAh8wMPM7cenA2v0eNIq4HaIXzZJ2Hgxh4Ei-CSYcD0f_TYEySqUEb8jd0dC8frpkYDkOUCVizRBDUEg_hkPSpVqfLP8ekxIHxkC9wcfL-d2FhptxBQYN8NFnIuG9NFXbZ5mdzdmIuN6WPr_CECcgL9qXsph9U-L829dU67ufeBvzEejJ8qwiswslRdx4ZcYjtaBdQ","e":"AQAB","x5c":["MIICnTCCAYUCBgGAUN05KzANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0aW5nMB4XDTIyMDQyMjEwNDAxN1oXDTMyMDQyMjEwNDE1N1owEjEQMA4GA1UEAwwHVGVzdGluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJO+RoXeK/If33cnUwF8jI6xmDZ7ohu8nr6FtWSCLnoBFCtyyxmNGd0PD4Qq5Joui6ZD8MEdQvHJPaZb0rOL2fRqplKIuWHEBIpXuh4zxtzQcEPnB1mOGR/w/iLXc3GVCg8Yx2GmPhltci3idUQIfMDDzO3HpwNr9HjSKuB2iF82Sdh4MYeBIvgkmHA9H/02BMkqlBG/I3dHQvH66ZGA5DlAlYs0QQ1BIP4ZD0qVanyz/HpMSB8ZAvcHHy/ndhYabcQUGDfDRZyLhvTRV22eZnc3ZiLjelj6/whAnIC/al7KYfVPi/NvXVOu7n3gb8xHoyfKsIrMLJUXceGXGI7WgXUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAeMUFrCX4eAfF8i6wILOP5dDJOBN10nPP63VNliQ7+YHu1ZI0VGB7TNrImRE9riH2IWenSXD21DxK31qBlZKNEgaH7rVwwvOZ22qCyWacv1+QdanxAiljD03rU7HOR/tyqcvjl6U2Yadxcq6OWlKKVaa0fNtbPigqAwQ3iVpg9N+OthANYyKHxlmzJKGeEaDA69/uJ6UwektHlv/9BnNFh8We6EwJxYG7/rejI02EgbJFxGO1RlcmigTxRc5l3Dw4WldBIRxWiJgSEkKSfUy5S7sQdFQokZjTyqy6h1ldb/tgrWLIE0srGQ2u/fQeSgPTbAzihaeOf+WKq5RDXoq5bw=="],"x5t":"FaWinuPZQiDMljn3x9DMAuepBYQ","x5t#S256":"_0B--Hh1KgNtdyZqAp1NWUAikRPvlt2HGm__xXpjTi0"}]}
22 changes: 20 additions & 2 deletions tests/test_api_jwk.py
Expand Up @@ -4,7 +4,7 @@

from jwt.algorithms import has_crypto
from jwt.api_jwk import PyJWK, PyJWKSet
from jwt.exceptions import InvalidKeyError, PyJWKError
from jwt.exceptions import InvalidKeyError, PyJWKError, PyJWKSetError

from .utils import crypto_required, key_path

Expand Down Expand Up @@ -274,4 +274,22 @@ def test_keyset_should_index_by_kid(self):
assert jwk == jwk_set["keyid-abc123"]

with pytest.raises(KeyError):
jwk_set["this-kid-does-not-exist"]
_ = jwk_set["this-kid-does-not-exist"]

@crypto_required
def test_keyset_with_unknown_alg(self):
# first keyset with unusable key and usable key
with open(key_path("jwk_keyset_with_unknown_alg.json")) as keyfile:
jwks_text = keyfile.read()
jwks = json.loads(jwks_text)
assert len(jwks.get("keys")) == 2
keyset = PyJWKSet.from_json(jwks_text)
assert len(keyset.keys) == 1

# second keyset with only unusable key -> catch exception
with open(key_path("jwk_keyset_only_unknown_alg.json")) as keyfile:
jwks_text = keyfile.read()
jwks = json.loads(jwks_text)
assert len(jwks.get("keys")) == 1
with pytest.raises(PyJWKSetError):
_ = PyJWKSet.from_json(jwks_text)

0 comments on commit 599aba9

Please sign in to comment.