python-jose
python-jose copied to clipboard
jwk construction: impossible to NOT raise an exception with A256GCM algo
Hi everyone,
There is an issue constructing jwk's. I'm using the [cryptography] module.
NOTE: I got around this issue by just using jwe directly.
Consider the following example:
from jose import jwk
hmac_key = {
"kty": "oct",
"use": "enc",
"alg": 'A256GCM',
"k": b'\xfe\xd6\xbf\xcf<Z\xcc\x18\xc4\x92\xe1\xb7\xe7p\xeb\x92Z\x02\xfcP\xde\xa5p\xbc\x0c\xbe"/\xb2\xce\xf3a',
"key_ops": ['encrypt, decrypt']
}
jwk.construct(hmac_key)
This calls the following code, which assumes first that key_data is supposed to be a dictionary, but later in the function call, it is supposed to be a key itself (failing the len(32) condition in the key_class constructor).
def construct(key_data, algorithm=None):
"""
Construct a Key object for the given algorithm with the given
key_data.
"""
# Allow for pulling the algorithm off of the passed in jwk.
if not algorithm and isinstance(key_data, dict):
algorithm = key_data.get('alg', None)
if not algorithm:
raise JWKError('Unable to find an algorithm for key: %s' % key_data)
key_class = get_key(algorithm)
if not key_class:
raise JWKError('Unable to find an algorithm for key: %s' % key_data)
# problem -- key_class for 'a256GCM' expects a key!!!
return key_class(key_data, algorithm)
# return key_class(key_data['k'], algorithm) # my proposed workaround
However, my guess is that some key classes take a dictionary, others take a key itself. So that workaround I proposed would likely break things. At the very least, the A256GCM algorithm key class needs to be updated to extract the key dict.
def construct(key_data, algorithm=None):
"""
Construct a Key object for the given algorithm with the given
key_data.
"""
# Allow for pulling the algorithm off of the passed-in JWK.
if not algorithm and isinstance(key_data, dict):
algorithm = key_data.get('alg', None)
if not algorithm:
raise JWKError('Unable to find an algorithm for key: %s' % key_data)
key_class = get_key(algorithm)
if not key_class:
raise JWKError('Unable to find an algorithm for key: %s' % key_data)
# Check if key_data is a dictionary or a key
if isinstance(key_data, dict):
key = key_data.get('k')
else:
key = key_data
# Construct the key object
return key_class(key, algorithm)