ClientAuth is working

Niko 2 years ago
parent b143f4aa66
commit 7c3402fc62
  1. 19
      ng-app-js/src/lib.rs
  2. 8
      p2p-broker/src/server.rs
  3. 34
      p2p-client-ws/src/connection_ws.rs
  4. 37
      p2p-client-ws/src/remote_ws.rs
  5. 17
      p2p-client-ws/src/remote_ws_wasm.rs
  6. 2
      p2p-net/src/broker.rs
  7. 185
      p2p-net/src/connection.rs
  8. 7
      p2p-net/src/errors.rs
  9. 12
      p2p-net/src/types.rs

@ -4,6 +4,7 @@ use js_sys::Reflect;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use p2p_client_ws::remote_ws_wasm::ConnectionWebSocket; use p2p_client_ws::remote_ws_wasm::ConnectionWebSocket;
use p2p_net::broker::*; use p2p_net::broker::*;
use p2p_net::connection::{ClientConfig, StartConfig};
use p2p_net::types::{DirectPeerId, IP}; use p2p_net::types::{DirectPeerId, IP};
use p2p_net::utils::{spawn_and_log_error, ResultSend}; use p2p_net::utils::{spawn_and_log_error, ResultSend};
use p2p_net::{log, sleep}; use p2p_net::{log, sleep};
@ -33,11 +34,14 @@ pub async fn greet(name: &str) {
241, 52, 155, 231, 83, 188, 189, 47, 135, 105, 213, 39, 91, 241, 52, 155, 231, 83, 188, 189, 47, 135, 105, 213, 39, 91,
]); ]);
log!("start connecting");
//let cnx = Arc::new();
let keys = p2p_net::utils::gen_keys(); let keys = p2p_net::utils::gen_keys();
let pub_key = PubKey::Ed25519PubKey(keys.1); let pub_key = PubKey::Ed25519PubKey(keys.1);
let (client_priv_key, client_pub_key) = generate_keypair();
let (user_priv_key, user_pub_key) = generate_keypair();
log!("start connecting");
let res = BROKER let res = BROKER
.write() .write()
.await .await
@ -48,6 +52,11 @@ pub async fn greet(name: &str) {
keys.0, keys.0,
pub_key, pub_key,
server_key, server_key,
StartConfig::Client(ClientConfig {
user: user_pub_key,
client: client_pub_key,
client_priv: client_priv_key,
}),
) )
.await; .await;
log!("broker.connect : {:?}", res); log!("broker.connect : {:?}", res);
@ -60,7 +69,7 @@ pub async fn greet(name: &str) {
async fn timer_close(remote_peer_id: DirectPeerId) -> ResultSend<()> { async fn timer_close(remote_peer_id: DirectPeerId) -> ResultSend<()> {
async move { async move {
sleep!(std::time::Duration::from_secs(10)); sleep!(std::time::Duration::from_secs(3));
log!("timeout"); log!("timeout");
BROKER BROKER
.write() .write()
@ -71,11 +80,11 @@ pub async fn greet(name: &str) {
.await; .await;
Ok(()) Ok(())
} }
spawn_and_log_error(timer_close(pub_key)); spawn_and_log_error(timer_close(server_key));
//Broker::graceful_shutdown().await; //Broker::graceful_shutdown().await;
Broker::join_shutdown_with_timeout(std::time::Duration::from_secs(12)).await; Broker::join_shutdown_with_timeout(std::time::Duration::from_secs(5)).await;
Ok(()) Ok(())
} }

@ -588,7 +588,7 @@ impl BrokerServer {
let mut path = self.store.path(); let mut path = self.store.path();
path.push(REPO_STORES_SUBDIR); path.push(REPO_STORES_SUBDIR);
path.push::<String>(repo_hash.clone().into()); path.push::<String>(repo_hash.clone().into());
std::fs::create_dir_all(path.clone()).map_err(|_e| ProtocolError::WriteError)?; std::fs::create_dir_all(path.clone()).map_err(|_e| ProtocolError::IoError)?;
println!("path for repo store: {}", path.to_str().unwrap()); println!("path for repo store: {}", path.to_str().unwrap());
let repo = LmdbRepoStore::open(&path, *key.slice()); let repo = LmdbRepoStore::open(&path, *key.slice());
let mut writer = self.repo_stores.write().expect("write repo_store hashmap"); let mut writer = self.repo_stores.write().expect("write repo_store hashmap");
@ -846,7 +846,7 @@ impl BrokerServer {
if !include_children { if !include_children {
let block = store.get(&id)?; let block = store.get(&id)?;
s.send_blocking(block) s.send_blocking(block)
.map_err(|_e| ProtocolError::WriteError)?; .map_err(|_e| ProtocolError::IoError)?;
Ok(r) Ok(r)
} else { } else {
let obj = Object::load(id, None, store); let obj = Object::load(id, None, store);
@ -863,7 +863,7 @@ impl BrokerServer {
let id = block.id(); let id = block.id();
if deduplicated.get(&id).is_none() { if deduplicated.get(&id).is_none() {
s.send_blocking(block.clone()) s.send_blocking(block.clone())
.map_err(|_e| ProtocolError::WriteError)?; .map_err(|_e| ProtocolError::IoError)?;
deduplicated.insert(id); deduplicated.insert(id);
} }
} }
@ -902,7 +902,7 @@ impl BrokerServer {
let id = block.id(); let id = block.id();
if deduplicated.get(&id).is_none() { if deduplicated.get(&id).is_none() {
s.send_blocking(block.clone()) s.send_blocking(block.clone())
.map_err(|_e| ProtocolError::WriteError)?; .map_err(|_e| ProtocolError::IoError)?;
deduplicated.insert(id); deduplicated.insert(id);
} }
} }

@ -2,7 +2,7 @@
* Copyright (c) 2022-2023 Niko Bonnieure, Par le Peuple, NextGraph.org developers * Copyright (c) 2022-2023 Niko Bonnieure, Par le Peuple, NextGraph.org developers
* All rights reserved. * All rights reserved.
* Licensed under the Apache License, Version 2.0 * Licensed under the Apache License, Version 2.0
* <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0> * <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
* or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>, * or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
* at your option. All files in the project carrying such * at your option. All files in the project carrying such
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
@ -13,27 +13,26 @@
use debug_print::*; use debug_print::*;
use p2p_repo::types::*; use futures::{future, pin_mut, stream, SinkExt, StreamExt};
use p2p_repo::utils::{generate_keypair, now_timestamp}; use p2p_client::connection_remote::*;
use p2p_net::broker_connection::*;
use p2p_net::errors::*; use p2p_net::errors::*;
use p2p_net::types::*; use p2p_net::types::*;
use p2p_net::broker_connection::*; use p2p_repo::types::*;
use p2p_client::connection_remote::*; use p2p_repo::utils::{generate_keypair, now_timestamp};
use futures::{future, pin_mut, stream, SinkExt, StreamExt};
use async_tungstenite::async_std::connect_async; use async_tungstenite::async_std::connect_async;
use async_tungstenite::client_async; use async_tungstenite::client_async;
use async_tungstenite::tungstenite::{Error, Message}; use async_tungstenite::tungstenite::{Error, Message};
pub struct BrokerConnectionWebSocket { pub struct BrokerConnectionWebSocket {}
}
impl BrokerConnectionWebSocket{
pub async fn open(url:&str, priv_key: PrivKey, pub_key: PubKey) -> Result<impl BrokerConnection, ProtocolError>
{
impl BrokerConnectionWebSocket {
pub async fn open(
url: &str,
priv_key: PrivKey,
pub_key: PubKey,
) -> Result<impl BrokerConnection, ProtocolError> {
let res = connect_async(url).await; let res = connect_async(url).await;
match (res) { match (res) {
@ -78,9 +77,7 @@ impl BrokerConnectionWebSocket{
.await; .await;
match cnx_res { match cnx_res {
Ok(mut cnx) => { Ok(mut cnx) => Ok(cnx),
Ok(cnx)
}
Err(e) => { Err(e) => {
debug_println!("cannot connect {:?}", e); debug_println!("cannot connect {:?}", e);
Err(e) Err(e)
@ -93,5 +90,4 @@ impl BrokerConnectionWebSocket{
} }
} }
} }
}
}

@ -47,6 +47,7 @@ impl IConnect for ConnectionWebSocket {
peer_privk: Sensitive<[u8; 32]>, peer_privk: Sensitive<[u8; 32]>,
peer_pubk: PubKey, peer_pubk: PubKey,
remote_peer: DirectPeerId, remote_peer: DirectPeerId,
config: StartConfig,
) -> Result<ConnectionBase, NetError> { ) -> Result<ConnectionBase, NetError> {
let mut cnx = ConnectionBase::new(ConnectionDir::Client, TransportProtocol::WS); let mut cnx = ConnectionBase::new(ConnectionDir::Client, TransportProtocol::WS);
@ -125,7 +126,7 @@ impl IConnect for ConnectionWebSocket {
debug_println!("END of WS loop"); debug_println!("END of WS loop");
}); });
cnx.start().await; cnx.start(config).await;
//spawn_and_log_error(ws_loop(ws, cnx.take_sender(), cnx.take_receiver())); //spawn_and_log_error(ws_loop(ws, cnx.take_sender(), cnx.take_receiver()));
@ -240,11 +241,11 @@ async fn ws_loop(
select! { select! {
r = stream.next().fuse() => match r { r = stream.next().fuse() => match r {
Some(Ok(msg)) => { Some(Ok(msg)) => {
log!("GOT MESSAGE {:?}", msg); //log!("GOT MESSAGE {:?}", msg);
if msg.is_close() { if msg.is_close() {
if let Message::Close(Some(cf)) = msg { if let Message::Close(Some(cf)) = msg {
log!("CLOSE from server with closeframe: {}",cf.reason); log!("CLOSE from remote with closeframe: {}",cf.reason);
let last_command = match cf.code { let last_command = match cf.code {
CloseCode::Normal => CloseCode::Normal =>
ConnectionCommand::Close, ConnectionCommand::Close,
@ -263,21 +264,20 @@ async fn ws_loop(
} }
else { else {
let _ = futures::SinkExt::send(receiver, ConnectionCommand::Close).await; let _ = futures::SinkExt::send(receiver, ConnectionCommand::Close).await;
log!("CLOSE from server"); log!("CLOSE from remote");
} }
return Ok(ProtocolError::Closing); return Ok(ProtocolError::Closing);
} else { } else {
futures::SinkExt::send(receiver,ConnectionCommand::Msg(serde_bare::from_slice::<ProtocolMessage>(&msg.into_data())?)).await futures::SinkExt::send(receiver,ConnectionCommand::Msg(serde_bare::from_slice::<ProtocolMessage>(&msg.into_data())?)).await
.map_err(|_e| NetError::IoError)?; .map_err(|_e| NetError::IoError)?;
} }
//return Ok(ProtocolError::Closing);
}, },
Some(Err(e)) => {log!("GOT ERROR {:?}",e);return Err(NetError::WsError);}, Some(Err(e)) => {log!("GOT ERROR {:?}",e);return Err(NetError::WsError);},
None => break None => break
}, },
s = sender.next().fuse() => match s { s = sender.next().fuse() => match s {
Some(msg) => { Some(msg) => {
log!("SENDING MESSAGE {:?}", msg); //log!("SENDING MESSAGE {:?}", msg);
match msg { match msg {
ConnectionCommand::Msg(m) => { ConnectionCommand::Msg(m) => {
futures::SinkExt::send(&mut stream,Message::binary(serde_bare::to_vec(&m)?)).await.map_err(|_e| NetError::IoError)?; futures::SinkExt::send(&mut stream,Message::binary(serde_bare::to_vec(&m)?)).await.map_err(|_e| NetError::IoError)?;
@ -302,7 +302,6 @@ async fn ws_loop(
match inner_loop(&mut ws, sender, &mut receiver).await { match inner_loop(&mut ws, sender, &mut receiver).await {
Ok(proto_err) => { Ok(proto_err) => {
if proto_err == ProtocolError::Closing { if proto_err == ProtocolError::Closing {
//FIXME: remove this case
log!("ProtocolError::Closing"); log!("ProtocolError::Closing");
let _ = ws.close(None).await; let _ = ws.close(None).await;
} else if proto_err == ProtocolError::NoError { } else if proto_err == ProtocolError::NoError {
@ -327,7 +326,7 @@ async fn ws_loop(
return Err(e); return Err(e);
} }
} }
log!("END OF LOOP"); //log!("END OF LOOP");
Ok(()) Ok(())
} }
@ -347,8 +346,8 @@ mod test {
#[async_std::test] #[async_std::test]
pub async fn test_ws() -> Result<(), NetError> { pub async fn test_ws() -> Result<(), NetError> {
let mut random_buf = [0u8; 32]; // let mut random_buf = [0u8; 32];
getrandom::getrandom(&mut random_buf).unwrap(); // getrandom::getrandom(&mut random_buf).unwrap();
let server_key = PubKey::Ed25519PubKey([ let server_key = PubKey::Ed25519PubKey([
22, 140, 190, 111, 82, 151, 27, 133, 83, 121, 71, 36, 209, 53, 53, 114, 52, 254, 218, 22, 140, 190, 111, 82, 151, 27, 133, 83, 121, 71, 36, 209, 53, 53, 114, 52, 254, 218,
@ -356,11 +355,12 @@ mod test {
]); ]);
let keys = p2p_net::utils::gen_keys(); let keys = p2p_net::utils::gen_keys();
let pub_key = PubKey::Ed25519PubKey(keys.1); let pub_key = PubKey::Ed25519PubKey(keys.1);
let (client_priv_key, client_pub_key) = generate_keypair();
let (user_priv_key, user_pub_key) = generate_keypair();
log!("start connecting"); log!("start connecting");
//let (priv_key, pub_key) = generate_keypair();
{ {
let res = BROKER let res = BROKER
.write() .write()
@ -372,15 +372,22 @@ mod test {
keys.0, keys.0,
pub_key.clone(), pub_key.clone(),
server_key, server_key,
StartConfig::Client(ClientConfig {
user: user_pub_key,
client: client_pub_key,
client_priv: client_priv_key,
}),
) )
.await; .await;
log!("broker.connect : {:?}", res); log!("broker.connect : {:?}", res);
res.expect("assume the connection succeeds"); res.expect("assume the connection succeeds");
} }
BROKER.read().await.print_status();
async fn timer_close(remote_peer_id: DirectPeerId) -> ResultSend<()> { async fn timer_close(remote_peer_id: DirectPeerId) -> ResultSend<()> {
async move { async move {
sleep!(std::time::Duration::from_secs(10)); sleep!(std::time::Duration::from_secs(3));
log!("timeout"); log!("timeout");
BROKER BROKER
.write() .write()
@ -391,11 +398,11 @@ mod test {
.await; .await;
Ok(()) Ok(())
} }
spawn_and_log_error(timer_close(pub_key)); spawn_and_log_error(timer_close(server_key));
//Broker::graceful_shutdown().await; //Broker::graceful_shutdown().await;
Broker::join_shutdown_with_timeout(std::time::Duration::from_secs(12)).await; Broker::join_shutdown_with_timeout(std::time::Duration::from_secs(5)).await;
Ok(()) Ok(())
} }
} }

@ -18,7 +18,7 @@ use p2p_net::errors::*;
use p2p_net::log; use p2p_net::log;
use p2p_net::types::*; use p2p_net::types::*;
use p2p_net::utils::*; use p2p_net::utils::*;
use p2p_net::{connection::*, WS_PORT}; use p2p_net::WS_PORT;
use p2p_repo::types::*; use p2p_repo::types::*;
use p2p_repo::utils::{generate_keypair, now_timestamp}; use p2p_repo::utils::{generate_keypair, now_timestamp};
use std::sync::Arc; use std::sync::Arc;
@ -40,6 +40,7 @@ impl IConnect for ConnectionWebSocket {
peer_privk: Sensitive<[u8; 32]>, peer_privk: Sensitive<[u8; 32]>,
peer_pubk: PubKey, peer_pubk: PubKey,
remote_peer: DirectPeerId, remote_peer: DirectPeerId,
config: StartConfig,
) -> Result<ConnectionBase, NetError> { ) -> Result<ConnectionBase, NetError> {
//pub async fn testt(url: &str) -> ResultSend<()> { //pub async fn testt(url: &str) -> ResultSend<()> {
let mut cnx = ConnectionBase::new(ConnectionDir::Client, TransportProtocol::WS); let mut cnx = ConnectionBase::new(ConnectionDir::Client, TransportProtocol::WS);
@ -65,12 +66,10 @@ impl IConnect for ConnectionWebSocket {
shutdown, shutdown,
)); ));
cnx.start().await; cnx.start(config).await;
//spawn_and_log_error(read_loop(receiver_rx, sender_tx.clone())); //spawn_and_log_error(read_loop(receiver_rx, sender_tx.clone()));
log!("sending...");
//cnx.close().await; //cnx.close().await;
// spawn_and_log_error(async move { // spawn_and_log_error(async move {
// TimeoutFuture::new(10_000).await; // TimeoutFuture::new(10_000).await;
@ -113,11 +112,10 @@ async fn ws_loop(
) -> Result<ProtocolError, NetError> { ) -> Result<ProtocolError, NetError> {
//let mut rx_sender = sender.fuse(); //let mut rx_sender = sender.fuse();
loop { loop {
log!("BEFORE SELECT");
select! { select! {
r = stream.next().fuse() => match r { r = stream.next().fuse() => match r {
Some(msg) => { Some(msg) => {
log!("GOT MESSAGE {:?}", msg); //log!("GOT MESSAGE {:?}", msg);
if let WsMessage::Binary(b) = msg { if let WsMessage::Binary(b) = msg {
receiver.send(ConnectionCommand::Msg(serde_bare::from_slice::<ProtocolMessage>(&b)?)).await receiver.send(ConnectionCommand::Msg(serde_bare::from_slice::<ProtocolMessage>(&b)?)).await
.map_err(|_e| NetError::IoError)?; .map_err(|_e| NetError::IoError)?;
@ -130,7 +128,7 @@ async fn ws_loop(
}, },
s = sender.next().fuse() => match s { s = sender.next().fuse() => match s {
Some(msg) => { Some(msg) => {
log!("SENDING MESSAGE {:?}", msg); //log!("SENDING MESSAGE {:?}", msg);
match msg { match msg {
ConnectionCommand::Msg(m) => { ConnectionCommand::Msg(m) => {
@ -152,16 +150,14 @@ async fn ws_loop(
}, },
} }
} }
log!("END SELECT");
Ok(ProtocolError::NoError) Ok(ProtocolError::NoError)
} }
log!("START of WS loop");
let mut events = ws let mut events = ws
.observe(ObserveConfig::default()) .observe(ObserveConfig::default())
//.observe(Filter::Pointer(WsEvent::is_closed).into()) //.observe(Filter::Pointer(WsEvent::is_closed).into())
.await .await
.expect_throw("observe"); .expect_throw("observe");
log!("OBSERVED");
match inner_loop(&mut stream, sender, receiver.clone()).await { match inner_loop(&mut stream, sender, receiver.clone()).await {
Ok(proto_err) => { Ok(proto_err) => {
if proto_err == ProtocolError::NoError { if proto_err == ProtocolError::NoError {
@ -220,5 +216,6 @@ async fn ws_loop(
.await .await
.map_err(|_e| NetError::IoError)?; .map_err(|_e| NetError::IoError)?;
log!("END of WS loop");
Ok(()) Ok(())
} }

@ -218,6 +218,7 @@ impl Broker {
peer_privk: Sensitive<[u8; 32]>, peer_privk: Sensitive<[u8; 32]>,
peer_pubk: PubKey, peer_pubk: PubKey,
remote_peer_id: DirectPeerId, remote_peer_id: DirectPeerId,
config: StartConfig,
) -> Result<(), NetError> { ) -> Result<(), NetError> {
if self.closing { if self.closing {
return Err(NetError::Closing); return Err(NetError::Closing);
@ -235,6 +236,7 @@ impl Broker {
Sensitive::<[u8; 32]>::from_slice(peer_privk.deref()), Sensitive::<[u8; 32]>::from_slice(peer_privk.deref()),
peer_pubk, peer_pubk,
remote_peer_id, remote_peer_id,
config,
) )
.await?; .await?;

@ -20,6 +20,7 @@ use noise_protocol::{patterns::noise_xk, CipherState, HandshakeState};
use noise_rust_crypto::sensitive::Sensitive; use noise_rust_crypto::sensitive::Sensitive;
use noise_rust_crypto::*; use noise_rust_crypto::*;
use p2p_repo::types::{PrivKey, PubKey}; use p2p_repo::types::{PrivKey, PubKey};
use p2p_repo::utils::{sign, verify};
use serde_bare::from_slice; use serde_bare::from_slice;
use unique_id::sequence::SequenceGenerator; use unique_id::sequence::SequenceGenerator;
use unique_id::Generator; use unique_id::Generator;
@ -42,6 +43,7 @@ pub trait IConnect: Send + Sync {
peer_privk: Sensitive<[u8; 32]>, peer_privk: Sensitive<[u8; 32]>,
peer_pubk: PubKey, peer_pubk: PubKey,
remote_peer: DirectPeerId, remote_peer: DirectPeerId,
config: StartConfig,
) -> Result<ConnectionBase, NetError>; ) -> Result<ConnectionBase, NetError>;
} }
@ -97,6 +99,9 @@ pub struct NoiseFSM {
from: Option<Sensitive<[u8; 32]>>, from: Option<Sensitive<[u8; 32]>>,
to: Option<PubKey>, to: Option<PubKey>,
nonce_for_hello: Vec<u8>,
config: Option<StartConfig>,
} }
impl fmt::Debug for NoiseFSM { impl fmt::Debug for NoiseFSM {
@ -114,6 +119,25 @@ pub enum StepReply {
NONE, NONE,
} }
pub struct ClientConfig {
pub user: PubKey,
pub client: PubKey,
pub client_priv: PrivKey,
}
pub struct ExtConfig {}
pub struct CoreConfig {}
pub struct AdminConfig {}
pub enum StartConfig {
Client(ClientConfig),
Ext(ExtConfig),
Core(CoreConfig),
Admin(AdminConfig),
}
impl NoiseFSM { impl NoiseFSM {
pub fn new( pub fn new(
tp: TransportProtocol, tp: TransportProtocol,
@ -137,6 +161,8 @@ impl NoiseFSM {
noise_cipher_state_dec: None, noise_cipher_state_dec: None,
from: Some(from), from: Some(from),
to, to,
nonce_for_hello: vec![],
config: None,
} }
} }
@ -168,14 +194,20 @@ impl NoiseFSM {
} }
pub async fn send(&mut self, msg: ProtocolMessage) -> Result<(), ProtocolError> { pub async fn send(&mut self, msg: ProtocolMessage) -> Result<(), ProtocolError> {
if self.state == FSMstate::AuthResult && self.noise_cipher_state_enc.is_some() { log!("SENDING: {:?}", msg);
if self.noise_cipher_state_enc.is_some() {
let cipher = self.encrypt(msg)?; let cipher = self.encrypt(msg)?;
self.sender self.sender
.send(ConnectionCommand::Msg(ProtocolMessage::Noise(cipher))) .send(ConnectionCommand::Msg(ProtocolMessage::Noise(cipher)))
.await; .await
.map_err(|e| ProtocolError::IoError)?;
return Ok(()); return Ok(());
} else { } else {
return Err(ProtocolError::InvalidState); self.sender
.send(ConnectionCommand::Msg(msg))
.await
.map_err(|e| ProtocolError::IoError)?;
return Ok(());
} }
} }
@ -207,6 +239,9 @@ impl NoiseFSM {
return Err(ProtocolError::MustBeEncrypted); return Err(ProtocolError::MustBeEncrypted);
} }
} }
if msg_opt.is_some() {
log!("RECEIVED: {:?}", msg_opt.as_ref().unwrap());
}
match self.state { match self.state {
// TODO verify that ID is zero // TODO verify that ID is zero
FSMstate::Local0 => { FSMstate::Local0 => {
@ -243,7 +278,7 @@ impl NoiseFSM {
.map_err(|e| ProtocolError::NoiseHandshakeFailed)?; .map_err(|e| ProtocolError::NoiseHandshakeFailed)?;
let noise = Noise::V0(NoiseV0 { data: payload }); let noise = Noise::V0(NoiseV0 { data: payload });
self.sender.send(ConnectionCommand::Msg(noise.into())).await; self.send(noise.into()).await?;
self.noise_handshake_state = Some(handshake); self.noise_handshake_state = Some(handshake);
@ -278,7 +313,7 @@ impl NoiseFSM {
})?; })?;
let noise = Noise::V0(NoiseV0 { data: payload }); let noise = Noise::V0(NoiseV0 { data: payload });
self.sender.send(ConnectionCommand::Msg(noise.into())).await; self.send(noise.into()).await?;
self.noise_handshake_state = Some(handshake); self.noise_handshake_state = Some(handshake);
@ -309,19 +344,31 @@ impl NoiseFSM {
return Err(ProtocolError::NoiseHandshakeFailed); return Err(ProtocolError::NoiseHandshakeFailed);
} }
let noise3 = ClientHello::Noise3(Noise::V0(NoiseV0 { data: payload }));
self.sender
.send(ConnectionCommand::Msg(noise3.into()))
.await;
let ciphers = handshake.get_ciphers(); let ciphers = handshake.get_ciphers();
match self.config.as_ref().unwrap() {
StartConfig::Client(client_config) => {
let noise3 =
ClientHello::Noise3(Noise::V0(NoiseV0 { data: payload }));
self.send(noise3.into()).await?;
self.state = FSMstate::ClientHello;
}
StartConfig::Ext(ext_config) => {
todo!();
}
StartConfig::Core(core_config) => {
todo!();
}
StartConfig::Admin(admin_config) => {
todo!();
}
}
self.noise_cipher_state_enc = Some(ciphers.0); self.noise_cipher_state_enc = Some(ciphers.0);
self.noise_cipher_state_dec = Some(ciphers.1); self.noise_cipher_state_dec = Some(ciphers.1);
self.noise_handshake_state = None; self.noise_handshake_state = None;
self.state = FSMstate::ClientHello;
return Ok(StepReply::NONE); return Ok(StepReply::NONE);
} }
} }
@ -356,14 +403,14 @@ impl NoiseFSM {
let mut nonce_buf = [0u8; 32]; let mut nonce_buf = [0u8; 32];
getrandom::getrandom(&mut nonce_buf).unwrap(); getrandom::getrandom(&mut nonce_buf).unwrap();
self.nonce_for_hello = nonce_buf.to_vec();
let server_hello = ServerHello::V0(ServerHelloV0 { let server_hello = ServerHello::V0(ServerHelloV0 {
nonce: nonce_buf.to_vec(), nonce: self.nonce_for_hello.clone(),
}); });
self.sender
.send(ConnectionCommand::Msg(server_hello.into()))
.await;
self.state = FSMstate::ServerHello; self.state = FSMstate::ServerHello;
self.send(server_hello.into()).await?;
return Ok(StepReply::NONE); return Ok(StepReply::NONE);
} }
@ -373,9 +420,92 @@ impl NoiseFSM {
FSMstate::Noise3 => {} FSMstate::Noise3 => {}
FSMstate::ExtRequest => {} FSMstate::ExtRequest => {}
FSMstate::ExtResponse => {} FSMstate::ExtResponse => {}
FSMstate::ClientHello => {} FSMstate::ClientHello => {
FSMstate::ServerHello => {} if let Some(msg) = msg_opt.as_ref() {
FSMstate::ClientAuth => {} if !self.dir.is_server() {
if let ProtocolMessage::ServerHello(hello) = msg {
if let StartConfig::Client(client_config) =
self.config.as_ref().unwrap()
{
let content = ClientAuthContentV0 {
user: client_config.user,
client: client_config.client,
/// Nonce from ServerHello
nonce: hello.nonce().clone(),
};
let ser = serde_bare::to_vec(&content)?;
let sig =
sign(client_config.client_priv, client_config.client, &ser)?;
let client_auth = ClientAuth::V0(ClientAuthV0 {
content,
/// Signature by client key
sig,
});
self.state = FSMstate::ClientAuth;
self.send(client_auth.into()).await?;
return Ok(StepReply::NONE);
}
}
}
}
}
FSMstate::ServerHello => {
if let Some(msg) = msg_opt.as_ref() {
if self.dir.is_server() {
if let ProtocolMessage::ClientAuth(client_auth) = msg {
if *client_auth.nonce() != self.nonce_for_hello {
return Err(ProtocolError::InvalidNonce);
}
let ser = serde_bare::to_vec(&client_auth.content_v0())?;
let mut result = ProtocolError::NoError;
let verif = verify(&ser, client_auth.sig(), client_auth.client());
if verif.is_err() {
result = verif.unwrap_err().into();
} else {
// TODO check that the device has been registered for this user. if not, set result = AccessDenied
}
let auth_result = AuthResult::V0(AuthResultV0 {
result: result.clone() as u16,
metadata: vec![],
});
self.send(auth_result.into()).await?;
if (result.is_err()) {
return Err(result);
}
log!("AUTHENTICATION SUCCESSFUL ! waiting for requests on the server side");
self.state = FSMstate::AuthResult;
return Ok(StepReply::NONE);
}
}
}
}
FSMstate::ClientAuth => {
if let Some(msg) = msg_opt.as_ref() {
if !self.dir.is_server() {
if let ProtocolMessage::AuthResult(auth_res) = msg {
if let StartConfig::Client(client_config) =
self.config.as_ref().unwrap()
{
if auth_res.result() != 0 {
return Err(ProtocolError::AccessDenied);
}
self.state = FSMstate::AuthResult;
log!("AUTHENTICATION SUCCESSFUL ! waiting for requests on the client side");
return Ok(StepReply::NONE);
}
}
}
}
}
FSMstate::AuthResult => { FSMstate::AuthResult => {
if let Some(msg) = msg_opt { if let Some(msg) = msg_opt {
let id = msg.id(); let id = msg.id();
@ -467,12 +597,11 @@ impl ConnectionBase {
fsm: Arc<Mutex<NoiseFSM>>, fsm: Arc<Mutex<NoiseFSM>>,
) -> ResultSend<()> { ) -> ResultSend<()> {
while let Some(msg) = receiver.next().await { while let Some(msg) = receiver.next().await {
log!("RECEIVED: {:?}", msg);
match msg { match msg {
ConnectionCommand::Close ConnectionCommand::Close
| ConnectionCommand::Error(_) | ConnectionCommand::Error(_)
| ConnectionCommand::ProtocolError(_) => { | ConnectionCommand::ProtocolError(_) => {
log!("EXIT READ LOOP"); log!("EXIT READ LOOP because : {:?}", msg);
break; break;
} }
ConnectionCommand::Msg(proto_msg) => { ConnectionCommand::Msg(proto_msg) => {
@ -537,6 +666,7 @@ impl ConnectionBase {
} }
} }
} }
log!("END OF READ LOOP");
Ok(()) Ok(())
} }
@ -584,15 +714,20 @@ impl ConnectionBase {
self.send(ConnectionCommand::Close).await; self.send(ConnectionCommand::Close).await;
} }
pub async fn start(&mut self) { pub async fn start(&mut self, config: StartConfig) {
// BOOTSTRAP the protocol // BOOTSTRAP the protocol from client-side
if !self.dir.is_server() { if !self.dir.is_server() {
let res; let res;
let fsm = self.fsm.as_ref().unwrap(); {
res = fsm.lock().await.step(None).await; let mut fsm = self.fsm.as_ref().unwrap().lock().await;
fsm.config = Some(config);
res = fsm.step(None).await;
}
if let Err(err) = res { if let Err(err) = res {
self.send(ConnectionCommand::ProtocolError(err)).await; self.send(ConnectionCommand::ProtocolError(err)).await;
} }
} else {
panic!("cannot call start on a server-side connection");
} }
} }

@ -47,7 +47,7 @@ pub enum ProtocolError {
PartialContent, PartialContent,
EndOfStream, EndOfStream,
WriteError, IoError,
WsError, WsError,
ActorError, ActorError,
InvalidState, InvalidState,
@ -77,12 +77,17 @@ pub enum ProtocolError {
NoiseHandshakeFailed, NoiseHandshakeFailed,
DecryptionError, DecryptionError,
EncryptionError, EncryptionError,
InvalidNonce,
} //MAX 949 ProtocolErrors } //MAX 949 ProtocolErrors
impl ProtocolError { impl ProtocolError {
pub fn is_stream(&self) -> bool { pub fn is_stream(&self) -> bool {
*self == ProtocolError::PartialContent || *self == ProtocolError::EndOfStream *self == ProtocolError::PartialContent || *self == ProtocolError::EndOfStream
} }
pub fn is_err(&self) -> bool {
*self != ProtocolError::NoError
}
} }
impl Error for ProtocolError {} impl Error for ProtocolError {}

@ -1822,6 +1822,12 @@ impl ClientAuth {
} }
} }
impl From<ClientAuth> for ProtocolMessage {
fn from(msg: ClientAuth) -> ProtocolMessage {
ProtocolMessage::ClientAuth(msg)
}
}
/// Authentication result /// Authentication result
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AuthResultV0 { pub struct AuthResultV0 {
@ -1849,6 +1855,12 @@ impl AuthResult {
} }
} }
impl From<AuthResult> for ProtocolMessage {
fn from(msg: AuthResult) -> ProtocolMessage {
ProtocolMessage::AuthResult(msg)
}
}
// //
// DIRECT / OUT-OF-BAND MESSAGES // DIRECT / OUT-OF-BAND MESSAGES
// //

Loading…
Cancel
Save