def test_receive_valid_json_valid_message_from_old_peer(self): """ A good message is received then the node handles the message as expected. The cached protocol object for the peer node is expired since a new protocol object is used in this instance. """ nc = NetstringConnector(self.event_loop) old_protocol = mock.MagicMock() network_id = sha512(PUBLIC_KEY.encode('ascii')).hexdigest() nc._connections[network_id] = old_protocol ok = { 'uuid': str(uuid.uuid4()), 'recipient': PUBLIC_KEY, 'sender': PUBLIC_KEY, 'reply_port': 1908, 'version': self.version, } seal = get_seal(ok, PRIVATE_KEY) ok['seal'] = seal ok['message'] = 'ok' raw = json.dumps(ok) sender = '192.168.0.1' handler = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, nc, 1908) handler.message_received = mock.MagicMock() protocol = mock.MagicMock() nc.receive(raw, sender, handler, protocol) self.assertIn(network_id, nc._connections) self.assertEqual(nc._connections[network_id], protocol) msg = from_dict(ok) handler.message_received.assert_called_once_with(msg, 'netstring', sender, msg.reply_port)
def test_receive_valid_json_invalid_message(self): """ If a message is received that consists of valid json but a malformed message then log the incident for later analysis. """ patcher = mock.patch('drogulus.net.netstring.log.error') nc = NetstringConnector(self.event_loop) ping = { 'uuid': str(uuid.uuid4()), 'recipient': PUBLIC_KEY, 'sender': BAD_PUBLIC_KEY, 'reply_port': 1908, 'version': self.version, } seal = get_seal(ping, PRIVATE_KEY) ping['seal'] = seal ping['message'] = 'ping' raw = json.dumps(ping) sender = '192.168.0.1' handler = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, nc, 1908) protocol = mock.MagicMock() mock_log = patcher.start() nc.receive(raw, sender, handler, protocol) self.assertEqual(3, mock_log.call_count) patcher.stop()
def test_receive(self): """ The good case. Should return whatever handler.message_received returns. """ connector = HttpConnector(self.event_loop) ok = { 'uuid': str(uuid.uuid4()), 'recipient': PUBLIC_KEY, 'sender': PUBLIC_KEY, 'reply_port': 1908, 'version': self.version, } seal = get_seal(ok, PRIVATE_KEY) ok['seal'] = seal ok['message'] = 'ok' raw = json.dumps(ok).encode('utf-8') sender = '192.168.0.1' handler = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) handler.message_received = mock.MagicMock() connector.receive(raw, sender, handler) msg = from_dict(ok) handler.message_received.assert_called_once_with(msg, 'http', sender, msg.reply_port)
def seal_message(msg_type, msg_dict, private_key): """ Returns a version of the message containing the cryptographic seal and message type. """ seal = get_seal(msg_dict, private_key) msg_dict['seal'] = seal msg_dict['message'] = msg_type return msg_dict
def test_check_seal_invalid_seal(self): """ Ensure a message with an invalid seal fails the check. """ ok_dict = { 'uuid': str(uuid.uuid4()), 'recipient': PUBLIC_KEY, 'sender': BAD_PUBLIC_KEY, 'reply_port': 1908, 'version': get_version() } seal = get_seal(ok_dict, PRIVATE_KEY) ok = OK(ok_dict['uuid'], ok_dict['recipient'], ok_dict['sender'], ok_dict['reply_port'], ok_dict['version'], seal) self.assertFalse(check_seal(ok))
def test_check_seal(self): """ Make sure message objects that contain a valid seal are correctly checked. """ ok_dict = { 'uuid': str(uuid.uuid4()), 'recipient': PUBLIC_KEY, 'sender': PUBLIC_KEY, 'reply_port': 1908, 'version': get_version() } seal = get_seal(ok_dict, PRIVATE_KEY) ok = OK(ok_dict['uuid'], ok_dict['recipient'], ok_dict['sender'], ok_dict['reply_port'], ok_dict['version'], seal) self.assertTrue(check_seal(ok))
def test_check_seal_invalid_seal(self): """ Ensure a message with an invalid seal fails the check. """ ok_dict = { "uuid": str(uuid.uuid4()), "recipient": PUBLIC_KEY, "sender": BAD_PUBLIC_KEY, "reply_port": 1908, "version": get_version(), } seal = get_seal(ok_dict, PRIVATE_KEY) ok = OK( ok_dict["uuid"], ok_dict["recipient"], ok_dict["sender"], ok_dict["reply_port"], ok_dict["version"], seal ) self.assertFalse(check_seal(ok))
def test_get_seal(self): """ Ensure a good "seal" is created for the passed in dict of values given the supplied private key and appropriate shared public key to be used to validate the seal. """ values = {"foo": "bar", "baz": {"a": 1, "b": True, "c": 3.141, "d": [1, 2, 3]}} seal = get_seal(values, PRIVATE_KEY) # Check it's a string and valid hexdecimal value self.assertIsInstance(seal, str) self.assertIsInstance(int(seal, 16), int) # Check it's a seal that can be validated with the correct public key. sig = binascii.unhexlify(seal.encode("ascii")) key = rsa.PublicKey.load_pkcs1(PUBLIC_KEY.encode("ascii")) root_hash = _get_hash(values).hexdigest() self.assertTrue(rsa.verify(root_hash.encode("ascii"), sig, key))
def test_check_seal(self): """ Make sure message objects that contain a valid seal are correctly checked. """ ok_dict = { "uuid": str(uuid.uuid4()), "recipient": PUBLIC_KEY, "sender": PUBLIC_KEY, "reply_port": 1908, "version": get_version(), } seal = get_seal(ok_dict, PRIVATE_KEY) ok = OK( ok_dict["uuid"], ok_dict["recipient"], ok_dict["sender"], ok_dict["reply_port"], ok_dict["version"], seal ) self.assertTrue(check_seal(ok))
def test_get_seal(self): """ Ensure a good "seal" is created for the passed in dict of values given the supplied private key and appropriate shared public key to be used to validate the seal. """ values = { 'foo': 'bar', 'baz': { 'a': 1, 'b': True, 'c': 3.141, 'd': [1, 2, 3] }, } seal = get_seal(values, PRIVATE_KEY) # Check it's a string and valid hexdecimal value self.assertIsInstance(seal, str) self.assertIsInstance(int(seal, 16), int) # Check it's a seal that can be validated with the correct public key. sig = binascii.unhexlify(seal.encode('ascii')) key = rsa.PublicKey.load_pkcs1(PUBLIC_KEY.encode('ascii')) root_hash = _get_hash(values).hexdigest() self.assertTrue(rsa.verify(root_hash.encode('ascii'), sig, key))