From b143f4aa66f94cc009170ed23c04bce54b0957d3 Mon Sep 17 00:00:00 2001 From: Niko Date: Thu, 4 May 2023 11:57:42 +0300 Subject: [PATCH] working test vectors for Noise handshake --- ng-app-js/src/lib.rs | 16 +++++++-------- ngd/src/main.rs | 22 +++++++++++++-------- p2p-broker/src/server_ws.rs | 15 ++++++++++++--- p2p-client-ws/src/remote_ws.rs | 23 +++++++++++++--------- p2p-client-ws/src/remote_ws_wasm.rs | 6 +++--- p2p-net/src/broker.rs | 16 ++++++++++++--- p2p-net/src/connection.rs | 30 +++++++++++++++++++---------- p2p-net/src/utils.rs | 9 +++++++++ 8 files changed, 93 insertions(+), 44 deletions(-) diff --git a/ng-app-js/src/lib.rs b/ng-app-js/src/lib.rs index 4d7139b..a961f07 100644 --- a/ng-app-js/src/lib.rs +++ b/ng-app-js/src/lib.rs @@ -28,16 +28,16 @@ pub async fn greet(name: &str) { //spawn_and_log_error(testt("ws://127.0.0.1:3012")); async fn method() -> ResultSend<()> { - let pubkey_null: [u8; 32] = [ - 59, 106, 39, 188, 206, 182, 164, 45, 98, 163, 168, 208, 42, 111, 13, 115, 101, 50, 21, - 119, 29, 226, 67, 166, 58, 192, 72, 161, 139, 89, 218, 41, - ]; - - let server_key = PubKey::Ed25519PubKey(pubkey_null); + let server_key = PubKey::Ed25519PubKey([ + 22, 140, 190, 111, 82, 151, 27, 133, 83, 121, 71, 36, 209, 53, 53, 114, 52, 254, 218, + 241, 52, 155, 231, 83, 188, 189, 47, 135, 105, 213, 39, 91, + ]); log!("start connecting"); //let cnx = Arc::new(); - let (priv_key, pub_key) = generate_keypair(); + let keys = p2p_net::utils::gen_keys(); + let pub_key = PubKey::Ed25519PubKey(keys.1); + let res = BROKER .write() .await @@ -45,7 +45,7 @@ pub async fn greet(name: &str) { Box::new(ConnectionWebSocket {}), IP::try_from(&IpAddr::from_str("127.0.0.1").unwrap()).unwrap(), None, - priv_key, + keys.0, pub_key, server_key, ) diff --git a/ngd/src/main.rs b/ngd/src/main.rs index 4b8f56d..bc34bc3 100644 --- a/ngd/src/main.rs +++ b/ngd/src/main.rs @@ -8,6 +8,7 @@ // according to those terms. use p2p_broker::server_ws::run_server; +use p2p_net::utils::{gen_keys, Sensitive, U8Array}; use p2p_net::WS_PORT; use p2p_repo::{ types::{PrivKey, PubKey}, @@ -17,17 +18,22 @@ use p2p_repo::{ #[async_std::main] async fn main() -> std::io::Result<()> { println!("Starting NextGraph daemon..."); - //let keys = generate_keypair(); - //println!("Public key of node: {:?}", keys.1); - //println!("Private key of node: {:?}", keys.0); + // let keys = generate_keypair(); + // let keys = gen_keys(); + // println!("Public key of node: {:?}", keys.1); + // println!("Private key of node: {:?}", keys.0.as_slice()); let pubkey = PubKey::Ed25519PubKey([ - 158, 209, 118, 156, 133, 101, 241, 72, 91, 80, 160, 184, 201, 66, 245, 2, 91, 16, 10, 143, - 50, 206, 222, 187, 24, 122, 51, 59, 214, 132, 169, 154, + 22, 140, 190, 111, 82, 151, 27, 133, 83, 121, 71, 36, 209, 53, 53, 114, 52, 254, 218, 241, + 52, 155, 231, 83, 188, 189, 47, 135, 105, 213, 39, 91, ]); - let privkey = PrivKey::Ed25519PrivKey([ - 254, 127, 162, 204, 53, 25, 141, 12, 4, 118, 23, 42, 52, 246, 37, 52, 76, 11, 176, 219, 31, - 241, 25, 73, 199, 118, 209, 85, 159, 234, 31, 206, + let privkey = Sensitive::<[u8; 32]>::from_slice(&[ + 160, 133, 237, 116, 151, 53, 156, 151, 21, 227, 226, 35, 1, 224, 44, 207, 148, 33, 79, 160, + 115, 173, 154, 118, 251, 146, 34, 204, 40, 190, 155, 112, ]); + + //let keys = gen_keys(); + println!("Public key of node: {:?}", pubkey); + println!("Private key of node: {:?}", privkey.as_slice()); run_server(format!("127.0.0.1:{}", WS_PORT).as_str(), privkey, pubkey).await?; Ok(()) diff --git a/p2p-broker/src/server_ws.rs b/p2p-broker/src/server_ws.rs index a88ee9c..f15b23e 100644 --- a/p2p-broker/src/server_ws.rs +++ b/p2p-broker/src/server_ws.rs @@ -24,11 +24,13 @@ use p2p_client_ws::remote_ws::ConnectionWebSocket; use p2p_net::broker::*; use p2p_net::connection::IAccept; use p2p_net::types::IP; +use p2p_net::utils::Sensitive; use p2p_repo::types::{PrivKey, PubKey}; use p2p_repo::utils::generate_keypair; use p2p_stores_lmdb::broker_store::LmdbBrokerStore; use p2p_stores_lmdb::repo_store::LmdbRepoStore; use std::fs; +use std::ops::Deref; use std::sync::Arc; use std::{thread, time}; use tempfile::Builder; @@ -146,10 +148,10 @@ pub async fn run_server_accept_one(addrs: &str) -> std::io::Result<()> { Ok(()) } - +use p2p_net::utils::U8Array; pub async fn run_server( addrs: &str, - peer_priv_key: PrivKey, + peer_priv_key: Sensitive<[u8; 32]>, peer_pub_key: PubKey, ) -> std::io::Result<()> { let root = tempfile::Builder::new() @@ -175,7 +177,14 @@ pub async fn run_server( let mut ws = accept_async(tcp).await.unwrap(); let cws = ConnectionWebSocket {}; - let base = cws.accept(peer_priv_key, peer_pub_key, ws).await.unwrap(); + let base = cws + .accept( + Sensitive::<[u8; 32]>::from_slice(peer_priv_key.deref()), + peer_pub_key, + ws, + ) + .await + .unwrap(); //TODO FIXME get remote_peer_id from ConnectionBase (once it is available) let (priv_key, pub_key) = generate_keypair(); diff --git a/p2p-client-ws/src/remote_ws.rs b/p2p-client-ws/src/remote_ws.rs index 2ff495a..892ec47 100644 --- a/p2p-client-ws/src/remote_ws.rs +++ b/p2p-client-ws/src/remote_ws.rs @@ -28,7 +28,7 @@ use async_std::task; use p2p_net::errors::*; use p2p_net::log; use p2p_net::types::*; -use p2p_net::utils::{spawn_and_log_error, Receiver, ResultSend, Sender}; +use p2p_net::utils::{spawn_and_log_error, Receiver, ResultSend, Sender, Sensitive}; use p2p_net::{connection::*, WS_PORT}; use p2p_repo::types::*; use p2p_repo::utils::{generate_keypair, now_timestamp}; @@ -44,7 +44,7 @@ impl IConnect for ConnectionWebSocket { async fn open( &self, ip: IP, - peer_privk: PrivKey, + peer_privk: Sensitive<[u8; 32]>, peer_pubk: PubKey, remote_peer: DirectPeerId, ) -> Result { @@ -169,7 +169,7 @@ impl IAccept for ConnectionWebSocket { type Socket = WebSocketStream; async fn accept( &self, - peer_privk: PrivKey, + peer_privk: Sensitive<[u8; 32]>, peer_pubk: PubKey, socket: Self::Socket, ) -> Result { @@ -211,8 +211,9 @@ async fn close_ws( } else { ConnectionCommand::Error(NetError::try_from(code - 4949).unwrap()) }; - + log!("sending to read loop {:?}", cmd); let _ = futures::SinkExt::send(receiver, cmd).await; + stream .close(Some(CloseFrame { code: CloseCode::Library(code), @@ -350,12 +351,16 @@ mod test { getrandom::getrandom(&mut random_buf).unwrap(); let server_key = PubKey::Ed25519PubKey([ - 158, 209, 118, 156, 133, 101, 241, 72, 91, 80, 160, 184, 201, 66, 245, 2, 91, 16, 10, - 143, 50, 206, 222, 187, 24, 122, 51, 59, 214, 132, 169, 154, + 22, 140, 190, 111, 82, 151, 27, 133, 83, 121, 71, 36, 209, 53, 53, 114, 52, 254, 218, + 241, 52, 155, 231, 83, 188, 189, 47, 135, 105, 213, 39, 91, ]); + let keys = p2p_net::utils::gen_keys(); + + let pub_key = PubKey::Ed25519PubKey(keys.1); + log!("start connecting"); - let (priv_key, pub_key) = generate_keypair(); + //let (priv_key, pub_key) = generate_keypair(); { let res = BROKER .write() @@ -364,8 +369,8 @@ mod test { Box::new(ConnectionWebSocket {}), IP::try_from(&IpAddr::from_str("127.0.0.1").unwrap()).unwrap(), None, - priv_key, - pub_key, + keys.0, + pub_key.clone(), server_key, ) .await; diff --git a/p2p-client-ws/src/remote_ws_wasm.rs b/p2p-client-ws/src/remote_ws_wasm.rs index 42664b8..41b0ad5 100644 --- a/p2p-client-ws/src/remote_ws_wasm.rs +++ b/p2p-client-ws/src/remote_ws_wasm.rs @@ -37,8 +37,8 @@ impl IConnect for ConnectionWebSocket { async fn open( &self, ip: IP, - peer_pubk: PrivKey, - peer_privk: PubKey, + peer_privk: Sensitive<[u8; 32]>, + peer_pubk: PubKey, remote_peer: DirectPeerId, ) -> Result { //pub async fn testt(url: &str) -> ResultSend<()> { @@ -54,7 +54,7 @@ impl IConnect for ConnectionWebSocket { //let (mut sender_tx, sender_rx) = mpsc::unbounded(); //let (mut receiver_tx, receiver_rx) = mpsc::unbounded(); - cnx.start_read_loop(peer_pubk, Some(remote_peer)); + cnx.start_read_loop(peer_privk, Some(remote_peer)); let mut shutdown = cnx.set_shutdown(); spawn_and_log_error(ws_loop( diff --git a/p2p-net/src/broker.rs b/p2p-net/src/broker.rs index 13d7885..500c272 100644 --- a/p2p-net/src/broker.rs +++ b/p2p-net/src/broker.rs @@ -9,11 +9,14 @@ use async_std::stream::StreamExt; use async_std::sync::{Arc, RwLock}; use futures::channel::mpsc; use futures::SinkExt; +use noise_protocol::U8Array; +use noise_rust_crypto::sensitive::Sensitive; use once_cell::sync::Lazy; use p2p_repo::types::{PrivKey, PubKey}; use p2p_repo::utils::generate_keypair; use std::collections::HashMap; use std::net::IpAddr; +use std::ops::Deref; #[derive(Debug)] pub enum PeerConnection { @@ -212,7 +215,7 @@ impl Broker { cnx: Box, ip: IP, core: Option, // the interface used as egress for this connection - peer_privk: PrivKey, + peer_privk: Sensitive<[u8; 32]>, peer_pubk: PubKey, remote_peer_id: DirectPeerId, ) -> Result<(), NetError> { @@ -226,7 +229,14 @@ impl Broker { //let cnx = Arc::new(); //let (priv_key, pub_key) = generate_keypair(); log!("CONNECTING"); - let mut connection = cnx.open(ip, peer_privk, peer_pubk, remote_peer_id).await?; + let mut connection = cnx + .open( + ip, + Sensitive::<[u8; 32]>::from_slice(peer_privk.deref()), + peer_pubk, + remote_peer_id, + ) + .await?; let join = connection.take_shutdown(); @@ -254,7 +264,7 @@ impl Broker { cnx: Box, ip: IP, core: Option, // the interface used as egress for this connection - peer_privk: PrivKey, + peer_privk: Sensitive<[u8; 32]>, peer_pubkey: PubKey, remote_peer_id: DirectPeerId, ) -> ResultSend<()> { diff --git a/p2p-net/src/connection.rs b/p2p-net/src/connection.rs index 1a02147..20a25fd 100644 --- a/p2p-net/src/connection.rs +++ b/p2p-net/src/connection.rs @@ -39,7 +39,7 @@ pub trait IConnect: Send + Sync { async fn open( &self, ip: IP, - peer_privk: PrivKey, + peer_privk: Sensitive<[u8; 32]>, peer_pubk: PubKey, remote_peer: DirectPeerId, ) -> Result; @@ -51,7 +51,7 @@ pub trait IAccept: Send + Sync { type Socket; async fn accept( &self, - peer_privk: PrivKey, + peer_privk: Sensitive<[u8; 32]>, peer_pubk: PubKey, socket: Self::Socket, ) -> Result; @@ -95,7 +95,7 @@ pub struct NoiseFSM { noise_cipher_state_enc: Option>, noise_cipher_state_dec: Option>, - from: PrivKey, + from: Option>, to: Option, } @@ -120,7 +120,7 @@ impl NoiseFSM { dir: ConnectionDir, actors: Arc>>>, sender: Sender, - from: PrivKey, + from: Sensitive<[u8; 32]>, to: Option, ) -> Self { Self { @@ -135,7 +135,7 @@ impl NoiseFSM { noise_handshake_state: None, noise_cipher_state_enc: None, noise_cipher_state_dec: None, - from, + from: Some(from), to, } } @@ -232,7 +232,7 @@ impl NoiseFSM { noise_xk(), true, &[], - Some(Sensitive::from_slice(self.from.slice())), + Some(self.from.take().unwrap()), None, Some(*self.to.unwrap().slice()), None, @@ -260,18 +260,23 @@ impl NoiseFSM { noise_xk(), false, &[], - Some(Sensitive::from_slice(self.from.slice())), + Some(self.from.take().unwrap()), None, None, None, ); - let payload = + let mut payload = handshake.read_message_vec(noise.data()).map_err(|e| { debug_println!("{:?}", e); ProtocolError::NoiseHandshakeFailed })?; + payload = handshake.write_message_vec(&payload).map_err(|e| { + debug_println!("{:?}", e); + ProtocolError::NoiseHandshakeFailed + })?; + let noise = Noise::V0(NoiseV0 { data: payload }); self.sender.send(ConnectionCommand::Msg(noise.into())).await; @@ -291,10 +296,15 @@ impl NoiseFSM { if let ProtocolMessage::Noise(noise) = msg { let handshake = self.noise_handshake_state.as_mut().unwrap(); - let payload = handshake + let mut payload = handshake .read_message_vec(noise.data()) .map_err(|e| ProtocolError::NoiseHandshakeFailed)?; + payload = handshake.write_message_vec(&payload).map_err(|e| { + debug_println!("{:?}", e); + ProtocolError::NoiseHandshakeFailed + })?; + if !handshake.completed() { return Err(ProtocolError::NoiseHandshakeFailed); } @@ -586,7 +596,7 @@ impl ConnectionBase { } } - pub fn start_read_loop(&mut self, from: PrivKey, to: Option) { + pub fn start_read_loop(&mut self, from: Sensitive<[u8; 32]>, to: Option) { let (sender_tx, sender_rx) = mpsc::unbounded(); let (receiver_tx, receiver_rx) = mpsc::unbounded(); self.sender = Some(sender_rx); diff --git a/p2p-net/src/utils.rs b/p2p-net/src/utils.rs index 19043c7..1c0345c 100644 --- a/p2p-net/src/utils.rs +++ b/p2p-net/src/utils.rs @@ -1,6 +1,9 @@ use crate::log; use async_std::task; use futures::{channel::mpsc, select, Future, FutureExt, SinkExt}; +pub use noise_protocol::U8Array; +use noise_protocol::DH; +pub use noise_rust_crypto::sensitive::Sensitive; #[cfg(target_arch = "wasm32")] pub fn spawn_and_log_error(fut: F) -> task::JoinHandle<()> @@ -33,3 +36,9 @@ where pub type Sender = mpsc::UnboundedSender; pub type Receiver = mpsc::UnboundedReceiver; + +pub fn gen_keys() -> (Sensitive<[u8; 32]>, [u8; 32]) { + let pri = noise_rust_crypto::X25519::genkey(); + let publ = noise_rust_crypto::X25519::pubkey(&pri); + (pri, publ) +}