From e902070c829aad0d3b1e88d17dd321b1411b4955 Mon Sep 17 00:00:00 2001 From: wikano Date: Wed, 17 Dec 2025 14:09:51 +0100 Subject: [PATCH] wip structures and message signature --- client-network/src/cryptographic_signature.rs | 46 +++++- client-network/src/messages_structure.rs | 146 ++++++++++++++---- client-network/src/registration.rs | 19 ++- todo.md | 2 + 4 files changed, 174 insertions(+), 39 deletions(-) diff --git a/client-network/src/cryptographic_signature.rs b/client-network/src/cryptographic_signature.rs index 7c510b8..3703f2d 100644 --- a/client-network/src/cryptographic_signature.rs +++ b/client-network/src/cryptographic_signature.rs @@ -1,8 +1,16 @@ +use crate::messages_structure::HandshakeMessage; use p256::ecdsa::{ Signature, SigningKey, VerifyingKey, signature::{Signer, Verifier}, }; use rand_core::OsRng; +use sha2::{Digest, Sha256}; + +pub enum MathError { + DivisionByZero, + NonPositiveLogarithm, + NegativeSquareRoot, + } /// /// contains the ecdsa private key, the ecdsa public key and the username @@ -40,16 +48,52 @@ pub fn formatPubKey(crypto_pair: CryptographicSignature) -> String { 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 { + Ok(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 + }, + Err(e) => { + panic!("error"); + } + } +} + #[cfg(test)] mod tests { // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; - #[test] + /*#[test] fn creating_cryptographic_signature() { let username = String::from("quoicoubeh"); let crypto_pair = CryptographicSignature::new(username); let formatted_pubkey =formatPubKey(crypto_pair); println!("pubkey : {}",formatted_pubkey); + }*/ + + #[test] + fn signing_message() { + let username = String::from("quoicoubeh"); + let crypto_pair = CryptographicSignature::new(username); + let username_b = String::from("quoicoubeh"); + let handshake = HandshakeMessage::hello(0, 12, username_b); + let ser = handshake.serialize(); + let signed_message = sign_message(crypto_pair, ser); + println!("unsigned_message: {:?}", ser); + println!("signed_message: {:?}", signed_message); } + + } diff --git a/client-network/src/messages_structure.rs b/client-network/src/messages_structure.rs index 06b955f..3fa5133 100644 --- a/client-network/src/messages_structure.rs +++ b/client-network/src/messages_structure.rs @@ -1,50 +1,130 @@ -struct UDPMessage { - id: [u8; 4], +pub struct UDPMessage { + id: u32, msg_type: u8, - length: [u8; 2], + length: u16, body: [u8; 985], signature: [u8; 32], } -struct HandshakeMessage { - id: [u8; 4], +pub struct HandshakeMessage { + id: u32, msg_type: u8, - length: [u8; 2], - extensions: [u8; 4], + length: u16, + extensions: u32, name: [u8; 981], signature: [u8; 32], } impl UDPMessage { - pub fn ping(id: i32) -> UDPMessage { - UDPMessage { id: id.to_ne_bytes(), msg_type: 0, length: [0; 2], body: [0; 985], signature: [0; 32]} + pub fn ping(id: u32) -> UDPMessage { + UDPMessage { id: id, msg_type: 0, length: 0, body: [0; 985], signature: [0; 32]} } - pub fn error(id: i32) -> UDPMessage { + pub fn error(id: u32) -> UDPMessage { - UDPMessage { id: id.to_ne_bytes(), msg_type: 129, length: [0; 2], body: [0; 985], signature: [0; 32]} - } - - pub fn hello(id: i32, length: i16, username: String) -> HandshakeMessage { - let username_bytes = username.as_bytes(); - - let mut body: [u8; 981] = [0; 981]; - - let length_to_copy = username_bytes.len().min(981); - body[..length_to_copy].copy_from_slice(&username_bytes[..length_to_copy]); - HandshakeMessage {id: id.to_ne_bytes(), msg_type: 1, length: length.to_ne_bytes(), extensions: [0;4], name: body, signature: [0;32]} - - } - - pub fn helloReply(id: i32, length: i16, username: String) -> HandshakeMessage { - let username_bytes = username.as_bytes(); - - let mut body: [u8; 981] = [0; 981]; - - let length_to_copy = username_bytes.len().min(981); - body[..length_to_copy].copy_from_slice(&username_bytes[..length_to_copy]); - HandshakeMessage {id: id.to_ne_bytes(), msg_type: 130, length: length.to_ne_bytes(), extensions: [0;4], name: body, signature: [0;32]} - + UDPMessage { id: id, msg_type: 129, length: 0, body: [0; 985], signature: [0; 32]} } } +impl HandshakeMessage { + pub fn display(&self) { + println!("ID: {:?}", self.id); + 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!("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]} + + } + + 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]} + + } + + pub fn serialize(&self) -> [u8; 1024] { + let mut buffer = [0u8; 1024]; + let mut offset = 0; + + buffer[offset..offset + 4].copy_from_slice(&self.id.to_be_bytes()); + offset += 4; + + buffer[offset] = self.msg_type; + offset += 1; + + buffer[offset..offset + 2].copy_from_slice(&self.length.to_be_bytes()); + offset += 2; + + buffer[offset..offset + 4].copy_from_slice(&self.extensions.to_be_bytes()); + offset += 4; + + buffer[offset..offset + 981].copy_from_slice(&self.name); + offset += 981; + + buffer[offset..offset + 32].copy_from_slice(&self.signature); + + buffer + } + + 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"); + 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, + } + } +} + +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. + use super::*; + + /*#[tokio::test] + async fn creating_cryptographic_signature() { + let username = String::from("charlie_kirk"); + let handshake = HandshakeMessage::hello(0, 12, username); + handshake.display(); + }*/ + + /*#[tokio::test] + async fn parse_handshakemessage() { + let username = String::from("charlie_kirk"); + let handshake = HandshakeMessage::hello(0, 12, username); + let ser = handshake.serialize(); + let parsed = HandshakeMessage::parse(ser); + handshake.display(); + parsed.display(); + }*/ +} + diff --git a/client-network/src/registration.rs b/client-network/src/registration.rs index 576a8f0..0b75414 100644 --- a/client-network/src/registration.rs +++ b/client-network/src/registration.rs @@ -1,4 +1,5 @@ -use crate::cryptographic_signature::{CryptographicSignature, formatPubKey}; +use crate::cryptographic_signature::{CryptographicSignature, formatPubKey, sign_message}; +use crate::messages_structure::HandshakeMessage; use std::net::UdpSocket; /// /// Registration with the server happens in two steps: first, the client @@ -30,8 +31,16 @@ async fn register_with_the_server(crypto_pair: CryptographicSignature) -> Result /// 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"); - //TODO + let socket = UdpSocket::bind("127.0.0.1:4242").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_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 mut buf = [0u8; 1024]; + socket.recv_from(&mut buf).expect("receive failed"); + let hello_handshake_received = HandshakeMessage::parse(buf); + hello_handshake_received.display(); } #[cfg(test)] @@ -39,12 +48,12 @@ mod tests { // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; - #[tokio::test] + /*#[tokio::test] async fn creating_cryptographic_signature() { let username = String::from("charlie_kirk"); let crypto_pair = CryptographicSignature::new(username); if let Err(e) = register_with_the_server(crypto_pair).await { eprintln!("Error during registration: {}", e); } - } + }*/ } diff --git a/todo.md b/todo.md index e6932fe..1cbac47 100644 --- a/todo.md +++ b/todo.md @@ -31,3 +31,5 @@ rechercher les fichiers d'un pair telechargement des fichiers choisir un dossier à partager se deconnecter du réseau + +2 channels -> un pour envoyer et un pour recevoir