Skip to content

Commit

Permalink
Add support for RFC 9278: JWK Thumbprint URI
Browse files Browse the repository at this point in the history
Signed-off-by: Simo Sorce <simo@redhat.com>
  • Loading branch information
simo5 committed Aug 13, 2022
1 parent e5c1e42 commit 70ce728
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
40 changes: 40 additions & 0 deletions jwcrypto/jwk.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,24 @@ class ParmType(Enum):
'secp521r1': 'P-521',
'secp256k1': 'secp256k1'}

IANANamedInformationHashAlgorithmRegistry = {
'sha-256': hashes.SHA256(),
'sha-256-128': None,
'sha-256-120': None,
'sha-256-96': None,
'sha-256-64': None,
'sha-256-32': None,
'sha-384': hashes.SHA384(),
'sha-512': hashes.SHA512(),
'sha3-224': hashes.SHA3_224(),
'sha3-256': hashes.SHA3_256(),
'sha3-384': hashes.SHA3_384(),
'sha3-512': hashes.SHA3_512(),
'blake2s-256': hashes.BLAKE2s(32),
'blake2b-256': None, # pyca supports only 64 bytes for BLAKEb
'blake2b-512': hashes.BLAKE2b(64),
}


class InvalidJWKType(JWException):
"""Invalid JWK Type Exception.
Expand Down Expand Up @@ -1050,6 +1068,28 @@ def thumbprint(self, hashalg=hashes.SHA256()):
digest.update(bytes(json_encode(t).encode('utf8')))
return base64url_encode(digest.finalize())

def thumbprint_uri(self, hname='sha-256'):
"""Returns the key thumbprint URI as specified by RFC 9278.
:param hname: A hash function name as specified in IANA's
Named Information registry:
https://www.iana.org/assignments/named-information/
Values from `IANANamedInformationHashAlgorithmRegistry`
:return: A JWK Thumbprint URI
:rtype: `str`
"""

try:
h = IANANamedInformationHashAlgorithmRegistry[hname]
except KeyError as e:
raise InvalidJWKValue('Unknown hash "{}"'.format(hname)) from e
if h is None:
raise InvalidJWKValue('Unsupported hash "{}"'.format(hname))

t = self.thumbprint(h)
return "urn:ietf:params:oauth:jwk-thumbprint:{}:{}".format(hname, t)

# Methods to constrain what this dict allows
def __setitem__(self, item, value):
kty = self.get('kty')
Expand Down
7 changes: 7 additions & 0 deletions jwcrypto/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,13 @@ def test_p256k_alias(self):
verify.verify(pub_k.public())
self.assertEqual(verify.payload, payload)

def test_thumbprint_uri(self):
k = jwk.JWK(**PublicKeys['keys'][1])
self.assertEqual(
k.thumbprint_uri(),
"urn:ietf:params:oauth:jwk-thumbprint:sha-256:{}".format(
PublicKeys['thumbprints'][1]))


# RFC 7515 - A.1
A1_protected = \
Expand Down

0 comments on commit 70ce728

Please sign in to comment.