66from cryptography .hazmat .primitives .asymmetric import ec , utils
77from cryptography .hazmat .primitives import hashes
88
9- from py_vapid .utils import b64urldecode , b64urlencode
9+ from py_vapid .utils import b64urldecode , b64urlencode , num_to_bytes
1010
1111
1212def extract_signature (auth ):
13- """Fix the JWT auth token
14-
15- convert a ecdsa integer pair into an OpenSSL DER pair.
13+ """
14+ Extracts the payload and signature from a JWT, converting the
15+ signature from the JOSE format (RFC 7518, section 3.4) to the
16+ RFC 3279 format that Cryptography requires.
1617
1718 :param auth: A JWT Authorization Token.
1819 :type auth: str
@@ -23,7 +24,7 @@ def extract_signature(auth):
2324 payload , asig = auth .encode ('utf8' ).rsplit (b'.' , 1 )
2425 sig = b64urldecode (asig )
2526 if len (sig ) != 64 :
26- return payload , sig
27+ raise InvalidSignature ()
2728
2829 encoded = utils .encode_dss_signature (
2930 s = int (binascii .hexlify (sig [32 :]), 16 ),
@@ -35,8 +36,6 @@ def extract_signature(auth):
3536def decode (token , key ):
3637 """Decode a web token into an assertion dictionary
3738
38- This attempts to rectify both ecdsa and openssl generated signatures.
39-
4039 :param token: VAPID auth token
4140 :type token: str
4241 :param key: bitarray containing the public key
@@ -84,5 +83,6 @@ def sign(claims, key):
8483 separators = (',' , ':' )).encode ('utf8' ))
8584 token = "{}.{}" .format (header , claims )
8685 rsig = key .sign (token .encode ('utf8' ), ec .ECDSA (hashes .SHA256 ()))
87- sig = b64urlencode (rsig )
86+ (r , s ) = utils .decode_dss_signature (rsig )
87+ sig = b64urlencode (num_to_bytes (r ) + num_to_bytes (s ))
8888 return "{}.{}" .format (token , sig )
0 commit comments