diff --git a/nucypher/core.py b/nucypher/core.py index d9ee52851..8fa36d3cd 100644 --- a/nucypher/core.py +++ b/nucypher/core.py @@ -200,7 +200,6 @@ class AuthorizedKeyFrag(Versioned): def verify(self, hrac: HRAC, - author_verifying_key: PublicKey, publisher_verifying_key: PublicKey, ) -> VerifiedKeyFrag: @@ -209,10 +208,11 @@ class AuthorizedKeyFrag(Versioned): if not self.signature.verify(message=signed_message, verifying_pk=publisher_verifying_key): raise InvalidSignature("HRAC + KeyFrag are not signed by the provided publisher") - try: - verified_kfrag = self.kfrag.verify(verifying_pk=author_verifying_key) - except VerificationError: - raise InvalidSignature("KeyFrag is not signed by the provided author") + # Ursula has no side channel to get the KeyFrag author's key, + # so verifying the keyfrag is useless. + # TODO: assuming here that VerifiedKeyFrag and KeyFrag have the same byte representation; + # would it be more clear if `kfrag` had some method like `force_verify()`? + verified_kfrag = VerifiedKeyFrag.from_verified_bytes(bytes(self.kfrag)) return verified_kfrag @@ -485,11 +485,9 @@ class ReencryptionRequest(Versioned): ursula_address: ChecksumAddress, capsules: Sequence[Capsule], treasure_map: TreasureMap, - alice_verifying_key: PublicKey, bob_verifying_key: PublicKey, ) -> 'ReencryptionRequest': return cls(hrac=treasure_map.hrac, - alice_verifying_key=alice_verifying_key, publisher_verifying_key=treasure_map.publisher_verifying_key, bob_verifying_key=bob_verifying_key, encrypted_kfrag=treasure_map.destinations[ursula_address], @@ -498,14 +496,12 @@ class ReencryptionRequest(Versioned): def __init__(self, hrac: HRAC, - alice_verifying_key: PublicKey, publisher_verifying_key: PublicKey, bob_verifying_key: PublicKey, encrypted_kfrag: EncryptedKeyFrag, capsules: List[Capsule]): self.hrac = hrac - self.alice_verifying_key = alice_verifying_key self.publisher_verifying_key = publisher_verifying_key self.bob_verifying_key = bob_verifying_key self.encrypted_kfrag = encrypted_kfrag @@ -513,7 +509,6 @@ class ReencryptionRequest(Versioned): def _payload(self) -> bytes: return (bytes(self.hrac) + - bytes(self.alice_verifying_key) + bytes(self.publisher_verifying_key) + bytes(self.bob_verifying_key) + VariableLengthBytestring(bytes(self.encrypted_kfrag)) + @@ -535,14 +530,13 @@ class ReencryptionRequest(Versioned): @classmethod def _from_bytes_current(cls, data): splitter = (hrac_splitter + - key_splitter + key_splitter + key_splitter + BytestringSplitter((EncryptedKeyFrag, VariableLengthBytestring))) - hrac, alice_vk, publisher_vk, bob_vk, ekfrag, remainder = splitter(data, return_remainder=True) + hrac, publisher_vk, bob_vk, ekfrag, remainder = splitter(data, return_remainder=True) capsules = capsule_splitter.repeat(remainder) - return cls(hrac, alice_vk, publisher_vk, bob_vk, ekfrag, capsules) + return cls(hrac, publisher_vk, bob_vk, ekfrag, capsules) class ReencryptionResponse(Versioned): diff --git a/nucypher/network/retrieval.py b/nucypher/network/retrieval.py index 75478f4b3..5bd8fa130 100644 --- a/nucypher/network/retrieval.py +++ b/nucypher/network/retrieval.py @@ -177,6 +177,7 @@ class RetrievalClient: def _request_reencryption(self, ursula: 'Ursula', reencryption_request: ReencryptionRequest, + alice_verifying_key: PublicKey, policy_key: PublicKey, bob_encrypting_key: PublicKey, ) -> Dict['Capsule', 'VerifiedCapsuleFrag']: @@ -218,7 +219,7 @@ class RetrievalClient: try: verified_cfrags = reencryption_response.verify(capsules=reencryption_request.capsules, - alice_verifying_key=reencryption_request.alice_verifying_key, + alice_verifying_key=alice_verifying_key, ursula_verifying_key=ursula_verifying_key, policy_key=policy_key, bob_encrypting_key=bob_encrypting_key, @@ -264,12 +265,12 @@ class RetrievalClient: ursula_address=work_order.ursula_address, capsules=work_order.capsules, treasure_map=treasure_map, - alice_verifying_key=alice_verifying_key, bob_verifying_key=bob_verifying_key) try: cfrags = self._request_reencryption(ursula=ursula, reencryption_request=reencryption_request, + alice_verifying_key=alice_verifying_key, policy_key=treasure_map.policy_encrypting_key, bob_encrypting_key=bob_encrypting_key) except Exception as e: diff --git a/nucypher/network/server.py b/nucypher/network/server.py index 04a2cc916..312906313 100644 --- a/nucypher/network/server.py +++ b/nucypher/network/server.py @@ -173,8 +173,6 @@ def _make_rest_app(datastore: Datastore, this_node, domain: str, log: Logger) -> if hrac in this_node.revoked_policies: return Response(response=f"Policy with {hrac} has been revoked.", status=401) # 401 - Unauthorized - # Alice & Publisher - author_verifying_key = reenc_request.alice_verifying_key publisher_verifying_key = reenc_request.publisher_verifying_key # Bob @@ -197,13 +195,16 @@ def _make_rest_app(datastore: Datastore, this_node, domain: str, log: Logger) -> # Verify KFrag Authorization (offchain) try: verified_kfrag = authorized_kfrag.verify(hrac=hrac, - author_verifying_key=author_verifying_key, publisher_verifying_key=publisher_verifying_key) except InvalidSignature as e: message = f'{bob_identity_message} Invalid signature for KeyFrag: {e}.' log.info(message) this_node.suspicious_activities_witnessed['unauthorized'].append(message) return Response(message, status=401) # 401 - Unauthorized + except Exception as e: + message = f'{bob_identity_message} Invalid KeyFrag: {e}.' + log.info(message) + return Response(message, status=400) # 400 - General error if not this_node.federated_only: diff --git a/tests/unit/test_treasure_maps.py b/tests/unit/test_treasure_maps.py index 32f4372dc..c7fa6bcf9 100644 --- a/tests/unit/test_treasure_maps.py +++ b/tests/unit/test_treasure_maps.py @@ -52,7 +52,6 @@ def test_complete_treasure_map_journey(federated_alice, federated_bob, federated ursula = ursula_rolodex[ursula_address] auth_kfrag = ursula._decrypt_kfrag(encrypted_kfrag) auth_kfrag.verify(hrac=treasure_map.hrac, - author_verifying_key=federated_alice.stamp.as_umbral_pubkey(), publisher_verifying_key=federated_alice.stamp.as_umbral_pubkey()) serialized_map = bytes(treasure_map)