Пример #1
0
    def reencrypt_via_rest(self, id_as_hex, request: http.Request):
        from nucypher.policy.models import WorkOrder  # Avoid circular import
        id = binascii.unhexlify(id_as_hex)
        work_order = WorkOrder.from_rest_payload(id, request.body)
        self.log.info("Work Order from {}, signed {}".format(
            work_order.bob, work_order.receipt_signature))
        with ThreadedSession(self.db_engine) as session:
            kfrag_bytes = self.datastore.get_policy_arrangement(
                id.hex().encode(), session=session).k_frag  # Careful!  :-)
        # TODO: Push this to a lower level.
        kfrag = KFrag.from_bytes(kfrag_bytes)
        cfrag_byte_stream = b""

        for capsule in work_order.capsules:
            # TODO: Sign the result of this.  See #141.
            cfrag = pre.reencrypt(kfrag, capsule)
            self.log.info(
                "Re-encrypting for Capsule {}, made CFrag {}.".format(
                    capsule, cfrag))
            cfrag_byte_stream += VariableLengthBytestring(cfrag)

        # TODO: Put this in Ursula's datastore
        self._work_orders.append(work_order)

        headers = {'Content-Type': 'application/octet-stream'}

        return Response(content=cfrag_byte_stream, headers=headers)
Пример #2
0
    def generate_work_orders(self, map_id, *capsules, num_ursulas=None):
        from nucypher.policy.models import WorkOrder  # Prevent circular import

        try:
            treasure_map_to_use = self.treasure_maps[map_id]
        except KeyError:
            raise KeyError(
                "Bob doesn't have the TreasureMap {}; can't generate work orders.".format(map_id))

        generated_work_orders = OrderedDict()

        if not treasure_map_to_use:
            raise ValueError(
                "Bob doesn't have a TreasureMap to match any of these capsules: {}".format(
                    capsules))

        for node_id, arrangement_id in treasure_map_to_use:
            ursula = self.known_nodes[node_id]

            capsules_to_include = []
            for capsule in capsules:
                if not capsule in self._saved_work_orders[node_id]:
                    capsules_to_include.append(capsule)

            if capsules_to_include:
                work_order = WorkOrder.construct_by_bob(
                    arrangement_id, capsules_to_include, ursula, self)
                generated_work_orders[node_id] = work_order
                self._saved_work_orders[node_id][capsule] = work_order

            if num_ursulas is not None:
                if num_ursulas == len(generated_work_orders):
                    break

        return generated_work_orders
Пример #3
0
    def reencrypt_via_rest(id_as_hex):
        from nucypher.policy.models import WorkOrder  # Avoid circular import
        arrangement_id = binascii.unhexlify(id_as_hex)
        work_order = WorkOrder.from_rest_payload(arrangement_id, request.data)
        log.info("Work Order from {}, signed {}".format(work_order.bob, work_order.receipt_signature))
        with ThreadedSession(db_engine) as session:
            policy_arrangement = datastore.get_policy_arrangement(arrangement_id=id_as_hex.encode(),
                                                                  session=session)

        kfrag_bytes = policy_arrangement.kfrag  # Careful!  :-)
        verifying_key_bytes = policy_arrangement.alice_pubkey_sig.key_data

        # TODO: Push this to a lower level.
        kfrag = KFrag.from_bytes(kfrag_bytes)
        alices_verifying_key = UmbralPublicKey.from_bytes(verifying_key_bytes)
        cfrag_byte_stream = b""

        for capsule, capsule_signature in zip(work_order.capsules, work_order.capsule_signatures):
            # This is the capsule signed by Bob
            capsule_signature = bytes(capsule_signature)
            # Ursula signs on top of it. Now both are committed to the same capsule.
            capsule_signed_by_both = bytes(stamp(capsule_signature))

            capsule.set_correctness_keys(verifying=alices_verifying_key)
            cfrag = pre.reencrypt(kfrag, capsule, metadata=capsule_signed_by_both)
            log.info("Re-encrypting for {}, made {}.".format(capsule, cfrag))
            signature = stamp(bytes(cfrag) + bytes(capsule))
            cfrag_byte_stream += VariableLengthBytestring(cfrag) + signature

        # TODO: Put this in Ursula's datastore
        work_order_tracker.append(work_order)

        headers = {'Content-Type': 'application/octet-stream'}

        return Response(response=cfrag_byte_stream, headers=headers)
Пример #4
0
def _mock_ursula_reencrypts(ursula, corrupt_cfrag: bool = False):
    delegating_privkey = UmbralPrivateKey.gen_key()
    _symmetric_key, capsule = pre._encapsulate(delegating_privkey.get_pubkey())
    signing_privkey = UmbralPrivateKey.gen_key()
    signing_pubkey = signing_privkey.get_pubkey()
    signer = Signer(signing_privkey)
    priv_key_bob = UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()
    kfrags = pre.generate_kfrags(delegating_privkey=delegating_privkey,
                                 signer=signer,
                                 receiving_pubkey=pub_key_bob,
                                 threshold=2,
                                 N=4,
                                 sign_delegating_key=False,
                                 sign_receiving_key=False)
    capsule.set_correctness_keys(delegating_privkey.get_pubkey(), pub_key_bob,
                                 signing_pubkey)

    ursula_pubkey = ursula.stamp.as_umbral_pubkey()

    alice_address = canonical_address_from_umbral_key(signing_pubkey)
    blockhash = bytes(32)

    specification = b''.join((bytes(capsule), bytes(ursula_pubkey),
                              bytes(ursula.decentralized_identity_evidence),
                              alice_address, blockhash))

    bobs_signer = Signer(priv_key_bob)
    task_signature = bytes(bobs_signer(specification))

    metadata = bytes(ursula.stamp(task_signature))

    cfrag = pre.reencrypt(kfrags[0], capsule, metadata=metadata)

    if corrupt_cfrag:
        cfrag.proof.bn_sig = CurveBN.gen_rand(capsule.params.curve)

    cfrag_signature = bytes(ursula.stamp(bytes(cfrag)))

    bob = Bob.from_public_keys(verifying_key=pub_key_bob)
    task = WorkOrder.Task(capsule, task_signature, cfrag, cfrag_signature)
    work_order = WorkOrder(bob, None, alice_address, [task], None, ursula,
                           blockhash)

    evidence = IndisputableEvidence(task, work_order)
    return evidence
Пример #5
0
    def reencrypt_via_rest(id_as_hex):
        from nucypher.policy.models import WorkOrder  # Avoid circular import
        arrangement_id = binascii.unhexlify(id_as_hex)
        work_order = WorkOrder.from_rest_payload(arrangement_id, request.data)
        log.info("Work Order from {}, signed {}".format(
            work_order.bob, work_order.receipt_signature))
        with ThreadedSession(db_engine) as session:
            policy_arrangement = datastore.get_policy_arrangement(
                arrangement_id=id_as_hex.encode(), session=session)
        kfrag_bytes = policy_arrangement.kfrag  # Careful!  :-)
        verifying_key_bytes = policy_arrangement.alice_pubkey_sig.key_data

        # TODO: Push this to a lower level. Perhaps to Ursula character? #619
        kfrag = KFrag.from_bytes(kfrag_bytes)
        alices_verifying_key = UmbralPublicKey.from_bytes(verifying_key_bytes)
        cfrag_byte_stream = b""

        alices_address = canonical_address_from_umbral_key(
            alices_verifying_key)
        if not alices_address == work_order.alice_address:
            message = f"This Bob ({work_order.bob}) sent an Alice's ETH address " \
                      f"({work_order.alice_address}) that doesn't match " \
                      f"the one I have ({alices_address})."
            raise SuspiciousActivity(message)

        bob_pubkey = work_order.bob.stamp.as_umbral_pubkey()
        if not work_order.alice_address_signature.verify(
                message=alices_address, verifying_key=bob_pubkey):
            message = f"This Bob ({work_order.bob}) sent an invalid signature of Alice's ETH address"
            raise InvalidSignature(message)

        # This is Bob's signature of Alice's verifying key as ETH address.
        alice_address_signature = bytes(work_order.alice_address_signature)

        for capsule, capsule_signature in zip(work_order.capsules,
                                              work_order.capsule_signatures):
            # This is the capsule signed by Bob
            capsule_signature = bytes(capsule_signature)
            # Ursula signs on top of it. Now both are committed to the same capsule.
            # She signs Alice's address too.
            ursula_signature = stamp(capsule_signature +
                                     alice_address_signature)
            capsule.set_correctness_keys(verifying=alices_verifying_key)
            cfrag = pre.reencrypt(kfrag,
                                  capsule,
                                  metadata=bytes(ursula_signature))
            log.info(f"Re-encrypting for {capsule}, made {cfrag}.")
            signature = stamp(bytes(cfrag) + bytes(capsule))
            cfrag_byte_stream += VariableLengthBytestring(cfrag) + signature

        # TODO: Put this in Ursula's datastore
        work_order_tracker.append(work_order)

        headers = {'Content-Type': 'application/octet-stream'}

        return Response(response=cfrag_byte_stream, headers=headers)
Пример #6
0
    def reencrypt_via_rest(id_as_hex):

        # TODO: How to pass Ursula's identity evidence to Bob? #962
        # 'Identity evidence' is a signature of her stamp with the checksum address

        from nucypher.policy.models import WorkOrder  # Avoid circular import
        arrangement_id = binascii.unhexlify(id_as_hex)

        with ThreadedSession(db_engine) as session:
            policy_arrangement = datastore.get_policy_arrangement(
                arrangement_id=id_as_hex.encode(), session=session)
        kfrag_bytes = policy_arrangement.kfrag  # Careful!  :-)
        verifying_key_bytes = policy_arrangement.alice_pubkey_sig.key_data

        # TODO: Push this to a lower level. Perhaps to Ursula character? #619
        kfrag = KFrag.from_bytes(kfrag_bytes)
        alices_verifying_key = UmbralPublicKey.from_bytes(verifying_key_bytes)
        alices_address = canonical_address_from_umbral_key(
            alices_verifying_key)

        work_order = WorkOrder.from_rest_payload(arrangement_id=arrangement_id,
                                                 rest_payload=request.data,
                                                 ursula_pubkey_bytes=bytes(
                                                     this_node.stamp),
                                                 alice_address=alices_address)

        log.info(
            f"Work Order from {work_order.bob}, signed {work_order.receipt_signature}"
        )

        cfrag_byte_stream = b""

        for task in work_order.tasks:
            # Ursula signs on top of Bob's signature of each task.
            # Now both are committed to the same task.  See #259.
            reencryption_metadata = bytes(
                this_node.stamp(bytes(task.signature)))

            capsule = task.capsule
            capsule.set_correctness_keys(verifying=alices_verifying_key)
            cfrag = pre.reencrypt(kfrag,
                                  capsule,
                                  metadata=reencryption_metadata)
            log.info(f"Re-encrypting for {capsule}, made {cfrag}.")

            # Finally, Ursula commits to her result
            reencryption_signature = this_node.stamp(bytes(cfrag))
            cfrag_byte_stream += VariableLengthBytestring(
                cfrag) + reencryption_signature

        # TODO: Put this in Ursula's datastore
        this_node._work_orders.append(work_order)

        headers = {'Content-Type': 'application/octet-stream'}

        return Response(response=cfrag_byte_stream, headers=headers)
Пример #7
0
    def reencrypt_via_rest(self, hrac_as_hex, request: http.Request):
        from nucypher.policy.models import WorkOrder  # Avoid circular import
        hrac = binascii.unhexlify(hrac_as_hex)
        work_order = WorkOrder.from_rest_payload(hrac, request.body)
        with ThreadedSession(self.db_engine) as session:
            kfrag_bytes = self.datastore.get_policy_arrangement(
                hrac.hex().encode(), session=session).k_frag  # Careful!  :-)
        # TODO: Push this to a lower level.
        kfrag = KFrag.from_bytes(kfrag_bytes)
        cfrag_byte_stream = b""

        for capsule in work_order.capsules:
            # TODO: Sign the result of this.  See #141.
            cfrag_byte_stream += VariableLengthBytestring(
                pre.reencrypt(kfrag, capsule))

        # TODO: Put this in Ursula's datastore
        self._work_orders.append(work_order)

        headers = {'Content-Type': 'application/octet-stream'}

        return Response(content=cfrag_byte_stream, headers=headers)
Пример #8
0
    def generate_work_orders(self, kfrag_hrac, *capsules, num_ursulas=None):
        from nucypher.policy.models import WorkOrder  # Prevent circular import

        try:
            treasure_map_to_use = self.treasure_maps[kfrag_hrac]
        except KeyError:
            raise KeyError(
                "Bob doesn't have a TreasureMap matching the hrac {}".format(
                    kfrag_hrac))

        generated_work_orders = OrderedDict()

        if not treasure_map_to_use:
            raise ValueError(
                "Bob doesn't have a TreasureMap to match any of these capsules: {}"
                .format(capsules))

        for ursula_dht_key in treasure_map_to_use:
            ursula = self.known_nodes[UmbralPublicKey.from_bytes(
                ursula_dht_key)]

            capsules_to_include = []
            for capsule in capsules:
                if not capsule in self._saved_work_orders[ursula_dht_key]:
                    capsules_to_include.append(capsule)

            if capsules_to_include:
                work_order = WorkOrder.construct_by_bob(
                    kfrag_hrac, capsules_to_include, ursula, self)
                generated_work_orders[ursula_dht_key] = work_order
                self._saved_work_orders[ursula_dht_key][capsule] = work_order

            if num_ursulas is not None:
                if num_ursulas == len(generated_work_orders):
                    break

        return generated_work_orders