def store_settings(self) -> None: """Store settings to an encrypted database. The plaintext in the encrypted database is a constant length bytestring regardless of stored setting values. """ attribute_list = [self.__getattribute__(k) for k in self.key_list] bytes_lst = [] for a in attribute_list: if isinstance(a, bool): bytes_lst.append(bool_to_bytes(a)) elif isinstance(a, int): bytes_lst.append(int_to_bytes(a)) elif isinstance(a, float): bytes_lst.append(double_to_bytes(a)) else: raise CriticalError("Invalid attribute type in settings.") pt_bytes = b''.join(bytes_lst) ct_bytes = encrypt_and_sign(pt_bytes, self.master_key.master_key) ensure_dir(DIR_USER_DATA) with open(self.file_name, 'wb+') as f: f.write(ct_bytes)
def test_invalid_window_raises_fr(self): # Setup message = b'testgroup' ts = datetime.datetime.now() timestamp = double_to_bytes(time.time() * 1000) header = GROUP_MESSAGE_HEADER + timestamp + b'test_group' + US_BYTE apct_list = self.create_message_apct(ORIGIN_CONTACT_HEADER, message, header=header) contact_list = ContactList(nicks=['Alice', 'Bob', 'local']) key_list = KeyList(nicks=['Alice', 'Bob', 'local']) keyset = key_list.get_keyset('*****@*****.**') keyset.rx_harac = 1 keyset.rx_key = 32 * b'\x01' keyset.rx_hek = 32 * b'\x01' group_list = GroupList(groups=['testgroup']) settings = Settings() packet_list = PacketList(contact_list=contact_list, settings=settings) window_list = WindowList(contact_list=contact_list, group_list=group_list, packet_list=packet_list, settings=settings) master_key = MasterKey() # Test for p in apct_list: self.assertFR("Received message to unknown group.", process_message, ts, p, window_list, packet_list, contact_list, key_list, group_list, settings, master_key) # Teardown cleanup()
def mock_entry_preprocessor(message: str, header: bytes = b'', group: bool = False) -> List[bytes]: if not header: if group: timestamp = double_to_bytes(time.time() * 1000) header = GROUP_MESSAGE_HEADER + timestamp + 'testgroup'.encode() + US_BYTE else: header = PRIVATE_MESSAGE_HEADER plaintext = message.encode() payload = header + plaintext payload = zlib.compress(payload, level=9) if len(payload) < 255: padded = byte_padding(payload) packet_list = [M_S_HEADER + padded] else: msg_key = bytes(32) payload = encrypt_and_sign(payload, msg_key) payload += msg_key padded = byte_padding(payload) p_list = split_byte_string(padded, item_len=255) packet_list = ([M_L_HEADER + p_list[0]] + [M_A_HEADER + p for p in p_list[1:-1]] + [M_E_HEADER + p_list[-1]]) return packet_list
def queue_message(user_input: Union['UserInput', 'Message'], window: Union['MockWindow', 'Window'], settings: 'Settings', m_queue: 'Queue', header: bytes = b'') -> None: """Convert message into set of assembly packets and queue them. :param user_input: UserInput object :param window: Window object :param settings: Settings object :param m_queue: Multiprocessing message queue :param header: Overrides message header with group management header :return: None """ if not header: if window.type == 'group': timestamp = double_to_bytes(time.time() * 1000) header = GROUP_MESSAGE_HEADER + timestamp + window.name.encode( ) + US_BYTE else: header = PRIVATE_MESSAGE_HEADER plaintext = user_input.plaintext.encode() payload = header + plaintext payload = zlib.compress(payload, level=9) if len(payload) < 255: padded = byte_padding(payload) packet_list = [M_S_HEADER + padded] else: msg_key = keygen() payload = encrypt_and_sign(payload, msg_key) payload += msg_key padded = byte_padding(payload) p_list = split_byte_string(padded, item_len=255) packet_list = ([M_L_HEADER + p_list[0]] + [M_A_HEADER + p for p in p_list[1:-1]] + [M_E_HEADER + p_list[-1]]) if settings.session_trickle: log_m_dictionary = dict((c.rx_account, c.log_messages) for c in window) for p in packet_list: m_queue.put((p, log_m_dictionary)) else: for c in window: log_setting = window.group.log_messages if window.type == 'group' else c.log_messages for p in packet_list: m_queue.put((p, settings, c.rx_account, c.tx_account, log_setting, window.uid))
def change_setting(self, key: str, value: str, contact_list: 'ContactList', group_list: 'GroupList') -> None: """Parse, update and store new setting value.""" attribute = self.__getattribute__(key) if isinstance(attribute, bool): value_ = value value = value.lower().capitalize() if value not in ['True', 'False']: raise FunctionReturn(f"Invalid value {value_}.") elif isinstance(attribute, int): if not value.isdigit() or eval(value) < 0 or eval( value) > 7378697629483820640: raise FunctionReturn(f"Invalid value {value}.") elif isinstance(attribute, float): if not isinstance(eval(value), float) or eval(value) < 0.0: raise FunctionReturn(f"Invalid value {value}.") try: double_to_bytes(eval(value)) except struct.error: raise FunctionReturn(f"Invalid value {value}.") elif isinstance(attribute, str): if len(value) > 255: raise FunctionReturn( f"Setting must be shorter than 256 chars.") else: raise CriticalError("Invalid attribute type in settings.") self.validate_key_value_pair(key, value, contact_list, group_list) value = value if isinstance(attribute, str) else eval(value) setattr(self, key, value) self.store_settings()
def store_settings(self) -> None: """Store settings to encrypted database.""" attribute_list = [self.__getattribute__(k) for k in self.key_list] # Convert attributes into constant length byte string pt_bytes = b'' for a in attribute_list: if isinstance(a, bool): pt_bytes += bool_to_bytes(a) elif isinstance(a, int): pt_bytes += int_to_bytes(a) elif isinstance(a, float): pt_bytes += double_to_bytes(a) elif isinstance(a, str): pt_bytes += str_to_bytes(a) else: raise CriticalError("Invalid attribute type in settings.") ct_bytes = encrypt_and_sign(pt_bytes, self.master_key.master_key) ensure_dir(f'{DIR_USER_DATA}/') with open(self.file_name, 'wb+') as f: f.write(ct_bytes)
def store_settings(self, replace: bool = True) -> None: """Store settings to an encrypted database. The plaintext in the encrypted database is a constant length bytestring regardless of stored setting values. """ attribute_list = [self.__getattribute__(k) for k in self.key_list] bytes_lst = [] for a in attribute_list: if isinstance(a, bool): bytes_lst.append(bool_to_bytes(a)) elif isinstance(a, int): bytes_lst.append(int_to_bytes(a)) elif isinstance(a, float): bytes_lst.append(double_to_bytes(a)) else: raise CriticalError("Invalid attribute type in settings.") pt_bytes = b''.join(bytes_lst) self.database.store_database(pt_bytes, replace)
def create_message_apct(origin, message, header=None, group_name=None): if not header: if group_name is not None: timestamp = double_to_bytes(time.time() * 1000) header = GROUP_MESSAGE_HEADER + timestamp + group_name + US_BYTE else: header = PRIVATE_MESSAGE_HEADER plaintext = header + message payload = zlib.compress(plaintext, level=9) if len(payload) < 255: padded = byte_padding(payload) packet_list = [M_S_HEADER + padded] else: msg_key = os.urandom(32) payload = encrypt_and_sign(payload, msg_key) payload += msg_key padded = byte_padding(payload) p_list = split_byte_string(padded, item_len=255) packet_list = ([M_L_HEADER + p_list[0]] + [M_A_HEADER + p for p in p_list[1:-1]] + [M_E_HEADER + p_list[-1]]) harac = 1 m_key = 32 * b'\x01' apctl = [] for p in packet_list: harac_in_bytes = int_to_bytes(harac) encrypted_harac = encrypt_and_sign(harac_in_bytes, 32 * b'\x01') encrypted_message = encrypt_and_sign(p, m_key) encrypted_packet = MESSAGE_PACKET_HEADER + encrypted_harac + encrypted_message + origin + b'*****@*****.**' apctl.append(encrypted_packet) harac += 1 m_key = hash_chain(m_key) return apctl
def test_double_to_bytes(self): self.assertEqual(double_to_bytes(1.0), bytes.fromhex('000000000000f03f')) self.assertEqual(double_to_bytes(1.1), bytes.fromhex('9a9999999999f13f')) self.assertEqual(len(double_to_bytes(1.1)), ENCODED_FLOAT_LENGTH)
def test_double_to_bytes(self): self.assertEqual(double_to_bytes(1.0), binascii.unhexlify('000000000000f03f')) self.assertEqual(double_to_bytes(1.1), binascii.unhexlify('9a9999999999f13f')) self.assertEqual(len(double_to_bytes(1.1)), FLOAT_SETTING_LEN)
def test_double_to_bytes(self): self.assertEqual(double_to_bytes(1.0), binascii.unhexlify('000000000000f03f')) self.assertEqual(double_to_bytes(1.1), binascii.unhexlify('9a9999999999f13f'))