def test_retrieve_cfrags(federated_porter,
                         federated_porter_rpc_controller,
                         enacted_federated_policy,
                         federated_bob,
                         federated_alice,
                         random_federated_treasure_map_data):
    method = 'retrieve_cfrags'

    # Setup
    retrieve_cfrags_params, _ = retrieval_request_setup(enacted_federated_policy,
                                                        federated_bob,
                                                        federated_alice,
                                                        encode_for_rest=True)

    # Success
    request_data = {'method': method, 'params': retrieve_cfrags_params}
    response = federated_porter_rpc_controller.send(request_data)
    assert response.success

    retrieval_results = response.data['result']['retrieval_results']
    assert retrieval_results

    # expected results - can only compare length of results, ursulas are randomized to obtain cfrags
    retrieve_args = retrieval_params_decode_from_rest(retrieve_cfrags_params)
    expected_results = federated_porter.retrieve_cfrags(**retrieve_args)
    assert len(retrieval_results) == len(expected_results)

    # Failure - use encrypted treasure map
    failure_retrieve_cfrags_params = dict(retrieve_cfrags_params)
    _, random_treasure_map = random_federated_treasure_map_data
    failure_retrieve_cfrags_params['treasure_map'] = b64encode(bytes(random_treasure_map)).decode()
    request_data = {'method': method, 'params': failure_retrieve_cfrags_params}
    with pytest.raises(InvalidInputData):
        federated_porter_rpc_controller.send(request_data)
Exemple #2
0
def test_retrieve_cfrags(blockchain_porter, blockchain_porter_rpc_controller,
                         random_blockchain_policy, blockchain_bob,
                         blockchain_alice):
    method = 'retrieve_cfrags'

    # Setup
    network_middleware = MockRestMiddleware()
    # enact new random policy since idle_blockchain_policy/enacted_blockchain_policy already modified in previous tests
    enacted_policy = random_blockchain_policy.enact(
        network_middleware=network_middleware)
    retrieve_cfrags_params, _ = retrieval_request_setup(enacted_policy,
                                                        blockchain_bob,
                                                        blockchain_alice,
                                                        encode_for_rest=True)

    # Success
    request_data = {'method': method, 'params': retrieve_cfrags_params}
    response = blockchain_porter_rpc_controller.send(request_data)
    assert response.success

    retrieval_results = response.data['result']['retrieval_results']
    assert retrieval_results

    # expected results - can only compare length of results, ursulas are randomized to obtain cfrags
    retrieve_args = retrieval_params_decode_from_rest(retrieve_cfrags_params)
    expected_results = blockchain_porter.retrieve_cfrags(**retrieve_args)
    assert len(retrieval_results) == len(expected_results)

    # Failure - use encrypted treasure map
    failure_retrieve_cfrags_params = dict(retrieve_cfrags_params)
    failure_retrieve_cfrags_params['treasure_map'] = b64encode(
        os.urandom(32)).decode()
    request_data = {'method': method, 'params': failure_retrieve_cfrags_params}
    with pytest.raises(InvalidInputData):
        blockchain_porter_rpc_controller.send(request_data)
def test_retrieve_cfrags(blockchain_porter, blockchain_porter_web_controller,
                         random_blockchain_policy, blockchain_bob,
                         blockchain_alice):
    # Send bad data to assert error return
    response = blockchain_porter_web_controller.post('/retrieve_cfrags',
                                                     data=json.dumps(
                                                         {'bad': 'input'}))
    assert response.status_code == 400

    # Setup
    network_middleware = MockRestMiddleware()
    # enact new random policy since idle_blockchain_policy/enacted_blockchain_policy already modified in previous tests
    enacted_policy = random_blockchain_policy.enact(
        network_middleware=network_middleware)

    original_message = b"Those who say it can't be done are usually interrupted by others doing it."  # - James Baldwin
    retrieve_cfrags_params, message_kit = retrieval_request_setup(
        enacted_policy,
        blockchain_bob,
        blockchain_alice,
        original_message=original_message,
        encode_for_rest=True)

    #
    # Success
    #
    response = blockchain_porter_web_controller.post(
        '/retrieve_cfrags', data=json.dumps(retrieve_cfrags_params))
    assert response.status_code == 200

    response_data = json.loads(response.data)
    retrieval_results = response_data['result']['retrieval_results']
    assert retrieval_results

    # expected results - can only compare length of results, ursulas are randomized to obtain cfrags
    retrieve_args = retrieval_params_decode_from_rest(retrieve_cfrags_params)
    expected_results = blockchain_porter.retrieve_cfrags(**retrieve_args)
    assert len(retrieval_results) == len(expected_results)

    # check that the re-encryption performed was valid
    treasure_map = retrieve_args['treasure_map']
    policy_message_kit = PolicyMessageKit.from_message_kit(
        message_kit=message_kit,
        policy_encrypting_key=enacted_policy.public_key,
        threshold=treasure_map.threshold)
    assert len(retrieval_results) == 1
    field = RetrievalResultSchema()
    cfrags = field.load(retrieval_results[0])['cfrags']
    verified_cfrags = {}
    for ursula, cfrag in cfrags.items():
        # need to obtain verified cfrags (verified cfrags are not deserializable, only non-verified cfrags)
        verified_cfrag = cfrag.verify(
            capsule=policy_message_kit.message_kit.capsule,
            verifying_pk=blockchain_alice.stamp.as_umbral_pubkey(),
            delegating_pk=enacted_policy.public_key,
            receiving_pk=blockchain_bob.public_keys(DecryptingPower))
        verified_cfrags[ursula] = verified_cfrag
    retrieval_result_object = RetrievalResult(cfrags=verified_cfrags)
    policy_message_kit = policy_message_kit.with_result(
        retrieval_result_object)

    assert policy_message_kit.is_decryptable_by_receiver()

    cleartext = blockchain_bob._crypto_power.power_ups(
        DecryptingPower).keypair.decrypt_message_kit(policy_message_kit)
    assert cleartext == original_message

    #
    # Try using multiple retrieval kits
    #
    multiple_retrieval_kits_params = dict(retrieve_cfrags_params)
    enrico = Enrico(policy_encrypting_key=enacted_policy.public_key)
    retrieval_kit_1 = RetrievalKit.from_message_kit(
        enrico.encrypt_message(b"Those who say it can't be done"))
    retrieval_kit_2 = RetrievalKit.from_message_kit(
        enrico.encrypt_message(b"are usually interrupted by others doing it."))
    retrieval_kit_field = RetrievalKitField()
    # use multiple retrieval kits and serialize for json
    multiple_retrieval_kits_params['retrieval_kits'] = [
        retrieval_kit_field._serialize(value=retrieval_kit_1,
                                       attr=None,
                                       obj=None),
        retrieval_kit_field._serialize(value=retrieval_kit_2,
                                       attr=None,
                                       obj=None)
    ]
    response = blockchain_porter_web_controller.post(
        '/retrieve_cfrags', data=json.dumps(multiple_retrieval_kits_params))
    assert response.status_code == 200

    response_data = json.loads(response.data)
    retrieval_results = response_data['result']['retrieval_results']
    assert retrieval_results
    assert len(retrieval_results) == 2

    #
    # Try same retrieval (with multiple retrieval kits) using query parameters
    #
    url_retrieve_params = dict(
        multiple_retrieval_kits_params)  # use multiple kit params from above
    # adjust parameter for url query parameter list format
    url_retrieve_params['retrieval_kits'] = ",".join(
        url_retrieve_params['retrieval_kits'])  # adjust for list
    response = blockchain_porter_web_controller.post(
        f'/retrieve_cfrags'
        f'?{urlencode(url_retrieve_params)}')
    assert response.status_code == 200
    response_data = json.loads(response.data)
    retrieval_results = response_data['result']['retrieval_results']
    assert retrieval_results
    assert len(retrieval_results) == 2

    #
    # Failure
    #
    failure_retrieve_cfrags_params = dict(retrieve_cfrags_params)
    # use invalid treasure map bytes
    failure_retrieve_cfrags_params['treasure_map'] = b64encode(
        os.urandom(32)).decode()
    response = blockchain_porter_web_controller.post(
        '/retrieve_cfrags', data=json.dumps(failure_retrieve_cfrags_params))
    assert response.status_code == 400  # invalid treasure map provided
Exemple #4
0
def test_retrieve_cfrags(federated_porter, federated_porter_web_controller,
                         enacted_federated_policy, federated_bob,
                         federated_alice, random_federated_treasure_map_data):
    # Send bad data to assert error return
    response = federated_porter_web_controller.post('/retrieve_cfrags',
                                                    data=json.dumps(
                                                        {'bad': 'input'}))
    assert response.status_code == 400

    # Setup
    original_message = b'The paradox of education is precisely this - that as one begins to become ' \
                       b'conscious one begins to examine the society in which ' \
                       b'he is (they are) being educated.'  # - James Baldwin
    retrieve_cfrags_params, message_kit = retrieval_request_setup(
        enacted_federated_policy,
        federated_bob,
        federated_alice,
        original_message=original_message,
        encode_for_rest=True)

    #
    # Success
    #
    response = federated_porter_web_controller.post(
        '/retrieve_cfrags', data=json.dumps(retrieve_cfrags_params))
    assert response.status_code == 200

    response_data = json.loads(response.data)
    retrieval_results = response_data['result']['retrieval_results']
    assert retrieval_results

    # expected results - can only compare length of results, ursulas are randomized to obtain cfrags
    retrieve_args = retrieval_params_decode_from_rest(retrieve_cfrags_params)
    expected_results = federated_porter.retrieve_cfrags(**retrieve_args)
    assert len(retrieval_results) == len(expected_results)

    # check that the re-encryption performed was valid
    treasure_map = retrieve_args['treasure_map']
    policy_message_kit = PolicyMessageKit.from_message_kit(
        message_kit=message_kit,
        policy_encrypting_key=enacted_federated_policy.public_key,
        threshold=treasure_map.threshold)
    assert len(retrieval_results) == 1
    field = RetrievalResultSchema()
    cfrags = field.load(retrieval_results[0])['cfrags']
    verified_cfrags = {}
    for ursula, cfrag in cfrags.items():
        # need to obtain verified cfrags (verified cfrags are not deserializable, only non-verified cfrags)
        verified_cfrag = cfrag.verify(
            capsule=policy_message_kit.message_kit.capsule,
            verifying_pk=federated_alice.stamp.as_umbral_pubkey(),
            delegating_pk=enacted_federated_policy.public_key,
            receiving_pk=federated_bob.public_keys(DecryptingPower))
        verified_cfrags[ursula] = verified_cfrag
    retrieval_result_object = RetrievalResult(cfrags=verified_cfrags)
    policy_message_kit = policy_message_kit.with_result(
        retrieval_result_object)

    assert policy_message_kit.is_decryptable_by_receiver()

    cleartext = federated_bob._crypto_power.power_ups(
        DecryptingPower).keypair.decrypt_message_kit(policy_message_kit)
    assert cleartext == original_message

    #
    # Try using multiple retrieval kits
    #
    multiple_retrieval_kits_params = dict(retrieve_cfrags_params)
    enrico = Enrico(policy_encrypting_key=enacted_federated_policy.public_key)
    retrieval_kit_1 = RetrievalKit.from_message_kit(
        enrico.encrypt_message(b'The paradox of education is precisely this'))
    retrieval_kit_2 = RetrievalKit.from_message_kit(
        enrico.encrypt_message(b'that as one begins to become conscious'))
    retrieval_kit_3 = RetrievalKit.from_message_kit(
        enrico.encrypt_message(b'begins to examine the society in which'))
    retrieval_kit_4 = RetrievalKit.from_message_kit(
        enrico.encrypt_message(b'he is (they are) being educated.'))
    retrieval_kit_field = RetrievalKitField()
    # use multiple retrieval kits and serialize for json
    multiple_retrieval_kits_params['retrieval_kits'] = [
        retrieval_kit_field._serialize(value=retrieval_kit_1,
                                       attr=None,
                                       obj=None),
        retrieval_kit_field._serialize(value=retrieval_kit_2,
                                       attr=None,
                                       obj=None),
        retrieval_kit_field._serialize(value=retrieval_kit_3,
                                       attr=None,
                                       obj=None),
        retrieval_kit_field._serialize(value=retrieval_kit_4,
                                       attr=None,
                                       obj=None)
    ]
    response = federated_porter_web_controller.post(
        '/retrieve_cfrags', data=json.dumps(multiple_retrieval_kits_params))
    assert response.status_code == 200

    response_data = json.loads(response.data)
    retrieval_results = response_data['result']['retrieval_results']
    assert retrieval_results
    assert len(retrieval_results) == 4

    #
    # Try same retrieval (with multiple retrieval kits) using query parameters
    #
    url_retrieve_params = dict(
        multiple_retrieval_kits_params)  # use multiple kit params from above
    # adjust parameter for url query parameter list format
    url_retrieve_params['retrieval_kits'] = ",".join(
        url_retrieve_params['retrieval_kits'])
    response = federated_porter_web_controller.post(
        f'/retrieve_cfrags'
        f'?{urlencode(url_retrieve_params)}')
    assert response.status_code == 200
    response_data = json.loads(response.data)
    retrieval_results = response_data['result']['retrieval_results']
    assert retrieval_results
    assert len(retrieval_results) == 4

    #
    # Failure
    #
    failure_retrieve_cfrags_params = dict(retrieve_cfrags_params)
    # use encrypted treasure map
    _, random_treasure_map = random_federated_treasure_map_data
    failure_retrieve_cfrags_params['treasure_map'] = b64encode(
        bytes(random_treasure_map)).decode()
    response = federated_porter_web_controller.post(
        '/retrieve_cfrags', data=json.dumps(failure_retrieve_cfrags_params))
    assert response.status_code == 400  # invalid treasure map provided