def bytes_to_integer(bytes): if not type(bytes) == netius.legacy.BYTES: raise netius.DataError("Invalid data type") number = 0 for byte in bytes: number = (number << 8) | netius.legacy.ord(byte) return number
def integer_to_bytes(number, length = 0): if not isinstance(number, netius.legacy.INTEGERS): raise netius.DataError("Invalid data type") bytes = [] number = abs(number) while number > 0: bytes.append(chr(number & 0xff)) number >>= 8 remaining = length - len(bytes) remaining = 0 if remaining < 0 else remaining for _index in range(remaining): bytes.append("\x00") bytes = reversed(bytes) bytes_s = "".join(bytes) bytes_s = netius.legacy.bytes(bytes_s) return bytes_s
def modinv(first, second): """ Uses the extended greatest common divisor algorithm to compute the modulus of an inverted value against another. The execution of this method is equivalent to (1 / first mod second) using mathematical terms. @type first: int @param first: The first value, that is going to be inverted before the modulus operation is performed. @type second: int @param second: The second value that is going to be used as the basis for the modulus operation. @rtype: int @return: The result of the computation of inverted modulus according to its mathematical definition. """ d, l, _e = egcd(first, second) if d != 1: raise netius.DataError("Modular inverse does not exist") else: return l % second
def decode_ws(data): # calculates the length of the data and runs the initial # verification ensuring that such data is larger than the # minimum value for a valid websockets frame data_l = len(data) assert_ws(data_l, 2) # retrieves the reference to the second byte in the frame # this is the byte that is going to be used in the initial # calculus of the length for the current data frame second_byte = data[1] # verifies if the current frame is a masked one and calculates # the number of mask bytes taking that into account has_mask = netius.legacy.ord(second_byte) & 128 mask_bytes = 4 if has_mask else 0 # retrieves the base length (simplified length) of the # frame as the seven last bits of the second byte in frame length = netius.legacy.ord(second_byte) & 127 index_mask_f = 2 # verifies if the length to be calculated is of type # extended (length equals to 126) if that's the case # two extra bytes must be taken into account on length if length == 126: assert_ws(data_l, 4) length = 0 length += netius.legacy.ord(data[2]) << 8 length += netius.legacy.ord(data[3]) index_mask_f = 4 # check if the length to be calculated is of type extended # payload length and if that's the case many more bytes # (eight) must be taken into account for length calculus elif length == 127: assert_ws(data_l, 10) length = 0 length += netius.legacy.ord(data[2]) << 56 length += netius.legacy.ord(data[3]) << 48 length += netius.legacy.ord(data[4]) << 40 length += netius.legacy.ord(data[5]) << 32 length += netius.legacy.ord(data[6]) << 24 length += netius.legacy.ord(data[7]) << 16 length += netius.legacy.ord(data[8]) << 8 length += netius.legacy.ord(data[9]) index_mask_f = 10 # calculates the size of the raw data part of the message and # in case its smaller than the defined length of the data returns # immediately indicating that there's not enough data to complete # the decoding of the data (should be re-trying again latter) raw_size = data_l - index_mask_f - mask_bytes if raw_size < length: raise netius.DataError("Not enough data") # in case the frame data is not masked the complete set of contents # may be returned immediately to the caller as there's no issue with # avoiding the unmasking operation (as the data is not masked) if not has_mask: return data[index_mask_f:], b"" # retrieves the mask part of the data that are going to be # used in the decoding part of the process mask = data[index_mask_f:index_mask_f + mask_bytes] # allocates the array that is going to be used # for the decoding of the data with the length # that was computed as the data length decoded_a = bytearray(length) # starts the initial data index and then iterates over the # range of decoded length applying the mask to the data # (decoding it consequently) to the created decoded array i = index_mask_f + 4 for j in range(length): decoded_a[j] = netius.legacy.chri( netius.legacy.ord(data[i]) ^ netius.legacy.ord(mask[j % 4])) i += 1 # converts the decoded array of data into a string and # and returns the "partial" string containing the data that # remained pending to be parsed decoded = bytes(decoded_a) return decoded, data[i:]
def assert_ws(data_l, size): if data_l < size: raise netius.DataError("Not enough data")