2019-11-29 19:37:48 +08:00
|
|
|
import logging
|
2019-11-26 16:10:20 +08:00
|
|
|
|
2019-11-29 19:37:48 +08:00
|
|
|
from libp2p.crypto.serialization import deserialize_public_key
|
|
|
|
from libp2p.peer.id import ID
|
2019-11-26 16:10:20 +08:00
|
|
|
|
2019-11-29 19:37:48 +08:00
|
|
|
from .pb import rpc_pb2
|
|
|
|
|
|
|
|
logger = logging.getLogger("libp2p.pubsub")
|
|
|
|
|
|
|
|
PUBSUB_SIGNING_PREFIX = "libp2p-pubsub:"
|
|
|
|
|
|
|
|
|
|
|
|
def signature_validator(msg: rpc_pb2.Message) -> bool:
|
2019-10-25 02:10:45 +08:00
|
|
|
"""
|
|
|
|
Verify the message against the given public key.
|
2019-10-24 14:41:10 +08:00
|
|
|
|
2019-08-04 18:13:23 +08:00
|
|
|
:param pubkey: the public key which signs the message.
|
|
|
|
:param msg: the message signed.
|
|
|
|
"""
|
2019-11-29 19:37:48 +08:00
|
|
|
# Check if signature is attached
|
|
|
|
if msg.signature == b"":
|
|
|
|
logger.debug("Reject because no signature attached for msg: %s", msg)
|
|
|
|
return False
|
|
|
|
|
|
|
|
# Validate if message sender matches message signer,
|
|
|
|
# i.e., check if `msg.key` matches `msg.from_id`
|
|
|
|
msg_pubkey = deserialize_public_key(msg.key)
|
|
|
|
if ID.from_pubkey(msg_pubkey) != msg.from_id:
|
|
|
|
logger.debug(
|
|
|
|
"Reject because signing key does not match sender ID for msg: %s", msg
|
|
|
|
)
|
|
|
|
return False
|
|
|
|
# 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()
|
2019-11-26 16:10:20 +08:00
|
|
|
try:
|
2019-11-29 19:37:48 +08:00
|
|
|
return msg_pubkey.verify(payload, msg.signature)
|
2019-11-26 16:10:20 +08:00
|
|
|
except Exception:
|
|
|
|
return False
|