@@ -188,6 +188,23 @@ class ParmType(Enum):
188
188
'secp521r1' : 'P-521' ,
189
189
'secp256k1' : 'secp256k1' }
190
190
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
+ }
191
208
192
209
class InvalidJWKType (JWException ):
193
210
"""Invalid JWK Type Exception.
@@ -1050,6 +1067,28 @@ def thumbprint(self, hashalg=hashes.SHA256()):
1050
1067
digest .update (bytes (json_encode (t ).encode ('utf8' )))
1051
1068
return base64url_encode (digest .finalize ())
1052
1069
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
+
1053
1092
# Methods to constrain what this dict allows
1054
1093
def __setitem__ (self , item , value ):
1055
1094
kty = self .get ('kty' )
0 commit comments