예제 #1
0
    def __init__(self, name: str, config: LogConfig, display: Dict[Users,
                                                                   Levels]):
        if name is not None and not isinstance(name, str):
            raise HTypeError("name", name, str, None)

        if not isinstance(config, LogConfig):
            raise HTypeError("config", config, LogConfig)

        if display is not Display.ALL and not isinstance(display, dict):
            raise HTypeError("display", display, dict)

        self._name = name
        self._config = config
        self._display = display

        for user in self._display:
            if user not in self._config.users():
                raise LoggerError(
                    f"Displayed user "
                    f"must be in {self._config.users()}, rather than {user}.")

            if self._display[user] is not Display.ALL\
                and not isinstance(self._display[user], Iterable):
                raise HTypeError("display of {}".format(user),
                                 self._display[user], Iterable, Display.ALL)

            if self._display[user] is Display.ALL:
                continue

            for level in self._display[user]:
                if level not in self._config.levels(user):
                    raise LoggerError(
                        f"Displayed "
                        f"level of '{user}' must be in the "
                        f"{self._config.levels(user)}, rather than {level}.")
예제 #2
0
def hash_cls_name(obj: object,
                  hash_obj_1: HKSHash = __default_sha1,
                  hash_obj_2: HKSHash = __default_sha256) -> bytes:
    if not isinstance(hash_obj_1, HKSHash):
        raise HTypeError("hash_obj_1", hash_obj_1, HKSHash)

    if not isinstance(hash_obj_2, HKSHash):
        raise HTypeError("hash_obj_2", hash_obj_2, HKSHash)

    if type(obj).__name__ == 'type' or\
        type(obj).__name__ == 'builtin_function_or_method':
        cls_name = str(obj).split(".")[-1][:-2].encode()
    else:
        cls_name = type(obj).__name__.encode()

    hash_obj_1.reset()
    hash_obj_2.reset()
    hash_value_1 = hash_obj_1.finalize(cls_name)
    hash_value_2 = hash_obj_2.finalize(cls_name)

    hash_value = bytearray(b"\x00\x00")
    for c in hash_value_1:
        hash_value[0] = hash_value[0] ^ c

    for c in hash_value_2:
        hash_value[1] = hash_value[1] ^ c

    return bytes(hash_value)
예제 #3
0
    def __init__(
                    self,
                    cipher: HKSCipher,
                    name: str,
                    buffer_size: int,
                    logger_generator: LoggerGenerator = InvisibleLoggerGenerator(),
                    display: dict = {}
                ):
        if not isinstance(cipher, HKSCipher):
            raise HTypeError("cipher", cipher, HKSCipher)

        if not isinstance(buffer_size, int):
            raise HTypeError("buffer_size", int)

        if buffer_size <= 0:
            raise HFormatError("Parameter buffer_size expected an positive integer.")
        
        if not isinstance(logger_generator, LoggerGenerator):
            raise HTypeError("logger_generator", logger_generator, LoggerGenerator)

        if not isinstance(display, dict):
            raise HTypeError("display", display, dict)

        if not isinstance(name, str):
            raise HTypeError("name", name, str)

        self._name = name
        self._logger_generator = logger_generator
        self._display = display
        self._log = self._logger_generator.generate(name, self._display)

        self._log(StdUsers.DEV, StdLevels.DEBUG, "Initialized with "
        "cipher {}.".format(CipherID.cls2name(type(cipher))))

        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.__cipher = cipher
        self.__cipher.reset()

        self.set_reload_time(STCPSocket.DEFAULT_RELOAD_TIME)
        self.set_recv_timeout(None)

        self.__packet_encoder = SecurePacketEncoder(self.__cipher)
        self.__packet_decoder = SecurePacketDecoder(self.__cipher)
        self.__buffer = None
        self.__buffer_size = buffer_size

        self.__buffer_available = threading.Event()
        self._stop_auto_recv = False
        self._prepare_close = False

        self._is_working = False
예제 #4
0
    def push(self, packet: bytes, append_to_end: bool = True):
        if not isinstance(packet, bytes):
            raise HTypeError("packet", packet, bytes)

        if not isinstance(append_to_end, bool):
            raise HTypeError("append_to_end", append_to_end, bool)

        self._push_lock.acquire()

        if append_to_end:
            self._buffer.append(packet)
        else:
            self._buffer.insert(0, packet)

        self._push_lock.release()
예제 #5
0
    def quantizer(float_range: tuple, int_size: int):
        if not isinstance(float_range, tuple):
            raise HTypeError("float_range", float_range, tuple)

        if len(float_range) != 2 or sum(float_range) != 0:
            raise HFormatError(
                "Parameter float_range must be a symmetric pair.")

        if not isinstance(int_size, int):
            raise HTypeError("int_size", int_size, int)

        SignedBatchNumber.__quantizer.set_float_range(*float_range)
        SignedBatchNumber.__quantizer.set_int_size(
            int_size - SignedInteger.sign_size() + 1, signed=True)
        SignedBatchNumber.__quantizer.compile()
예제 #6
0
    def get_header(self, packet: bytes):
        if not isinstance(packet, bytes):
            raise HTypeError("packet", packet, bytes)

        if len(packet) > MAX_PACKET_SIZE:
            raise PacketSizeError("Packet size is too large "
                                  "(expected < {}).".format(MAX_PACKET_SIZE))

        if len(packet) < MIN_HEADER_SIZE:
            raise IncompletePacketError("Incomplete header.")

        header_size, payload_size = struct.unpack(">HI",
                                                  packet[:MIN_HEADER_SIZE])
        if header_size > MAX_HEADER_SIZE:
            raise PacketSizeError("Header size is too large "
                                  "(expected < {}).".format(MAX_HEADER_SIZE))

        if len(packet) < header_size:
            raise IncompletePacketError("Incomplete header.")

        header_dict = {}
        header_dict["header_size"] = header_size
        header_dict["payload_size"] = payload_size

        return header_dict
예제 #7
0
    def decrypt(self, ciphertext: bytes, finalize=True) -> bytes:
        if not isinstance(ciphertext, bytes):
            raise HTypeError("ciphertext", ciphertext, bytes)
  
        if not self._key:
            raise KeyError("Please provide key before calling decrypt()")

        if self._in_process is CipherProcess.NONE:
            self._in_process = CipherProcess.DECRYPT
            self._data = b""
        
        if self._in_process is not CipherProcess.DECRYPT:
            raise ResetError("You are in {} process, please call reset() "
            "before calling decrypt().".format(self._in_process.name))

        if self._iv is None:
            raise CipherParameterError("IV has not yet been set.")

        self._data += ciphertext
        plaintext = b""
        while len(self._data) > len(self._key):
            data_to_enc, self._data = self._data[:len(self._key)], self._data[len(self._key):]
            block = bxor(data_to_enc, self._key)
            plaintext += bxor(block, self._iv)

        if finalize:
            plaintext += self.finalize()

        return plaintext
예제 #8
0
    def __init__(self, logger_cls: Type[BaseLogger], **kwargs) -> None:
        if not issubclass(logger_cls, BaseLogger):
            raise HTypeError("logger_cls", logger_cls, Type[BaseLogger])

        super().__init__()
        self._logger_cls = logger_cls
        self._logger_kwargs = kwargs
예제 #9
0
    def decrypt(self, ciphertext: bytes, finalize=True) -> bytes:
        if not isinstance(ciphertext, bytes):
            raise HTypeError("ciphertext", ciphertext, bytes)

        if not self._key:
            raise KeyError("Please provide key before calling decrypt()")

        if self._aes is None:
            raise CipherParameterError("Please set iv value "
            "before calling decrypt().")

        if self._in_process is CipherProcess.NONE:
            self._in_process = CipherProcess.DECRYPT
            self._decryptor = self._aes.decryptor()
            self._unpadder = self._pkcs7.unpadder()

        if self._in_process is not CipherProcess.DECRYPT:
            raise ResetError("You are in {} process, please call reset() "
            "before calling decrypt().".format(self._in_process.name))

        padded_text = self._decryptor.update(ciphertext)
        plaintext = self._unpadder.update(padded_text)

        if finalize:
            plaintext += self.finalize()

        return plaintext
예제 #10
0
    def sendall(self, data: bytes) -> int:
        if not isinstance(data, bytes):
            raise HTypeError("data", data, bytes)

        self.__cipher.reset()
        packet = self.__packet_encoder.encode(data)
        return self._socket.sendall(packet)
예제 #11
0
    def use_dict(self, print_dict: dict):
        if not isinstance(print_dict, dict):
            raise HTypeError("print_dict", dict)

        for user in print_dict.keys():
            for level in print_dict[user]:
                self.__call__(user, level, print_dict[user][level])
예제 #12
0
    def decrypt(self, ciphertext: bytes, finalize=True) -> bytes:
        if not isinstance(ciphertext, bytes):
            raise HTypeError("ciphertext", ciphertext, bytes)

        if self._in_process is CipherProcess.NONE:
            self._in_process = CipherProcess.DECRYPT
            self._stored_digest = b""

        if self._in_process is not CipherProcess.DECRYPT:
            raise ResetError("You are in {} process, please call reset() "
            "before calling decrypt()".format(self._in_process.name))
        
        plaintext = self._cipher.decrypt(ciphertext, finalize=False)

        all_plaintext = self._stored_digest + plaintext

        actual_plaintext = all_plaintext[ : -self._hash.digest_size]

        self._stored_digest = all_plaintext[-self._hash.digest_size : ]

        self._hash.update(actual_plaintext)

        if finalize:
            actual_plaintext += self.finalize()

        return actual_plaintext
예제 #13
0
    def encrypt(self, plaintext: bytes, finalize=True) -> bytes:
        if not isinstance(plaintext, bytes):
            raise HTypeError("plaintext", plaintext, bytes)

        if not self._key:
            raise KeyError("Please provide key before calling encrypt()")

        if self._aes is None:
            raise CipherParameterError("Please set nonce "
            "value before calling encrypt().")

        if self._in_process is CipherProcess.NONE:
            self._in_process = CipherProcess.ENCRYPT
            self._encryptor = self._aes.encryptor()

        if self._in_process is not CipherProcess.ENCRYPT:
            raise ResetError("You are in {} process, please call reset() "
            "before calling encrypt().".format(self._in_process.name))

        ciphertext = self._encryptor.update(plaintext)

        if finalize:
            ciphertext += self.finalize()

        return ciphertext
예제 #14
0
    def finalize(self, msg: bytes = None) -> bytes:
        if msg is not None and not isinstance(msg, bytes):
            raise HTypeError("msg", msg, bytes, None)

        if msg is not None:
            self.update(msg)

        return self._digest.finalize()
예제 #15
0
    def __init__(self, key: bytes):
        if not isinstance(key, bytes) :
            raise HTypeError("key", key, bytes)

        super().__init__(key, 1)
        self._in_process: CipherProcess = CipherProcess.NONE
        self._data: bytes = None
        self._iv: bytes = None
예제 #16
0
    def set_padding_size(value: int):
        if not isinstance(value, int):
            raise HTypeError("value", value, int)

        if value <= 0:
            raise HFormatError("Parameter error expected an positive integer.")

        BatchNumber.__PADDING_SIZE = value
예제 #17
0
    def __add__(self, other: BatchNumber):
        if not isinstance(other, type(self)):
            raise HTypeError("other", other, type(self))

        result = super().__add__(other)
        result = GenericBatchNumber(result.raw(), len(result),
                                    result.value_size())
        result._n_cumulative = self._n_cumulative + other._n_cumulative
        return result
예제 #18
0
    def set_sign_size(value: int):
        if not isinstance(value, int):
            raise HTypeError("value", value, int)

        if value < 1:
            raise HFormatError(
                "The parameter value expected an positive integer.")

        SignedInteger.__SIGN_SIZE = value
예제 #19
0
    def set_recv_timeout(self, value: float):
        if value is not None and not isinstance(value, (int, float)):
            raise HTypeError("value", value, float, int, None)

        if value is not None and value < 0:
            raise HFormatError("Parameter value expected a non-negative number.")

        self._log(StdUsers.DEV, StdLevels.DEBUG, "Set received "
        "timeout to {}.".format(value))
        self.__recv_timeout = value
예제 #20
0
    def set_reload_time(self, value: float):
        if not isinstance(value, (int, float)):
            raise HTypeError("value", value, float, int)

        if value < 0:
            raise HFormatError("Parameter value expected a non-negative number.")

        self._log(StdUsers.DEV, StdLevels.DEBUG, "Set reload "
        "time to {}.".format(value))
        self.__reload_time = value
예제 #21
0
    def __init__(
            self,
            name: str = None,
            logger_generator: LoggerGenerator = InvisibleLoggerGenerator(),
            display: dict = {}):
        if name is not None and not isinstance(name, str):
            raise HTypeError("name", name, str, None)

        if not isinstance(logger_generator, LoggerGenerator):
            raise HTypeError("logger_generator", logger_generator,
                             LoggerGenerator)

        if not isinstance(display, dict):
            raise HTypeError("display", display, dict)

        if name is None:
            while name is None or name in LocalNode.node_names:
                name = str(random.randint(1000000, 9999999))

        if name in LocalNode.node_names:
            raise ChannelSlotError(f"Name {name} is in use.")

        if len(LocalNode.nodes) >= LocalNode.MAX_NODES:
            raise ChannelSlotError("No available slot in Local Node list.")

        LocalNode.lock.acquire()
        LocalNode.node_names.append(name)
        LocalNode.nodes.append(self)
        LocalNode.lock.release()

        self.name = name
        self._buffer = ChannelBuffer()
        self._closed = False

        self._buffer_available = threading.Event()
        self.__send_lock = threading.Lock()
        self.__recv_lock = threading.Lock()

        self._log = logger_generator.generate(name, display)

        self._log(StdUsers.DEV, StdLevels.INFO,
                  "{} join to Local Nodes.".format(name))
예제 #22
0
    def settimeout_raw(self, value: float):
        if value is not None and not isinstance(value, (int, float)):
            raise HTypeError("value", value, float, int, None)

        if value < 0:
            raise HFormatError("Parameter value expected a non-negative number.")

        self._log(StdUsers.DEV, StdLevels.DEBUG, "Set timeout "
        "to {}.".format(value))

        return self._socket.settimeout(value)
예제 #23
0
    def __ops__(self, other, operator):
        if not isinstance(other, type(self)):
            raise HTypeError("other", other, type(self))

        if self.size() != other.size():
            raise IntegerError("Two operands must be "
                               "the same size ({} != {}).".format(
                                   self.size(), other.size()))

        raw_result = operator(self.raw(), other.raw())

        return SignedInteger(raw_result, self.size())
예제 #24
0
    def register(cipher_cls: Type[HKSCipher]):
        if not issubclass(cipher_cls, HKSCipher):
            raise HTypeError("cipher_cls", cipher_cls, Type[HKSCipher])

        if hash_cls_name(cipher_cls) in CipherID._cipher_hashs.keys():
            raise CipherIDError()

        CipherID._cipher_hashs[hash_cls_name(cipher_cls)] = cipher_cls
        CipherID._cipher_names[cipher_cls.__name__] = cipher_cls
        CipherID._cipher_hashs_invert[cipher_cls] = hash_cls_name(cipher_cls)
        CipherID._cipher_names_invert[cipher_cls] = cipher_cls.__name__
        return cipher_cls
예제 #25
0
    def set_param(self, index: int, value: bytes) -> None:
        if not isinstance(value, bytes):
            raise HTypeError("value", value, bytes)

        if index == 0:
            if len(value) != len(self._key):
                raise CipherParameterError("IV of XorCipher must be a bytes object "
                "which is the same size as the key.")
            else:
                self._iv = value
        else:
            raise CipherParameterError("Index exceeds (XorCipher use only one parameter).")
예제 #26
0
def get_enum(cls: Iterable, obj: object, default: object = unknown):
    if not isinstance(cls, Iterable) and not issubclass(cls, Enum):
        raise HTypeError("cls", cls, Iterable, Type[Enum])

    if default == _Default.unknown:
        default = Default.unknown

    for e in cls:
        if e.value == obj or e == obj:
            return e

    return default
예제 #27
0
    def __call__(self, user: Users, level: Levels, *values, **kwargs):
        if not isinstance(user, Users):
            raise HTypeError("user", user, Users)

        if not isinstance(level, Levels):
            raise HTypeError("level", level, Levels)

        if user not in self._config.users():
            raise LoggerError(
                f"User must be in "
                f"{list(self._config.users())}, rather than {user}.")

        if level not in self._config.levels(user):
            raise LoggerError(
                f"Level of '{user}' "
                f"must be in {self._config.levels(user)}, rather than {level}."
            )

        if user not in self._display:
            return

        if self._display[
                user] is not Display.ALL and level not in self._display[user]:
            return

        output = self._config.output(user)
        output.open()

        now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S")

        if self._name:
            output.write(f"{now} {level.name.upper()} [{self._name}] -",
                         *values, **kwargs)
        else:
            output.write(f"{now} {level.name.upper()} -", *values, **kwargs)

        output.close()
예제 #28
0
    def send(self, destination_name: str, message: bytes, obj: object = None):
        if not isinstance(destination_name, str):
            raise HTypeError("destination_name", destination_name, str)

        if not isinstance(message, bytes):
            raise HTypeError("message", message, bytes)

        self.__send_lock.acquire()
        if isinstance(message, bytes) is False:
            raise Exception("Message must be a bytes object.")

        if self._closed:
            raise ChannelClosedError("Channel closed.")

        try:
            slot_of_destination = LocalNode.node_names.index(destination_name)
            destination_node: LocalNode = LocalNode.nodes[slot_of_destination]
        except ValueError:
            raise ChannelSlotError(
                f"Channel name {destination_name} doesn't exist.")

        destination_node._buffer.push(self.name, message, obj)
        destination_node._buffer_available.set()
        self.__send_lock.release()
예제 #29
0
    def __init__(
                    self,
                    decoder: PacketDecoder,
                    name: str,
                    logger_generator: LoggerGenerator = InvisibleLoggerGenerator(),
                    display: dict = {}
                ) -> None:
        if not isinstance(decoder, PacketDecoder):
            raise HTypeError("decoder", decoder, PacketDecoder)

        if name is not None and not isinstance(name, str):
            raise HTypeError("name", name, str, None)

        self._buffer = []

        self._packet_decoder = decoder

        self.__print = logger_generator.generate(name, display)
        
        self._current_packet = b""
        self._current_packet_size = 0
        self._expected_current_packet_size = 0
        
        self._push_lock = threading.Lock()
예제 #30
0
    def __init__(self, key: bytes):
        if not isinstance(key, bytes):
            raise HTypeError("key", key, bytes)

        if len(key) * 8 not in algorithms.AES.key_sizes:
            raise CipherParameterError("Key size of AES must be in {} (bits), "
            "not {} (bytes).".format(
                set(algorithms.AES.key_sizes),
                len(key)
            ))

        super().__init__(key, number_of_params=1)
        self._aes: Cipher = None
        self._encryptor: CipherContext = None
        self._decryptor: CipherContext = None
        self._in_process: CipherProcess = CipherProcess.NONE
        self._nonce = None