Пример #1
0
class TestGetDataLoop(unittest.TestCase):

    url_token_private_key_user = X448.generate_private_key()
    url_token_public_key_user = X448.derive_public_key(
        url_token_private_key_user)
    url_token_public_key_contact = X448.derive_public_key(
        X448.generate_private_key())
    url_token = X448.shared_key(url_token_private_key_user,
                                url_token_public_key_contact).hex()

    class MockResponse(object):
        """Mock Response object."""
        def __init__(self):
            self.test_no = 0

        def iter_lines(self):
            """Return data depending test number."""
            self.test_no += 1
            message = b''

            # Empty message
            if self.test_no == 1:
                pass

            # Invalid message
            elif self.test_no == 2:
                message = MESSAGE_DATAGRAM_HEADER + b'\x1f'

            # Valid message
            elif self.test_no == 3:
                message = MESSAGE_DATAGRAM_HEADER + base64.b85encode(
                    b'test') + b'\n'

            # Invalid public key
            elif self.test_no == 4:
                message = PUBLIC_KEY_DATAGRAM_HEADER + base64.b85encode(
                    (TFC_PUBLIC_KEY_LENGTH - 1) * b'\x01')

            # Valid public key
            elif self.test_no == 5:
                message = PUBLIC_KEY_DATAGRAM_HEADER + base64.b85encode(
                    TFC_PUBLIC_KEY_LENGTH * b'\x01')

            # Group management headers
            elif self.test_no == 6:
                message = GROUP_MSG_INVITE_HEADER

            elif self.test_no == 7:
                message = GROUP_MSG_JOIN_HEADER

            elif self.test_no == 8:
                message = GROUP_MSG_MEMBER_ADD_HEADER

            elif self.test_no == 9:
                message = GROUP_MSG_MEMBER_REM_HEADER

            elif self.test_no == 10:
                message = GROUP_MSG_EXIT_GROUP_HEADER

            # Invalid header
            elif self.test_no == 11:
                message = b'\x1f'

            # RequestException (no remaining data)
            elif self.test_no == 12:
                (_ for _ in ()).throw(requests.exceptions.RequestException)

            return message.split(b'\n')

    class MockFileResponse(object):
        """MockFileResponse object."""
        def __init__(self, content):
            self.content = content

    class Session(object):
        """Mock session object."""
        def __init__(self) -> None:
            """Create new Session object."""
            self.proxies = dict()
            self.timeout = None
            self.url = None
            self.stream = False
            self.test_no = 0
            self.response = TestGetDataLoop.MockResponse()
            self.url_token = TestGetDataLoop.url_token
            self.onion_url = 'http://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaam2dqd.onion'

        def get(self, url: str, timeout: int = 0, stream: bool = False) -> Any:
            """Return data depending on what test is in question."""

            self.stream = stream
            self.timeout = timeout

            if url == f"{self.onion_url}/{self.url_token}/messages":

                # Test function recovers from RequestException.
                if self.test_no == 1:
                    self.test_no += 1
                    (_ for _ in ()).throw(requests.exceptions.RequestException)

                if self.test_no >= 2:
                    self.test_no += 1
                    return self.response

            elif url == f"{self.onion_url}/{self.url_token}/files":

                # Test file data is received
                if self.test_no == 0:
                    self.test_no += 1
                    return TestGetDataLoop.MockFileResponse(b'test')

                # Test function recovers from RequestException.
                if self.test_no > 1:
                    (_ for _ in ()).throw(requests.exceptions.RequestException)

    @staticmethod
    def mock_session() -> Session:
        """Return mock Session object."""
        return TestGetDataLoop.Session()

    def setUp(self):
        """Pre-test actions."""
        self.o_session = requests.session
        self.queues = gen_queue_dict()
        requests.session = TestGetDataLoop.mock_session

    def tearDown(self):
        """Post-test actions."""
        requests.session = self.o_session
        tear_queues(self.queues)

    def test_get_data_loop(self):

        onion_pub_key = bytes(ONION_SERVICE_PUBLIC_KEY_LENGTH)
        settings = Gateway()
        onion_addr = pub_key_to_onion_address(
            bytes(ONION_SERVICE_PUBLIC_KEY_LENGTH))
        short_addr = pub_key_to_short_address(
            bytes(ONION_SERVICE_PUBLIC_KEY_LENGTH))
        url_token = TestGetDataLoop.url_token
        session = TestGetDataLoop.mock_session()

        self.assertIsNone(
            get_data_loop(onion_addr, url_token, short_addr, onion_pub_key,
                          self.queues, session, settings))

        self.assertIsNone(
            get_data_loop(onion_addr, url_token, short_addr, onion_pub_key,
                          self.queues, session, settings))

        self.assertEqual(self.queues[DST_MESSAGE_QUEUE].qsize(),
                         2)  # Message and file
        self.assertEqual(self.queues[GROUP_MSG_QUEUE].qsize(),
                         5)  # 5 group management messages
Пример #2
0
 def test_derive_public_key_returns_public_key_with_correct_type_and_size(
         self):
     private_key = X448.generate_private_key()
     public_key = X448.derive_public_key(private_key)
     self.assertIsInstance(public_key, bytes)
     self.assertEqual(len(public_key), TFC_PUBLIC_KEY_LENGTH)
Пример #3
0
 def test_generate_private_key_function_returns_private_key_object(self):
     self.assertIsInstance(X448.generate_private_key(), X448PrivateKey)
Пример #4
0
 def test_x448_private_key_size(self):
     private_key_bytes = X448.generate_private_key().private_bytes(
         encoding=Encoding.Raw,
         format=PrivateFormat.Raw,
         encryption_algorithm=NoEncryption())
     self.assertEqual(len(private_key_bytes), TFC_PRIVATE_KEY_LENGTH)
Пример #5
0
class TestClient(unittest.TestCase):

    url_token_private_key = X448.generate_private_key()
    url_token_public_key = X448.derive_public_key(url_token_private_key)
    url_token = X448.shared_key(url_token_private_key,
                                url_token_public_key).hex()

    class MockResponse(object):
        """Mock Response object."""
        def __init__(self, text) -> None:
            """Create new MockResponse object."""
            self.text = text
            self.content = text

    class MockSession(object):
        """Mock Session object."""
        def __init__(self) -> None:
            """Create new MockSession object."""
            self.proxies = dict()
            self.timeout = None
            self.url = None
            self.test_no = 0

        def get(self, url, timeout=0, stream=False) -> Any:
            """Mock .get() method."""

            self.timeout = timeout

            # When we reach `get_data_loop` that loads stream, throw exception to close the test.
            if stream:
                (_ for _ in ()).throw(requests.exceptions.RequestException)

            if url.startswith(
                    "http://hpcrayuxhrcy2wtpfwgwjibderrvjll6azfr4tqat3eka2m2gbb55bid.onion/"
            ):

                if self.test_no == 0:
                    self.test_no += 1
                    (_ for _ in ()).throw(requests.exceptions.RequestException)

                if self.test_no == 1:
                    self.test_no += 1
                    return TestClient.MockResponse('OK')

                # Test function recovers from RequestException.
                if self.test_no == 2:
                    self.test_no += 1
                    (_ for _ in ()).throw(requests.exceptions.RequestException)

                # Test function recovers from invalid public key.
                if self.test_no == 3:
                    self.test_no += 1
                    return TestClient.MockResponse(
                        ((ONION_SERVICE_PUBLIC_KEY_LENGTH - 1) * b'a').hex())

                # Test client prints online/offline messages.
                if self.test_no < 10:
                    self.test_no += 1
                    return TestClient.MockResponse('')

                # Test valid public key moves function to `get_data_loop`.
                if self.test_no == 10:
                    self.test_no += 1
                    return TestClient.MockResponse(
                        TestClient.url_token_public_key.hex())

    @staticmethod
    def mock_session() -> MockSession:
        """Return MockSession object."""
        return TestClient.MockSession()

    def setUp(self) -> None:
        """Pre-test actions."""
        self.o_session = requests.session
        self.queues = gen_queue_dict()
        requests.session = TestClient.mock_session

    def tearDown(self) -> None:
        """Post-test actions."""
        requests.session = self.o_session
        tear_queues(self.queues)

    @mock.patch('time.sleep', return_value=None)
    def test_client(self, _) -> None:
        onion_pub_key = nick_to_pub_key('Alice')
        onion_address = nick_to_onion_address('Alice')
        tor_port = '1337'
        settings = Gateway()
        sk = TestClient.url_token_private_key
        self.assertIsNone(
            client(onion_pub_key,
                   self.queues,
                   sk,
                   tor_port,
                   settings,
                   onion_address,
                   unit_test=True))
        self.assertEqual(self.queues[URL_TOKEN_QUEUE].get(),
                         (onion_pub_key, TestClient.url_token))