diff options
Diffstat (limited to 'src/swarm/auth.rs')
| -rw-r--r-- | src/swarm/auth.rs | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/src/swarm/auth.rs b/src/swarm/auth.rs index 8b1352c..31230a5 100644 --- a/src/swarm/auth.rs +++ b/src/swarm/auth.rs @@ -1,15 +1,15 @@ //! Swarm membership by pre-shared key. //! //! Mycelium authenticates the sender of every message (`src_pk` can't be forged), so we -//! always know *who* talks to us. With a swarm key configured, only peers that also know +//! always know *who* talks to us. With a swarm key configured, only nodes that also know //! the key may take part: HELLO and HELLO_REPLY carry a tag proving it, and until a peer //! has sent a valid one, everything else it sends is ignored. //! //! The tag is `HMAC-SHA256(key, label ‖ swarm_id ‖ from_pk ‖ to_pk)`. It needs no //! challenge: it is bound to both keys, and only `from_pk` can send as `from_pk`, so a //! captured tag is useless to anyone else. Different labels for HELLO and HELLO_REPLY -//! keep one from being passed off as the other. A HELLO has no swarm ID yet (a new node -//! doesn't know it), so its tag binds an empty one. +//! keep one from being passed off as the other. A HELLO binds the swarm ID its sender +//! claims, or an empty one from a new node that doesn't know it yet. //! //! Limits of a shared key: every member holds the same secret, so a single member can't //! be revoked (forgetting it lasts until it says HELLO again), and changing the key @@ -19,7 +19,7 @@ use std::path::Path; use std::sync::Mutex; use std::time::{Duration, Instant}; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result, bail}; use sha2::{Digest, Sha256}; const HELLO_LABEL: &[u8] = b"continuum/hello/1"; @@ -82,9 +82,9 @@ impl SwarmKey { Some(std::mem::take(&mut rejections.suppressed)) } - /// Tag for a HELLO from `from` to `to`. - pub(crate) fn hello_tag(&self, from: &str, to: &str) -> Vec<u8> { - self.tag(HELLO_LABEL, "", from, to).to_vec() + /// Tag for a HELLO from `from` to `to`, claiming `swarm_id` ("" if unknown). + pub(crate) fn hello_tag(&self, swarm_id: &str, from: &str, to: &str) -> Vec<u8> { + self.tag(HELLO_LABEL, swarm_id, from, to).to_vec() } /// Tag for a HELLO_REPLY from `from` to `to`, naming the swarm. @@ -92,8 +92,8 @@ impl SwarmKey { self.tag(HELLO_REPLY_LABEL, swarm_id, from, to).to_vec() } - pub(crate) fn verify_hello(&self, tag: &[u8], from: &str, to: &str) -> bool { - constant_time_eq(tag, &self.tag(HELLO_LABEL, "", from, to)) + pub(crate) fn verify_hello(&self, tag: &[u8], swarm_id: &str, from: &str, to: &str) -> bool { + constant_time_eq(tag, &self.tag(HELLO_LABEL, swarm_id, from, to)) } pub(crate) fn verify_hello_reply( @@ -176,18 +176,19 @@ mod tests { let key = SwarmKey::new(vec![1; 32]); let other = SwarmKey::new(vec![2; 32]); - let hello = key.hello_tag("A", "B"); - assert!(key.verify_hello(&hello, "A", "B")); - assert!(!other.verify_hello(&hello, "A", "B")); - assert!(!key.verify_hello(&hello, "B", "A")); - assert!(!key.verify_hello(&hello, "A", "C")); - assert!(!key.verify_hello(&[], "A", "B")); + let hello = key.hello_tag("swarm", "A", "B"); + assert!(key.verify_hello(&hello, "swarm", "A", "B")); + assert!(!key.verify_hello(&hello, "", "A", "B")); + assert!(!other.verify_hello(&hello, "swarm", "A", "B")); + assert!(!key.verify_hello(&hello, "swarm", "B", "A")); + assert!(!key.verify_hello(&hello, "swarm", "A", "C")); + assert!(!key.verify_hello(&[], "swarm", "A", "B")); let reply = key.hello_reply_tag("swarm", "A", "B"); assert!(key.verify_hello_reply(&reply, "swarm", "A", "B")); assert!(!key.verify_hello_reply(&reply, "other-swarm", "A", "B")); // A HELLO tag is no HELLO_REPLY tag, and the other way round. - assert!(!key.verify_hello_reply(&hello, "", "A", "B")); - assert!(!key.verify_hello(&key.hello_reply_tag("", "A", "B"), "A", "B")); + assert!(!key.verify_hello_reply(&hello, "swarm", "A", "B")); + assert!(!key.verify_hello(&key.hello_reply_tag("swarm", "A", "B"), "swarm", "A", "B")); } } |
