diff --git a/swap/src/network/transfer_proof.rs b/swap/src/network/transfer_proof.rs index be6bb09e..def98bb9 100644 --- a/swap/src/network/transfer_proof.rs +++ b/swap/src/network/transfer_proof.rs @@ -68,6 +68,7 @@ impl From<(PeerId, Message)> for bob::OutEvent { } => Self::TransferProofReceived { msg: Box::new(request), channel, + peer, }, Message::Response { .. } => Self::unexpected_response(peer), } diff --git a/swap/src/protocol/alice/event_loop.rs b/swap/src/protocol/alice/event_loop.rs index 51c5ce92..af21f28b 100644 --- a/swap/src/protocol/alice/event_loop.rs +++ b/swap/src/protocol/alice/event_loop.rs @@ -195,11 +195,32 @@ where } } SwarmEvent::Behaviour(OutEvent::EncryptedSignatureReceived{ msg, channel, peer }) => { - let sender = match self.recv_encrypted_signature.remove(&msg.swap_id) { + let swap_id = msg.swap_id; + let swap_peer = self.db.get_peer_id(swap_id); + + // Ensure that an incoming encrypted signature is sent by the peer-id associated with the swap + let swap_peer = match swap_peer { + Ok(swap_peer) => swap_peer, + Err(_) => { + tracing::warn!("Ignoring encrypted signature for unknown swap {} from {}", swap_id, peer); + continue; + } + }; + + if swap_peer != peer { + tracing::warn!( + %swap_id, + "Ignoring malicious encrypted signature from {}, expected to receive it from {}", + peer, + swap_peer); + continue; + } + + let sender = match self.recv_encrypted_signature.remove(&swap_id) { Some(sender) => sender, None => { // TODO: Don't just drop encsig if we currently don't have a running swap for it, save in db - tracing::warn!(%peer, "No sender for encrypted signature, maybe already handled?"); + tracing::warn!(%swap_id, "No sender for encrypted signature, maybe already handled?"); continue; } }; @@ -207,7 +228,7 @@ where let mut responder = match sender.send(msg.tx_redeem_encsig).await { Ok(responder) => responder, Err(_) => { - tracing::warn!(%peer, "Failed to relay encrypted signature to swap"); + tracing::warn!(%swap_id, "Failed to relay encrypted signature to swap"); continue; } }; diff --git a/swap/src/protocol/bob/behaviour.rs b/swap/src/protocol/bob/behaviour.rs index 06ca9a8c..91a7c47b 100644 --- a/swap/src/protocol/bob/behaviour.rs +++ b/swap/src/protocol/bob/behaviour.rs @@ -21,6 +21,7 @@ pub enum OutEvent { TransferProofReceived { msg: Box, channel: ResponseChannel<()>, + peer: PeerId, }, EncryptedSignatureAcknowledged { id: RequestId, diff --git a/swap/src/protocol/bob/event_loop.rs b/swap/src/protocol/bob/event_loop.rs index ba63880b..c4bfc0a8 100644 --- a/swap/src/protocol/bob/event_loop.rs +++ b/swap/src/protocol/bob/event_loop.rs @@ -117,11 +117,22 @@ impl EventLoop { let _ = responder.respond(*response); } } - SwarmEvent::Behaviour(OutEvent::TransferProofReceived { msg, channel }) => { - if msg.swap_id != self.swap_id { + SwarmEvent::Behaviour(OutEvent::TransferProofReceived { msg, channel, peer }) => { + let swap_id = msg.swap_id; + + if peer != self.alice_peer_id { + tracing::warn!( + %swap_id, + "Ignoring malicious transfer proof from {}, expected to receive it from {}", + peer, + self.alice_peer_id); + continue; + } + + if swap_id != self.swap_id { // TODO: Save unexpected transfer proofs in the database and check for messages in the database when handling swaps - tracing::warn!("Received unexpected transfer proof for swap {} while running swap {}. This transfer proof will be ignored.", msg.swap_id, self.swap_id); + tracing::warn!("Received unexpected transfer proof for swap {} while running swap {}. This transfer proof will be ignored.", swap_id, self.swap_id); // When receiving a transfer proof that is unexpected we still have to acknowledge that it was received let _ = self.swarm.behaviour_mut().transfer_proof.send_response(channel, ());