@@ -15,6 +15,8 @@ def _str2bytes(raw):
15
15
except : # Otherwise we treat it as bytes and return it as-is
16
16
return raw
17
17
18
+ def _encode_thumbprint (thumbprint ):
19
+ return base64 .urlsafe_b64encode (binascii .a2b_hex (thumbprint )).decode ()
18
20
19
21
class AssertionCreator (object ):
20
22
def create_normal_assertion (
@@ -65,7 +67,11 @@ def __call__(self):
65
67
66
68
67
69
class JwtAssertionCreator (AssertionCreator ):
68
- def __init__ (self , key , algorithm , sha1_thumbprint = None , headers = None ):
70
+ def __init__ (
71
+ self , key , algorithm , sha1_thumbprint = None , headers = None ,
72
+ * ,
73
+ sha256_thumbprint = None ,
74
+ ):
69
75
"""Construct a Jwt assertion creator.
70
76
71
77
Args:
@@ -80,13 +86,15 @@ def __init__(self, key, algorithm, sha1_thumbprint=None, headers=None):
80
86
RSA and ECDSA algorithms require "pip install cryptography".
81
87
sha1_thumbprint (str): The x5t aka X.509 certificate SHA-1 thumbprint.
82
88
headers (dict): Additional headers, e.g. "kid" or "x5c" etc.
89
+ sha256_thumbprint (str): The x5t#S256 aka X.509 certificate SHA-256 thumbprint.
83
90
"""
84
91
self .key = key
85
92
self .algorithm = algorithm
86
93
self .headers = headers or {}
94
+ if sha256_thumbprint : # https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.8
95
+ self .headers ["x5t#S256" ] = _encode_thumbprint (sha256_thumbprint )
87
96
if sha1_thumbprint : # https://tools.ietf.org/html/rfc7515#section-4.1.7
88
- self .headers ["x5t" ] = base64 .urlsafe_b64encode (
89
- binascii .a2b_hex (sha1_thumbprint )).decode ()
97
+ self .headers ["x5t" ] = _encode_thumbprint (sha1_thumbprint )
90
98
91
99
def create_normal_assertion (
92
100
self , audience , issuer , subject = None , expires_at = None , expires_in = 600 ,
0 commit comments