Exemple #1
0
    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
Exemple #2
0
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))
Exemple #3
0
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
Exemple #4
0
 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()
Exemple #5
0
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
Exemple #6
0
 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
Exemple #7
0
    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
Exemple #8
0
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))
Exemple #9
0
    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:])])
Exemple #10
0
    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)
Exemple #11
0
    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
Exemple #12
0
    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:])])
Exemple #13
0
 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))
Exemple #14
0
 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))
Exemple #15
0
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))
Exemple #16
0
    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)
Exemple #17
0
    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)
Exemple #18
0
    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)
Exemple #19
0
    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))
Exemple #20
0
    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
Exemple #21
0
    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)
Exemple #22
0
    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)
Exemple #23
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)
Exemple #24
0
    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
            })
Exemple #25
0
    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)
Exemple #26
0
    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)
Exemple #27
0
    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
Exemple #28
0
    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)
Exemple #29
0
    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))
Exemple #30
0
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