diff options
Diffstat (limited to 'frozen_deps/Cryptodome/Util')
-rw-r--r-- | frozen_deps/Cryptodome/Util/Counter.py | 9 | ||||
-rw-r--r-- | frozen_deps/Cryptodome/Util/Padding.py | 2 | ||||
-rwxr-xr-x | frozen_deps/Cryptodome/Util/_cpuid_c.abi3.so | bin | 0 -> 19304 bytes | |||
-rwxr-xr-x | frozen_deps/Cryptodome/Util/_cpuid_c.cpython-38-x86_64-linux-gnu.so | bin | 10899 -> 0 bytes | |||
-rw-r--r-- | frozen_deps/Cryptodome/Util/_raw_api.py | 68 | ||||
-rwxr-xr-x | frozen_deps/Cryptodome/Util/_strxor.abi3.so | bin | 0 -> 20376 bytes | |||
-rwxr-xr-x | frozen_deps/Cryptodome/Util/_strxor.cpython-38-x86_64-linux-gnu.so | bin | 13213 -> 0 bytes | |||
-rw-r--r-- | frozen_deps/Cryptodome/Util/asn1.py | 226 | ||||
-rw-r--r-- | frozen_deps/Cryptodome/Util/asn1.pyi | 18 | ||||
-rw-r--r-- | frozen_deps/Cryptodome/Util/number.py | 182 | ||||
-rw-r--r-- | frozen_deps/Cryptodome/Util/py3compat.py | 45 | ||||
-rw-r--r-- | frozen_deps/Cryptodome/Util/py3compat.pyi | 12 | ||||
-rw-r--r-- | frozen_deps/Cryptodome/Util/strxor.py | 51 |
13 files changed, 418 insertions, 195 deletions
diff --git a/frozen_deps/Cryptodome/Util/Counter.py b/frozen_deps/Cryptodome/Util/Counter.py index 423f91f..269b5a7 100644 --- a/frozen_deps/Cryptodome/Util/Counter.py +++ b/frozen_deps/Cryptodome/Util/Counter.py @@ -45,11 +45,14 @@ def new(nbits, prefix=b"", suffix=b"", initial_value=1, little_endian=False, all used. initial_value (integer): The initial value of the counter. Default value is 1. + Its length in bits must not exceed the argument ``nbits``. little_endian (boolean): If ``True``, the counter number will be encoded in little endian format. If ``False`` (default), in big endian format. allow_wraparound (boolean): This parameter is ignored. + An ``OverflowError`` exception is always raised when the counter wraps + around to zero. Returns: An object that can be passed with the :data:`counter` parameter to a CTR mode cipher. @@ -61,6 +64,12 @@ def new(nbits, prefix=b"", suffix=b"", initial_value=1, little_endian=False, all if (nbits % 8) != 0: raise ValueError("'nbits' must be a multiple of 8") + iv_bl = initial_value.bit_length() + if iv_bl > nbits: + raise ValueError("Initial value takes %d bits but it is longer than " + "the counter (%d bits)" % + (iv_bl, nbits)) + # Ignore wraparound return {"counter_len": nbits // 8, "prefix": prefix, diff --git a/frozen_deps/Cryptodome/Util/Padding.py b/frozen_deps/Cryptodome/Util/Padding.py index 1c353d1..b525475 100644 --- a/frozen_deps/Cryptodome/Util/Padding.py +++ b/frozen_deps/Cryptodome/Util/Padding.py @@ -82,6 +82,8 @@ def unpad(padded_data, block_size, style='pkcs7'): """ pdata_len = len(padded_data) + if pdata_len == 0: + raise ValueError("Zero-length input cannot be unpadded") if pdata_len % block_size: raise ValueError("Input data is not padded") if style in ('pkcs7', 'x923'): diff --git a/frozen_deps/Cryptodome/Util/_cpuid_c.abi3.so b/frozen_deps/Cryptodome/Util/_cpuid_c.abi3.so Binary files differnew file mode 100755 index 0000000..51e31b7 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/_cpuid_c.abi3.so diff --git a/frozen_deps/Cryptodome/Util/_cpuid_c.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Util/_cpuid_c.cpython-38-x86_64-linux-gnu.so Binary files differdeleted file mode 100755 index a555959..0000000 --- a/frozen_deps/Cryptodome/Util/_cpuid_c.cpython-38-x86_64-linux-gnu.so +++ /dev/null diff --git a/frozen_deps/Cryptodome/Util/_raw_api.py b/frozen_deps/Cryptodome/Util/_raw_api.py index 9423738..cd64ac8 100644 --- a/frozen_deps/Cryptodome/Util/_raw_api.py +++ b/frozen_deps/Cryptodome/Util/_raw_api.py @@ -28,6 +28,7 @@ # POSSIBILITY OF SUCH DAMAGE. # =================================================================== +import os import abc import sys from Cryptodome.Util.py3compat import byte_string @@ -50,10 +51,7 @@ else: extension_suffixes = machinery.EXTENSION_SUFFIXES # Which types with buffer interface we support (apart from byte strings) -if sys.version_info[0] == 2 and sys.version_info[1] < 7: - _buffer_type = (bytearray) -else: - _buffer_type = (bytearray, memoryview) +_buffer_type = (bytearray, memoryview) class _VoidPointer(object): @@ -69,9 +67,6 @@ class _VoidPointer(object): try: - if sys.version_info[0] == 2 and sys.version_info[1] < 7: - raise ImportError("CFFI is only supported with Python 2.7+") - # Starting from v2.18, pycparser (used by cffi for in-line ABI mode) # stops working correctly when PYOPTIMIZE==2 or the parameter -OO is # passed. In that case, we fall back to ctypes. @@ -81,6 +76,12 @@ try: if '__pypy__' not in sys.builtin_module_names and sys.flags.optimize == 2: raise ImportError("CFFI with optimize=2 fails due to pycparser bug.") + # cffi still uses PyUnicode_GetSize, which was removed in Python 3.12 + # thus leading to a crash on cffi.dlopen() + # See https://groups.google.com/u/1/g/python-cffi/c/oZkOIZ_zi5k + if sys.version_info >= (3, 12) and os.name == "nt": + raise ImportError("CFFI is not compatible with Python 3.12 on Windows") + from cffi import FFI ffi = FFI() @@ -98,7 +99,10 @@ try: @cdecl, the C function declarations. """ - lib = ffi.dlopen(name) + if hasattr(ffi, "RTLD_DEEPBIND") and not os.getenv('PYCRYPTODOME_DISABLE_DEEPBIND'): + lib = ffi.dlopen(name, ffi.RTLD_DEEPBIND) + else: + lib = ffi.dlopen(name) ffi.cdef(cdecl) return lib @@ -108,6 +112,7 @@ try: c_ulonglong = c_ulong c_uint = c_ulong + c_ubyte = c_ulong def c_size_t(x): """Convert a Python integer to size_t""" @@ -171,6 +176,11 @@ except ImportError: null_pointer = None cached_architecture = [] + def c_ubyte(c): + if not (0 <= c < 256): + raise OverflowError() + return ctypes.c_ubyte(c) + def load_lib(name, cdecl): if not cached_architecture: # platform.architecture() creates a subprocess, so caching the @@ -193,12 +203,7 @@ except ImportError: # ---- Get raw pointer --- - if sys.version_info[0] == 2 and sys.version_info[1] == 6: - # ctypes in 2.6 does not define c_ssize_t. Replacing it - # with c_size_t keeps the structure correctely laid out - _c_ssize_t = c_size_t - else: - _c_ssize_t = ctypes.c_ssize_t + _c_ssize_t = ctypes.c_ssize_t _PyBUF_SIMPLE = 0 _PyObject_GetBuffer = ctypes.pythonapi.PyObject_GetBuffer @@ -207,7 +212,7 @@ except ImportError: _c_ssize_p = ctypes.POINTER(_c_ssize_t) # See Include/object.h for CPython - # and https://github.com/pallets/click/blob/master/click/_winconsole.py + # and https://github.com/pallets/click/blob/master/src/click/_winconsole.py class _Py_buffer(ctypes.Structure): _fields_ = [ ('buf', c_void_p), @@ -235,7 +240,7 @@ except ImportError: buf = _Py_buffer() _PyObject_GetBuffer(obj, byref(buf), _PyBUF_SIMPLE) try: - buffer_type = c_ubyte * buf.len + buffer_type = ctypes.c_ubyte * buf.len return buffer_type.from_address(buf.buf) finally: _PyBuffer_Release(byref(buf)) @@ -260,7 +265,6 @@ except ImportError: return VoidPointer_ctypes() backend = "ctypes" - del ctypes class SmartPointer(object): @@ -301,27 +305,21 @@ def load_pycryptodome_raw_lib(name, cdecl): for ext in extension_suffixes: try: filename = basename + ext - return load_lib(pycryptodome_filename(dir_comps, filename), - cdecl) + full_name = pycryptodome_filename(dir_comps, filename) + if not os.path.isfile(full_name): + attempts.append("Not found '%s'" % filename) + continue + return load_lib(full_name, cdecl) except OSError as exp: - attempts.append("Trying '%s': %s" % (filename, str(exp))) + attempts.append("Cannot load '%s': %s" % (filename, str(exp))) raise OSError("Cannot load native module '%s': %s" % (name, ", ".join(attempts))) -if sys.version_info[:2] != (2, 6): - - def is_buffer(x): - """Return True if object x supports the buffer interface""" - return isinstance(x, (bytes, bytearray, memoryview)) - - def is_writeable_buffer(x): - return (isinstance(x, bytearray) or - (isinstance(x, memoryview) and not x.readonly)) - -else: +def is_buffer(x): + """Return True if object x supports the buffer interface""" + return isinstance(x, (bytes, bytearray, memoryview)) - def is_buffer(x): - return isinstance(x, (bytes, bytearray)) - def is_writeable_buffer(x): - return isinstance(x, bytearray) +def is_writeable_buffer(x): + return (isinstance(x, bytearray) or + (isinstance(x, memoryview) and not x.readonly)) diff --git a/frozen_deps/Cryptodome/Util/_strxor.abi3.so b/frozen_deps/Cryptodome/Util/_strxor.abi3.so Binary files differnew file mode 100755 index 0000000..f0f3784 --- /dev/null +++ b/frozen_deps/Cryptodome/Util/_strxor.abi3.so diff --git a/frozen_deps/Cryptodome/Util/_strxor.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Util/_strxor.cpython-38-x86_64-linux-gnu.so Binary files differdeleted file mode 100755 index ea7566c..0000000 --- a/frozen_deps/Cryptodome/Util/_strxor.cpython-38-x86_64-linux-gnu.so +++ /dev/null diff --git a/frozen_deps/Cryptodome/Util/asn1.py b/frozen_deps/Cryptodome/Util/asn1.py index 18e080c..36f2d72 100644 --- a/frozen_deps/Cryptodome/Util/asn1.py +++ b/frozen_deps/Cryptodome/Util/asn1.py @@ -22,13 +22,20 @@ import struct -from Cryptodome.Util.py3compat import byte_string, b, bchr, bord +from Cryptodome.Util.py3compat import byte_string, bchr, bord from Cryptodome.Util.number import long_to_bytes, bytes_to_long -__all__ = ['DerObject', 'DerInteger', 'DerOctetString', 'DerNull', - 'DerSequence', 'DerObjectId', 'DerBitString', 'DerSetOf'] +__all__ = ['DerObject', 'DerInteger', 'DerBoolean', 'DerOctetString', + 'DerNull', 'DerSequence', 'DerObjectId', 'DerBitString', 'DerSetOf'] +# Useful references: +# - https://luca.ntop.org/Teaching/Appunti/asn1.html +# - https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/ +# - https://www.zytrax.com/tech/survival/asn1.html +# - https://www.oss.com/asn1/resources/books-whitepapers-pubs/larmouth-asn1-book.pdf +# - https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf +# - https://misc.daniel-marschall.de/asn.1/oid-converter/online.php def _is_number(x, only_non_negative=False): test = 0 @@ -46,7 +53,7 @@ class BytesIO_EOF(object): def __init__(self, initial_bytes): self._buffer = initial_bytes self._index = 0 - self._bookmark = None + self._bookmark = None def set_bookmark(self): self._bookmark = self._index @@ -82,7 +89,7 @@ class DerObject(object): """Initialize the DER object according to a specific ASN.1 type. :Parameters: - asn1Id : integer + asn1Id : integer or byte The universal DER tag number for this object (e.g. 0x10 for a SEQUENCE). If None, the tag is not known yet. @@ -92,16 +99,20 @@ class DerObject(object): the content octets). If not specified, the payload is empty. - implicit : integer - The IMPLICIT tag number to use for the encoded object. + implicit : integer or byte + The IMPLICIT tag number (< 0x1F) to use for the encoded object. It overrides the universal tag *asn1Id*. + It cannot be combined with the ``explicit`` parameter. + By default, there is no IMPLICIT tag. constructed : bool True when the ASN.1 type is *constructed*. - False when it is *primitive*. + False when it is *primitive* (default). - explicit : integer - The EXPLICIT tag number to use for the encoded object. + explicit : integer or byte + The EXPLICIT tag number (< 0x1F) to use for the encoded object. + It cannot be combined with the ``implicit`` parameter. + By default, there is no EXPLICIT tag. """ if asn1Id is None: @@ -125,23 +136,26 @@ class DerObject(object): # context-spec | 1 0 (default for IMPLICIT/EXPLICIT) # private | 1 1 # + + constructed_bit = 0x20 if constructed else 0x00 + if None not in (explicit, implicit): raise ValueError("Explicit and implicit tags are" " mutually exclusive") if implicit is not None: - self._tag_octet = 0x80 | 0x20 * constructed | self._convertTag(implicit) - return - - if explicit is not None: - self._tag_octet = 0xA0 | self._convertTag(explicit) - self._inner_tag_octet = 0x20 * constructed | asn1Id - return - - self._tag_octet = 0x20 * constructed | asn1Id + # IMPLICIT tag overrides asn1Id + self._tag_octet = 0x80 | constructed_bit | self._convertTag(implicit) + elif explicit is not None: + # 'constructed bit' is always asserted for an EXPLICIT tag + self._tag_octet = 0x80 | 0x20 | self._convertTag(explicit) + self._inner_tag_octet = constructed_bit | asn1Id + else: + # Neither IMPLICIT nor EXPLICIT + self._tag_octet = constructed_bit | asn1Id def _convertTag(self, tag): - """Check if *tag* is a real DER tag. + """Check if *tag* is a real DER tag (5 bits). Convert it from a character to number if necessary. """ if not _is_number(tag): @@ -306,7 +320,7 @@ class DerInteger(DerObject): return DerObject.encode(self) def decode(self, der_encoded, strict=False): - """Decode a complete DER INTEGER DER, and re-initializes this + """Decode a DER-encoded INTEGER, and re-initializes this object with it. Args: @@ -341,6 +355,89 @@ class DerInteger(DerObject): self.value -= bits +class DerBoolean(DerObject): + """Class to model a DER-encoded BOOLEAN. + + An example of encoding is:: + + >>> from Cryptodome.Util.asn1 import DerBoolean + >>> bool_der = DerBoolean(True) + >>> print(bool_der.encode().hex()) + + which will show ``0101ff``, the DER encoding of True. + + And for decoding:: + + >>> s = bytes.fromhex('0101ff') + >>> try: + >>> bool_der = DerBoolean() + >>> bool_der.decode(s) + >>> print(bool_der.value) + >>> except ValueError: + >>> print "Not a valid DER BOOLEAN" + + the output will be ``True``. + + :ivar value: The boolean value + :vartype value: boolean + """ + def __init__(self, value=False, implicit=None, explicit=None): + """Initialize the DER object as a BOOLEAN. + + Args: + value (boolean): + The value of the boolean. Default is False. + + implicit (integer or byte): + The IMPLICIT tag number (< 0x1F) to use for the encoded object. + It overrides the universal tag for BOOLEAN (1). + It cannot be combined with the ``explicit`` parameter. + By default, there is no IMPLICIT tag. + + explicit (integer or byte): + The EXPLICIT tag number (< 0x1F) to use for the encoded object. + It cannot be combined with the ``implicit`` parameter. + By default, there is no EXPLICIT tag. + """ + + DerObject.__init__(self, 0x01, b'', implicit, False, explicit) + self.value = value # The boolean value + + def encode(self): + """Return the DER BOOLEAN, fully encoded as a binary string.""" + + self.payload = b'\xFF' if self.value else b'\x00' + return DerObject.encode(self) + + def decode(self, der_encoded, strict=False): + """Decode a DER-encoded BOOLEAN, and re-initializes this object with it. + + Args: + der_encoded (byte string): A DER-encoded BOOLEAN. + + Raises: + ValueError: in case of parsing errors. + """ + + return DerObject.decode(self, der_encoded, strict) + + def _decodeFromStream(self, s, strict): + """Decode a DER-encoded BOOLEAN from a file.""" + + # Fill up self.payload + DerObject._decodeFromStream(self, s, strict) + + if len(self.payload) != 1: + raise ValueError("Invalid encoding for DER BOOLEAN: payload is not 1 byte") + + if bord(self.payload[0]) == 0: + self.value = False + elif bord(self.payload[0]) == 0xFF: + self.value = True + else: + raise ValueError("Invalid payload for DER BOOLEAN") + + class DerSequence(DerObject): """Class to model a DER SEQUENCE. @@ -384,7 +481,7 @@ class DerSequence(DerObject): """ - def __init__(self, startSeq=None, implicit=None): + def __init__(self, startSeq=None, implicit=None, explicit=None): """Initialize the DER object as a SEQUENCE. :Parameters: @@ -392,12 +489,19 @@ class DerSequence(DerObject): A sequence whose element are either integers or other DER objects. - implicit : integer - The IMPLICIT tag to use for the encoded object. + implicit : integer or byte + The IMPLICIT tag number (< 0x1F) to use for the encoded object. It overrides the universal tag for SEQUENCE (16). + It cannot be combined with the ``explicit`` parameter. + By default, there is no IMPLICIT tag. + + explicit : integer or byte + The EXPLICIT tag number (< 0x1F) to use for the encoded object. + It cannot be combined with the ``implicit`` parameter. + By default, there is no EXPLICIT tag. """ - DerObject.__init__(self, 0x10, b'', implicit, True) + DerObject.__init__(self, 0x10, b'', implicit, True, explicit) if startSeq is None: self._seq = [] else: @@ -434,6 +538,10 @@ class DerSequence(DerObject): self._seq.append(item) return self + def insert(self, index, item): + self._seq.insert(index, item) + return self + def hasInts(self, only_non_negative=True): """Return the number of items in this sequence that are integers. @@ -442,7 +550,7 @@ class DerSequence(DerObject): only_non_negative (boolean): If ``True``, negative integers are not counted in. """ - + items = [x for x in self._seq if _is_number(x, only_non_negative)] return len(items) @@ -527,7 +635,6 @@ class DerSequence(DerObject): self._seq.append(p.data_since_bookmark()) else: derInt = DerInteger() - #import pdb; pdb.set_trace() data = p.data_since_bookmark() derInt.decode(data, strict=strict) self._seq.append(derInt.value) @@ -648,19 +755,25 @@ class DerObjectId(DerObject): binary string.""" comps = [int(x) for x in self.value.split(".")] + if len(comps) < 2: raise ValueError("Not a valid Object Identifier string") - self.payload = bchr(40*comps[0]+comps[1]) - for v in comps[2:]: - if v == 0: - enc = [0] - else: - enc = [] - while v: - enc.insert(0, (v & 0x7F) | 0x80) - v >>= 7 - enc[-1] &= 0x7F - self.payload += b''.join([bchr(x) for x in enc]) + if comps[0] > 2: + raise ValueError("First component must be 0, 1 or 2") + if comps[0] < 2 and comps[1] > 39: + raise ValueError("Second component must be 39 at most") + + subcomps = [40 * comps[0] + comps[1]] + comps[2:] + + encoding = [] + for v in reversed(subcomps): + encoding.append(v & 0x7F) + v >>= 7 + while v: + encoding.append((v & 0x7F) | 0x80) + v >>= 7 + + self.payload = b''.join([bchr(x) for x in reversed(encoding)]) return DerObject.encode(self) def decode(self, der_encoded, strict=False): @@ -687,15 +800,27 @@ class DerObjectId(DerObject): # Derive self.value from self.payload p = BytesIO_EOF(self.payload) - comps = [str(x) for x in divmod(p.read_byte(), 40)] + + subcomps = [] v = 0 while p.remaining_data(): c = p.read_byte() - v = v*128 + (c & 0x7F) + v = (v << 7) + (c & 0x7F) if not (c & 0x80): - comps.append(str(v)) + subcomps.append(v) v = 0 - self.value = '.'.join(comps) + + if len(subcomps) == 0: + raise ValueError("Empty payload") + + if subcomps[0] < 40: + subcomps[:1] = [0, subcomps[0]] + elif subcomps[0] < 80: + subcomps[:1] = [1, subcomps[0] - 40] + else: + subcomps[:1] = [2, subcomps[0] - 80] + + self.value = ".".join([str(x) for x in subcomps]) class DerBitString(DerObject): @@ -704,21 +829,20 @@ class DerBitString(DerObject): An example of encoding is: >>> from Cryptodome.Util.asn1 import DerBitString - >>> from binascii import hexlify, unhexlify - >>> bs_der = DerBitString(b'\\xaa') - >>> bs_der.value += b'\\xbb' - >>> print hexlify(bs_der.encode()) + >>> bs_der = DerBitString(b'\\xAA') + >>> bs_der.value += b'\\xBB' + >>> print(bs_der.encode().hex()) - which will show ``040300aabb``, the DER encoding for the bit string + which will show ``030300aabb``, the DER encoding for the bit string ``b'\\xAA\\xBB'``. For decoding: - >>> s = unhexlify(b'040300aabb') + >>> s = bytes.fromhex('030300aabb') >>> try: >>> bs_der = DerBitString() >>> bs_der.decode(s) - >>> print hexlify(bs_der.value) + >>> print(bs_der.value.hex()) >>> except ValueError: >>> print "Not a valid DER BIT STRING" @@ -737,7 +861,7 @@ class DerBitString(DerObject): If not specified, the bit string is empty. implicit : integer The IMPLICIT tag to use for the encoded object. - It overrides the universal tag for OCTET STRING (3). + It overrides the universal tag for BIT STRING (3). explicit : integer The EXPLICIT tag to use for the encoded object. """ @@ -751,7 +875,7 @@ class DerBitString(DerObject): def encode(self): """Return the DER BIT STRING, fully encoded as a - binary string.""" + byte string.""" # Add padding count byte self.payload = b'\x00' + self.value diff --git a/frozen_deps/Cryptodome/Util/asn1.pyi b/frozen_deps/Cryptodome/Util/asn1.pyi index dac023b..ee4891c 100644 --- a/frozen_deps/Cryptodome/Util/asn1.pyi +++ b/frozen_deps/Cryptodome/Util/asn1.pyi @@ -19,13 +19,19 @@ class DerObject: def __init__(self, asn1Id: Optional[int]=None, payload: Optional[bytes]=..., implicit: Optional[int]=None, constructed: Optional[bool]=False, explicit: Optional[int]=None) -> None: ... def encode(self) -> bytes: ... - def decode(self, der_encoded: bytes, strict: Optional[bool]=False) -> DerObject: ... + def decode(self, der_encoded: bytes, strict: bool=...) -> DerObject: ... class DerInteger(DerObject): value: int def __init__(self, value: Optional[int]= 0, implicit: Optional[int]=None, explicit: Optional[int]=None) -> None: ... def encode(self) -> bytes: ... - def decode(self, der_encoded: bytes, strict: Optional[bool]=False) -> DerInteger: ... + def decode(self, der_encoded: bytes, strict: bool=...) -> DerInteger: ... + +class DerBoolean(DerObject): + value: bool + def __init__(self, value: bool=..., implicit: Optional[Union[int, bytes]]=..., explicit: Optional[Union[int, bytes]]=...) -> None: ... + def encode(self) -> bytes: ... + def decode(self, der_encoded: bytes, strict: bool=...) -> DerBoolean: ... class DerSequence(DerObject): def __init__(self, startSeq: Optional[Sequence[Union[int, DerInteger, DerObject]]]=None, implicit: Optional[int]=None) -> None: ... @@ -41,7 +47,7 @@ class DerSequence(DerObject): def hasInts(self, only_non_negative: Optional[bool]=True) -> int: ... def hasOnlyInts(self, only_non_negative: Optional[bool]=True) -> bool: ... def encode(self) -> bytes: ... - def decode(self, der_encoded: bytes, strict: Optional[bool]=False, nr_elements: Optional[int]=None, only_ints_expected: Optional[bool]=False) -> DerSequence: ... + def decode(self, der_encoded: bytes, strict: bool=..., nr_elements: Optional[int]=None, only_ints_expected: Optional[bool]=False) -> DerSequence: ... class DerOctetString(DerObject): payload: bytes @@ -54,13 +60,13 @@ class DerObjectId(DerObject): value: str def __init__(self, value: Optional[str]=..., implicit: Optional[int]=None, explicit: Optional[int]=None) -> None: ... def encode(self) -> bytes: ... - def decode(self, der_encoded: bytes, strict: Optional[bool]=False) -> DerObjectId: ... + def decode(self, der_encoded: bytes, strict: bool=...) -> DerObjectId: ... class DerBitString(DerObject): value: bytes def __init__(self, value: Optional[bytes]=..., implicit: Optional[int]=None, explicit: Optional[int]=None) -> None: ... def encode(self) -> bytes: ... - def decode(self, der_encoded: bytes, strict: Optional[bool]=False) -> DerBitString: ... + def decode(self, der_encoded: bytes, strict: bool=...) -> DerBitString: ... DerSetElement = Union[bytes, int] @@ -70,5 +76,5 @@ class DerSetOf(DerObject): def __iter__(self) -> Iterable: ... def __len__(self) -> int: ... def add(self, elem: DerSetElement) -> None: ... - def decode(self, der_encoded: bytes, strict: Optional[bool]=False) -> DerObject: ... + def decode(self, der_encoded: bytes, strict: bool=...) -> DerObject: ... def encode(self) -> bytes: ... diff --git a/frozen_deps/Cryptodome/Util/number.py b/frozen_deps/Cryptodome/Util/number.py index 0367fdc..6d59fd9 100644 --- a/frozen_deps/Cryptodome/Util/number.py +++ b/frozen_deps/Cryptodome/Util/number.py @@ -28,7 +28,7 @@ import math import sys import struct from Cryptodome import Random -from Cryptodome.Util.py3compat import _memoryview, iter_range +from Cryptodome.Util.py3compat import iter_range # Backward compatibility _fastmath = None @@ -51,12 +51,8 @@ def size (N): """Returns the size of the number N in bits.""" if N < 0: - raise ValueError("Size in bits only avialable for non-negative numbers") - - bits = 0 - while N >> bits: - bits += 1 - return bits + raise ValueError("Size in bits only available for non-negative numbers") + return N.bit_length() def getRandomInteger(N, randfunc=None): @@ -113,27 +109,56 @@ def getRandomNBitInteger(N, randfunc=None): assert size(value) >= N return value -def GCD(x,y): - """Greatest Common Denominator of :data:`x` and :data:`y`. - """ - x = abs(x) ; y = abs(y) - while x > 0: - x, y = y % x, x - return y +if sys.version_info[:2] >= (3, 5): + + GCD = math.gcd + +else: + + def GCD(x,y): + """Greatest Common Denominator of :data:`x` and :data:`y`. + """ + + x = abs(x) ; y = abs(y) + while x > 0: + x, y = y % x, x + return y + -def inverse(u, v): - """The inverse of :data:`u` *mod* :data:`v`.""" +if sys.version_info[:2] >= (3, 8): - u3, v3 = u, v - u1, v1 = 1, 0 - while v3 > 0: - q = u3 // v3 - u1, v1 = v1, u1 - v1*q - u3, v3 = v3, u3 - v3*q - while u1<0: - u1 = u1 + v - return u1 + def inverse(u, v): + """The inverse of :data:`u` *mod* :data:`v`.""" + + if v == 0: + raise ZeroDivisionError("Modulus cannot be zero") + if v < 0: + raise ValueError("Modulus cannot be negative") + + return pow(u, -1, v) + +else: + + def inverse(u, v): + """The inverse of :data:`u` *mod* :data:`v`.""" + + if v == 0: + raise ZeroDivisionError("Modulus cannot be zero") + if v < 0: + raise ValueError("Modulus cannot be negative") + + u3, v3 = u, v + u1, v1 = 1, 0 + while v3 > 0: + q = u3 // v3 + u1, v1 = v1, u1 - v1*q + u3, v3 = v3, u3 - v3*q + if u3 != 1: + raise ValueError("No inverse value can be computed") + while u1<0: + u1 = u1 + v + return u1 # Given a number of bits to generate and a random generation function, # find a prime number of the appropriate size. @@ -141,14 +166,19 @@ def inverse(u, v): def getPrime(N, randfunc=None): """Return a random N-bit prime number. + N must be an integer larger than 1. If randfunc is omitted, then :meth:`Random.get_random_bytes` is used. """ if randfunc is None: randfunc = Random.get_random_bytes - number=getRandomNBitInteger(N, randfunc) | 1 - while (not isPrime(number, randfunc=randfunc)): - number=number+2 + if N < 2: + raise ValueError("N must be larger than 1") + + while True: + number = getRandomNBitInteger(N, randfunc) | 1 + if isPrime(number, randfunc=randfunc): + break return number @@ -254,7 +284,7 @@ def getStrongPrime(N, e=0, false_positive_prob=1e-6, randfunc=None): # calculate range for X # lower_bound = sqrt(2) * 2^{511 + 128*x} # upper_bound = 2^{512 + 128*x} - 1 - x = (N - 512) >> 7; + x = (N - 512) >> 7 # We need to approximate the sqrt(2) in the lower_bound by an integer # expression because floating point math overflows with these numbers lower_bound = (14142135623730950489 * (2 ** (511 + 128*x))) // 10000000000000000000 @@ -361,12 +391,12 @@ def isPrime(N, false_positive_prob=1e-6, randfunc=None): return N == 2 for p in sieve_base: if N == p: - return 1 + return True if N % p == 0: - return 0 + return False rounds = int(math.ceil(-math.log(false_positive_prob)/math.log(4))) - return _rabinMillerTest(N, rounds, randfunc) + return bool(_rabinMillerTest(N, rounds, randfunc)) # Improved conversion functions contributed by Barry Warsaw, after @@ -375,46 +405,72 @@ def isPrime(N, false_positive_prob=1e-6, randfunc=None): import struct def long_to_bytes(n, blocksize=0): - """Convert an integer to a byte string. + """Convert a positive integer to a byte string using big endian encoding. - In Python 3.2+, use the native method instead:: + If :data:`blocksize` is absent or zero, the byte string will + be of minimal length. - >>> n.to_bytes(blocksize, 'big') + Otherwise, the length of the byte string is guaranteed to be a multiple + of :data:`blocksize`. If necessary, zeroes (``\\x00``) are added at the left. - For instance:: + .. note:: + In Python 3, if you are sure that :data:`n` can fit into + :data:`blocksize` bytes, you can simply use the native method instead:: - >>> n = 80 - >>> n.to_bytes(2, 'big') - b'\x00P' + >>> n.to_bytes(blocksize, 'big') - If the optional :data:`blocksize` is provided and greater than zero, - the byte string is padded with binary zeros (on the front) so that - the total length of the output is a multiple of blocksize. + For instance:: - If :data:`blocksize` is zero or not provided, the byte string will - be of minimal length. + >>> n = 80 + >>> n.to_bytes(2, 'big') + b'\\x00P' + + However, and unlike this ``long_to_bytes()`` function, + an ``OverflowError`` exception is raised if :data:`n` does not fit. """ - # after much testing, this algorithm was deemed to be the fastest - s = b'' - n = int(n) + + if n < 0 or blocksize < 0: + raise ValueError("Values must be non-negative") + + result = [] pack = struct.pack - while n > 0: - s = pack('>I', n & 0xffffffff) + s + + # Fill the first block independently from the value of n + bsr = blocksize + while bsr >= 8: + result.insert(0, pack('>Q', n & 0xFFFFFFFFFFFFFFFF)) + n = n >> 64 + bsr -= 8 + + while bsr >= 4: + result.insert(0, pack('>I', n & 0xFFFFFFFF)) n = n >> 32 - # strip off leading zeros - for i in range(len(s)): - if s[i] != b'\x00'[0]: - break + bsr -= 4 + + while bsr > 0: + result.insert(0, pack('>B', n & 0xFF)) + n = n >> 8 + bsr -= 1 + + if n == 0: + if len(result) == 0: + bresult = b'\x00' + else: + bresult = b''.join(result) else: - # only happens when n == 0 - s = b'\x00' - i = 0 - s = s[i:] - # add back some pad bytes. this could be done more efficiently w.r.t. the - # de-padding being done above, but sigh... - if blocksize > 0 and len(s) % blocksize: - s = (blocksize - len(s) % blocksize) * b'\x00' + s - return s + # The encoded number exceeds the block size + while n > 0: + result.insert(0, pack('>Q', n & 0xFFFFFFFFFFFFFFFF)) + n = n >> 64 + result[0] = result[0].lstrip(b'\x00') + bresult = b''.join(result) + # bresult has minimum length here + if blocksize > 0: + target_len = ((len(bresult) - 1) // blocksize + 1) * blocksize + bresult = b'\x00' * (target_len - len(bresult)) + bresult + + return bresult + def bytes_to_long(s): """Convert a byte string to a long integer (big endian). @@ -439,7 +495,7 @@ def bytes_to_long(s): if sys.version_info[0:3] < (2, 7, 4): if isinstance(s, bytearray): s = bytes(s) - elif isinstance(s, _memoryview): + elif isinstance(s, memoryview): s = s.tobytes() length = len(s) diff --git a/frozen_deps/Cryptodome/Util/py3compat.py b/frozen_deps/Cryptodome/Util/py3compat.py index 40ef752..3294b66 100644 --- a/frozen_deps/Cryptodome/Util/py3compat.py +++ b/frozen_deps/Cryptodome/Util/py3compat.py @@ -78,6 +78,8 @@ if sys.version_info[0] == 2: return s elif isinstance(s, bytearray): return bytes(s) + elif isinstance(s, memoryview): + return s.tobytes() else: return ''.join(s) def tostr(bs): @@ -85,17 +87,19 @@ if sys.version_info[0] == 2: def byte_string(s): return isinstance(s, str) - # In Pyton 2.x, StringIO is a stand-alone module - from StringIO import StringIO as BytesIO + # In Python 2, a memoryview does not support concatenation + def concat_buffers(a, b): + if isinstance(a, memoryview): + a = a.tobytes() + if isinstance(b, memoryview): + b = b.tobytes() + return a + b + + from StringIO import StringIO + BytesIO = StringIO from sys import maxint - if sys.version_info[1] < 7: - import types - _memoryview = types.NoneType - else: - _memoryview = memoryview - iter_range = xrange def is_native_int(x): @@ -104,8 +108,15 @@ if sys.version_info[0] == 2: def is_string(x): return isinstance(x, basestring) + def is_bytes(x): + return isinstance(x, str) or \ + isinstance(x, bytearray) or \ + isinstance(x, memoryview) + ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()}) + FileNotFoundError = IOError + else: def b(s): return s.encode("latin-1") # utf-8 would cause some side-effects we don't want @@ -125,6 +136,8 @@ else: return bytes(s) elif isinstance(s,str): return s.encode(encoding) + elif isinstance(s, memoryview): + return s.tobytes() else: return bytes([s]) def tostr(bs): @@ -132,12 +145,13 @@ else: def byte_string(s): return isinstance(s, bytes) - # In Python 3.x, StringIO is a sub-module of io + def concat_buffers(a, b): + return a + b + from io import BytesIO + from io import StringIO from sys import maxsize as maxint - _memoryview = memoryview - iter_range = range def is_native_int(x): @@ -146,14 +160,21 @@ else: def is_string(x): return isinstance(x, str) + def is_bytes(x): + return isinstance(x, bytes) or \ + isinstance(x, bytearray) or \ + isinstance(x, memoryview) + from abc import ABC + FileNotFoundError = FileNotFoundError + def _copy_bytes(start, end, seq): """Return an immutable copy of a sequence (byte string, byte array, memoryview) in a certain interval [start:seq]""" - if isinstance(seq, _memoryview): + if isinstance(seq, memoryview): return seq[start:end].tobytes() elif isinstance(seq, bytearray): return bytes(seq[start:end]) diff --git a/frozen_deps/Cryptodome/Util/py3compat.pyi b/frozen_deps/Cryptodome/Util/py3compat.pyi index 3297dc0..74e04a2 100644 --- a/frozen_deps/Cryptodome/Util/py3compat.pyi +++ b/frozen_deps/Cryptodome/Util/py3compat.pyi @@ -13,23 +13,21 @@ def bytestring(x: Any) -> bool: ... def is_native_int(s: Any) -> bool: ... def is_string(x: Any) -> bool: ... +def is_bytes(x: Any) -> bool: ... def BytesIO(b: bytes) -> IO[bytes]: ... +def StringIO(s: str) -> IO[str]: ... if sys.version_info[0] == 2: from sys import maxint iter_range = xrange - if sys.version_info[1] < 7: - import types - _memoryview = types.NoneType - else: - _memoryview = memoryview - else: from sys import maxsize as maxint iter_range = range - _memoryview = memoryview +class FileNotFoundError: + def __init__(self, err: int, msg: str, filename: str) -> None: + pass def _copy_bytes(start: Optional[int], end: Optional[int], seq: Buffer) -> bytes: ... diff --git a/frozen_deps/Cryptodome/Util/strxor.py b/frozen_deps/Cryptodome/Util/strxor.py index 91fb4c9..6b16155 100644 --- a/frozen_deps/Cryptodome/Util/strxor.py +++ b/frozen_deps/Cryptodome/Util/strxor.py @@ -32,7 +32,8 @@ from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, c_size_t, create_string_buffer, get_raw_buffer, c_uint8_ptr, is_writeable_buffer) -_raw_strxor = load_pycryptodome_raw_lib("Cryptodome.Util._strxor", +_raw_strxor = load_pycryptodome_raw_lib( + "Cryptodome.Util._strxor", """ void strxor(const uint8_t *in1, const uint8_t *in2, @@ -45,33 +46,38 @@ _raw_strxor = load_pycryptodome_raw_lib("Cryptodome.Util._strxor", def strxor(term1, term2, output=None): - """XOR two byte strings. - + """From two byte strings of equal length, + create a third one which is the byte-by-byte XOR of the two. + Args: term1 (bytes/bytearray/memoryview): - The first term of the XOR operation. + The first byte string to XOR. term2 (bytes/bytearray/memoryview): - The second term of the XOR operation. + The second byte string to XOR. output (bytearray/memoryview): - The location where the result must be written to. + The location where the result will be written to. + It must have the same length as ``term1`` and ``term2``. If ``None``, the result is returned. :Return: - If ``output`` is ``None``, a new ``bytes`` string with the result. + If ``output`` is ``None``, a new byte string with the result. Otherwise ``None``. + + .. note:: + ``term1`` and ``term2`` must have the same length. """ if len(term1) != len(term2): raise ValueError("Only byte strings of equal length can be xored") - + if output is None: result = create_string_buffer(len(term1)) else: # Note: output may overlap with either input result = output - + if not is_writeable_buffer(output): raise TypeError("output must be a bytearray or a writeable memoryview") - + if len(term1) != len(output): raise ValueError("output must have the same length as the input" " (%d bytes)" % len(term1)) @@ -88,15 +94,19 @@ def strxor(term1, term2, output=None): def strxor_c(term, c, output=None): - """XOR a byte string with a repeated sequence of characters. + """From a byte string, create a second one of equal length + where each byte is XOR-red with the same value. Args: - term(bytes/bytearray/memoryview): - The first term of the XOR operation. - c (bytes): - The byte that makes up the second term of the XOR operation. - output (None or bytearray/memoryview): - If not ``None``, the location where the result is stored into. + term(bytes/bytearray/memoryview): + The byte string to XOR. + c (int): + Every byte in the string will be XOR-ed with this value. + It must be between 0 and 255 (included). + output (None or bytearray/memoryview): + The location where the result will be written to. + It must have the same length as ``term``. + If ``None``, the result is returned. Return: If ``output`` is ``None``, a new ``bytes`` string with the result. @@ -105,16 +115,16 @@ def strxor_c(term, c, output=None): if not 0 <= c < 256: raise ValueError("c must be in range(256)") - + if output is None: result = create_string_buffer(len(term)) else: # Note: output may overlap with either input result = output - + if not is_writeable_buffer(output): raise TypeError("output must be a bytearray or a writeable memoryview") - + if len(term) != len(output): raise ValueError("output must have the same length as the input" " (%d bytes)" % len(term)) @@ -134,4 +144,3 @@ def strxor_c(term, c, output=None): def _strxor_direct(term1, term2, result): """Very fast XOR - check conditions!""" _raw_strxor.strxor(term1, term2, result, c_size_t(len(term1))) - |