def test_alice_character_control_grant(alice_control_test_client, federated_bob): bob_pubkey_enc = federated_bob.public_keys(DecryptingPower) request_data = { 'bob_encrypting_key': bytes(bob_pubkey_enc).hex(), 'bob_verifying_key': bytes(federated_bob.stamp).hex(), 'label': 'test', 'm': 2, 'n': 3, 'expiration': (maya.now() + datetime.timedelta(days=3)).iso8601(), } response = alice_control_test_client.put('/grant', data=json.dumps(request_data)) assert response.status_code == 200 response_data = json.loads(response.data) assert 'treasure_map' in response_data['result'] assert 'policy_encrypting_key' in response_data['result'] assert 'alice_verifying_key' in response_data['result'] map_bytes = b64decode(response_data['result']['treasure_map']) encrypted_map = TreasureMap.from_bytes(map_bytes) assert encrypted_map._hrac is not None # Send bad data to assert error returns response = alice_control_test_client.put('/grant', data=json.dumps({'bad': 'input'})) assert response.status_code == 400 # Malform the request del (request_data['bob_encrypting_key']) response = alice_control_test_client.put('/grant', data=json.dumps(request_data)) assert response.status_code == 400
def rpc_store(self, sender, nodeid, key, value): source = kademlia.node.Node(nodeid, sender[0], sender[1]) self.welcomeIfNewNode(source) self.log.debug("got a store request from %s" % str(sender)) header, payload = default_constant_splitter(value, return_remainder=True) if header == constants.BYTESTRING_IS_URSULA_IFACE_INFO: from nucypher.characters import Ursula stranger_ursula = Ursula.from_bytes(payload, federated_only=self.sourceNode.federated_only) # TODO: Is federated_only the right thing here? if stranger_ursula.interface_is_valid() and key == digest(stranger_ursula.canonical_public_address): self.sourceNode._node_storage[stranger_ursula.checksum_public_address] = stranger_ursula # TODO: 340 return True else: self.log.warning("Got request to store invalid node: {} / {}".format(key, value)) self.illegal_keys_seen.append(key) return False elif header == constants.BYTESTRING_IS_TREASURE_MAP: from nucypher.policy.models import TreasureMap try: treasure_map = TreasureMap.from_bytes(payload) self.log.info("Storing TreasureMap: {} / {}".format(key, value)) self.sourceNode._treasure_maps[treasure_map.public_id()] = value return True except TreasureMap.InvalidSignature: self.log.warning("Got request to store invalid TreasureMap: {} / {}".format(key, value)) self.illegal_keys_seen.append(key) return False else: self.log.info( "Got request to store bad k/v: {} / {}".format(key, value)) return False
def receive_treasure_map(treasure_map_id): from nucypher.policy.models import TreasureMap try: treasure_map = TreasureMap.from_bytes( bytes_representation=request.data, verify=True) except TreasureMap.InvalidSignature: do_store = False else: do_store = treasure_map.public_id() == treasure_map_id if do_store: log.info("{} storing TreasureMap {}".format( stamp, treasure_map_id)) # # # # # TODO: Now that the DHT is retired, let's do this another way. # self.dht_server.set_now(binascii.unhexlify(treasure_map_id), # constants.BYTESTRING_IS_TREASURE_MAP + bytes(treasure_map)) # # # # # TODO 341 - what if we already have this TreasureMap? treasure_map_tracker[keccak_digest( binascii.unhexlify(treasure_map_id))] = treasure_map return Response(bytes(treasure_map), status=202) else: # TODO: Make this a proper 500 or whatever. log.info( "Bad TreasureMap ID; not storing {}".format(treasure_map_id)) assert False
def receive_treasure_map(self, treasure_map_id, request: http.Request): from nucypher.policy.models import TreasureMap try: treasure_map = TreasureMap.from_bytes( bytes_representation=request.body, verify=True) except TreasureMap.InvalidSignature: do_store = False else: do_store = treasure_map.public_id() == treasure_map_id if do_store: self.log.info("{} storing TreasureMap {}".format( self, treasure_map_id)) self.dht_server.set_now( binascii.unhexlify(treasure_map_id), constants.BYTESTRING_IS_TREASURE_MAP + bytes(treasure_map)) # TODO 341 - what if we already have this TreasureMap? self.treasure_maps[digest(treasure_map_id)] = treasure_map return Response(content=bytes(treasure_map), status_code=202) else: # TODO: Make this a proper 500 or whatever. self.log.info( "Bad TreasureMap ID; not storing {}".format(treasure_map_id)) assert False
def get_treasure_map_from_known_ursulas(self, network_middleware, map_id): """ Iterate through the nodes we know, asking for the TreasureMap. Return the first one who has it. """ from nucypher.policy.models import TreasureMap for node in self.known_nodes.shuffled(): try: response = network_middleware.get_treasure_map_from_node(node=node, map_id=map_id) except NodeSeemsToBeDown: continue if response.status_code == 200 and response.content: try: treasure_map = TreasureMap.from_bytes(response.content) except InvalidSignature: # TODO: What if a node gives a bunk TreasureMap? raise break else: continue # TODO: Actually, handle error case here. else: # TODO: Work out what to do in this scenario - if Bob can't get the TreasureMap, he needs to rest on the learning mutex or something. raise TreasureMap.NowhereToBeFound return treasure_map
def test_alice_web_character_control_grant(alice_web_controller_test_client, grant_control_request): method_name, params = grant_control_request endpoint = f'/{method_name}' response = alice_web_controller_test_client.put(endpoint, data=json.dumps(params)) assert response.status_code == 200 response_data = json.loads(response.data) assert 'treasure_map' in response_data['result'] assert 'policy_encrypting_key' in response_data['result'] assert 'alice_verifying_key' in response_data['result'] map_bytes = b64decode(response_data['result']['treasure_map']) encrypted_map = TreasureMap.from_bytes(map_bytes) assert encrypted_map._hrac is not None # Send bad data to assert error returns response = alice_web_controller_test_client.put(endpoint, data=json.dumps( {'bad': 'input'})) assert response.status_code == 400 # Malform the request del (params['bob_encrypting_key']) response = alice_web_controller_test_client.put(endpoint, data=json.dumps(params)) assert response.status_code == 400
def get_treasure_map_from_known_ursulas(self, networky_stuff, map_id): """ Iterate through swarm, asking for the TreasureMap. Return the first one who has it. TODO: What if a node gives a bunk TreasureMap? """ for node in self.known_nodes: response = networky_stuff.get_treasure_map_from_node(node, map_id) if response.status_code == 200 and response.content: from nucypher.policy.models import TreasureMap treasure_map = TreasureMap.from_bytes(response.content) break else: continue # TODO: Actually, handle error case here. else: # TODO: Work out what to do in this scenario - if Bob can't get the TreasureMap, he needs to rest on the learning mutex or something. assert False return treasure_map
def receive_treasure_map(treasure_map_id): from nucypher.policy.models import TreasureMap try: treasure_map = TreasureMap.from_bytes(bytes_representation=request.data, verify=True) except TreasureMap.InvalidSignature: do_store = False else: do_store = treasure_map.public_id() == treasure_map_id if do_store: log.info("{} storing TreasureMap {}".format(this_node.stamp, treasure_map_id)) # TODO 341 - what if we already have this TreasureMap? treasure_map_index = bytes.fromhex(treasure_map_id) this_node.treasure_maps[treasure_map_index] = treasure_map return Response(bytes(treasure_map), status=202) else: # TODO: Make this a proper 500 or whatever. log.info("Bad TreasureMap ID; not storing {}".format(treasure_map_id)) assert False
def test_treasure_map_serialization(enacted_federated_policy, federated_bob): treasure_map = enacted_federated_policy.treasure_map assert treasure_map.m is not None assert treasure_map.m != NO_DECRYPTION_PERFORMED assert treasure_map.m == MOCK_POLICY_DEFAULT_M, 'm value is not correct' serialized_map = bytes(treasure_map) deserialized_map = TreasureMap.from_bytes(serialized_map) assert deserialized_map._hrac == treasure_map._hrac # TreasureMap is currently encrypted with pytest.raises(TypeError): deserialized_map.m with pytest.raises(TypeError): deserialized_map.destinations compass = federated_bob.make_compass_for_alice( enacted_federated_policy.alice) deserialized_map.orient(compass) assert deserialized_map.m == treasure_map.m assert deserialized_map.destinations == treasure_map.destinations