From 064c109b647b2f1452ad1e96ceb74503c9261793 Mon Sep 17 00:00:00 2001 From: NIC619 Date: Thu, 28 Nov 2019 18:45:00 +0800 Subject: [PATCH] Fix signature validator: Add prefix and return verify result --- libp2p/pubsub/pubsub.py | 20 ++++++++++++++++++-- libp2p/pubsub/validators.py | 7 ++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/libp2p/pubsub/pubsub.py b/libp2p/pubsub/pubsub.py index 0fea734f..69f873af 100644 --- a/libp2p/pubsub/pubsub.py +++ b/libp2p/pubsub/pubsub.py @@ -49,6 +49,8 @@ SyncValidatorFn = Callable[[ID, rpc_pb2.Message], bool] AsyncValidatorFn = Callable[[ID, rpc_pb2.Message], Awaitable[bool]] ValidatorFn = Union[SyncValidatorFn, AsyncValidatorFn] +PUBSUB_SIGNING_PREFIX = "libp2p-pubsub:" + class TopicValidator(NamedTuple): validator: ValidatorFn @@ -475,7 +477,9 @@ class Pubsub: if self.strict_signing: priv_key = self.sign_key - signature = priv_key.sign(msg.SerializeToString()) + signature = priv_key.sign( + PUBSUB_SIGNING_PREFIX.encode() + msg.SerializeToString() + ) msg.key = self.host.get_public_key().serialize() msg.signature = signature @@ -536,7 +540,19 @@ class Pubsub: logger.debug("Reject because no signature attached for msg: %s", msg) return # Validate the signature of the message - if not signature_validator(deserialize_public_key(msg.key), msg): + # First, construct the original payload that's signed by 'msg.key' + msg_without_key_sig = rpc_pb2.Message( + data=msg.data, + topicIDs=msg.topicIDs, + from_id=msg.from_id, + seqno=msg.seqno, + ) + payload = ( + PUBSUB_SIGNING_PREFIX.encode() + msg_without_key_sig.SerializeToString() + ) + if not signature_validator( + deserialize_public_key(msg.key), payload, msg.signature + ): logger.debug("Signature validation failed for msg: %s", msg) return diff --git a/libp2p/pubsub/validators.py b/libp2p/pubsub/validators.py index 0f6e55ee..2683c0e9 100644 --- a/libp2p/pubsub/validators.py +++ b/libp2p/pubsub/validators.py @@ -1,9 +1,7 @@ from libp2p.crypto.keys import PublicKey -from .pb import rpc_pb2 - -def signature_validator(pubkey: PublicKey, msg: rpc_pb2.Message) -> bool: +def signature_validator(pubkey: PublicKey, payload: bytes, signature: bytes) -> bool: """ Verify the message against the given public key. @@ -11,7 +9,6 @@ def signature_validator(pubkey: PublicKey, msg: rpc_pb2.Message) -> bool: :param msg: the message signed. """ try: - pubkey.verify(msg.SerializeToString(), msg.signature) + return pubkey.verify(payload, signature) except Exception: return False - return True