python-jwt
python-jwt copied to clipboard
jwt.exceptions.UnsupportedKeyTypeError: could not deserialize
First encountered in https://github.com/NixOS/nixpkgs/issues/418879; confirmed as an upstream issue and reported here.
Steps to Reproduce
docker run -it --rm python:3.13.4 bash
git clone https://github.com/GehirnInc/python-jwt --depth 1
cd python-jwt
pip install -r ./requirements-dev.txt
sed -i 's/--flake8//' setup.cfg
pytest
Log
jwt/jwk.py:345: ValueError:
Could not deserialize key data. The data may be in an incorrect format,
it may be encrypted with an unsupported algorithm, or it may be an unsupported key type
(e.g. EC curves with explicit parameters).
Details: ASN.1 parsing error: unexpected tag (got Tag { value: 2, constructed: false, class: Universal })
jwt/jwk.py:350: UnsupportedKeyTypeError: this is probably a public key
jwt/jwk.py:371: UnsupportedKeyTypeError: could not deserialize
jwt/tests/test_jwk.py:90: in test_jwk_from_der
jwk_priv = jwk_from_der(load_testdata('rsa_privkey.der'))
==========short test summary info ==========
FAILED jwt/tests/test_jwk.py::test_jwk_from_der - jwt.exceptions.UnsupportedKeyTypeError: could not deserialize
======================================================= test session starts =======================================================
platform linux -- Python 3.13.4, pytest-6.2.5, py-1.11.0, pluggy-1.6.0
rootdir: /workdir/python-jwt, configfile: setup.cfg
plugins: flake8-1.1.0, cov-6.2.1
collected 48 items
jwt/tests/test_jwa.py .... [ 8%]
jwt/tests/test_jwk.py .......F................ [ 58%]
jwt/tests/test_jwkset.py ... [ 64%]
jwt/tests/test_jws.py ... [ 70%]
jwt/tests/test_jwt.py ....... [ 85%]
jwt/tests/test_utils.py ....... [100%]
============================================================ FAILURES =============================================================
________________________________________________________ test_jwk_from_der ________________________________________________________
content = b'0\x82\x04\xa4\x02\x01\x00\x02\x82\x01\x01\x00\xb4\xcf\xd1^3)\xec\x0b\xcf\xaev\xf5\xfe-\xc8\x99\xc6xy\xb9\x18\xf8\x0b...7X\xc4\x9d\x1a\xa9\x03\x01\x1d\xc3\xb4\xbe\xf2]2W&\x8d\x92n\xbay\x12<\xd2\x9f\xb0\xdc\x0cMm/a\'\xfe\xd4\x95]\xe5\x18\n'
private_loader = <built-in function load_der_private_key>
@jwk_from_bytes_argument_conversion
def jwk_from_private_bytes(
content: bytes,
private_loader: PrivateKeyLoaderT,
*,
password: Optional[str] = None,
backend: Optional[object] = None,
options: Optional[Mapping[str, object]] = None,
) -> AbstractJWKBase:
"""This function is meant to be called from jwk_from_bytes"""
if options is None:
options = {}
try:
> privkey = private_loader(content, password, backend) # type: ignore[operator] # noqa: E501
E ValueError: Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters). Details: ASN.1 parsing error: unexpected tag (got Tag { value: 2, constructed: false, class: Universal })
jwt/jwk.py:345: ValueError
The above exception was the direct cause of the following exception:
content = b'0\x82\x04\xa4\x02\x01\x00\x02\x82\x01\x01\x00\xb4\xcf\xd1^3)\xec\x0b\xcf\xaev\xf5\xfe-\xc8\x99\xc6xy\xb9\x18\xf8\x0b...7X\xc4\x9d\x1a\xa9\x03\x01\x1d\xc3\xb4\xbe\xf2]2W&\x8d\x92n\xbay\x12<\xd2\x9f\xb0\xdc\x0cMm/a\'\xfe\xd4\x95]\xe5\x18\n'
private_loader = 'load_der_private_key', public_loader = 'load_der_public_key'
def jwk_from_bytes(
content: bytes,
private_loader: PrivateKeyLoaderT,
public_loader: PublicKeyLoaderT,
*,
private_password: Optional[str] = None,
backend: Optional[object] = None,
options: Optional[Mapping[str, object]] = None,
) -> AbstractJWKBase:
try:
> return jwk_from_private_bytes(
content,
private_loader,
password=private_password,
backend=backend,
options=options,
)
jwt/jwk.py:384:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
content = b'0\x82\x04\xa4\x02\x01\x00\x02\x82\x01\x01\x00\xb4\xcf\xd1^3)\xec\x0b\xcf\xaev\xf5\xfe-\xc8\x99\xc6xy\xb9\x18\xf8\x0b...7X\xc4\x9d\x1a\xa9\x03\x01\x1d\xc3\xb4\xbe\xf2]2W&\x8d\x92n\xbay\x12<\xd2\x9f\xb0\xdc\x0cMm/a\'\xfe\xd4\x95]\xe5\x18\n'
loader = <built-in function load_der_private_key>, kwargs = {'backend': None, 'options': {}, 'password': None}
@wraps(func)
def wrapper(content, loader, **kwargs):
# now convert it to a Callable if it's a string
if isinstance(loader, str):
loader = getattr(serialization_module, loader)
if kwargs.get('options') is None:
kwargs['options'] = {}
> return func(content, loader, **kwargs)
jwt/jwk.py:328:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
content = b'0\x82\x04\xa4\x02\x01\x00\x02\x82\x01\x01\x00\xb4\xcf\xd1^3)\xec\x0b\xcf\xaev\xf5\xfe-\xc8\x99\xc6xy\xb9\x18\xf8\x0b...7X\xc4\x9d\x1a\xa9\x03\x01\x1d\xc3\xb4\xbe\xf2]2W&\x8d\x92n\xbay\x12<\xd2\x9f\xb0\xdc\x0cMm/a\'\xfe\xd4\x95]\xe5\x18\n'
private_loader = <built-in function load_der_private_key>
@jwk_from_bytes_argument_conversion
def jwk_from_private_bytes(
content: bytes,
private_loader: PrivateKeyLoaderT,
*,
password: Optional[str] = None,
backend: Optional[object] = None,
options: Optional[Mapping[str, object]] = None,
) -> AbstractJWKBase:
"""This function is meant to be called from jwk_from_bytes"""
if options is None:
options = {}
try:
privkey = private_loader(content, password, backend) # type: ignore[operator] # noqa: E501
if isinstance(privkey, RSAPrivateKey):
return RSAJWK(privkey, **options)
raise UnsupportedKeyTypeError('unsupported key type')
except ValueError as ex:
> raise UnsupportedKeyTypeError('this is probably a public key') from ex
E jwt.exceptions.UnsupportedKeyTypeError: this is probably a public key
jwt/jwk.py:350: UnsupportedKeyTypeError
During handling of the above exception, another exception occurred:
content = b'0\x82\x04\xa4\x02\x01\x00\x02\x82\x01\x01\x00\xb4\xcf\xd1^3)\xec\x0b\xcf\xaev\xf5\xfe-\xc8\x99\xc6xy\xb9\x18\xf8\x0b...7X\xc4\x9d\x1a\xa9\x03\x01\x1d\xc3\xb4\xbe\xf2]2W&\x8d\x92n\xbay\x12<\xd2\x9f\xb0\xdc\x0cMm/a\'\xfe\xd4\x95]\xe5\x18\n'
public_loader = <built-in function load_der_public_key>
@jwk_from_bytes_argument_conversion
def jwk_from_public_bytes(
content: bytes,
public_loader: PublicKeyLoaderT,
*,
backend: Optional[object] = None,
options: Optional[Mapping[str, object]] = None
) -> AbstractJWKBase:
"""This function is meant to be called from jwk_from_bytes"""
if options is None:
options = {}
try:
> pubkey = public_loader(content, backend) # type: ignore[operator]
E ValueError: Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters). Details: ASN.1 parsing error: unexpected tag (got Tag { value: 2, constructed: false, class: Universal })
jwt/jwk.py:365: ValueError
The above exception was the direct cause of the following exception:
def test_jwk_from_der():
> jwk_priv = jwk_from_der(load_testdata('rsa_privkey.der'))
jwt/tests/test_jwk.py:90:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
jwt/jwk.py:420: in jwk_from_der
return jwk_from_bytes(
jwt/jwk.py:392: in jwk_from_bytes
return jwk_from_public_bytes(
jwt/jwk.py:328: in wrapper
return func(content, loader, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
content = b'0\x82\x04\xa4\x02\x01\x00\x02\x82\x01\x01\x00\xb4\xcf\xd1^3)\xec\x0b\xcf\xaev\xf5\xfe-\xc8\x99\xc6xy\xb9\x18\xf8\x0b...7X\xc4\x9d\x1a\xa9\x03\x01\x1d\xc3\xb4\xbe\xf2]2W&\x8d\x92n\xbay\x12<\xd2\x9f\xb0\xdc\x0cMm/a\'\xfe\xd4\x95]\xe5\x18\n'
public_loader = <built-in function load_der_public_key>
@jwk_from_bytes_argument_conversion
def jwk_from_public_bytes(
content: bytes,
public_loader: PublicKeyLoaderT,
*,
backend: Optional[object] = None,
options: Optional[Mapping[str, object]] = None
) -> AbstractJWKBase:
"""This function is meant to be called from jwk_from_bytes"""
if options is None:
options = {}
try:
pubkey = public_loader(content, backend) # type: ignore[operator]
if isinstance(pubkey, RSAPublicKey):
return RSAJWK(pubkey, **options)
raise UnsupportedKeyTypeError(
'unsupported key type') # pragma: no cover
except ValueError as why:
> raise UnsupportedKeyTypeError('could not deserialize') from why
E jwt.exceptions.UnsupportedKeyTypeError: could not deserialize
jwt/jwk.py:371: UnsupportedKeyTypeError
======================================================== warnings summary =========================================================
../../usr/local/lib/python3.13/site-packages/_pytest/assertion/rewrite.py:689
/usr/local/lib/python3.13/site-packages/_pytest/assertion/rewrite.py:689: DeprecationWarning: ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead
and isinstance(item.value, ast.Str)
../../usr/local/lib/python3.13/site-packages/_pytest/assertion/rewrite.py:691
/usr/local/lib/python3.13/site-packages/_pytest/assertion/rewrite.py:691: DeprecationWarning: Attribute s is deprecated and will be removed in Python 3.14; use value instead
doc = item.value.s
jwt/tests/test_jwa.py: 4 warnings
jwt/tests/test_jwk.py: 16 warnings
jwt/tests/test_jwkset.py: 3 warnings
jwt/tests/test_jws.py: 3 warnings
jwt/tests/test_jwt.py: 7 warnings
/usr/local/lib/python3.13/unittest/case.py:597: RuntimeWarning: TestResult has no addDuration method
warnings.warn("TestResult has no addDuration method",
-- Docs: https://docs.pytest.org/en/stable/warnings.html
========================================================= tests coverage ==========================================================
_________________________________________ coverage: platform linux, python 3.13.4-final-0 _________________________________________
Name Stmts Miss Cover Missing
--------------------------------------------------------
jwt/__init__.py 6 0 100%
jwt/exceptions.py 15 0 100%
jwt/jwa.py 80 12 85% 38-44, 77, 109, 111, 146, 148
jwt/jwk.py 191 3 98% 176, 343, 363
jwt/jwkset.py 22 1 95% 23
jwt/jws.py 46 6 87% 50-51, 78-79, 97, 102
jwt/jwt.py 46 12 74% 60-61, 68-69, 91-92, 95-96, 104-105, 114-115
jwt/tests/__init__.py 0 0 100%
jwt/tests/helper.py 6 0 100%
jwt/tests/test_jwa.py 25 0 100%
jwt/tests/test_jwk.py 106 2 98% 92-93
jwt/tests/test_jwkset.py 25 0 100%
jwt/tests/test_jws.py 23 0 100%
jwt/tests/test_jwt.py 41 0 100%
jwt/tests/test_utils.py 23 0 100%
jwt/utils.py 29 0 100%
--------------------------------------------------------
TOTAL 684 36 95%
===================================================== short test summary info =====================================================
FAILED jwt/tests/test_jwk.py::test_jwk_from_der - jwt.exceptions.UnsupportedKeyTypeError: could not deserialize
============================================ 1 failed, 47 passed, 35 warnings in 1.32s ============================================