diff --git a/protocol/src/chacha20poly1305.rs b/protocol/src/chacha20poly1305.rs index 1144670..e0046dc 100644 --- a/protocol/src/chacha20poly1305.rs +++ b/protocol/src/chacha20poly1305.rs @@ -1,12 +1,12 @@ -mod chacha20; +pub(crate) mod chacha20; mod poly1305; -pub(crate) use chacha20::ChaCha20; +use chacha20::ChaCha20; use poly1305::Poly1305; use alloc::fmt; -// Zero array for padding slices. +/// Zero array for padding slices. const ZEROES: [u8; 16] = [0u8; 16]; #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/protocol/src/fschacha20poly1305.rs b/protocol/src/fschacha20poly1305.rs index d8395c4..5c6392f 100644 --- a/protocol/src/fschacha20poly1305.rs +++ b/protocol/src/fschacha20poly1305.rs @@ -1,6 +1,7 @@ use alloc::{fmt, vec::Vec}; -use crate::chacha20poly1305::{ChaCha20, ChaCha20Poly1305}; +use crate::chacha20poly1305::chacha20::ChaCha20; +use crate::chacha20poly1305::ChaCha20Poly1305; const CHACHA_BLOCKS_USED: u32 = 3; pub(crate) const REKEY_INTERVAL: u32 = 224; diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index 1e5f112..f55187c 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -484,7 +484,7 @@ impl<'a> Handshake<'a> { buffer[0..64].copy_from_slice(&point.elligator_swift.to_array()); if let Some(garbage) = garbage { - buffer[64..64 + garbage.len()].copy_from_slice(&garbage); + buffer[64..64 + garbage.len()].copy_from_slice(garbage); } Ok(Handshake { @@ -522,8 +522,7 @@ impl<'a> Handshake<'a> { self.network, ); response[..16].copy_from_slice(&materials.initiator_garbage_terminator); - self.remote_garbage_terminator = - Some(materials.responder_garbage_terminator.clone()); + self.remote_garbage_terminator = Some(materials.responder_garbage_terminator); materials } @@ -536,8 +535,7 @@ impl<'a> Handshake<'a> { self.network, ); response[..16].copy_from_slice(&materials.responder_garbage_terminator); - self.remote_garbage_terminator = - Some(materials.initiator_garbage_terminator.clone()); + self.remote_garbage_terminator = Some(materials.initiator_garbage_terminator); materials } @@ -587,9 +585,15 @@ impl<'a> Handshake<'a> { // Authenticate received garbage and get version packet. // The version packet is ignored in this version of the protocol, but // moves along state in the ciphers. + // TODO: Allow this to handle different sized buffers (too small, too large). + let packet_length = packet_handler.decypt_len( + garbage_and_version.1[0..LENGTH_FIELD_LEN] + .try_into() + .expect("at least 3 version bytes"), + ); packet_handler - .receive_v2_packets( - garbage_and_version.1.to_vec(), + .decrypt_contents( + garbage_and_version.1[LENGTH_FIELD_LEN..packet_length + LENGTH_FIELD_LEN].to_vec(), Some(garbage_and_version.0.to_vec()), ) .expect("find version packet"); @@ -600,10 +604,10 @@ impl<'a> Handshake<'a> { /// Split a message on the garbage terminator returning the garbage itself /// and the remaing message, expected to be the version packet. -fn split_garbage_and_version<'a>( - message: &'a [u8], +fn split_garbage_and_version( + message: &[u8], garbage_term: [u8; 16], -) -> Result<(&'a [u8], &'a [u8]), Error> { +) -> Result<(&[u8], &[u8]), Error> { if let Some(index) = message .windows(garbage_term.len()) .position(|window| window == garbage_term) @@ -665,7 +669,7 @@ mod tests { .unwrap(); response - .complete_materials(message.try_into().unwrap(), &mut response_message[64..]) + .complete_materials(message, &mut response_message[64..]) .unwrap(); } @@ -1078,7 +1082,7 @@ mod tests { let enc = alice_packet_handler .prepare_v2_packet(message.clone(), None, false) .unwrap(); - if (&enc.to_lower_hex_string()) + if (enc.to_lower_hex_string()) .eq("1da1bcf589f9b61872f45b7fa5371dd3f8bdf5d515b0c5f9fe9f0044afb8dc0aa1cd39a8c4") { found = i; diff --git a/proxy/src/main.rs b/proxy/src/main.rs index ad898e7..30975a6 100644 --- a/proxy/src/main.rs +++ b/proxy/src/main.rs @@ -3,35 +3,51 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::{TcpListener, TcpStream}; /// Validate and bootstrap proxy connection. -async fn proxy_conn(mut client: TcpStream) -> Result<(), Box> { +#[allow(clippy::unused_io_amount)] +async fn proxy_conn(client: TcpStream) -> Result<(), Box> { let remote_ip = bip324_proxy::peek_addr(&client).await?; println!("Reaching out to {}.", remote_ip); let mut outbound = TcpStream::connect(remote_ip).await?; println!("Initiating handshake."); - let mut message = vec![0u8; 64]; - let mut init_handshake = - Handshake::new(Network::Mainnet, Role::Initiator, None, &mut message).unwrap(); - outbound.write_all(&message).await?; + let mut local_material_message = vec![0u8; 64]; + let mut handshake = Handshake::new( + Network::Mainnet, + Role::Initiator, + None, + &mut local_material_message, + ) + .unwrap(); + outbound.write_all(&local_material_message).await?; println!("Sent handshake to remote."); // 64 bytes ES. - let mut material_message = vec![0u8; 64]; + let mut remote_material_message = [0u8; 64]; println!("Reading handshake response from remote."); - outbound.read_exact(&mut material_message).await?; + outbound.read_exact(&mut remote_material_message).await?; println!("Completing materials."); - let mut garbage_terminator_message = vec![0u8; 36]; - init_handshake + let mut local_garbage_terminator_message = [0u8; 36]; + handshake .complete_materials( - material_message.try_into().unwrap(), - &mut garbage_terminator_message, + remote_material_message, + &mut local_garbage_terminator_message, ) .unwrap(); - println!("Remote handshake accepted. Sending garbage terminator."); - outbound.write_all(&garbage_terminator_message).await?; + println!("Sending garbage terminator and version packet."); + outbound + .write_all(&local_garbage_terminator_message) + .await?; + + println!("Authenticating garbage and version packet."); + let mut remote_garbage_and_version = vec![0u8; 5000]; + outbound.read(&mut remote_garbage_and_version).await?; + handshake + .authenticate_garbage_and_version(&remote_garbage_and_version) + .expect("authenticated garbage"); + println!("Channel authenticated."); // TODO: setup read/write loop. Ok(())