From d605f06dd9766f481333181df86ef2101175c44d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=BA=C3=B1ez?= Date: Thu, 6 Dec 2018 17:16:30 +0100 Subject: [PATCH] Include Alice's address in the CFrag metadata and validate it --- nucypher/network/server.py | 11 +++++++---- nucypher/policy/models.py | 22 ++++++++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/nucypher/network/server.py b/nucypher/network/server.py index 01ebb905d..f39059366 100644 --- a/nucypher/network/server.py +++ b/nucypher/network/server.py @@ -315,15 +315,18 @@ def make_rest_app( alices_verifying_key = UmbralPublicKey.from_bytes(verifying_key_bytes) cfrag_byte_stream = b"" + # This is Alice's verifying key as ETH address, signed by Bob + 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. - capsule_signed_by_both = bytes(stamp(capsule_signature)) - + # 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=capsule_signed_by_both) - log.info("Re-encrypting for {}, made {}.".format(capsule, cfrag)) + 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 diff --git a/nucypher/policy/models.py b/nucypher/policy/models.py index 7c8bde6ce..c802c1e80 100644 --- a/nucypher/policy/models.py +++ b/nucypher/policy/models.py @@ -622,7 +622,7 @@ class WorkOrder: (self.receipt_bytes, msgpack.dumps(capsules_as_bytes), msgpack.dumps(capsule_signatures_as_bytes), - self.alice_address, + self.alice_address, # TODO: if Ursula computes ETH address, we can remove this self.alice_address_signature, ) ) @@ -631,13 +631,27 @@ class WorkOrder: def complete(self, cfrags_and_signatures): good_cfrags = [] if not len(self) == len(cfrags_and_signatures): - raise ValueError("Ursula gave back the wrong number of cfrags. She's up to something.") + raise ValueError("Ursula gave back the wrong number of cfrags. " + "She's up to something.") + + alice_address_signature = bytes(self.alice_address_signature) + ursula_verifying_key = self.ursula.stamp.as_umbral_pubkey() + for counter, capsule in enumerate(self.capsules): cfrag, signature = cfrags_and_signatures[counter] - if signature.verify(bytes(cfrag) + bytes(capsule), self.ursula.stamp.as_umbral_pubkey()): + + # Validate CFrag metadata + capsule_signature = bytes(self.capsule_signatures[counter]) + metadata_input = capsule_signature + alice_address_signature + metadata_as_signature = Signature.from_bytes(cfrag.proof.metadata) + if not metadata_as_signature.verify(metadata_input, ursula_verifying_key): + raise InvalidSignature("Invalid metadata for {}.".format(cfrag)) + + # Validate work order response signatures + if signature.verify(bytes(cfrag) + bytes(capsule), ursula_verifying_key): good_cfrags.append(cfrag) else: - raise self.ursula.InvalidSignature("This CFrag is not properly signed by Ursula.") + raise InvalidSignature("{} is not properly signed by Ursula.".format(cfrag)) else: self.completed = maya.now() return good_cfrags