From 35b0af9a6833dbaf9089bd97ed98d386a8fd1256 Mon Sep 17 00:00:00 2001 From: Alexis Sellier Date: Thu, 1 Sep 2022 11:17:22 +0200 Subject: [PATCH] node: Implement signature verification Signed-off-by: Alexis Sellier --- node/src/crypto.rs | 2 ++ node/src/protocol/message.rs | 18 ++++++++++++++++++ node/src/protocol/peer.rs | 11 ++++++++++- node/src/test/crypto.rs | 17 +++++++++++++---- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/node/src/crypto.rs b/node/src/crypto.rs index 53a570f0..c3d9b08d 100644 --- a/node/src/crypto.rs +++ b/node/src/crypto.rs @@ -9,6 +9,8 @@ pub use ed25519::Signature; pub trait Signer: 'static { /// Return this signer's public/verification key. fn public_key(&self) -> &PublicKey; + /// Sign a message and return the signature. + fn sign(&self, msg: &[u8]) -> Signature; } /// The public/verification key. diff --git a/node/src/protocol/message.rs b/node/src/protocol/message.rs index 46b3ce14..6f98fdfc 100644 --- a/node/src/protocol/message.rs +++ b/node/src/protocol/message.rs @@ -58,6 +58,14 @@ pub struct NodeAnnouncement { addresses: Vec
, } +impl NodeAnnouncement { + /// Verify a signature on this message. + pub fn verify(&self, signature: &crypto::Signature) -> bool { + let msg = serde_json::to_vec(self).unwrap(); + self.id.verify(signature, &msg).is_ok() + } +} + /// Message payload. /// These are the messages peers send to each other. #[derive(Debug, Serialize, Deserialize, Clone)] @@ -110,6 +118,16 @@ impl Message { } } + pub fn node(announcement: NodeAnnouncement, signer: S) -> Self { + let msg = serde_json::to_vec(&announcement).unwrap(); + let signature = signer.sign(&msg); + + Self::Node { + signature, + announcement, + } + } + pub fn inventory(ctx: &mut Context) -> Result where T: storage::ReadStorage, diff --git a/node/src/protocol/peer.rs b/node/src/protocol/peer.rs index 807ac683..66ae863d 100644 --- a/node/src/protocol/peer.rs +++ b/node/src/protocol/peer.rs @@ -194,7 +194,16 @@ impl Peer { })); } } - (PeerState::Negotiated { .. }, Message::Node { .. }) => { + ( + PeerState::Negotiated { .. }, + Message::Node { + announcement, + signature, + }, + ) => { + if !announcement.verify(&signature) { + return Err(PeerError::Misbehavior); + } todo!(); } (PeerState::Negotiated { .. }, Message::Hello { .. }) => { diff --git a/node/src/test/crypto.rs b/node/src/test/crypto.rs index 3577b824..0f624082 100644 --- a/node/src/test/crypto.rs +++ b/node/src/test/crypto.rs @@ -1,8 +1,11 @@ +use ed25519_consensus as ed25519; + use crate::crypto::{PublicKey, SecretKey, Signer}; #[derive(Debug)] pub struct MockSigner { - key: PublicKey, + pk: PublicKey, + sk: SecretKey, } impl MockSigner { @@ -15,7 +18,8 @@ impl MockSigner { let sk = SecretKey::from(bytes); Self { - key: sk.verification_key().into(), + pk: sk.verification_key().into(), + sk, } } } @@ -26,13 +30,18 @@ impl Default for MockSigner { let sk = SecretKey::from(bytes); Self { - key: sk.verification_key().into(), + pk: sk.verification_key().into(), + sk, } } } impl Signer for MockSigner { fn public_key(&self) -> &PublicKey { - &self.key + &self.pk + } + + fn sign(&self, msg: &[u8]) -> ed25519::Signature { + self.sk.sign(msg) } }