diff --git a/ng-sdk-js/src/lib.rs b/ng-sdk-js/src/lib.rs index 9f1f0c1..1baca07 100644 --- a/ng-sdk-js/src/lib.rs +++ b/ng-sdk-js/src/lib.rs @@ -265,20 +265,20 @@ pub async fn start() { //res.expect_throw("assume the connection succeeds"); - async fn timer_close(remote_peer_id: DirectPeerId) -> ResultSend<()> { + async fn timer_close(remote_peer_id: DirectPeerId, user: Option) -> ResultSend<()> { async move { sleep!(std::time::Duration::from_secs(3)); log_info!("timeout"); BROKER .write() .await - .close_peer_connection(&remote_peer_id) + .close_peer_connection(&remote_peer_id, user) .await; } .await; Ok(()) } - spawn_and_log_error(timer_close(server_key)); + spawn_and_log_error(timer_close(server_key, Some(user))); //Broker::graceful_shutdown().await; diff --git a/ng-wallet/src/types.rs b/ng-wallet/src/types.rs index 16ffaba..eda5eae 100644 --- a/ng-wallet/src/types.rs +++ b/ng-wallet/src/types.rs @@ -151,7 +151,17 @@ pub struct WalletContentV0 { /// Wallet Log #[derive(Clone, Debug, Serialize, Deserialize)] pub struct WalletLog0 { - pub log: Vec<(SystemTime, WalletOperationV0)>, + pub log: Vec<(u128, WalletOperationV0)>, +} + +impl WalletLog0 { + pub fn add(&mut self, op: WalletOperationV0) { + let duration = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_nanos(); + self.log.push((duration, op)); + } } /// WalletOperation diff --git a/ngd/src/main.rs b/ngd/src/main.rs index 14fcb13..97cae0f 100644 --- a/ngd/src/main.rs +++ b/ngd/src/main.rs @@ -28,6 +28,8 @@ use p2p_net::utils::{ }; use p2p_net::{WS_PORT, WS_PORT_REVERSE_PROXY}; use p2p_repo::log::*; +use p2p_repo::types::SymKey; +use p2p_repo::utils::ed_keypair_from_priv_bytes; use p2p_repo::{ types::{PrivKey, PubKey}, utils::{decode_key, generate_keypair, sign, verify}, @@ -285,7 +287,10 @@ fn parse_domain_and_port( Ok((parts[0].to_string(), domain_with_port, port)) } -fn prepare_accept_forward_for_domain(domain: String, args: &Cli) -> Result { +fn prepare_accept_forward_for_domain( + domain: String, + args: &mut Cli, +) -> Result { if args.domain_peer.is_some() { let key = decode_key(args.domain_peer.as_ref().unwrap().as_str())?; args.domain_peer.as_mut().unwrap().zeroize(); @@ -308,7 +313,7 @@ async fn main() -> std::io::Result<()> { } async fn main_inner() -> Result<(), ()> { - let args = Cli::parse(); + let mut args = Cli::parse(); if args.list_interfaces { println!("list of network interfaces"); @@ -348,10 +353,10 @@ async fn main_inner() -> Result<(), ()> { key_path.push("key"); let key_from_file: Option<[u8; 32]>; let res = |key_path| -> Result<[u8; 32], &str> { - let file = read_to_string(key_path).map_err(|_| "")?; + let mut file = read_to_string(key_path).map_err(|_| "")?; let first_line = file.lines().nth(0).ok_or("empty file")?; let res = decode_key(first_line.trim()).map_err(|_| "invalid file"); - first_line.zeroize(); + file.zeroize(); res }(&key_path); @@ -364,34 +369,35 @@ async fn main_inner() -> Result<(), ()> { } key_from_file = res.ok(); - let keys: [[u8; 32]; 4] = match &args.key { + let mut keys: [[u8; 32]; 4] = match &args.key { Some(key_string) => { if key_from_file.is_some() { log_err!("provided --key option will not be used as a key file is already present"); + args.key.as_mut().unwrap().zeroize(); gen_broker_keys(key_from_file) } else { let res = decode_key(key_string.as_str()) .map_err(|_| log_err!("provided key is invalid. cannot start"))?; if args.save_key { - let master_key = base64_url::encode(&res); - write(key_path.clone(), master_key).map_err(|e| { + let mut master_key = base64_url::encode(&res); + write(key_path.clone(), &master_key).map_err(|e| { log_err!("cannot save key to file. {}.cannot start", e.to_string()) })?; master_key.zeroize(); log_info!("The key has been saved to {}", key_path.to_str().unwrap()); } + args.key.as_mut().unwrap().zeroize(); gen_broker_keys(Some(res)) } - args.key.as_mut().unwrap().zeroize(); } None => { if key_from_file.is_some() { gen_broker_keys(key_from_file) } else { let res = gen_broker_keys(None); - let master_key = base64_url::encode(&res[0]); + let mut master_key = base64_url::encode(&res[0]); if args.save_key { - write(key_path.clone(), master_key).map_err(|e| { + write(key_path.clone(), &master_key).map_err(|e| { log_err!("cannot save key to file. {}.cannot start", e.to_string()) })?; log_info!("The key has been saved to {}", key_path.to_str().unwrap()); @@ -409,7 +415,7 @@ async fn main_inner() -> Result<(), ()> { key_from_file.and_then(|mut key| { key.zeroize(); - None + None::<()> }); // DEALING WITH CONFIG @@ -500,7 +506,7 @@ async fn main_inner() -> Result<(), ()> { overlays_config.server = BrokerOverlayPermission::AllRegisteredUser; let mut listener = ListenerV0::new_direct(loopback, !args.no_ipv6, local_port); listener.accept_direct = false; - let res = prepare_accept_forward_for_domain(domain, &args).map_err(|_| { + let res = prepare_accept_forward_for_domain(domain, &mut args).map_err(|_| { log_err!("The --domain-peer option has an invalid key. it must be a base64_url encoded serialization of a PrivKey. cannot start") })?; listener.accept_forward_for = res; @@ -770,7 +776,7 @@ async fn main_inner() -> Result<(), ()> { Some(inter) => { overlays_config.server = BrokerOverlayPermission::AllRegisteredUser; - let res = prepare_accept_forward_for_domain(domain, &args).map_err(|_| { + let res = prepare_accept_forward_for_domain(domain, &mut args).map_err(|_| { log_err!("The --domain-peer option has an invalid key. it must be a base64_url encoded serialization of a PrivKey. cannot start")})?; if listeners.last().is_some() @@ -957,14 +963,7 @@ async fn main_inner() -> Result<(), ()> { match config.unwrap() { DaemonConfig::V0(v0) => { - run_server_v0( - privkey, - pubkey, - Sensitive::<[u8; 32]>::from_slice(&keys[2]), - v0, - path, - ) - .await? + run_server_v0(privkey, pubkey, SymKey::from_array(keys[2]), v0, path).await? } } diff --git a/p2p-broker/src/server_ws.rs b/p2p-broker/src/server_ws.rs index 3aba018..40e0e76 100644 --- a/p2p-broker/src/server_ws.rs +++ b/p2p-broker/src/server_ws.rs @@ -35,10 +35,11 @@ use p2p_client_ws::remote_ws::ConnectionWebSocket; use p2p_net::broker::*; use p2p_net::connection::IAccept; use p2p_net::types::*; +use p2p_net::utils::get_domain_without_port; use p2p_net::utils::is_private_ip; use p2p_net::utils::is_public_ip; -use p2p_net::utils::{get_domain_without_port, Sensitive, U8Array}; use p2p_repo::log::*; +use p2p_repo::types::SymKey; use p2p_repo::types::{PrivKey, PubKey}; use p2p_repo::utils::generate_keypair; use rust_embed::RustEmbed; @@ -582,7 +583,7 @@ pub async fn run_server_accept_one( pub async fn run_server_v0( peer_priv_key: PrivKey, peer_id: PubKey, - wallet_master_key: Sensitive<[u8; 32]>, + wallet_master_key: SymKey, config: DaemonConfigV0, mut path: PathBuf, ) -> Result<(), ()> { diff --git a/p2p-client-ws/src/remote_ws.rs b/p2p-client-ws/src/remote_ws.rs index d40943f..cb8a7c4 100644 --- a/p2p-client-ws/src/remote_ws.rs +++ b/p2p-client-ws/src/remote_ws.rs @@ -27,7 +27,7 @@ use futures::{FutureExt, SinkExt}; use async_std::task; use p2p_net::errors::*; use p2p_net::types::*; -use p2p_net::utils::{spawn_and_log_error, Receiver, ResultSend, Sender, Sensitive}; +use p2p_net::utils::{spawn_and_log_error, Receiver, ResultSend, Sender}; use p2p_net::{connection::*, WS_PORT}; use p2p_repo::log::*; use p2p_repo::types::*; @@ -44,7 +44,7 @@ impl IConnect for ConnectionWebSocket { async fn open( &self, url: String, - peer_privk: Sensitive<[u8; 32]>, + peer_privk: PrivKey, peer_pubk: PubKey, remote_peer: DirectPeerId, config: StartConfig, @@ -346,20 +346,20 @@ mod test { BROKER.read().await.print_status(); - async fn timer_close(remote_peer_id: DirectPeerId) -> ResultSend<()> { + async fn timer_close(remote_peer_id: DirectPeerId, user: Option) -> ResultSend<()> { async move { sleep!(std::time::Duration::from_secs(3)); log_info!("timeout"); BROKER .write() .await - .close_peer_connection(&remote_peer_id) + .close_peer_connection(&remote_peer_id, user) .await; } .await; Ok(()) } - spawn_and_log_error(timer_close(server_key)); + spawn_and_log_error(timer_close(server_key, Some(user))); //Broker::graceful_shutdown().await; diff --git a/p2p-client-ws/src/remote_ws_wasm.rs b/p2p-client-ws/src/remote_ws_wasm.rs index bdecd13..f865dd1 100644 --- a/p2p-client-ws/src/remote_ws_wasm.rs +++ b/p2p-client-ws/src/remote_ws_wasm.rs @@ -38,7 +38,7 @@ impl IConnect for ConnectionWebSocket { async fn open( &self, url: String, - peer_privk: Sensitive<[u8; 32]>, + peer_privk: PrivKey, peer_pubk: PubKey, remote_peer: DirectPeerId, config: StartConfig, @@ -94,7 +94,7 @@ async fn ws_loop( mut stream: WsStream, sender: Receiver, mut receiver: Sender, - mut shutdown: Sender>, + mut shutdown: Sender>, ) -> ResultSend<()> { async fn inner_loop( stream: &mut WsStream, diff --git a/p2p-net/src/broker.rs b/p2p-net/src/broker.rs index 2170fcb..c836316 100644 --- a/p2p-net/src/broker.rs +++ b/p2p-net/src/broker.rs @@ -53,7 +53,7 @@ pub struct BrokerPeerInfo { pub struct DirectConnection { ip: IP, interface: String, - remote_peer_id: DirectPeerId, + remote_peer_id: X25519PrivKey, tp: TransportProtocol, //dir: ConnectionDir, cnx: ConnectionBase, @@ -249,8 +249,8 @@ impl Broker { (rx, tx.clone()) } - pub fn reconnecting(&mut self, peer_id: &DirectPeerId, user: Option) { - let peerinfo = self.peers.get_mut(&(user, peer_id.to_dh_slice())); + pub fn reconnecting(&mut self, peer_id: X25519PrivKey, user: Option) { + let peerinfo = self.peers.get_mut(&(user, peer_id)); match peerinfo { Some(info) => match &info.connected { PeerConnection::NONE => {} @@ -265,8 +265,8 @@ impl Broker { None => {} } } - pub fn remove_peer_id(&mut self, peer_id: &DirectPeerId, user: Option) { - let removed = self.peers.remove(&(user, peer_id.to_dh_slice())); + pub fn remove_peer_id(&mut self, peer_id: X25519PrivKey, user: Option) { + let removed = self.peers.remove(&(user, peer_id)); match removed { Some(info) => match info.connected { PeerConnection::NONE => {} @@ -404,7 +404,8 @@ impl Broker { return Err(NetError::Closing); } - let join: mpsc::UnboundedReceiver> = connection.take_shutdown(); + let join: mpsc::UnboundedReceiver> = + connection.take_shutdown(); if self .anonymous_connections .insert((local_bind_address, remote_bind_address), connection) @@ -418,7 +419,7 @@ impl Broker { } async fn watch_close( - mut join: Receiver>, + mut join: Receiver>, remote_bind_address: BindAddress, local_bind_address: BindAddress, ) -> ResultSend<()> { @@ -428,7 +429,7 @@ impl Broker { Some(Either::Right(remote_peer_id)) => { let res = join.next().await; log_info!("SOCKET IS CLOSED {:?} peer_id: {:?}", res, remote_peer_id); - BROKER.write().await.remove_peer_id(&remote_peer_id, None); + BROKER.write().await.remove_peer_id(remote_peer_id, None); } _ => { log_info!( @@ -456,10 +457,10 @@ impl Broker { &mut self, remote_bind_address: BindAddress, local_bind_address: BindAddress, - remote_peer_id: PubKey, + remote_peer_id: X25519PrivKey, core: Option, ) -> Result<(), NetError> { - log_debug!("ATTACH PEER_ID {}", remote_peer_id); + log_debug!("ATTACH PEER_ID {:?}", remote_peer_id); let mut connection = self .anonymous_connections .remove(&(local_bind_address, remote_bind_address)) @@ -484,7 +485,7 @@ impl Broker { lastPeerAdvert: None, connected, }; - self.peers.insert((None, remote_peer_id.to_dh_slice()), bpi); + self.peers.insert((None, remote_peer_id), bpi); Ok(()) } @@ -528,14 +529,14 @@ impl Broker { .await?; let join = connection.take_shutdown(); - + let remote_peer_id_dh = remote_peer_id.to_dh_slice(); let connected = match &config { StartConfig::Core(config) => { let ip = config.addr.ip.clone(); let dc = DirectConnection { ip, interface: config.interface.clone(), - remote_peer_id, + remote_peer_id: remote_peer_id_dh, tp: connection.transport_protocol(), cnx: connection, }; @@ -550,27 +551,28 @@ impl Broker { lastPeerAdvert: None, connected, }; + self.peers - .insert((config.get_user(), remote_peer_id.to_dh_slice()), bpi); + .insert((config.get_user(), remote_peer_id_dh), bpi); async fn watch_close( - mut join: Receiver>, + mut join: Receiver>, cnx: Box, peer_privk: PrivKey, peer_pubkey: PubKey, - remote_peer_id: DirectPeerId, + remote_peer_id: [u8; 32], config: StartConfig, ) -> ResultSend<()> { async move { let res = join.next().await; - log_info!("SOCKET IS CLOSED {:?} {:?}", res, &remote_peer_id); + log_info!("SOCKET IS CLOSED {:?} {:?}", res, remote_peer_id); if res.is_some() && res.as_ref().unwrap().is_left() && res.unwrap().unwrap_left() != NetError::Closing { // we intend to reconnect let mut broker = BROKER.write().await; - broker.reconnecting(&remote_peer_id, config.get_user()); + broker.reconnecting(remote_peer_id, config.get_user()); // TODO: deal with cycle error https://users.rust-lang.org/t/recursive-async-method-causes-cycle-error/84628/5 // let result = broker // .connect(cnx, ip, core, peer_pubk, peer_privk, remote_peer_id) @@ -582,7 +584,7 @@ impl Broker { BROKER .write() .await - .remove_peer_id(&remote_peer_id, config.get_user()); + .remove_peer_id(remote_peer_id, config.get_user()); } } .await; @@ -593,7 +595,7 @@ impl Broker { cnx, peer_privk, peer_pubk, - remote_peer_id, + remote_peer_id_dh, config, )); Ok(()) diff --git a/p2p-net/src/connection.rs b/p2p-net/src/connection.rs index 86a6a27..2be5a14 100644 --- a/p2p-net/src/connection.rs +++ b/p2p-net/src/connection.rs @@ -32,7 +32,7 @@ use noise_protocol::{patterns::noise_xk, CipherState, HandshakeState}; use noise_rust_crypto::sensitive::Sensitive; use noise_rust_crypto::*; use p2p_repo::log::*; -use p2p_repo::types::{PrivKey, PubKey}; +use p2p_repo::types::{PrivKey, PubKey, X25519PrivKey}; use p2p_repo::utils::{sign, verify}; use serde_bare::from_slice; use unique_id::sequence::SequenceGenerator; @@ -537,8 +537,8 @@ impl NoiseFSM { if !handshake.completed() { return Err(ProtocolError::NoiseHandshakeFailed); } - let peer_id = PubKey::Ed25519PubKey(handshake.get_rs().unwrap()); - self.remote = Some(peer_id); + let peer_id = handshake.get_rs().unwrap(); + //self.remote = Some(peer_id); let (local_bind_address, remote_bind_address) = self.bind_addresses.ok_or(ProtocolError::BrokerError)?; BROKER @@ -688,8 +688,8 @@ pub struct ConnectionBase { receiver: Option>, sender_tx: Option>, receiver_tx: Option>, - shutdown: Option>>, - shutdown_sender: Option>>, + shutdown: Option>>, + shutdown_sender: Option>>, dir: ConnectionDir, next_request_id: SequenceGenerator, tp: TransportProtocol, @@ -718,7 +718,7 @@ impl ConnectionBase { self.tp } - pub fn take_shutdown(&mut self) -> Receiver> { + pub fn take_shutdown(&mut self) -> Receiver> { self.shutdown.take().unwrap() } @@ -735,7 +735,7 @@ impl ConnectionBase { } // only used by accept - pub async fn reset_shutdown(&mut self, remote_peer_id: PubKey) { + pub async fn reset_shutdown(&mut self, remote_peer_id: X25519PrivKey) { let _ = self .shutdown_sender .take() @@ -744,8 +744,9 @@ impl ConnectionBase { .await; } - pub fn set_shutdown(&mut self) -> Sender> { - let (shutdown_sender, shutdown_receiver) = mpsc::unbounded::>(); + pub fn set_shutdown(&mut self) -> Sender> { + let (shutdown_sender, shutdown_receiver) = + mpsc::unbounded::>(); self.shutdown = Some(shutdown_receiver); self.shutdown_sender = Some(shutdown_sender.clone()); shutdown_sender diff --git a/p2p-repo/src/types.rs b/p2p-repo/src/types.rs index 39703dc..b78d6ad 100644 --- a/p2p-repo/src/types.rs +++ b/p2p-repo/src/types.rs @@ -64,6 +64,9 @@ impl SymKey { pub fn random() -> Self { SymKey::ChaCha20Key(random_key()) } + pub fn from_array(array: [u8; 32]) -> Self { + SymKey::ChaCha20Key(array) + } } /// Curve25519 public key Edwards form @@ -99,11 +102,14 @@ impl PubKey { ), } } - pub fn dh_from_ed_slice(slice: &[u8]) -> PubKey { - dh_pubkey_from_ed_pubkey_slice(slice) - } + // pub fn dh_from_ed_slice(slice: &[u8]) -> PubKey { + // dh_pubkey_from_ed_pubkey_slice(slice) + // } pub fn to_dh_slice(&self) -> [u8; 32] { - dh_pubkey_array_from_ed_pubkey_slice(self.slice()) + match self { + PubKey::Ed25519PubKey(o) => dh_pubkey_array_from_ed_pubkey_slice(o), + _ => panic!("can only convert an edward key to montgomery"), + } } } diff --git a/p2p-repo/src/utils.rs b/p2p-repo/src/utils.rs index 7550f3f..005b7c0 100644 --- a/p2p-repo/src/utils.rs +++ b/p2p-repo/src/utils.rs @@ -85,16 +85,15 @@ pub fn dh_pubkey_from_ed_pubkey_slice(public: &[u8]) -> PubKey { } pub fn dh_pubkey_array_from_ed_pubkey_slice(public: &[u8]) -> X25519PubKey { - // the zeroize are not mandatory, because it is a PubKey. let mut bits: [u8; 32] = [0u8; 32]; bits.copy_from_slice(public); - let mut compressed = CompressedEdwardsY(bits); - let mut ed_point: EdwardsPoint = compressed.decompress().unwrap(); - compressed.zeroize(); - let mut mon_point = ed_point.to_montgomery(); - ed_point.zeroize(); + let compressed = CompressedEdwardsY(bits); + let ed_point: EdwardsPoint = compressed.decompress().unwrap(); + //compressed.zeroize(); + let mon_point = ed_point.to_montgomery(); + //ed_point.zeroize(); let array = mon_point.to_bytes(); - mon_point.zeroize(); + //mon_point.zeroize(); array }