diff --git a/client-network/src/cryptographic_signature.rs b/client-network/src/cryptographic_signature.rs index 3703f2d..b63512e 100644 --- a/client-network/src/cryptographic_signature.rs +++ b/client-network/src/cryptographic_signature.rs @@ -7,10 +7,10 @@ use rand_core::OsRng; use sha2::{Digest, Sha256}; pub enum MathError { - DivisionByZero, - NonPositiveLogarithm, - NegativeSquareRoot, - } + DivisionByZero, + NonPositiveLogarithm, + NegativeSquareRoot, +} /// /// contains the ecdsa private key, the ecdsa public key and the username @@ -42,28 +42,39 @@ impl CryptographicSignature { /// /// returns a string representing the pub_key as a String /// -pub fn formatPubKey(crypto_pair: CryptographicSignature) -> String { +pub fn formatPubKey(crypto_pair: CryptographicSignature) -> String { let encoded_point = crypto_pair.pub_key.to_encoded_point(false); let pubkey_bytes = encoded_point.as_bytes(); hex::encode(pubkey_bytes) } -pub fn sign_message(crypto_pair: CryptographicSignature, message: [u8; 1024]) -> [u8; 1024] { - let digest = Sha256::digest(&message[0..992]); - let str = hex::encode(digest); - let signature = crypto_pair.priv_key.sign_prehash_recoverable(str.as_bytes()); - let mut signed_message = [0;1024]; - signed_message[..992].copy_from_slice(&message[..992]); - match signature { +pub fn sign_message(crypto_pair: CryptographicSignature, message: Vec) -> Vec { + let length_bytes: [u8; 2] = message[5..7] + .try_into() + .expect("slice with incorrect length"); + let msg_length = u16::from_be_bytes(length_bytes); + println!("{}", msg_length); + let digest = Sha256::digest(&message[..8 + msg_length as usize]); + let signature = crypto_pair.priv_key.sign_prehash_recoverable(&digest); + + let message_length = 12 + msg_length as usize + 32; + let mut signed_message = Vec::with_capacity(message_length); + println!("{}", message_length); + signed_message.extend_from_slice(&message[..8 + msg_length as usize]); + signed_message.pop(); + println!("signed_tmp:{:?}", signed_message); + match signature { Ok(signature) => { - println!("Signature: {:?}", signature); + //println!("Signature: {:?}", signature); let r = signature.0.r(); - + let r_bytes = r.to_bytes(); // Returns a GenericArray/bytes object - signed_message[992..].copy_from_slice(&r_bytes[..32]); + signed_message.extend_from_slice(&r_bytes[..32]); + println!("signed:{:?}", signed_message); + println!("rbytes:{:?}", &r_bytes[..32]); signed_message - }, + } Err(e) => { panic!("error"); } @@ -83,7 +94,7 @@ mod tests { println!("pubkey : {}",formatted_pubkey); }*/ - #[test] + /*#[test] fn signing_message() { let username = String::from("quoicoubeh"); let crypto_pair = CryptographicSignature::new(username); @@ -93,7 +104,5 @@ mod tests { let signed_message = sign_message(crypto_pair, ser); println!("unsigned_message: {:?}", ser); println!("signed_message: {:?}", signed_message); - } - - + }*/ } diff --git a/client-network/src/messages_channels.rs b/client-network/src/messages_channels.rs new file mode 100644 index 0000000..e69de29 diff --git a/client-network/src/messages_structure.rs b/client-network/src/messages_structure.rs index 3fa5133..88a47c1 100644 --- a/client-network/src/messages_structure.rs +++ b/client-network/src/messages_structure.rs @@ -11,18 +11,60 @@ pub struct HandshakeMessage { msg_type: u8, length: u16, extensions: u32, - name: [u8; 981], - signature: [u8; 32], + name: Vec, + signature: Vec, } impl UDPMessage { pub fn ping(id: u32) -> UDPMessage { - UDPMessage { id: id, msg_type: 0, length: 0, body: [0; 985], signature: [0; 32]} + UDPMessage { + id: id, + msg_type: 0, + length: 0, + body: [0; 985], + signature: [0; 32], + } } pub fn error(id: u32) -> UDPMessage { - - UDPMessage { id: id, msg_type: 129, length: 0, body: [0; 985], signature: [0; 32]} + UDPMessage { + id: id, + msg_type: 129, + length: 0, + body: [0; 985], + signature: [0; 32], + } + } + + pub fn parse(received_message: [u8; 1024]) -> UDPMessage { + let id_bytes: [u8; 4] = received_message[0..4] + .try_into() + .expect("Taille incorrecte"); + let length_bytes: [u8; 2] = received_message[5..7] + .try_into() + .expect("Taille incorrecte"); + let name_bytes: [u8; 985] = received_message[7..992] + .try_into() + .expect("Taille incorrecte"); + let signature_bytes: [u8; 32] = received_message[992..1024] + .try_into() + .expect("Taille incorrecte"); + UDPMessage { + id: u32::from_be_bytes(id_bytes), + msg_type: received_message[4], + length: u16::from_be_bytes(length_bytes), + body: name_bytes, + signature: signature_bytes, + } + } + + pub fn display(&self) { + println!("ID: {:?}", self.id); + println!("Message Type: {}", self.msg_type); + println!("Length: {:?}", self.length); + let good_length = usize::min(self.length as usize, 985); + println!("name: {:?}", &self.body[..good_length]); + println!("Signature: {:?}", self.signature); } } @@ -32,69 +74,74 @@ impl HandshakeMessage { println!("Message Type: {}", self.msg_type); println!("Length: {:?}", self.length); println!("extensions: {:?}", self.extensions); - let good_length = usize::min(self.length as usize, 981); - println!("name: {:?}", &self.name[..good_length]); + println!("name: {:?}", &self.name[..(self.length - 4) as usize]); println!("Signature: {:?}", self.signature); } pub fn hello(id: u32, length: u16, username: String) -> HandshakeMessage { - let username_bytes = username.as_bytes(); - - let mut name: [u8; 981] = [0; 981]; - - let length_to_copy = username_bytes.len().min(981); - name[..length_to_copy].copy_from_slice(&username_bytes[..length_to_copy]); - HandshakeMessage {id: id, msg_type: 1, length: length, extensions: 0, name: name, signature: [0;32]} - + let name_vec = username.trim_end_matches(char::from(0)).as_bytes().to_vec(); + HandshakeMessage { + id: id, + msg_type: 1, + length: length, + extensions: 0, + name: name_vec, + signature: vec![0; 64], + } } pub fn helloReply(id: u32, length: u16, username: String) -> HandshakeMessage { - let username_bytes = username.as_bytes(); - - let mut name: [u8; 981] = [0; 981]; - - let length_to_copy = username_bytes.len().min(981); - name[..length_to_copy].copy_from_slice(&username_bytes[..length_to_copy]); - HandshakeMessage {id: id, msg_type: 130, length: length, extensions: 0, name: name, signature: [0;32]} - + let name_vec = username.trim_end_matches(char::from(0)).as_bytes().to_vec(); + HandshakeMessage { + id: id, + msg_type: 130, + length: length, + extensions: 0, + name: name_vec, + signature: vec![0; 64], + } } - pub fn serialize(&self) -> [u8; 1024] { - let mut buffer = [0u8; 1024]; - let mut offset = 0; + pub fn serialize(&self) -> Vec { + let mut out = Vec::with_capacity(4 + 1 + 2 + 4 + self.name.len() + self.signature.len()); - buffer[offset..offset + 4].copy_from_slice(&self.id.to_be_bytes()); - offset += 4; + // id: u32 little-endian + out.extend_from_slice(&self.id.to_be_bytes()); - buffer[offset] = self.msg_type; - offset += 1; + // msg_type: u8 + out.push(self.msg_type); - buffer[offset..offset + 2].copy_from_slice(&self.length.to_be_bytes()); - offset += 2; + out.extend_from_slice(&self.length.to_be_bytes()); - buffer[offset..offset + 4].copy_from_slice(&self.extensions.to_be_bytes()); - offset += 4; + out.extend_from_slice(&self.extensions.to_be_bytes()); - buffer[offset..offset + 981].copy_from_slice(&self.name); - offset += 981; + out.extend_from_slice(&self.name); - buffer[offset..offset + 32].copy_from_slice(&self.signature); - - buffer + out.extend_from_slice(&self.signature); + + out } - pub fn parse(received_message: [u8; 1024]) -> HandshakeMessage { - let id_bytes: [u8; 4] = received_message[0..4].try_into().expect("Taille incorrecte"); - let length_bytes: [u8; 2] = received_message[5..7].try_into().expect("Taille incorrecte"); - let extensions_bytes: [u8; 4] = received_message[7..11].try_into().expect("Taille incorrecte"); - let name_bytes: [u8; 981] = received_message[11..992].try_into().expect("Taille incorrecte"); - let signature_bytes: [u8; 32] = received_message[992..1024].try_into().expect("Taille incorrecte"); + pub fn parse(received_message: Vec) -> HandshakeMessage { + let id_bytes: [u8; 4] = received_message[0..4] + .try_into() + .expect("Taille incorrecte"); + let length_bytes: [u8; 2] = received_message[5..7] + .try_into() + .expect("Taille incorrecte"); + let msg_length = u16::from_be_bytes(length_bytes); + let extensions_bytes: [u8; 4] = received_message[7..11] + .try_into() + .expect("Taille incorrecte"); + let name_bytes = &received_message[11..12 + msg_length as usize]; + let signature_bytes = + &received_message[12 + msg_length as usize..(13 + msg_length + 32) as usize]; HandshakeMessage { id: u32::from_be_bytes(id_bytes), msg_type: received_message[4], length: u16::from_be_bytes(length_bytes), extensions: u32::from_be_bytes(extensions_bytes), - name: name_bytes, - signature: signature_bytes, + name: name_bytes.to_vec(), + signature: signature_bytes.to_vec(), } } } @@ -103,8 +150,6 @@ fn convert_to_u16(bytes: [u8; 2]) -> u16 { ((bytes[0] as u16) << 8) | (bytes[1] as u16) } - - #[cfg(test)] mod tests { // Note this useful idiom: importing names from outer (for mod tests) scope. @@ -116,7 +161,7 @@ mod tests { let handshake = HandshakeMessage::hello(0, 12, username); handshake.display(); }*/ - + /*#[tokio::test] async fn parse_handshakemessage() { let username = String::from("charlie_kirk"); @@ -127,4 +172,3 @@ mod tests { parsed.display(); }*/ } - diff --git a/client-network/src/registration.rs b/client-network/src/registration.rs index 0b75414..cee4ccd 100644 --- a/client-network/src/registration.rs +++ b/client-network/src/registration.rs @@ -1,45 +1,74 @@ +use bytes::Bytes; + use crate::cryptographic_signature::{CryptographicSignature, formatPubKey, sign_message}; -use crate::messages_structure::HandshakeMessage; +use crate::messages_structure::{HandshakeMessage, UDPMessage}; use std::net::UdpSocket; /// /// Registration with the server happens in two steps: first, the client -/// sends its cryptographic signature to the server using a PUT request over the HTTP API. -async fn register_with_the_server(crypto_pair: CryptographicSignature) -> Result<(), reqwest::Error>{ +/// sends its cryptographic signature to the server using a PUT request over the HTTP API. +async fn register_with_the_server( + crypto_pair: CryptographicSignature, +) -> Result<(), reqwest::Error> { let client = reqwest::Client::new(); - let uri = format!("https://jch.irif.fr:8443/peers/{}/key", crypto_pair.username); + let uri = format!( + "https://jch.irif.fr:8443/peers/{}/key", + crypto_pair.username + ); let encoded_point = crypto_pair.pub_key.to_encoded_point(false); let pubkey_bytes = encoded_point.as_ref().to_vec(); - let pubkey_bytes_minus = pubkey_bytes[1..].to_vec(); - // In order to register with the server, a peer ϕ makes a PUT request to the URL /peers/ϕ/key with its 64-byte public key in the body - let res = client.put(uri) - .body(pubkey_bytes_minus) - .send() - .await?; + let pubkey_bytes_minus = pubkey_bytes[1..].to_vec(); + // In order to register with the server, a peer ϕ makes a PUT request to the URL /peers/ϕ/key with its 64-byte public key in the body + let res = client.put(uri).body(pubkey_bytes_minus).send().await?; if res.status().is_success() { println!("Successfully registered with the server."); } else { - eprintln!("Failed to register with the server. Status: {}", res.status()); + eprintln!( + "Failed to register with the server. Status: {}", + res.status() + ); let str = hex::encode(res.bytes().await?); eprintln!("erreur : {}", str); } + println!("register ip adresses"); + register_ip_addresses(crypto_pair); Ok(()) } +async fn get_socket_address(username: String) -> Result { + let client = reqwest::Client::new(); + let uri = format!("https://jch.irif.fr:8443/peers/{}/addresses", username); + let res = client.get(uri).send().await?; + if res.status().is_success() { + println!("Successfully retreived the addresses."); + } else { + eprintln!( + "Failed to register with the server. Status: {}", + res.status() + ); + } + let body: Bytes = res.bytes().await?; + Ok(body) +} + /// It then /// registers each of its IP addresses by sending a Hello request to the server. /// After the client sends a Hello request to the server, the server will verify that the client is able /// to receive requests by sending a Hello request to the client. If the client doesn’t reply to the Hello /// request with a properly signed message, its address will not be published by the server. fn register_ip_addresses(crypto_pair: CryptographicSignature) { - let socket = UdpSocket::bind("127.0.0.1:4242").expect("bind failed"); + let socket = UdpSocket::bind("0.0.0.0:0").expect("bind failed"); let username_size = crypto_pair.username.len(); - let hello_handshake = HandshakeMessage::hello(0, username_size as u16, crypto_pair.username.clone()); + let hello_handshake = + HandshakeMessage::hello(545, username_size as u16 + 4, crypto_pair.username.clone()); + //HandshakeMessage::display(&hello_handshake); let hello_handshake_serialized = hello_handshake.serialize(); - let message_signed = sign_message(crypto_pair, hello_handshake_serialized); - socket.send_to(&message_signed, "jch.irif.fr:8443").expect("send failed"); + let message_signed = sign_message(crypto_pair, hello_handshake_serialized.to_vec()); + socket + .send_to(&message_signed, "81.194.30.229:8443") + .expect("send failed"); let mut buf = [0u8; 1024]; socket.recv_from(&mut buf).expect("receive failed"); - let hello_handshake_received = HandshakeMessage::parse(buf); + let hello_handshake_received = UDPMessage::parse(buf); hello_handshake_received.display(); } @@ -48,12 +77,25 @@ mod tests { // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; - /*#[tokio::test] - async fn creating_cryptographic_signature() { - let username = String::from("charlie_kirk"); + #[tokio::test] + async fn registering_with_server() { + let username = String::from("gamemixtreize"); let crypto_pair = CryptographicSignature::new(username); - if let Err(e) = register_with_the_server(crypto_pair).await { - eprintln!("Error during registration: {}", e); + if let Err(e) = register_with_the_server(crypto_pair).await { + eprintln!("Error during registration: {}", e); + } } + + /*#[tokio::test] + async fn retreive_socket_addr() { + let username = String::from("ipjkndqfshjldfsjlbsdfjhhj"); + match get_socket_address(username).await { + Ok(body) => { + println!("{:?}",body); + } + Err(e) => { + eprintln!("Erreur HTTP: {}", e); + } + } }*/ }