Browse Source

Started fleshing out crypto infrastructure.

Kestrel 2 years ago
parent
commit
8eb579dc42

+ 3 - 24
Cargo.lock

@@ -189,7 +189,7 @@ checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
 dependencies = [
  "curve25519-dalek",
  "ed25519",
- "rand 0.7.3",
+ "rand",
  "serde",
  "serde_bytes",
  "sha2",
@@ -241,7 +241,7 @@ dependencies = [
  "log",
  "mio",
  "pretty_env_logger",
- "rand 0.8.5",
+ "rand",
  "rudp",
  "serde",
  "timerfd",
@@ -460,22 +460,11 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
 dependencies = [
  "getrandom 0.1.16",
  "libc",
- "rand_chacha 0.2.2",
+ "rand_chacha",
  "rand_core 0.5.1",
  "rand_hc",
 ]
 
-[[package]]
-name = "rand"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
-dependencies = [
- "libc",
- "rand_chacha 0.3.1",
- "rand_core 0.6.4",
-]
-
 [[package]]
 name = "rand_chacha"
 version = "0.2.2"
@@ -486,16 +475,6 @@ dependencies = [
  "rand_core 0.5.1",
 ]
 
-[[package]]
-name = "rand_chacha"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
-dependencies = [
- "ppv-lite86",
- "rand_core 0.6.4",
-]
-
 [[package]]
 name = "rand_core"
 version = "0.5.1"

+ 1 - 1
fleck/Cargo.toml

@@ -23,7 +23,7 @@ timerfd = "1.3.0"
 aes-gcm = "0.10.1"
 ed25519-dalek = { version = "1.0.1", features = ["serde"] }
 x25519-dalek = { version = "1.2.0" }
-rand = "0.8"
+rand = { version = "0.7", features = ["getrandom"] }
 
 [dev-dependencies]
 pretty_env_logger = "0.4.0"

+ 6 - 0
fleck/examples/simple_node.rs

@@ -1,7 +1,13 @@
+use fleck::prelude::*;
+
 fn main() {
     pretty_env_logger::init_timed();
 
     let fleck = fleck::Fleck::new();
 
+    fleck.services().with_service(|node: &fleck_core::Nodes| {
+        node.self_node().gen_keypair();
+    });
+
     fleck.run();
 }

+ 41 - 0
fleck/src/crypto.rs

@@ -38,6 +38,47 @@ pub struct SymmetricKey {
     nonce: [u8; 16],
 }
 
+#[derive(Default)]
+pub(crate) struct VerifyPacketSignature {}
+
+impl Service for std::rc::Rc<VerifyPacketSignature> {
+    fn register_channels(&self, eroot: &mut EventRoot) {
+        eroot
+            .priority_channel::<fleck_core::ReceivePacketChannel>()
+            .with::<order::Preprocessing>()
+            .subscribe(self, VerifyPacketSignature::check);
+    }
+}
+
+impl VerifyPacketSignature {
+    fn check(&self, api: &crate::Fleck, event : &mut FleckEvent<FleckPacket>) {
+        let packet = &event.data;
+        
+        let message: Option<crate::msg::Message> =
+            bincode::deserialize(packet.data.as_ref().unwrap()).ok();
+        if message.is_none() {
+            return;
+        }
+        let mut message = message.unwrap();
+
+        match message.crypto_header {
+            PacketHeader::Signed(signature) => {
+                message.crypto_header = PacketHeader::NoCrypto;
+                let to_verify = bincode::serialize(&message).expect("assume that we can re-serialize the message");
+
+                signature.verify(to_verify, signature);
+                
+                // let pubkey = api.services().with_service(|ns: &fleck_core::Nodes| { ns.self_node().pubkey() });
+
+                // match pubkey {
+                    // msg.crypto_header = PacketHeader::Signed(keypair.sign(&sign_data));
+                // }
+            }
+            _ => {},
+        }
+    }
+}
+
 #[derive(Default)]
 pub(crate) struct SignPacket {}
 

+ 4 - 0
fleck/src/io.rs

@@ -31,6 +31,10 @@ impl Packet {
         self.msg.as_ref().expect("told we could assume a Message was present")
     }
 
+    pub fn assume_msg_mut(&mut self) -> &mut crate::msg::Message {
+        self.msg.as_mut().expect("told we could assume a Message was present")
+    }
+
     pub fn as_msg<T: crate::msg::MessageParams + serde::de::DeserializeOwned>(&self) -> Option<&T> {
         self.msg.as_ref().and_then(|m| m.downcast())
     }

+ 6 - 0
fleck/src/lib.rs

@@ -71,6 +71,12 @@ impl Fleck {
     pub fn services(&self) -> std::cell::Ref<service::ServiceStack> {
         self.services.borrow()
     }
+    pub fn with_service<S: 'static, R, F: FnOnce(&S) -> R>(&self, f: F) -> R
+    where
+        Rc<S>: Service,
+    {
+        self.services.borrow().with_service(f)
+    }
     pub fn queue<CS: service::ChannelSpec>(&self, data: CS::Data) {
         self.services
             .borrow()

+ 7 - 0
fleck/src/service.rs

@@ -45,6 +45,13 @@ pub mod core {
     }
 
     pub use super::lowlevel::SendPacketChannel;
+    pub mod receive_order {
+        use super::super::order;
+        pub type Decryption = order::First;
+        pub type Verify = order::Between<Decryption, Parse>;
+        pub type Parse = order::Preprocessing;
+        pub type Dispatch = order::Processing;
+    }
     pub type ReceivePacketChannel = (channel_tags::ReceivePacketTag, crate::io::Packet);
     pub type MinorTickChannel = (channel_tags::MinorTickTag, ());
     pub type MajorTickChannel = (channel_tags::MajorTickTag, ());

+ 10 - 12
fleck/src/service/lowlevel.rs

@@ -78,18 +78,16 @@ impl Service for Rc<LocalDiscovery> {
 impl LocalDiscovery {
     fn packet(&self, api: &crate::Fleck, pkt: &mut Event<Packet>) {
         if let Some(discovery) = pkt.data.as_msg::<DiscoveryMsg>() {
-            let own_msg = api.services().with_service(|n: &super::core::Nodes| {
-                Some(&discovery.pkey) == n.self_node().pubkey()
-                || discovery.pkey == Default::default()
-            });
-
-            // if is self-message, ignore
-            if own_msg {
-                pkt.emptied = true;
-                return
-            }
-
             log::trace!("received discovery message");
+
+            // this will automatically ignore self-messages because we already know the pubkey
+            api.with_service(|nodes: &super::core::Nodes| {
+                if nodes.node_by_pubkey(&discovery.pkey).is_none() {
+                    let node = super::core::Node::build_with_addr(pkt.data.addr.unwrap());
+                    node.set_pubkey(discovery.pkey);
+                    nodes.inform_of(node);
+                }
+            });
         }
     }
 
@@ -100,7 +98,7 @@ impl LocalDiscovery {
             io_channel: Some(api.raw_io().local().clone()),
             node: None,
             msg: Some(crate::msg::Message::build(DiscoveryMsg {
-                pkey: Default::default(),
+                pkey: api.with_service(|nodes: &super::core::Nodes| nodes.self_node().pubkey().unwrap().to_owned())
             })),
         });
     }

+ 62 - 8
fleck/src/service/nodes.rs

@@ -1,3 +1,5 @@
+use rand::prelude::*;
+
 use std::{rc::Rc, collections::{HashMap, HashSet}, cell::{RefCell, Ref}};
 
 use super::Service;
@@ -37,32 +39,74 @@ impl<'l, T> std::ops::Deref for InnerRef<'l, T> {
 #[derive(Default)]
 pub struct Node {
     addr: Option<std::net::SocketAddr>,
-    pubkey: Option<PublicKey>,
+    pubkey: RefCell<Option<PublicKey>>,
     keypair: RefCell<Option<Keypair>>,
 }
 
 impl Node {
-    pub fn pubkey(&self) -> Option<&PublicKey> {
-        self.pubkey.as_ref()
+    pub fn build_with_addr(addr: std::net::SocketAddr) -> Self {
+        Self {
+            addr: Some(addr),
+            ..Default::default()
+        }
+    }
+
+    pub fn addr(&self) -> Option<std::net::SocketAddr> {
+        self.addr
+    }
+
+    pub fn pubkey(&self) -> Option<InnerRef<'_, PublicKey>> {
+        InnerRef::build(self.pubkey.borrow())
     }
     pub(crate) fn keypair(&self) -> Option<InnerRef<'_, Keypair>> {
         InnerRef::build(self.keypair.borrow())
     }
+
+    pub fn set_pubkey(&self, pk: PublicKey) {
+        let mut pkey = self.pubkey.borrow_mut();
+        if pkey.is_some() {
+            panic!("Tried to set public key on node that already has a public key!")
+        }
+        *pkey = Some(pk);
+    }
+
+    pub fn set_keypair(&self, kp: Keypair) {
+        let mut keyp = self.keypair.borrow_mut();
+        if keyp.is_some() {
+            panic!("Tried to set keypair on node that already has a keypair!")
+        }
+        *keyp = Some(kp);
+    }
+
+    pub fn gen_keypair(&self) {
+        let mut pkey = self.pubkey.borrow_mut();
+        let mut keyp = self.keypair.borrow_mut();
+        if pkey.is_some() {
+            panic!("Tried to generate keypair for node that already has a pubkey!")
+        }
+        if keyp.is_some() {
+            panic!("Tried to generate keypair for node that already has a keypair!")
+        }
+        let mut csprng = StdRng::from_entropy();
+        let kp = Keypair::generate(&mut csprng);
+        *pkey = Some(kp.public);
+        *keyp = Some(kp);
+    }
 }
 
 pub struct Nodes {
-    all_nodes: Vec<Rc<Node>>,
+    all_nodes: RefCell<Vec<Rc<Node>>>,
     self_node: Rc<Node>,
 }
 
 impl Default for Nodes {
     fn default() -> Self {
-        let mut ret = Self {
+        let ret = Self {
             all_nodes: Default::default(),
             self_node: Default::default(),
         };
 
-        ret.all_nodes.push(ret.self_node.clone());
+        ret.all_nodes.borrow_mut().push(ret.self_node.clone());
 
         ret
     }
@@ -73,8 +117,18 @@ impl Nodes {
         &self.self_node
     }
 
-    pub fn node_by_pubkey(&self, pubkey: PublicKey) -> Option<Rc<Node>> {
-        None
+    pub fn node_by_pubkey(&self, pubkey: &PublicKey) -> Option<Rc<Node>> {
+        self.all_nodes.borrow().iter().find(|n| n.pubkey().as_deref() == Some(pubkey)).map(|r| r.to_owned())
+    }
+
+    // nodes we know the address of
+    pub fn direct_neighbours(&self) -> Vec<Rc<Node>> {
+        self.all_nodes.borrow().iter().filter(|n| n.addr.is_some()).map(|r| r.to_owned()).collect()
+    }
+
+    pub fn inform_of(&self, node: Node) {
+        // TODO: check for duplicates here
+        self.all_nodes.borrow_mut().push(Rc::new(node));
     }
 }