Esempio n. 1
0
    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
Esempio n. 2
0
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
Esempio n. 3
0
    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
Esempio n. 4
0
    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
Esempio n. 5
0
    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
Esempio n. 6
0
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
Esempio n. 7
0
    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
Esempio n. 8
0
    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
Esempio n. 10
0
    def get_treasure_map(self,
                         alice_pubkey_sig,
                         hrac,
                         using_dht=False,
                         verify_sig=True):
        map_id = keccak_digest(alice_pubkey_sig + hrac)

        if using_dht:
            ursula_coro = self.server.get(map_id)
            event_loop = asyncio.get_event_loop()
            packed_encrypted_treasure_map = event_loop.run_until_complete(
                ursula_coro)
        else:
            if not self.known_nodes:
                # TODO: Try to find more Ursulas on the blockchain.
                raise self.NotEnoughUrsulas
            tmap_message_kit = self.get_treasure_map_from_known_ursulas(
                self.network_middleware, map_id)

        if verify_sig:
            alice = Alice.from_public_keys({SigningPower: alice_pubkey_sig})
            verified, packed_node_list = self.verify_from(alice,
                                                          tmap_message_kit,
                                                          decrypt=True)
        else:
            assert False

        if not verified:
            return constants.NOT_FROM_ALICE
        else:
            from nucypher.policy.models import TreasureMap
            node_list = msgpack.loads(packed_node_list)
            m = node_list.pop()
            treasure_map = TreasureMap(m=m, ursula_interface_ids=node_list)
            self.treasure_maps[hrac] = treasure_map
            return treasure_map