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)
}
}