From dfed3b448f30249a9b65cba998dba77667e6c76d Mon Sep 17 00:00:00 2001 From: Mathias Hall-Andersen Date: Fri, 12 Jul 2019 14:49:53 +0200 Subject: Add peers and psks to device --- Cargo.lock | 143 +++++++++++++++++++++++++------------------------------ Cargo.toml | 2 +- src/lib.rs | 12 +---- src/machine.rs | 146 ++++++++++++++++++++++++++++++++++++++++----------------- src/noise.rs | 5 +- src/types.rs | 10 ++++ 6 files changed, 184 insertions(+), 134 deletions(-) create mode 100644 src/types.rs diff --git a/Cargo.lock b/Cargo.lock index 76201a3..5a579b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,10 +1,24 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "autocfg" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "byteorder" version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "c2-chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cc" version = "1.0.32" @@ -39,47 +53,60 @@ dependencies = [ ] [[package]] -name = "fuchsia-cprng" -version = "0.1.1" +name = "generic-array" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "gcc" -version = "0.3.55" +name = "getrandom" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "generic-array" -version = "0.12.0" +name = "lazy_static" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libc" -version = "0.2.50" +version = "0.2.59" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ppv-lite86" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rand" -version = "0.3.23" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rand" -version = "0.4.6" +name = "rand_chacha" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -96,33 +123,24 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "rdrand" -version = "0.4.0" +name = "rand_core" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "redox_syscall" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rust-crypto" -version = "0.2.36" +name = "rand_hc" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rustc-serialize" -version = "0.3.24" +name = "spin" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -130,16 +148,6 @@ name = "subtle" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "time" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "typenum" version = "1.10.0" @@ -149,29 +157,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "wg-handshake" version = "0.1.0" dependencies = [ - "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "x25519-dalek 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "winapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "x25519-dalek" version = "0.5.1" @@ -183,27 +172,25 @@ dependencies = [ ] [metadata] +"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" +"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" "checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1f8a6fc0376eb52dc18af94915cc04dfdf8353746c0e8c550ae683a0815e5c1" "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" -"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" -"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" -"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55" +"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" +"checksum libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "3262021842bf00fe07dbd6cf34ff25c99d7a7ebef8deea84db72be3ea3bb0aff" +"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" +"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" +"checksum rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e193067942ef6f485a349a113329140d0ab9e2168ce92274499bb0e9a4190d9d" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" -"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" "checksum subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "702662512f3ddeb74a64ce2fbbf3707ee1b6bb663d28bb054e0779bbc720d926" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum x25519-dalek 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4aca1ba6bec2719576bd20dfe5b24d9359552e616d10bff257e50cd85f745d17" diff --git a/Cargo.toml b/Cargo.toml index b4363ca..a83e3a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Mathias Hall-Andersen "] edition = "2018" [dependencies] -rust-crypto = "0.2.36" +rand = "0.7.0" [dependencies.x25519-dalek] version = "^0.5" diff --git a/src/lib.rs b/src/lib.rs index 33f2d81..42f8449 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,4 @@ +mod types; +mod noise; mod messages; mod machine; -mod noise; - -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - assert_eq!(2 + 2, 4); - } -} - diff --git a/src/machine.rs b/src/machine.rs index a8d4d07..8cb6fba 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -1,61 +1,57 @@ +use std::sync::Mutex; +use std::collections::HashMap; + +use rand::prelude::*; +use rand::rngs::OsRng; + use x25519_dalek::PublicKey; use x25519_dalek::StaticSecret; use x25519_dalek::SharedSecret; -use std::sync::Mutex; -use std::sync::mpsc::channel; -use std::collections::HashMap; +use crate::noise; +use crate::types; + +pub struct Output ( + Option, // resulting key-pair of successful handshake + Option> // message to send +); pub struct Peer { - m : StateMutable, - sk : StaticSecret, - pk : PublicKey, - ss : SharedSecret, - psk : [u8; 32] + // mutable state + m : Mutex, + + // constant state + pk : PublicKey, // public key of peer + ss : SharedSecret, // precomputed DH(static, static) + psk : [u8; 32] // psk of peer } -/* Mutable part of handshake state */ -enum StateMutable { +enum State { Reset, InitiationSent, - InitiationProcessed, - ReponseSent -} - -/* Immutable part of the handshake state */ -struct StateFixed { } -struct StateMachine { - peers : Vec>, // peer index -> state +struct Device { + sk : StaticSecret, // static secret key + pk : PublicKey, // static public key + peers : Vec, // peer index -> state pkmap : HashMap<[u8; 32], usize>, // public key -> peer index ids : Mutex> // receive ids -> peer index } -struct Key { - key : [u8; 32], - id : u32 -} - -struct KeyPair { - confimed : bool, // has the key-pair been confirmed - send : Key, // key for outbound messages - recv : Key // key for inbound messages -} - -struct Output ( - Option, // resulting key-pair of successful handshake - Option // id to be released -); - -impl StateMachine { +/* A mutable reference to the state machine needs to be held, + * during configuration. + */ +impl Device { /// Initialize a new handshake state machine /// /// # Arguments /// /// * `sk` - x25519 scalar representing the local private key - pub fn new(sk : StaticSecret) -> StateMachine { - StateMachine { + pub fn new(sk : StaticSecret) -> Device { + Device { + pk : PublicKey::from(&sk), + sk : sk, peers : vec![], pkmap : HashMap::new(), ids : Mutex::new(HashMap::new()) @@ -73,8 +69,56 @@ impl StateMachine { /// /// The call might fail if the public key corresponds to the secret key of the machine pub fn add(&mut self, pk : PublicKey) -> Result<(), ()> { - // let ss = sk.diffie_hellman(&pk); - Err(()) + // check that the pk is not added twice + + if let Some(_) = self.pkmap.get(pk.as_bytes()) { + return Err(()); + }; + + // check that the pk is not that of the device + + if *self.pk.as_bytes() == *pk.as_bytes() { + return Err(()); + } + + // map : pk -> new index + + self.pkmap.insert(*pk.as_bytes(), self.peers.len()); + + // map : new index -> peer + + self.peers.push(Peer { + m : Mutex::new(State::Reset), + pk : pk, + ss : self.sk.diffie_hellman(&pk), + psk : [0u8; 32] + }); + + Ok(()) + } + + /// Add a psk to the peer + /// + /// # Arguments + /// + /// * `pk` - The public key of the peer + /// * `psk` - The psk to set / unset + /// + /// # Returns + /// + /// The call might fail if the public key is not found + pub fn psk(&mut self, pk : PublicKey, psk : Option<[u8; 32]>) -> Result<(), ()> { + match self.pkmap.get(pk.as_bytes()) { + Some(&idx) => { + let peer = &mut self.peers[idx]; + peer.psk = match psk { + Some(v) => v, + None => [0u8; 32], + }; + Ok(()) + }, + _ => Err(()) + } } /// Release an id back to the pool @@ -91,12 +135,13 @@ impl StateMachine { /// # Arguments /// /// * `pk` - Public key of peer to initiate handshake for - pub fn begin(&self, pk : PublicKey) -> Result { + pub fn begin(&self, pk : PublicKey) -> Result, ()> { match self.pkmap.get(pk.as_bytes()) { None => Err(()), Some(&idx) => { - let mut peer = self.peers.get(idx).unwrap().lock().unwrap(); - Err(()) + let peer = &self.peers[idx]; + let id = self.allocate(idx); + noise::create_initiation(peer, id) } } } @@ -106,10 +151,25 @@ impl StateMachine { /// # Arguments /// /// * `msg` - Byte slice containing the message (untrusted input) - fn process(&self, msg : &[u8]) -> Result { + pub fn process(&self, msg : &[u8]) -> Result { // inspect type field match msg.get(0) { _ => Err(()) } } } + +impl Device { + // allocate a new index (id), for peer with idx + fn allocate(&self, idx : usize) -> u32 { + let mut rng = OsRng; + let mut table = self.ids.lock().unwrap(); + loop { + let id = rng.gen(); + if !table.contains_key(&id) { + table.insert(id, idx); + return id; + } + } + } +} diff --git a/src/noise.rs b/src/noise.rs index 189ada0..2d4c122 100644 --- a/src/noise.rs +++ b/src/noise.rs @@ -1,5 +1,6 @@ use crate::machine::Peer; +use crate::machine::Output; -fn create_initiation(st : &mut Peer) { - +pub fn create_initiation(peer : &Peer, id : u32) -> Result, ()> { + Ok(vec![]) } diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 0000000..3729555 --- /dev/null +++ b/src/types.rs @@ -0,0 +1,10 @@ +struct Key { + key : [u8; 32], + id : u32 +} + +pub struct KeyPair { + confimed : bool, // has the key-pair been confirmed? + send : Key, // key for outbound messages + recv : Key // key for inbound messages +} -- cgit v1.2.3-59-g8ed1b