def deserialize(cls, protobuf_bytes: bytes) -> "NoiseHandshakePayload": msg = noise_pb.NoiseHandshakePayload.FromString(protobuf_bytes) return cls( id_pubkey=deserialize_public_key(msg.identity_key), id_sig=msg.identity_sig, early_data=msg.data if msg.data != b"" else None, )
def signature_validator(msg: rpc_pb2.Message) -> bool: """ Verify the message against the given public key. :param pubkey: the public key which signs the message. :param msg: the message signed. """ # 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() try: return msg_pubkey.verify(payload, msg.signature) except Exception: return False
def test_public_key_serialize_deserialize_round_trip(): key_pair = create_new_key_pair() public_key = key_pair.public_key public_key_bytes = public_key.serialize() another_public_key = deserialize_public_key(public_key_bytes) assert public_key == another_public_key
def deserialize(cls, protobuf_bytes: bytes) -> "Proposal": protobuf = Propose.FromString(protobuf_bytes) nonce = protobuf.rand public_key_protobuf_bytes = protobuf.public_key public_key = deserialize_public_key(public_key_protobuf_bytes) exchanges = protobuf.exchanges ciphers = protobuf.ciphers hashes = protobuf.hashes return cls(nonce, public_key, exchanges, ciphers, hashes)
async def run_handshake(self) -> None: """Raise `HandshakeFailure` when handshake failed.""" msg = make_exchange_message(self.local_private_key.get_public_key()) msg_bytes = msg.SerializeToString() encoded_msg_bytes = encode_fixedint_prefixed(msg_bytes) try: await self.write(encoded_msg_bytes) except RawConnError: raise HandshakeFailure("connection closed") try: remote_msg_bytes = await read_fixedint_prefixed(self.conn) except RawConnError: raise HandshakeFailure("connection closed") remote_msg = plaintext_pb2.Exchange() remote_msg.ParseFromString(remote_msg_bytes) received_peer_id = ID(remote_msg.id) # Verify if the receive `ID` matches the one we originally initialize the session. # We only need to check it when we are the initiator, because only in that condition # we possibly knows the `ID` of the remote. if self.is_initiator and self.remote_peer_id != received_peer_id: raise HandshakeFailure( "remote peer sent unexpected peer ID. " f"expected={self.remote_peer_id} received={received_peer_id}" ) # Verify if the given `pubkey` matches the given `peer_id` try: received_pubkey = deserialize_public_key( remote_msg.pubkey.SerializeToString() ) except ValueError: raise HandshakeFailure( f"unknown `key_type` of remote_msg.pubkey={remote_msg.pubkey}" ) except MissingDeserializerError as error: raise HandshakeFailure(error) peer_id_from_received_pubkey = ID.from_pubkey(received_pubkey) if peer_id_from_received_pubkey != received_peer_id: raise HandshakeFailure( "peer id and pubkey from the remote mismatch: " f"received_peer_id={received_peer_id}, remote_pubkey={received_pubkey}, " f"peer_id_from_received_pubkey={peer_id_from_received_pubkey}" ) # Nothing is wrong. Store the `pubkey` and `peer_id` in the session. self.remote_permanent_pubkey = received_pubkey # Only need to set peer's id when we don't know it before, # i.e. we are not the connection initiator. if not self.is_initiator: self.remote_peer_id = received_peer_id
def deserialize(cls, protobuf_bytes: bytes) -> "Proposal": protobuf = Propose.FromString(protobuf_bytes) nonce = protobuf.rand public_key_protobuf_bytes = protobuf.public_key try: public_key = deserialize_public_key(public_key_protobuf_bytes) except MissingDeserializerError as error: raise SedesException(error) exchanges = protobuf.exchanges ciphers = protobuf.ciphers hashes = protobuf.hashes return cls(nonce, public_key, exchanges, ciphers, hashes)
async def run_handshake( local_peer: ID, local_private_key: PrivateKey, conn: IRawConnection, is_initiator: bool, remote_peer_id: ID, ) -> ISecureConn: """Raise `HandshakeFailure` when handshake failed.""" msg = make_exchange_message(local_private_key.get_public_key()) msg_bytes = msg.SerializeToString() read_writer = PlaintextHandshakeReadWriter(conn) try: await read_writer.write_msg(msg_bytes) except RawConnError as e: raise HandshakeFailure("connection closed") from e try: remote_msg_bytes = await read_writer.read_msg() except RawConnError as e: raise HandshakeFailure("connection closed") from e remote_msg = plaintext_pb2.Exchange() remote_msg.ParseFromString(remote_msg_bytes) received_peer_id = ID(remote_msg.id) # Verify if the receive `ID` matches the one we originally initialize the session. # We only need to check it when we are the initiator, because only in that condition # we possibly knows the `ID` of the remote. if is_initiator and remote_peer_id != received_peer_id: raise HandshakeFailure( "remote peer sent unexpected peer ID. " f"expected={remote_peer_id} received={received_peer_id}" ) # Verify if the given `pubkey` matches the given `peer_id` try: received_pubkey = deserialize_public_key(remote_msg.pubkey.SerializeToString()) except ValueError as e: raise HandshakeFailure( f"unknown `key_type` of remote_msg.pubkey={remote_msg.pubkey}" ) from e except MissingDeserializerError as error: raise HandshakeFailure() from error peer_id_from_received_pubkey = ID.from_pubkey(received_pubkey) if peer_id_from_received_pubkey != received_peer_id: raise HandshakeFailure( "peer id and pubkey from the remote mismatch: " f"received_peer_id={received_peer_id}, remote_pubkey={received_pubkey}, " f"peer_id_from_received_pubkey={peer_id_from_received_pubkey}" ) secure_conn = InsecureSession( local_peer=local_peer, local_private_key=local_private_key, remote_peer=received_peer_id, remote_permanent_pubkey=received_pubkey, is_initiator=is_initiator, conn=conn, ) # TODO: Store `pubkey` and `peer_id` to `PeerStore` return secure_conn