From c804695725230bc019e21596cb4fb125856073fb Mon Sep 17 00:00:00 2001 From: wikano Date: Wed, 31 Dec 2025 19:40:25 +0100 Subject: [PATCH] signature verification --- client-network/src/cryptographic_signature.rs | 52 +++++++++++++++ client-network/src/lib.rs | 2 +- client-network/src/message_handling.rs | 65 ++++++++++++------- client-network/src/messages_structure.rs | 10 +-- client-network/src/registration.rs | 2 +- 5 files changed, 100 insertions(+), 31 deletions(-) diff --git a/client-network/src/cryptographic_signature.rs b/client-network/src/cryptographic_signature.rs index 96e4a2c..8a857ed 100644 --- a/client-network/src/cryptographic_signature.rs +++ b/client-network/src/cryptographic_signature.rs @@ -1,4 +1,8 @@ +use std::io::Read; + use crate::messages_structure::HandshakeMessage; +use bytes::Bytes; +use p256::EncodedPoint; use p256::ecdsa::{ Signature, SigningKey, VerifyingKey, signature::{Signer, Verifier}, @@ -9,6 +13,7 @@ use sha2::{Digest, Sha256}; /// /// contains the ecdsa private key, the ecdsa public key and the username /// +/// pub struct CryptographicSignature { priv_key: SigningKey, pub pub_key: VerifyingKey, @@ -42,6 +47,53 @@ pub fn formatPubKey(crypto_pair: CryptographicSignature) -> String { hex::encode(pubkey_bytes) } +pub async fn get_peer_key(username: &String) -> Result { + let client = reqwest::Client::new(); + let uri = format!("https://jch.irif.fr:8443/peers/{}/key", username); + let res = client.get(uri).send().await?; + if res.status().is_success() { + println!("Successfully retreived the peers key."); + } else { + eprintln!( + "Failed to get the peers key from the server. Status: {}", + res.status() + ); + } + let body: Bytes = res.bytes().await?; + let slice: &[u8] = body.as_ref(); + let body_bytes: &[u8; 64] = slice.try_into().expect("size error"); + let received_key = convert_verifyingkey(body_bytes); + Ok(received_key) +} + +fn convert_verifyingkey(raw_xy: &[u8; 64]) -> VerifyingKey { + let mut sec1 = [0u8; 65]; + sec1[0] = 0x04; + sec1[1..].copy_from_slice(raw_xy); + + let ep = EncodedPoint::from_bytes(&sec1).expect("invalid point bytes"); + let pk = VerifyingKey::from_encoded_point(&ep).expect("invalid encoded point"); + VerifyingKey::from(pk) +} + +pub fn verify_signature(pubkey: VerifyingKey, message: &Vec) -> bool { + let length_bytes: [u8; 2] = message[5..7].try_into().expect("Taille incorrecte"); + let length = u16::from_be_bytes(length_bytes); + println!("message length: {}", length); + let msg_to_hash = &message[..length as usize + 7]; + let signature_bytes = &message[length as usize + 7..length as usize + 7 + 64]; + println!("conversion start"); + let sig = match Signature::from_bytes(signature_bytes.try_into().expect("conversion error")) { + Ok(s) => s, + Err(_) => return false, + }; + println!("conversion done"); + match pubkey.verify(&msg_to_hash, &sig) { + Ok(()) => true, + Err(_) => false, + } +} + /// /// takes a serialized message and adds the signature using the private key /// diff --git a/client-network/src/lib.rs b/client-network/src/lib.rs index 48c3cf8..03b2db3 100644 --- a/client-network/src/lib.rs +++ b/client-network/src/lib.rs @@ -104,7 +104,7 @@ pub fn start_p2p_executor( let messages_list = HashMap::::new(); - let username = String::from("Gamixtreize"); + let username = String::from("az"); let crypto_pair = CryptographicSignature::new(username); diff --git a/client-network/src/message_handling.rs b/client-network/src/message_handling.rs index 5e22048..7744a96 100644 --- a/client-network/src/message_handling.rs +++ b/client-network/src/message_handling.rs @@ -1,5 +1,7 @@ use crate::{ - cryptographic_signature::{CryptographicSignature, sign_message}, + cryptographic_signature::{ + CryptographicSignature, get_peer_key, sign_message, verify_signature, + }, messages_channels::MultipleSenders, messages_structure::HandshakeMessage, registration, @@ -58,34 +60,49 @@ pub fn handle_recevied_message( match eventtype { Some(EventType::ServerHelloReply) => { /*registration::register_ip_addresses( - crypto_pair, - socket_addr.to_string(), - senders, - &messages_list, // Pass the mutable reference inside the lock - 546, - );*/ + crypto_pair, + socket_addr.to_string(), + senders, + &messages_list, // Pass the mutable reference inside the lock + 546, + );*/ } Some(_) => print!("Not implemented"), None => { let message_type = recevied_message[4]; if message_type == 1 { - let username_size = crypto_pair.username.len(); - let hello_handshake = HandshakeMessage::helloReply( - id as u32, - 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); - senders.send_via(0, message_signed, socket_addr.to_string()); - let mut list = messages_list.lock().expect("Failed to lock messages_list"); - match list.get(&id) { - Some(_) => { - list.remove(&id); - } - None => { - list.insert(id, EventType::ServerHelloReply); + println!("verify the signature"); + let parsed_received_message = HandshakeMessage::parse(recevied_message.to_vec()); + let received_name = String::from_utf8(parsed_received_message.name).expect("error"); + let peer_pubkey = tokio::runtime::Runtime::new() + .unwrap() + .block_on(get_peer_key(&received_name)) + .expect("failed to retrieve public key"); + + if !verify_signature(peer_pubkey, recevied_message) { + println!( + "incorrect signature from given peer: {}, ignoring message {}", + &received_name, id + ); + } else { + let username_size = crypto_pair.username.len(); + let hello_handshake = HandshakeMessage::helloReply( + id as u32, + 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); + senders.send_via(0, message_signed, socket_addr.to_string()); + let mut list = messages_list.lock().expect("Failed to lock messages_list"); + match list.get(&id) { + Some(_) => { + list.remove(&id); + } + None => { + list.insert(id, EventType::ServerHelloReply); + } } } } diff --git a/client-network/src/messages_structure.rs b/client-network/src/messages_structure.rs index fd4691e..94c7a16 100644 --- a/client-network/src/messages_structure.rs +++ b/client-network/src/messages_structure.rs @@ -7,12 +7,12 @@ pub struct UDPMessage { } pub struct HandshakeMessage { - id: u32, + pub id: u32, msg_type: u8, length: u16, extensions: u32, - name: Vec, - signature: Vec, + pub name: Vec, + pub signature: Vec, } impl UDPMessage { @@ -130,9 +130,9 @@ impl HandshakeMessage { 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 name_bytes = &received_message[11..(11 + msg_length - 4) as usize]; let signature_bytes = - &received_message[12 + msg_length as usize..(13 + msg_length + 32) as usize]; + &received_message[(11 + msg_length - 4) as usize..(11 + msg_length - 4 + 64) as usize]; HandshakeMessage { id: u32::from_be_bytes(id_bytes), msg_type: received_message[4], diff --git a/client-network/src/registration.rs b/client-network/src/registration.rs index f8c3fc2..eca62be 100644 --- a/client-network/src/registration.rs +++ b/client-network/src/registration.rs @@ -48,7 +48,7 @@ pub async fn get_socket_address(username: String) -> Result