Skip to content

Commit 52341be

Browse files
committed
Add support for RFC 9278: JWK Thumbprint URI
Signed-off-by: Simo Sorce <[email protected]>
1 parent e5c1e42 commit 52341be

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

jwcrypto/jwk.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,23 @@ class ParmType(Enum):
188188
'secp521r1': 'P-521',
189189
'secp256k1': 'secp256k1'}
190190

191+
IANANamedInformationHashAlgorithmRegistry = {
192+
'sha-256': hashes.SHA256(),
193+
'sha-256-128': None,
194+
'sha-256-120': None,
195+
'sha-256-96': None,
196+
'sha-256-64': None,
197+
'sha-256-32': None,
198+
'sha-384': hashes.SHA384(),
199+
'sha-512': hashes.SHA512(),
200+
'sha3-224': hashes.SHA3_224(),
201+
'sha3-256': hashes.SHA3_256(),
202+
'sha3-384': hashes.SHA3_384(),
203+
'sha3-512': hashes.SHA3_512(),
204+
'blake2s-256': hashes.BLAKE2s(32),
205+
'blake2b-256': None, # pyca supports only 64 bytes for BLAKEb
206+
'blake2b-512': hashes.BLAKE2b(64),
207+
}
191208

192209
class InvalidJWKType(JWException):
193210
"""Invalid JWK Type Exception.
@@ -1050,6 +1067,28 @@ def thumbprint(self, hashalg=hashes.SHA256()):
10501067
digest.update(bytes(json_encode(t).encode('utf8')))
10511068
return base64url_encode(digest.finalize())
10521069

1070+
def thumbprint_uri(self, hname='sha-256'):
1071+
"""Returns the key thumbprint URI as specified by RFC 9278.
1072+
1073+
:param hname: A hash function name as specified in IANA's
1074+
Named Information registry:
1075+
https://www.iana.org/assignments/named-information/
1076+
Values from `IANANamedInformationHashAlgorithmRegistry`
1077+
1078+
:return: A JWK Thumbprint URI
1079+
:rtype: `str`
1080+
"""
1081+
1082+
try:
1083+
h = IANANamedInformationHashAlgorithmRegistry[hname]
1084+
except KeyError as e:
1085+
raise InvalidJWKValue('Unknown hash "{}"'.format(hname)) from e
1086+
if h is None:
1087+
raise InvalidJWKValue('Unsupported hash "{}"'.format(hname))
1088+
1089+
t = self.thumbprint(h)
1090+
return "urn:ietf:params:oauth:jwk-thumbprint:{}:{}".format(hname, t)
1091+
10531092
# Methods to constrain what this dict allows
10541093
def __setitem__(self, item, value):
10551094
kty = self.get('kty')

jwcrypto/tests.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,13 @@ def test_p256k_alias(self):
642642
verify.verify(pub_k.public())
643643
self.assertEqual(verify.payload, payload)
644644

645+
def test_thumbprint_uri(self):
646+
k = jwk.JWK(**PublicKeys['keys'][1])
647+
self.assertEqual(
648+
k.thumbprint_uri(),
649+
"urn:ietf:params:oauth:jwk-thumbprint:sha-256:" +
650+
PublicKeys['thumbprints'][1])
651+
645652

646653
# RFC 7515 - A.1
647654
A1_protected = \

0 commit comments

Comments
 (0)