|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- import base64
- import binascii
- import struct
-
- from .compat import binary_type, bytes_from_int, text_type
-
- try:
- from cryptography.hazmat.primitives.asymmetric.utils import (
- decode_dss_signature, encode_dss_signature
- )
- except ImportError:
- pass
-
-
- def force_unicode(value):
- if isinstance(value, binary_type):
- return value.decode('utf-8')
- elif isinstance(value, text_type):
- return value
- else:
- raise TypeError('Expected a string value')
-
-
- def force_bytes(value):
- if isinstance(value, text_type):
- return value.encode('utf-8')
- elif isinstance(value, binary_type):
- return value
- else:
- raise TypeError('Expected a string value')
-
-
- def base64url_decode(input):
- if isinstance(input, text_type):
- input = input.encode('ascii')
-
- rem = len(input) % 4
-
- if rem > 0:
- input += b'=' * (4 - rem)
-
- return base64.urlsafe_b64decode(input)
-
-
- def base64url_encode(input):
- return base64.urlsafe_b64encode(input).replace(b'=', b'')
-
-
- def to_base64url_uint(val):
- if val < 0:
- raise ValueError('Must be a positive integer')
-
- int_bytes = bytes_from_int(val)
-
- if len(int_bytes) == 0:
- int_bytes = b'\x00'
-
- return base64url_encode(int_bytes)
-
-
- def from_base64url_uint(val):
- if isinstance(val, text_type):
- val = val.encode('ascii')
-
- data = base64url_decode(val)
-
- buf = struct.unpack('%sB' % len(data), data)
- return int(''.join(["%02x" % byte for byte in buf]), 16)
-
-
- def merge_dict(original, updates):
- if not updates:
- return original
-
- try:
- merged_options = original.copy()
- merged_options.update(updates)
- except (AttributeError, ValueError) as e:
- 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_dss_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_dss_signature(r, s)
|