Beispiel #1
0
def test_bob_can_follow_treasure_map_even_if_he_only_knows_of_one_node(
        enacted_federated_policy, federated_ursulas, certificates_tempdir):
    """
    Similar to above, but this time, we'll show that if Bob can connect to a single node, he can
    learn enough to follow the TreasureMap.

    Also, we'll get the TreasureMap from the hrac alone (ie, not via a side channel).
    """

    from nucypher.characters.lawful import Bob

    bob = Bob(network_middleware=MockRestMiddleware(),
              domain=TEMPORARY_DOMAIN,
              start_learning_now=False,
              abort_on_learning_error=True,
              federated_only=True)

    # Again, let's assume that he received the TreasureMap via a side channel.
    hrac, treasure_map = enacted_federated_policy.hrac(
    ), enacted_federated_policy.treasure_map
    map_id = treasure_map.public_id()
    bob.treasure_maps[map_id] = treasure_map

    # Now, let's create a scenario in which Bob knows of only one node.
    assert len(bob.known_nodes) == 0
    first_ursula = list(federated_ursulas).pop(0)
    bob.remember_node(first_ursula)
    assert len(bob.known_nodes) == 1

    # This time, when he follows the TreasureMap...
    unknown_nodes, known_nodes = bob.peek_at_treasure_map(map_id=map_id)

    # Bob already knew about one node; the rest are unknown.
    assert len(unknown_nodes) == len(treasure_map) - 1

    # He needs to actually follow the treasure map to get the rest.
    bob.follow_treasure_map(map_id=map_id)

    # The nodes in the learning loop are now his top target, but he's not learning yet.
    assert not bob._learning_task.running

    # ...so he hasn't learned anything (ie, Bob still knows of just one node).
    assert len(bob.known_nodes) == 1

    # Now, we'll start his learning loop.
    bob.start_learning_loop()

    # ...and block until the unknown_nodes have all been found.
    d = threads.deferToThread(bob.block_until_specific_nodes_are_known,
                              unknown_nodes)
    yield d

    # ...and he now has no more unknown_nodes.
    assert len(bob.known_nodes) == len(treasure_map)
    bob.disenchant()
Beispiel #2
0
for counter, plaintext in enumerate(finnegans_wake):

    # Enrico knows the policy's public key from a side-channel.
    # In this demo a new enrico is being constructed for each line of text.
    # This demonstrates how many individual encryptors may encrypt for a single policy.
    # In other words -- Many data sources (Enricos) can encrypt for the policy's public key.
    enrico = Enrico(policy_encrypting_key=policy_public_key)

    # In this case, the plaintext is a single passage from James Joyce's Finnegan's Wake.
    # The matter of whether encryption makes the passage more or less readable
    # is left to the reader to determine.
    message_kit = enrico.encrypt_message(plaintext)
    enrico_public_key = bytes(enrico.stamp)
    del enrico

    ###############
    # Back to Bob #
    ###############

    # Now Bob can retrieve the original message by requesting re-encryption from nodes.
    cleartexts = bob.retrieve_and_decrypt(
        [message_kit],
        alice_verifying_key=alice_verifying_key,
        encrypted_treasure_map=policy.treasure_map)

    # We show that indeed this is the passage originally encrypted by Enrico.
    assert plaintext == cleartexts[0]
    print(cleartexts)

bob.disenchant()
def test_bob_joins_policy_and_retrieves(federated_alice,
                                        federated_ursulas,
                                        certificates_tempdir,
                                        ):
    # Let's partition Ursulas in two parts
    a_couple_of_ursulas = list(federated_ursulas)[:2]
    rest_of_ursulas = list(federated_ursulas)[2:]

    # Bob becomes
    bob = Bob(federated_only=True,
              domain=TEMPORARY_DOMAIN,
              start_learning_now=True,
              network_middleware=MockRestMiddleware(),
              abort_on_learning_error=True,
              known_nodes=a_couple_of_ursulas,
              )

    # Bob has only connected to - at most - 2 nodes.
    assert sum(node.verified_node for node in bob.known_nodes) <= 2

    # Alice creates a policy granting access to Bob
    # Just for fun, let's assume she distributes KFrags among Ursulas unknown to Bob
    n = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK - 2
    label = b'label://' + os.urandom(32)
    contract_end_datetime = maya.now() + datetime.timedelta(days=5)
    policy = federated_alice.grant(bob=bob,
                                   label=label,
                                   m=3,
                                   n=n,
                                   expiration=contract_end_datetime,
                                   handpicked_ursulas=set(rest_of_ursulas),
                                   )

    assert bob == policy.bob
    assert label == policy.label

    try:
        # Now, Bob joins the policy
        bob.join_policy(label=label,
                        alice_verifying_key=federated_alice.stamp,
                        block=True)
    except policy.treasure_map.NowhereToBeFound:
        maps = []
        for ursula in federated_ursulas:
            for map in ursula.treasure_maps.values():
                maps.append(map)
        if policy.treasure_map in maps:
            # This is a nice place to put a breakpoint to examine Bob's failure to join a policy.
            bob.join_policy(label=label,
                            alice_verifying_key=federated_alice.stamp,
                            block=True)
            pytest.fail(f"Bob didn't find map {policy.treasure_map} even though it was available.  Come on, Bob.")
        else:
            pytest.fail(f"It seems that Alice didn't publish {policy.treasure_map}.  Come on, Alice.")

    # In the end, Bob should know all the Ursulas
    assert len(bob.known_nodes) == len(federated_ursulas)

    # Enrico becomes
    enrico = Enrico(policy_encrypting_key=policy.public_key)

    plaintext = b"What's your approach?  Mississippis or what?"
    message_kit, _signature = enrico.encrypt_message(plaintext)

    alices_verifying_key = federated_alice.stamp.as_umbral_pubkey()

    # Bob takes the message_kit and retrieves the message within
    delivered_cleartexts = bob.retrieve(message_kit,
                                        enrico=enrico,
                                        alice_verifying_key=alices_verifying_key,
                                        label=policy.label,
                                        retain_cfrags=True)

    assert plaintext == delivered_cleartexts[0]

    # Bob tries to retrieve again, but without using the cached CFrags, it fails.
    with pytest.raises(TypeError):
        delivered_cleartexts = bob.retrieve(message_kit,
                                            enrico=enrico,
                                            alice_verifying_key=alices_verifying_key,
                                            label=policy.label)

    cleartexts_delivered_a_second_time = bob.retrieve(message_kit,
                                                      enrico=enrico,
                                                      alice_verifying_key=alices_verifying_key,
                                                      label=policy.label,
                                                      use_attached_cfrags=True)

    # Indeed, they're the same cleartexts.
    assert delivered_cleartexts == cleartexts_delivered_a_second_time

    # Let's try retrieve again, but Alice revoked the policy.
    failed_revocations = federated_alice.revoke(policy)
    assert len(failed_revocations) == 0

    # One thing to note here is that Bob *can* still retrieve with the cached CFrags, even though this Policy has been revoked.  #892
    _cleartexts = bob.retrieve(message_kit,
                               enrico=enrico,
                               alice_verifying_key=alices_verifying_key,
                               label=policy.label,
                               use_precedent_work_orders=True,
                               )
    assert _cleartexts == delivered_cleartexts  # TODO: 892

    # OK, but we imagine that the message_kit is fresh here.
    message_kit.capsule.clear_cfrags()

    with pytest.raises(Ursula.NotEnoughUrsulas):
        _cleartexts = bob.retrieve(message_kit,
                                   enrico=enrico,
                                   alice_verifying_key=alices_verifying_key,
                                   label=policy.label,
                                   )

    bob.disenchant()
    # In this case, the plaintext is a
    # single passage from James Joyce's Finnegan's Wake.
    # The matter of whether encryption makes the passage more or less readable
    # is left to the reader to determine.
    single_passage_ciphertext, _signature = enrico.encrypt_message(plaintext)
    data_source_public_key = bytes(enrico.stamp)
    del enrico

    ###############
    # Back to Bob #
    ###############

    enrico_as_understood_by_bob = Enrico.from_public_keys(
        verifying_key=data_source_public_key,
        policy_encrypting_key=policy_pubkey)

    # Now Bob can retrieve the original message.
    alice_pubkey_restored_from_ancient_scroll = UmbralPublicKey.from_bytes(
        alices_pubkey_bytes_saved_for_posterity)
    delivered_cleartexts = BOB.retrieve(
        single_passage_ciphertext,
        enrico=enrico_as_understood_by_bob,
        alice_verifying_key=alice_pubkey_restored_from_ancient_scroll,
        label=label)

    # We show that indeed this is the passage originally encrypted by Enrico.
    assert plaintext == delivered_cleartexts[0]
    print("Retrieved: {}".format(delivered_cleartexts[0]))

BOB.disenchant()
Beispiel #5
0
def test_bob_retrieves(federated_alice, federated_ursulas,
                       certificates_tempdir):
    # Let's partition Ursulas in two parts
    a_couple_of_ursulas = list(federated_ursulas)[:2]
    rest_of_ursulas = list(federated_ursulas)[2:]

    # Bob becomes
    bob = Bob(
        federated_only=True,
        domain=TEMPORARY_DOMAIN,
        start_learning_now=True,
        network_middleware=MockRestMiddleware(),
        abort_on_learning_error=True,
        known_nodes=a_couple_of_ursulas,
    )

    # Bob has only connected to - at most - 2 nodes.
    assert sum(node.verified_node for node in bob.known_nodes) <= 2

    # Alice creates a policy granting access to Bob
    # Just for fun, let's assume she distributes KFrags among Ursulas unknown to Bob
    shares = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK - 2
    label = b'label://' + os.urandom(32)
    contract_end_datetime = maya.now() + datetime.timedelta(days=5)
    policy = federated_alice.grant(
        bob=bob,
        label=label,
        threshold=3,
        shares=shares,
        expiration=contract_end_datetime,
        ursulas=set(rest_of_ursulas),
    )

    assert label == policy.label

    # Enrico becomes
    enrico = Enrico(policy_encrypting_key=policy.public_key)

    plaintext = b"What's your approach?  Mississippis or what?"
    message_kit = enrico.encrypt_message(plaintext)

    alices_verifying_key = federated_alice.stamp.as_umbral_pubkey()

    # Bob takes the message_kit and retrieves the message within
    delivered_cleartexts = bob.retrieve_and_decrypt(
        [message_kit],
        alice_verifying_key=alices_verifying_key,
        encrypted_treasure_map=policy.treasure_map)

    assert plaintext == delivered_cleartexts[0]

    cleartexts_delivered_a_second_time = bob.retrieve_and_decrypt(
        [message_kit],
        alice_verifying_key=alices_verifying_key,
        encrypted_treasure_map=policy.treasure_map)

    # Indeed, they're the same cleartexts.
    assert delivered_cleartexts == cleartexts_delivered_a_second_time

    # Let's try retrieve again, but Alice revoked the policy.
    receipt, failed_revocations = federated_alice.revoke(policy)
    assert len(failed_revocations) == 0

    # One thing to note here is that Bob *can* still retrieve with the cached CFrags,
    # even though this Policy has been revoked.  #892
    _cleartexts = bob.retrieve_and_decrypt(
        [message_kit],
        alice_verifying_key=alices_verifying_key,
        encrypted_treasure_map=policy.treasure_map)
    assert _cleartexts == delivered_cleartexts  # TODO: 892

    bob.disenchant()