diff options
author | Determinant <[email protected]> | 2024-08-23 03:14:03 +0000 |
---|---|---|
committer | Determinant <[email protected]> | 2024-08-22 20:34:57 -0700 |
commit | 8d1c76ec7caf247d5675e14260d20fc508977ffb (patch) | |
tree | 8fa7c8ce3b7e3f4ece150a6da5922b5eb2dc7772 /frozen_deps/Cryptodome/Util | |
parent | 258780284151d49cba1d9c0d2ce33f9a19bb058b (diff) |
release v0.1.8
Diffstat (limited to 'frozen_deps/Cryptodome/Util')
-rw-r--r-- | frozen_deps/Cryptodome/Util/Counter.py | 2 | ||||
-rwxr-xr-x | frozen_deps/Cryptodome/Util/_cpuid_c.abi3.so | bin | 12776 -> 19304 bytes | |||
-rwxr-xr-x | frozen_deps/Cryptodome/Util/_cpuid_c.cpython-39-x86_64-linux-gnu.so | bin | 10899 -> 0 bytes | |||
-rw-r--r-- | frozen_deps/Cryptodome/Util/_raw_api.py | 6 | ||||
-rwxr-xr-x | frozen_deps/Cryptodome/Util/_strxor.abi3.so | bin | 14960 -> 20376 bytes | |||
-rwxr-xr-x | frozen_deps/Cryptodome/Util/_strxor.cpython-39-x86_64-linux-gnu.so | bin | 13213 -> 0 bytes | |||
-rw-r--r-- | frozen_deps/Cryptodome/Util/asn1.py | 209 | ||||
-rw-r--r-- | frozen_deps/Cryptodome/Util/asn1.pyi | 18 | ||||
-rw-r--r-- | frozen_deps/Cryptodome/Util/number.py | 81 | ||||
-rw-r--r-- | frozen_deps/Cryptodome/Util/py3compat.py | 11 |
10 files changed, 251 insertions, 76 deletions
diff --git a/frozen_deps/Cryptodome/Util/Counter.py b/frozen_deps/Cryptodome/Util/Counter.py index c67bc95..269b5a7 100644 --- a/frozen_deps/Cryptodome/Util/Counter.py +++ b/frozen_deps/Cryptodome/Util/Counter.py @@ -51,6 +51,8 @@ def new(nbits, prefix=b"", suffix=b"", initial_value=1, little_endian=False, all 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. diff --git a/frozen_deps/Cryptodome/Util/_cpuid_c.abi3.so b/frozen_deps/Cryptodome/Util/_cpuid_c.abi3.so Binary files differindex 60f1e26..51e31b7 100755 --- a/frozen_deps/Cryptodome/Util/_cpuid_c.abi3.so +++ b/frozen_deps/Cryptodome/Util/_cpuid_c.abi3.so diff --git a/frozen_deps/Cryptodome/Util/_cpuid_c.cpython-39-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Util/_cpuid_c.cpython-39-x86_64-linux-gnu.so Binary files differdeleted file mode 100755 index 718bec8..0000000 --- a/frozen_deps/Cryptodome/Util/_cpuid_c.cpython-39-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 c2e0187..cd64ac8 100644 --- a/frozen_deps/Cryptodome/Util/_raw_api.py +++ b/frozen_deps/Cryptodome/Util/_raw_api.py @@ -76,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() diff --git a/frozen_deps/Cryptodome/Util/_strxor.abi3.so b/frozen_deps/Cryptodome/Util/_strxor.abi3.so Binary files differindex c028978..f0f3784 100755 --- a/frozen_deps/Cryptodome/Util/_strxor.abi3.so +++ b/frozen_deps/Cryptodome/Util/_strxor.abi3.so diff --git a/frozen_deps/Cryptodome/Util/_strxor.cpython-39-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Util/_strxor.cpython-39-x86_64-linux-gnu.so Binary files differdeleted file mode 100755 index dd3fb45..0000000 --- a/frozen_deps/Cryptodome/Util/_strxor.cpython-39-x86_64-linux-gnu.so +++ /dev/null diff --git a/frozen_deps/Cryptodome/Util/asn1.py b/frozen_deps/Cryptodome/Util/asn1.py index a88f087..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. @@ -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): @@ -736,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. """ 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 5af85a3..6d59fd9 100644 --- a/frozen_deps/Cryptodome/Util/number.py +++ b/frozen_deps/Cryptodome/Util/number.py @@ -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. @@ -259,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 @@ -366,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 diff --git a/frozen_deps/Cryptodome/Util/py3compat.py b/frozen_deps/Cryptodome/Util/py3compat.py index 9a982e9..3294b66 100644 --- a/frozen_deps/Cryptodome/Util/py3compat.py +++ b/frozen_deps/Cryptodome/Util/py3compat.py @@ -87,6 +87,14 @@ if sys.version_info[0] == 2: def byte_string(s): return isinstance(s, str) + # 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 @@ -137,6 +145,9 @@ else: def byte_string(s): return isinstance(s, bytes) + def concat_buffers(a, b): + return a + b + from io import BytesIO from io import StringIO from sys import maxsize as maxint |