Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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