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_command(payload: bytes, settings: 'Settings', c_queue: 'Queue') -> None: """Split command into assembly packets and queue them. :param payload: Command's plaintext string. :param settings: Settings object :param c_queue: Multiprocessing queue for commands :return: None """ payload = zlib.compress(payload, level=9) if len(payload) < 255: padded = byte_padding(payload) packet_list = [C_S_HEADER + padded] else: payload += hash_chain(payload) padded = byte_padding(payload) p_list = split_byte_string(padded, item_len=255) packet_list = ([C_L_HEADER + p_list[0]] + [C_A_HEADER + p for p in p_list[1:-1]] + [C_E_HEADER + p_list[-1]]) if settings.session_trickle: for p in packet_list: c_queue.put(p) else: for p in packet_list: c_queue.put((p, settings))
def split_to_assembly_packets(payload: bytes, p_type: str) -> List[bytes]: """Split payload to assembly packets. Messages and commands are compressed to reduce transmission time. Files directed to this function during traffic masking have been compressed at an earlier point. If the compressed message cannot be sent over one packet, it is split into multiple assembly packets. Long messages are encrypted with an inner layer of XChaCha20-Poly1305 to provide sender based control over partially transmitted data. Regardless of packet size, files always have an inner layer of encryption, and it is added before the file data is passed to this function. Commands do not need sender-based control, so they are only delivered with a hash that makes integrity check easy. First assembly packet in file transmission is prepended with an 8-byte packet counter header that tells the sender and receiver how many packets the file transmission requires. Each assembly packet is prepended with a header that tells the Receiver Program if the packet is a short (single packet) transmission or if it's the start packet, a continuation packet, or the last packet of a multi-packet transmission. """ s_header = {MESSAGE: M_S_HEADER, FILE: F_S_HEADER, COMMAND: C_S_HEADER}[p_type] l_header = {MESSAGE: M_L_HEADER, FILE: F_L_HEADER, COMMAND: C_L_HEADER}[p_type] a_header = {MESSAGE: M_A_HEADER, FILE: F_A_HEADER, COMMAND: C_A_HEADER}[p_type] e_header = {MESSAGE: M_E_HEADER, FILE: F_E_HEADER, COMMAND: C_E_HEADER}[p_type] if p_type in [MESSAGE, COMMAND]: payload = zlib.compress(payload, level=COMPRESSION_LEVEL) if len(payload) < PADDING_LENGTH: padded = byte_padding(payload) packet_list = [s_header + padded] else: if p_type == MESSAGE: msg_key = csprng() payload = encrypt_and_sign(payload, msg_key) payload += msg_key elif p_type == FILE: payload = bytes(FILE_PACKET_CTR_LENGTH) + payload elif p_type == COMMAND: payload += blake2b(payload) padded = byte_padding(payload) p_list = split_byte_string(padded, item_len=PADDING_LENGTH) if p_type == FILE: p_list[0] = int_to_bytes(len(p_list)) + p_list[0][FILE_PACKET_CTR_LENGTH:] packet_list = ([l_header + p_list[0]] + [a_header + p for p in p_list[1:-1]] + [e_header + p_list[-1]]) return packet_list
def test_invalid_padding_size_raises_critical_error(self, mock_padder): """\ This test makes sure TFC detects if the length of the message padded by pyca/cryptography library is not correct. The `mock_padder` object replaces the message b'test_string' with a message that has an incorrect length of 256 bytes. """ with self.assertRaises(SystemExit): byte_padding(b'test_string') mock_padder.assert_called()
def split_to_assembly_packets(payload: bytes, p_type: str) -> List[bytes]: """Split payload to assembly packets. Messages and commands are compressed to reduce transmission time. Files have been compressed at earlier phase, before B85 encoding. If the compressed message can not be sent over one packet, it is split into multiple assembly packets with headers. Long messages are encrypted with inner layer of XSalsa20-Poly1305 to provide sender based control over partially transmitted data. Regardless of packet size, files always have an inner layer of encryption, and it is added in earlier phase. Commands do not need sender-based control, so they are only delivered with hash that makes integrity check easy. First assembly packet in file transmission is prepended with 8-byte packet counter that tells sender and receiver how many packets the file transmission requires. """ s_header = {MESSAGE: M_S_HEADER, FILE: F_S_HEADER, COMMAND: C_S_HEADER}[p_type] l_header = {MESSAGE: M_L_HEADER, FILE: F_L_HEADER, COMMAND: C_L_HEADER}[p_type] a_header = {MESSAGE: M_A_HEADER, FILE: F_A_HEADER, COMMAND: C_A_HEADER}[p_type] e_header = {MESSAGE: M_E_HEADER, FILE: F_E_HEADER, COMMAND: C_E_HEADER}[p_type] if p_type in [MESSAGE, COMMAND]: payload = zlib.compress(payload, level=COMPRESSION_LEVEL) if len(payload) < PADDING_LEN: padded = byte_padding(payload) packet_list = [s_header + padded] else: if p_type == MESSAGE: msg_key = csprng() payload = encrypt_and_sign(payload, msg_key) payload += msg_key elif p_type == FILE: payload = bytes(FILE_PACKET_CTR_LEN) + payload elif p_type == COMMAND: payload += hash_chain(payload) padded = byte_padding(payload) p_list = split_byte_string(padded, item_len=PADDING_LEN) if p_type == FILE: p_list[0] = int_to_bytes(len(p_list)) + p_list[0][FILE_PACKET_CTR_LEN:] packet_list = ([l_header + p_list[0]] + [a_header + p for p in p_list[1:-1]] + [e_header + p_list[-1]]) return packet_list
def mock_command_preprocessor(command): payload = zlib.compress(command, level=9) if len(payload) < 255: padded = byte_padding(payload) packet_list = [C_S_HEADER + padded] else: payload += hash_chain(payload) padded = byte_padding(payload) p_list = split_byte_string(padded, item_len=255) packet_list = ([C_L_HEADER + p_list[0]] + [C_A_HEADER + p for p in p_list[1:-1]] + [C_E_HEADER + p_list[-1]]) return packet_list
def mock_file_preprocessor(payload): if len(payload) < 255: padded = byte_padding(payload) packet_list = [F_S_HEADER + padded] else: payload = bytes(8) + payload padded = byte_padding(payload) p_list = split_byte_string(padded, item_len=255) packet_list = ([F_L_HEADER + int_to_bytes(len(p_list)) + p_list[0][8:]] + [F_A_HEADER + p for p in p_list[1:-1]] + [F_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 test_padding(self): for s in range(0, PADDING_LEN): string = s * b'm' padded = byte_padding(string) self.assertEqual(len(padded), PADDING_LEN) # Verify removal of padding doesn't alter the string self.assertEqual(string, padded[:-ord(padded[-1:])]) for s in range(PADDING_LEN, 1000): string = s * b'm' padded = byte_padding(string) self.assertEqual(len(padded) % PADDING_LEN, 0) self.assertEqual(string, padded[:-ord(padded[-1:])])
def test_contact_canceled_file(self): # Setup account = '*****@*****.**' contact = create_contact('Alice') origin = ORIGIN_CONTACT_HEADER type_ = 'file' settings = Settings() packet = Packet(account, contact, origin, type_, settings) file_data = os.urandom(10000) compressed = zlib.compress(file_data, level=9) file_key = os.urandom(32) encrypted = encrypt_and_sign(compressed, key=file_key) encrypted += file_key encoded = base64.b85encode(encrypted) file_data = US_BYTE.join([b'testfile.txt', b'11.0B', b'00d 00h 00m 00s', encoded]) packets = self.mock_file_preprocessor(file_data) packets = packets[:20] packets.append(byte_padding(F_C_HEADER)) # Add cancel packet # Test for p in packets: packet.add_packet(p) self.assertEqual(len(packet.assembly_pt_list), 0) # Cancel packet empties packet list self.assertFalse(packet.lt_active) self.assertFalse(packet.is_complete)
def create_packet(self, data, header=C_S_HEADER): payload = zlib.compress(data, level=COMPRESSION_LEVEL) packet = header + byte_padding(payload) harac_in_bytes = int_to_bytes(self.key_set.tx_harac) encrypted_harac = encrypt_and_sign(harac_in_bytes, self.key_set.tx_hek) encrypted_message = encrypt_and_sign(packet, self.key_set.tx_key) return COMMAND_PACKET_HEADER + encrypted_harac + encrypted_message
def test_padding_with_length_check(self): for s in range(0, 255): string = s * b'm' padded = byte_padding(string) self.assertEqual(len(padded), 255) # Verify removal of padding doesn't alter the string. self.assertEqual(string, padded[:-ord(padded[-1:])])
def count_number_of_packets(self) -> int: """Count number of packets needed for file delivery.""" packet_data = self.time_bytes + self.size + self.name + US_BYTE + self.data if len(packet_data) < PADDING_LEN: return 1 else: packet_data += bytes(FILE_PACKET_CTR_LEN) packet_data = byte_padding(packet_data) return len(split_byte_string(packet_data, item_len=PADDING_LEN))
def count_number_of_packets(name: bytes, size: bytes, processed: bytes, time_bytes: bytes) -> int: """Count number of packets needed for file delivery.""" packet_data = time_bytes + size + name + US_BYTE + processed if len(packet_data) < PADDING_LENGTH: return 1 else: packet_data += bytes(FILE_PACKET_CTR_LENGTH) packet_data = byte_padding(packet_data) return len(split_byte_string(packet_data, item_len=PADDING_LENGTH))
def queue_file(window: 'Window', settings: 'Settings', f_queue: 'Queue', gateway: 'Gateway') -> None: """Ask file path and load file data.""" path = ask_path_gui("Select file to send...", settings, get_file=True) file = File(path, window, settings, gateway) name = file.name.decode() size = file.size.decode() payload = file.plaintext if len(payload) < 255: padded = byte_padding(payload) packet_list = [F_S_HEADER + padded] else: payload = bytes(8) + payload padded = byte_padding(payload) p_list = split_byte_string(padded, item_len=255) # < number of packets > packet_list = ( [F_L_HEADER + int_to_bytes(len(p_list)) + p_list[0][8:]] + [F_A_HEADER + p for p in p_list[1:-1]] + [F_E_HEADER + p_list[-1]]) for p in packet_list: assert len(p) == 256 if settings.confirm_sent_files: if not yes( f"Send {name} ({size}) to {window.type} {window.name} " f"({len(packet_list)} packets, time: {file.time_s})?", tail=1): raise FunctionReturn("File selection aborted.") if settings.session_trickle: log_m_dictionary = dict((c.rx_account, c.log_messages) for c in window) for p in packet_list: f_queue.put((p, log_m_dictionary)) else: for c in window: for p in packet_list: f_queue.put((p, settings, c.rx_account, c.tx_account, c.log_messages, window.uid))
def test_compression_error_raises_fr(self): # Setup packet = Packet('*****@*****.**', self.contact, ORIGIN_USER_HEADER, MESSAGE, self.settings) payload = zlib.compress(b"Lorem ipsum", level=COMPRESSION_LEVEL)[::-1] packet_list = [M_S_HEADER + byte_padding(payload)] for p in packet_list: packet.add_packet(p) # Test self.assertFR("Error: Decompression of message failed.", packet.assemble_message_packet)
def test_padding_length_is_divisible_by_packet_length(self): padded_bytestrings = [] for length in range(1000): string = length * b'm' padded = byte_padding(string) self.assertIsInstance(padded, bytes) self.assertEqual(len(padded) % PADDING_LENGTH, 0) padded_bytestrings.append(len(padded)) self.assertNotEqual(len(list(set(padded_bytestrings))), 1)
def test_successful_command_decryption(self): # Setup command = byte_padding(b'test') encrypted_message = encrypt_and_sign(command, KEY_LENGTH*b'\x01') encrypted_harac = encrypt_and_sign(int_to_bytes(1), KEY_LENGTH*b'\x01') packet = COMMAND_PACKET_HEADER + encrypted_harac + encrypted_message keyset = self.key_list.get_keyset(LOCAL_ID) keyset.tx_harac = 1 # Test assembly_pt, account, origin = decrypt_assembly_packet(packet, self.window_list, self.contact_list, self.key_list) self.assertEqual(assembly_pt, command) self.assertEqual(account, LOCAL_ID) self.assertEqual(origin, ORIGIN_USER_HEADER)
def test_noise_packet_interrupts_file(self): # Setup packet = Packet(self.onion_pub_key, ORIGIN_CONTACT_HEADER, FILE, self.contact, self.settings) packet_list = assembly_packet_creator(FILE)[:20] packet_list.append(byte_padding(P_N_HEADER)) # Add noise packet for p in packet_list: packet.add_packet(p) # Test self.assertEqual(len(packet.assembly_pt_list), 0) # Noise packet empties packet list self.assertFalse(packet.long_active) self.assertFalse(packet.is_complete) self.assertEqual(packet.log_masking_ctr, len(packet_list))
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_expired_harac_raises_fr(self): # Setup encrypted_message = encrypt_and_sign(PRIVATE_MESSAGE_HEADER + byte_padding(b'test'), 32 * b'\x01') harac_in_bytes = int_to_bytes(1) encrypted_harac = encrypt_and_sign(harac_in_bytes, 32 * b'\x01') packet = MESSAGE_PACKET_HEADER + encrypted_harac + encrypted_message + ORIGIN_CONTACT_HEADER + b'*****@*****.**' window_list = WindowList(nicks=['Alice', 'local']) contact_list = ContactList(nicks=['Alice', 'local']) key_list = KeyList(nicks=['Alice', 'local']) keyset = key_list.get_keyset('*****@*****.**') keyset.rx_harac = 3 # Test self.assertFR("Warning! Received packet from Alice had an expired hash ratchet counter.", decrypt_assembly_packet, packet, window_list, contact_list, key_list)
def test_long_command_compression_error_raises_fr(self): # Setup packet = Packet(LOCAL_ID, self.contact, ORIGIN_CONTACT_HEADER, COMMAND, self.settings) command = os.urandom(500) + b'a' payload = zlib.compress(command, level=COMPRESSION_LEVEL)[::-1] payload += hash_chain(payload) padded = byte_padding(payload) p_list = split_byte_string(padded, item_len=PADDING_LEN) packet_list = ([C_L_HEADER + p_list[0]] + [C_A_HEADER + p for p in p_list[1:-1]] + [C_E_HEADER + p_list[-1]]) for p in packet_list: packet.add_packet(p) # Test self.assertFR("Error: Decompression of command failed.", packet.assemble_command_packet) self.assertEqual(packet.log_masking_ctr, 0)
def test_decryption_error_raises_fr(self): # Setup packet = Packet('*****@*****.**', self.contact, ORIGIN_USER_HEADER, MESSAGE, self.settings) payload = zlib.compress(self.msg.encode(), level=COMPRESSION_LEVEL) msg_key = bytes(KEY_LENGTH) payload = encrypt_and_sign(payload, msg_key)[::-1] payload += msg_key padded = byte_padding(payload) p_list = split_byte_string(padded, item_len=PADDING_LEN) 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]]) for p in packet_list: packet.add_packet(p) # Test self.assertFR("Error: Decryption of message failed.", packet.assemble_message_packet)
def test_length_of_the_padded_message_is_divisible_by_padding_size(self): padded_bytestring_lengths = set() for message_length in range(4 * PADDING_LENGTH): message = os.urandom(message_length) padded = byte_padding(message) self.assertIsInstance(padded, bytes) self.assertEqual(len(padded) % PADDING_LENGTH, 0) padded_bytestring_lengths.add(len(padded)) # Check that all messages were padded to multiples of # PADDING_LENGTH in the range of the loop above. self.assertEqual( padded_bytestring_lengths, { 1 * PADDING_LENGTH, 2 * PADDING_LENGTH, 3 * PADDING_LENGTH, 4 * PADDING_LENGTH })
def test_successful_packet_decryption_with_offset(self): # Setup message = PRIVATE_MESSAGE_HEADER + byte_padding(b'test') encrypted_message = encrypt_and_sign(message, hash_chain(32 * b'\x01')) harac_in_bytes = int_to_bytes(2) encrypted_harac = encrypt_and_sign(harac_in_bytes, 32 * b'\x01') packet = MESSAGE_PACKET_HEADER + encrypted_harac + encrypted_message + ORIGIN_CONTACT_HEADER + b'*****@*****.**' window_list = WindowList(nicks=['Alice', 'local']) contact_list = ContactList(nicks=['Alice', 'local']) key_list = KeyList(nicks=['Alice', 'local']) keyset = key_list.get_keyset('*****@*****.**') keyset.rx_harac = 1 # Test assembly_pt, account, origin = decrypt_assembly_packet(packet, window_list, contact_list, key_list) self.assertEqual(assembly_pt, message) self.assertEqual(account, '*****@*****.**') self.assertEqual(origin, ORIGIN_CONTACT_HEADER)
def test_successful_command_decryption(self): # Setup command = byte_padding(b'test') encrypted_message = encrypt_and_sign(command, 32 * b'\x01') harac_in_bytes = int_to_bytes(1) encrypted_harac = encrypt_and_sign(harac_in_bytes, 32 * b'\x01') packet = COMMAND_PACKET_HEADER + encrypted_harac + encrypted_message window_list = WindowList(nicks=['Alice', 'local']) contact_list = ContactList(nicks=['Alice', 'local']) key_list = KeyList(nicks=['Alice', 'local']) keyset = key_list.get_keyset('local') keyset.tx_harac = 1 # Test assembly_pt, account, origin = decrypt_assembly_packet(packet, window_list, contact_list, key_list) self.assertEqual(assembly_pt, command) self.assertEqual(account, 'local') self.assertEqual(origin, ORIGIN_USER_HEADER)
def test_harac_dos_can_be_interrupted(self): # Setup encrypted_message = encrypt_and_sign(PRIVATE_MESSAGE_HEADER + byte_padding(b'test'), 32 * b'\x01') harac_in_bytes = int_to_bytes(10000) encrypted_harac = encrypt_and_sign(harac_in_bytes, 32 * b'\x01') packet = MESSAGE_PACKET_HEADER + encrypted_harac + encrypted_message + ORIGIN_CONTACT_HEADER + b'*****@*****.**' o_input = builtins.input builtins.input = lambda x: 'No' window_list = WindowList(nicks=['Alice', 'local']) contact_list = ContactList(nicks=['Alice', 'local']) key_list = KeyList(nicks=['Alice', 'local']) keyset = key_list.get_keyset('*****@*****.**') keyset.rx_harac = 3 # Test self.assertFR("Dropped packet from Alice.", decrypt_assembly_packet, packet, window_list, contact_list, key_list) # Teardown builtins.input = o_input
def test_decryption_error_raises_fr(self): # Setup account = '*****@*****.**' contact = create_contact('Alice') origin = ORIGIN_USER_HEADER type_ = 'message' settings = Settings() packet = Packet(account, contact, origin, type_, settings) long_msg = ("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean condimentum consectetur purus quis" " dapibus. Fusce venenatis lacus ut rhoncus faucibus. Cras sollicitudin commodo sapien, sed bibendu" "m velit maximus in. Aliquam ac metus risus. Sed cursus ornare luctus. Integer aliquet lectus id ma" "ssa blandit imperdiet. Ut sed massa eget quam facilisis rutrum. Mauris eget luctus nisl. Sed ut el" "it iaculis, faucibus lacus eget, sodales magna. Nunc sed commodo arcu. In hac habitasse platea dic" "tumst. Integer luctus aliquam justo, at vestibulum dolor iaculis ac. Etiam laoreet est eget odio r" "utrum, vel malesuada lorem rhoncus. Cras finibus in neque eu euismod. Nulla facilisi. Nunc nec ali" "quam quam, quis ullamcorper leo. Nunc egestas lectus eget est porttitor, in iaculis felis sceleris" "que. In sem elit, fringilla id viverra commodo, sagittis varius purus. Pellentesque rutrum loborti" "s neque a facilisis. Mauris id tortor placerat, aliquam dolor ac, venenatis arcu.") plaintext = long_msg.encode() payload = zlib.compress(plaintext, level=9) msg_key = bytes(32) payload = encrypt_and_sign(payload, msg_key) if payload[:-1] == b'a': # Remove false positives payload = payload[-1:] + b'c' else: payload = payload[-1:] + b'a' 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]]) # Test for p in packet_list: packet.add_packet(p) self.assertFR('Decryption of long message failed.', packet.assemble_message_packet)
def test_noise_packet_interrupts_file(self): # Setup packet = Packet('*****@*****.**', self.contact, ORIGIN_CONTACT_HEADER, FILE, self.settings) compressed = zlib.compress(os.urandom(10000), level=COMPRESSION_LEVEL) file_key = os.urandom(KEY_LENGTH) encrypted = encrypt_and_sign(compressed, key=file_key) encrypted += file_key encoded = base64.b85encode(encrypted) file_data = int_to_bytes(1000) + int_to_bytes(10000) + b'testfile.txt' + US_BYTE + encoded packets = split_to_assembly_packets(file_data, FILE) packets = packets[:20] packets.append(byte_padding(P_N_HEADER)) # Add cancel packet for p in packets: packet.add_packet(p) # Test self.assertEqual(len(packet.assembly_pt_list), 0) # Cancel packet empties packet list self.assertFalse(packet.long_active) self.assertFalse(packet.is_complete) self.assertEqual(packet.log_masking_ctr, len(packets))
def noise_process(header: bytes, queue: 'Queue', contact_list: 'ContactList' = None) -> None: """Ensure noise queues have noise packets (with padded length of 256) always available.""" packet = header + byte_padding(header) if contact_list is None: content = packet # type: Union[bytes, Tuple[bytes, Dict[str, bool]]] else: log_dict = dict() for c in contact_list: log_dict[c.rx_account] = False content = (packet, log_dict) while True: try: if queue.qsize() < 1000: queue.put(content) else: time.sleep(0.1) except (EOFError, KeyboardInterrupt): pass