@@ -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
192209class 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' )
0 commit comments