summaryrefslogtreecommitdiff
path: root/jwt/utils.py
diff options
context:
space:
mode:
authoresneider <dariosn@gmail.com>2015-05-13 03:15:56 -0300
committeresneider <dariosn@gmail.com>2015-05-13 03:15:56 -0300
commit01b7fb0e65c8a6de5c67c1b0c9df0a4c27805ba8 (patch)
tree35f4bac54c9a3db5ac60dd1b0b199d2e7cca1b0e /jwt/utils.py
parentb8771db171187a83a69257221cd441e013e1041a (diff)
downloadpyjwt-01b7fb0e65c8a6de5c67c1b0c9df0a4c27805ba8.tar.gz
Fix the ECDSA signature serialization format when using cryptography
Diffstat (limited to 'jwt/utils.py')
-rw-r--r--jwt/utils.py40
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)