diff options
author | esneider <dariosn@gmail.com> | 2015-05-13 03:15:56 -0300 |
---|---|---|
committer | esneider <dariosn@gmail.com> | 2015-05-13 03:15:56 -0300 |
commit | 01b7fb0e65c8a6de5c67c1b0c9df0a4c27805ba8 (patch) | |
tree | 35f4bac54c9a3db5ac60dd1b0b199d2e7cca1b0e /jwt/utils.py | |
parent | b8771db171187a83a69257221cd441e013e1041a (diff) | |
download | pyjwt-01b7fb0e65c8a6de5c67c1b0c9df0a4c27805ba8.tar.gz |
Fix the ECDSA signature serialization format when using cryptography
Diffstat (limited to 'jwt/utils.py')
-rw-r--r-- | jwt/utils.py | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/jwt/utils.py b/jwt/utils.py index bb7b3a3..85e3ae0 100644 --- a/jwt/utils.py +++ b/jwt/utils.py @@ -1,4 +1,12 @@ import base64 +import binascii + +try: + from cryptography.hazmat.primitives.asymmetric.utils import ( + decode_rfc6979_signature, encode_rfc6979_signature + ) +except ImportError: + pass def base64url_decode(input): @@ -25,3 +33,35 @@ def merge_dict(original, updates): raise TypeError('original and updates must be a dictionary: %s' % e) return merged_options + + +def number_to_bytes(num, num_bytes): + padded_hex = '%0*x' % (2 * num_bytes, num) + big_endian = binascii.a2b_hex(padded_hex.encode('ascii')) + return big_endian + + +def bytes_to_number(string): + return int(binascii.b2a_hex(string), 16) + + +def der_to_raw_signature(der_sig, curve): + num_bits = curve.key_size + num_bytes = (num_bits + 7) / 8 + + r, s = decode_rfc6979_signature(der_sig) + + return number_to_bytes(r, num_bytes) + number_to_bytes(s, num_bytes) + + +def raw_to_der_signature(raw_sig, curve): + num_bits = curve.key_size + num_bytes = (num_bits + 7) / 8 + + if len(raw_sig) != 2 * num_bytes: + raise ValueError('Invalid signature') + + r = bytes_to_number(raw_sig[:num_bytes]) + s = bytes_to_number(raw_sig[num_bytes:]) + + return encode_rfc6979_signature(r, s) |