def test_invalid_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(3) encrypted_harac = encrypt_and_sign(harac_in_bytes, 32 * b'\x02') 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 invalid hash ratchet MAC.", decrypt_assembly_packet, packet, window_list, contact_list, key_list)
def setUp(self): """Pre-test actions.""" self.unit_test_dir = cd_unit_test() self.ts = datetime.now() self.packet = b'' self.file_keys = dict() self.file_buf = dict() self.contact_list = ContactList(nicks=['Alice']) self.window_list = WindowList() self.file_key = SYMMETRIC_KEY_LENGTH * b'a' self.settings = Settings() self.compressed = zlib.compress(str_to_bytes("test_file.txt") + b'file_data', level=COMPRESSION_LEVEL) self.args = self.file_keys, self.file_buf, self.contact_list, self.window_list, self.settings
def setUp(self) -> None: """Pre-test actions.""" self.unit_test_dir = cd_unit_test() self.ts = datetime.now() self.master_key = MasterKey() self.settings = Settings() self.contact_list = ContactList(nicks=[LOCAL_ID]) self.window_list = WindowList(nicks=[LOCAL_ID]) self.group_list = GroupList() self.key_list = KeyList() self.args = (self.ts, self.window_list, self.contact_list, self.group_list, self.key_list, self.settings, self.master_key) self.log_file = f'{DIR_USER_DATA}{self.settings.software_operation}_logs' self.tfc_log_database = MessageLog(self.log_file, self.master_key.master_key)
class TestResetActiveWindow(unittest.TestCase): def setUp(self): self.cmd_data = b'*****@*****.**' self.window_list = WindowList() self.window_list.windows = [ RxWindow(uid='*****@*****.**', name='Alice'), RxWindow(uid='*****@*****.**', name='Bob') ] self.window = self.window_list.get_window('*****@*****.**') self.window.message_log = [(datetime.now(), 'Hi Bob', '*****@*****.**', ORIGIN_CONTACT_HEADER)] def test_screen_reset(self): self.assertEqual(len(self.window.message_log), 1) self.assertIsNone(reset_active_window(self.cmd_data, self.window_list)) self.assertEqual(len(self.window.message_log), 0)
def test_successful_group_creation(self) -> None: # Setup group_list = GroupList(groups=['test_group']) cmd_data = group_name_to_group_id( 'test_group') + b'test_group2' + US_BYTE + nick_to_pub_key('Bob') contact_list = ContactList(nicks=['Alice', 'Bob']) window_list = WindowList(nicks=['Alice', 'Bob'], contact_list=contact_list, group_lis=group_list, packet_list=None, settings=Settings) # Test self.assertIsNone( group_create(cmd_data, self.ts, window_list, contact_list, group_list, self.settings)) self.assertEqual(len(group_list.get_group('test_group')), 2)
def setUp(self): self.ts = datetime.now() self.settings = Settings() self.master_key = MasterKey() self.group_list = GroupList() self.exit_queue = Queue() self.pubkey_buf = dict() self.window_list = WindowList(nicks=[LOCAL_ID]) self.contact_list = ContactList(nicks=[LOCAL_ID]) self.packet_list = PacketList(self.settings, self.contact_list) self.key_list = KeyList(nicks=[LOCAL_ID]) self.key_set = self.key_list.get_keyset(LOCAL_ID) self.key_set.rx_key = bytes(KEY_LENGTH) self.key_set.rx_hek = bytes(KEY_LENGTH) self.key_set.tx_harac = 1 self.key_set.rx_harac = 1
def test_enable_logging_group(self): # Setup cmd_data = b'e' + US_BYTE + b'testgroup' ts = datetime.datetime.now() contact_list = ContactList(nicks=['Bob']) window_list = WindowList(windows=[ RxMWindow(type='group', name='testgroup', uid='testgroup') ]) group_list = GroupList(groups=['testgroup']) setting_type = 'L' # Test group_list.get_group('testgroup').log_messages = False self.assertIsNone( contact_setting(cmd_data, ts, window_list, contact_list, group_list, setting_type)) self.assertTrue(group_list.get_group('testgroup').log_messages)
def test_function(self): # Setup ts = datetime.datetime.now() no_msg = int_to_bytes(1) cmd_data = b'*****@*****.**' + US_BYTE + no_msg window_list = WindowList() contact_list = ContactList() settings = Settings() master_key = MasterKey() write_log_entry(F_S_HEADER + bytes(255), '*****@*****.**', settings, master_key) # Test self.assertIsNone( export_logs(cmd_data, ts, window_list, contact_list, settings, master_key)) os.remove('Unittest - Plaintext log (None)') cleanup()
def test_successful_removal(self): # Setup cmd_data = b'*****@*****.**' ts = datetime.datetime.now() contact_list = ContactList(nicks=['Alice', 'Bob']) contact = contact_list.get_contact('*****@*****.**') group_list = GroupList(groups=['testgroup', 'testgroup2']) key_list = KeyList(nicks=['Alice', 'Bob']) window_list = WindowList() # Test self.assertIsNone( remove_contact(cmd_data, ts, window_list, contact_list, group_list, key_list)) self.assertFalse(contact_list.has_contact('*****@*****.**')) self.assertFalse(key_list.has_keyset('*****@*****.**')) for g in group_list: self.assertFalse(contact in g.members)
class TestChangeNick(TFCTestCase): def setUp(self): self.ts = datetime.now() self.contact_list = ContactList(nicks=['Alice']) self.window_list = WindowList(contact_list=self.contact_list) self.group_list = GroupList() def test_nick_change(self): # Setup cmd_data = b'*****@*****.**' + US_BYTE + b'Alice_' # Test self.assertIsNone( change_nick(cmd_data, self.ts, self.window_list, self.contact_list)) self.assertEqual( self.contact_list.get_contact('*****@*****.**').nick, 'Alice_') self.assertEqual( self.window_list.get_window('*****@*****.**').name, 'Alice_')
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_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_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_enable_logging_contact(self): # Setup cmd_data = b'e' + US_BYTE + b'*****@*****.**' ts = datetime.datetime.now() contact_list = ContactList(nicks=['Bob']) window_list = WindowList(windows=[ RxMWindow(type='contact', name='Bob', uid='*****@*****.**') ]) group_list = GroupList() setting_type = 'L' # Test contact_list.get_contact('*****@*****.**').log_messages = False self.assertFalse( contact_list.get_contact('*****@*****.**').log_messages) self.assertIsNone( contact_setting(cmd_data, ts, window_list, contact_list, group_list, setting_type)) self.assertTrue( contact_list.get_contact('*****@*****.**').log_messages)
def test_enable_file_reception_group(self): # Setup cmd_data = b'd' + US_BYTE + b'testgroup' ts = datetime.datetime.now() contact_list = ContactList(nicks=['Bob', 'Alice']) group_list = GroupList(groups=['testgroup']) window_list = WindowList(windows=[ RxMWindow(type='group', name='testgroup', uid='testgroup') ]) setting_type = 'F' for c in contact_list: self.assertTrue(c.file_reception) # Test self.assertIsNone( contact_setting(cmd_data, ts, window_list, contact_list, group_list, setting_type)) for c in contact_list: self.assertFalse(c.file_reception)
def test_enable_logging_all(self): # Setup cmd_data = b'E' ts = datetime.datetime.now() contact_list = ContactList(nicks=['Alice', 'Bob', 'Charlie']) window_list = WindowList(windows=[ RxMWindow(type='group', name='testgroup', uid='testgroup') ]) group_list = GroupList(groups=['testgroup']) setting_type = 'L' # Test for c in contact_list: c.log_messages = False group_list.get_group('testgroup').log_messages = False self.assertIsNone( contact_setting(cmd_data, ts, window_list, contact_list, group_list, setting_type)) self.assertTrue(group_list.get_group('testgroup').log_messages) for c in contact_list: self.assertTrue(c.log_messages)
def test_invalid_keys_raise_fr(self): # Setup packet = b'*****@*****.**' contact_list = ContactList(nicks=['Alice', 'local']) key_list = KeyList(nicks=['Alice', 'local']) keyset = key_list.get_keyset('*****@*****.**') keyset.rx_key = bytes(32) keyset.rx_hek = bytes(32) window_list = WindowList(nicks=['Alice', 'local']) ts = datetime.datetime.now() settings = Settings(disable_gui_dialog=True) o_input = builtins.input o_getpass = getpass.getpass builtins.input = lambda x: 'ut_psk' input_list = ['bad', 'testpassword'] gen = iter(input_list) def mock_input(_): return str(next(gen)) getpass.getpass = mock_input password = '******' salt = os.urandom(32) rx_key = bytes(32) rx_hek = os.urandom(32) kek, _ = argon2_kdf(password, salt, rounds=16, memory=128000, parallelism=1) ct_tag = encrypt_and_sign(rx_key + rx_hek, key=kek) with open('ut_psk', 'wb+') as f: f.write(salt + ct_tag) # Test self.assertFR("Keys from contact are not valid.", psk_import, packet, ts, window_list, contact_list, key_list, settings) # Teardown os.remove('ut_psk') builtins.input = o_input getpass.getpass = o_getpass
def test_invalid_name_raises_fr(self): # Setup file_name = str_to_bytes('\x01testfile.txt') data = file_name + os.urandom(1000) compressed = zlib.compress(data, level=9) key = os.urandom(32) key_b58 = b58encode(key) packet = IMPORTED_FILE_CT_HEADER + encrypt_and_sign(compressed, key) ts = datetime.datetime.now() window_list = WindowList(nicks=['local']) o_input = builtins.input input_list = ['2QJL5gVSPEjMTaxWPfYkzG9UJxzZDNSx6PPeVWdzS5CFN7knZy', key_b58] gen = iter(input_list) def mock_input(_): return str(next(gen)) builtins.input = mock_input # Test self.assertFR("Received file had an invalid name.", process_imported_file, ts, packet, window_list) # Teardown builtins.input = o_input
class ProcessAssembledFile(TFCTestCase): def setUp(self) -> None: """Pre-test actions.""" self.unit_test_dir = cd_unit_test() self.ts = datetime.now() self.onion_pub_key = nick_to_pub_key('Alice') self.nick = 'Alice' self.settings = Settings() self.window_list = WindowList(nick=['Alice', 'Bob']) self.key = os.urandom(SYMMETRIC_KEY_LENGTH) self.args = self.onion_pub_key, self.nick, self.settings, self.window_list def tearDown(self) -> None: """Post-test actions.""" cleanup(self.unit_test_dir) def test_invalid_structure_raises_soft_error(self) -> None: # Setup payload = b'testfile.txt' # Test self.assert_se("Error: Received file had an invalid structure.", process_assembled_file, self.ts, payload, *self.args) def test_invalid_encoding_raises_soft_error(self) -> None: # Setup payload = UNDECODABLE_UNICODE + US_BYTE + b'file_data' # Test self.assert_se("Error: Received file name had an invalid encoding.", process_assembled_file, self.ts, payload, *self.args) def test_invalid_name_raises_soft_error(self) -> None: # Setup payload = b'\x01filename' + US_BYTE + b'file_data' # Test self.assert_se("Error: Received file had an invalid name.", process_assembled_file, self.ts, payload, *self.args) def test_slash_in_file_name_raises_soft_error(self) -> None: # Setup payload = b'file/name' + US_BYTE + b'file_data' # Test self.assert_se("Error: Received file had an invalid name.", process_assembled_file, self.ts, payload, *self.args) def test_invalid_key_raises_soft_error(self) -> None: # Setup payload = b'testfile.txt' + US_BYTE + b'file_data' # Test self.assert_se("Error: Received file had an invalid key.", process_assembled_file, self.ts, payload, *self.args) def test_decryption_fail_raises_soft_error(self) -> None: # Setup file_data = encrypt_and_sign(b'file_data', self.key)[::-1] payload = b'testfile.txt' + US_BYTE + file_data # Test self.assert_se("Error: Decryption of file data failed.", process_assembled_file, self.ts, payload, *self.args) def test_invalid_compression_raises_soft_error(self) -> None: # Setup compressed = zlib.compress(b'file_data', level=COMPRESSION_LEVEL)[::-1] file_data = encrypt_and_sign(compressed, self.key) + self.key payload = b'testfile.txt' + US_BYTE + file_data # Test self.assert_se("Error: Decompression of file data failed.", process_assembled_file, self.ts, payload, *self.args) def test_successful_reception(self) -> None: # Setup compressed = zlib.compress(b'file_data', level=COMPRESSION_LEVEL) file_data = encrypt_and_sign(compressed, self.key) + self.key payload = b'testfile.txt' + US_BYTE + file_data # Test self.assertIsNone(process_assembled_file(self.ts, payload, *self.args)) self.assertTrue(os.path.isfile(f'{DIR_RECV_FILES}Alice/testfile.txt')) def test_successful_reception_during_traffic_masking(self) -> None: # Setup self.settings.traffic_masking = True self.window_list.active_win = self.window_list.get_window(nick_to_pub_key('Bob')) compressed = zlib.compress(b'file_data', level=COMPRESSION_LEVEL) file_data = encrypt_and_sign(compressed, self.key) + self.key payload = b'testfile.txt' + US_BYTE + file_data # Test self.assertIsNone(process_assembled_file(self.ts, payload, *self.args)) self.assertEqual(self.window_list.get_window(nick_to_pub_key('Bob')).message_log[0][1], "Stored file from Alice as 'testfile.txt'.") self.assertTrue(os.path.isfile(f'{DIR_RECV_FILES}Alice/testfile.txt'))
class TestProcessFile(TFCTestCase): def setUp(self) -> None: """Pre-test actions.""" self.unit_test_dir = cd_unit_test() self.ts = datetime.now() self.account = nick_to_pub_key('Alice') self.file_key = SYMMETRIC_KEY_LENGTH*b'a' self.file_ct = encrypt_and_sign(50 * b'a', key=self.file_key) self.contact_list = ContactList(nicks=['Alice']) self.window_list = WindowList() self.settings = Settings() self.args = self.file_key, self.contact_list, self.window_list, self.settings def tearDown(self) -> None: """Post-test actions.""" cleanup(self.unit_test_dir) def test_invalid_key_raises_soft_error(self) -> None: self.file_key = SYMMETRIC_KEY_LENGTH * b'f' self.args = self.file_key, self.contact_list, self.window_list, self.settings self.assert_se("Error: Decryption key for file from Alice was invalid.", process_file, self.ts, self.account, self.file_ct, *self.args) def test_invalid_compression_raises_soft_error(self) -> None: compressed = zlib.compress(b'file_data', level=COMPRESSION_LEVEL)[::-1] file_data = encrypt_and_sign(compressed, self.file_key) self.assert_se("Error: Failed to decompress file from Alice.", process_file, self.ts, self.account, file_data, *self.args) @mock.patch('time.sleep', return_value=None) def test_invalid_file_name_raises_soft_error(self, _: Any) -> None: compressed = zlib.compress(UNDECODABLE_UNICODE + b'file_data', level=COMPRESSION_LEVEL) file_data = encrypt_and_sign(compressed, self.file_key) self.assert_se("Error: Name of file from Alice had an invalid encoding.", process_file, self.ts, self.account, file_data, *self.args) @mock.patch('time.sleep', return_value=None) def test_non_printable_name_raises_soft_error(self, _: Any) -> None: compressed = zlib.compress(str_to_bytes("file\x01") + b'file_data', level=COMPRESSION_LEVEL) file_data = encrypt_and_sign(compressed, self.file_key) self.assert_se("Error: Name of file from Alice was invalid.", process_file, self.ts, self.account, file_data, *self.args) @mock.patch('time.sleep', return_value=None) def test_slash_in_name_raises_soft_error(self, _: Any) -> None: compressed = zlib.compress(str_to_bytes("Alice/file.txt") + b'file_data', level=COMPRESSION_LEVEL) file_data = encrypt_and_sign(compressed, self.file_key) self.assert_se("Error: Name of file from Alice was invalid.", process_file, self.ts, self.account, file_data, *self.args) @mock.patch('time.sleep', return_value=None) def test_successful_storage_of_file(self, _: Any) -> None: compressed = zlib.compress(str_to_bytes("test_file.txt") + b'file_data', level=COMPRESSION_LEVEL) file_data = encrypt_and_sign(compressed, self.file_key) self.assertIsNone(process_file(self.ts, self.account, file_data, *self.args)) @mock.patch('time.sleep', return_value=None) def test_successful_storage_during_traffic_masking(self, _: Any) -> None: # Setup self.settings.traffic_masking = True self.window_list.active_win = self.window_list.get_window(nick_to_pub_key('Bob')) compressed = zlib.compress(str_to_bytes("testfile.txt") + b'file_data', level=COMPRESSION_LEVEL) file_data = encrypt_and_sign(compressed, self.file_key) self.assertIsNone(process_file(self.ts, self.account, file_data, *self.args)) self.assertEqual(self.window_list.get_window(nick_to_pub_key('Bob')).message_log[0][1], "Stored file from Alice as 'testfile.txt'.") self.assertTrue(os.path.isfile(f'{DIR_RECV_FILES}Alice/testfile.txt'))