From 671e55f4d52f63d331d2b086813fc811810509d7 Mon Sep 17 00:00:00 2001 From: aniampio Date: Tue, 17 Dec 2019 17:29:10 +0100 Subject: [PATCH] Change SHA256 to HMAC --- Cargo.lock | 1 + Cargo.toml | 3 +- src/provider/client_handling/mod.rs | 49 ++++++++++++++++++----------- src/provider/mod.rs | 8 ++--- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 115e089e64..5821926502 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -518,6 +518,7 @@ dependencies = [ "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 0148e6b005..5cff3783e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,5 @@ sphinx = { path = "../sphinx" } tokio = { version = "0.2.4", features = ["full"] } sha2 = "0.8.0" serde = "1.0" -serde_json = "1.0" \ No newline at end of file +serde_json = "1.0" +hmac = "0.7.1" \ No newline at end of file diff --git a/src/provider/client_handling/mod.rs b/src/provider/client_handling/mod.rs index 5f8a2d7c37..ef6fbad6d3 100644 --- a/src/provider/client_handling/mod.rs +++ b/src/provider/client_handling/mod.rs @@ -10,6 +10,10 @@ use std::collections::HashMap; use serde_json::json; use serde::{Deserialize, Serialize}; use std::hash::Hash; +use curve25519_dalek::scalar::Scalar; +use hmac::{Hmac, Mac}; + +type HmacSha256 = Hmac; #[derive(Debug)] pub enum ClientProcessingError { @@ -57,12 +61,13 @@ impl ClientRequestProcessor { pub(crate) fn process_client_request( data: &[u8], processing_data: &RwLock, + provider_secret_key: Scalar ) -> Result, ClientProcessingError> { let client_request = ProviderRequests::from_bytes(&data)?; println!("Received the following request: {:?}", client_request); match client_request { ProviderRequests::Register(req) => { - Ok(ClientRequestProcessor::register_new_client(req, processing_data.read().unwrap().store_dir.as_path(),&mut processing_data.read().unwrap().registered_clients_ledger.clone())?.to_bytes()) + Ok(ClientRequestProcessor::register_new_client(req, processing_data.read().unwrap().store_dir.as_path(),&mut processing_data.read().unwrap().registered_clients_ledger.clone(), provider_secret_key)?.to_bytes()) }, ProviderRequests::PullMessages(req) => { Ok(ClientRequestProcessor::process_pull_messages_request( @@ -84,9 +89,9 @@ impl ClientRequestProcessor { Ok(PullResponse::new(retrieved_messages)) } - fn register_new_client(req:RegisterRequest, store_dir: &Path, registered_client_ledger: &mut HashMap<[u8; 32], Vec>) -> Result{ + fn register_new_client(req:RegisterRequest, store_dir: &Path, registered_client_ledger: &mut HashMap<[u8; 32], Vec>, provider_secret_key: Scalar) -> Result{ println!("Processing register new client request!"); - let auth_token = ClientRequestProcessor::generate_new_auth_token(req.destination_address.to_vec()); + let auth_token = ClientRequestProcessor::generate_new_auth_token(req.destination_address.to_vec(), provider_secret_key); if !registered_client_ledger.contains_key(&auth_token.value) { registered_client_ledger.insert(auth_token.value.clone(), req.destination_address.to_vec()); ClientRequestProcessor::create_storage_dir(req.destination_address, store_dir); @@ -102,13 +107,16 @@ impl ClientRequestProcessor { Ok(()) } - fn generate_new_auth_token(data: Vec) -> AuthToken{ - // TODO: We can use hmac with providers secret key to have HMAC instead of SHA - let hash= sha2::Sha256::digest(&data).to_vec(); - // TODO: this probably can be coverted in some better way + fn generate_new_auth_token(data: Vec, key: Scalar) -> AuthToken{ + let mut auth_token = HmacSha256::new_varkey(&key.to_bytes()).expect("HMAC can take key of any size"); + auth_token.input(&data); let mut result = [0u8; 32]; - result.copy_from_slice(&hash); + result.copy_from_slice(&auth_token.result().code().to_vec()); AuthToken{value: result} +// let hash= sha2::Sha256::digest(&data).to_vec(); +// let mut result = [0u8; 32]; +// result.copy_from_slice(&hash); +// AuthToken{value: result} } } @@ -122,12 +130,13 @@ mod register_new_client { let req1 = RegisterRequest{destination_address: [1u8; 32]}; let mut registered_client_ledger: HashMap<[u8; 32], Vec> = HashMap::new(); let store_dir = Path::new("./foo/"); + let key = Scalar::from_bytes_mod_order([1u8; 32]); assert_eq!(0, registered_client_ledger.len()); - ClientRequestProcessor::register_new_client(req1, &store_dir, &mut registered_client_ledger); + ClientRequestProcessor::register_new_client(req1, &store_dir, &mut registered_client_ledger, key); assert_eq!(1, registered_client_ledger.len()); let req2 = RegisterRequest{destination_address: [2u8; 32]}; - ClientRequestProcessor::register_new_client(req2, &store_dir, &mut registered_client_ledger); + ClientRequestProcessor::register_new_client(req2, &store_dir, &mut registered_client_ledger, key); assert_eq!(2, registered_client_ledger.len()); } @@ -136,9 +145,10 @@ mod register_new_client { let req1 = RegisterRequest{destination_address: [1u8; 32]}; let mut registered_client_ledger: HashMap<[u8; 32], Vec> = HashMap::new(); let store_dir = Path::new("./foo/"); - ClientRequestProcessor::register_new_client(req1, &store_dir, &mut registered_client_ledger); + let key = Scalar::from_bytes_mod_order([1u8; 32]); + ClientRequestProcessor::register_new_client(req1, &store_dir, &mut registered_client_ledger, key); let req2 = RegisterRequest{destination_address: [1u8; 32]}; - ClientRequestProcessor::register_new_client(req2, &store_dir, &mut registered_client_ledger); + ClientRequestProcessor::register_new_client(req2, &store_dir, &mut registered_client_ledger, key); assert_eq!(1, registered_client_ledger.len()) } } @@ -164,8 +174,9 @@ mod generating_new_auth_token { fn for_the_same_input_generates_the_same_auth_token(){ let data1 = vec![1u8; 55]; let data2 = vec![1u8; 55]; - let token1 = ClientRequestProcessor::generate_new_auth_token(data1); - let token2 = ClientRequestProcessor::generate_new_auth_token(data2); + let key = Scalar::from_bytes_mod_order([1u8; 32]); + let token1 = ClientRequestProcessor::generate_new_auth_token(data1, key); + let token2 = ClientRequestProcessor::generate_new_auth_token(data2, key); assert_eq!(token1.value, token2.value); } @@ -173,14 +184,16 @@ mod generating_new_auth_token { fn for_different_inputs_generates_different_auth_tokens(){ let data1 = vec![1u8; 55]; let data2 = vec![2u8; 55]; - let token1 = ClientRequestProcessor::generate_new_auth_token(data1); - let token2 = ClientRequestProcessor::generate_new_auth_token(data2); + let key = Scalar::from_bytes_mod_order([1u8; 32]); + let token1 = ClientRequestProcessor::generate_new_auth_token(data1, key); + let token2 = ClientRequestProcessor::generate_new_auth_token(data2, key); assert_ne!(token1.value, token2.value); let data1 = vec![1u8; 50]; let data2 = vec![2u8; 55]; - let token1 = ClientRequestProcessor::generate_new_auth_token(data1); - let token2 = ClientRequestProcessor::generate_new_auth_token(data2); + let key = Scalar::from_bytes_mod_order([1u8; 32]); + let token1 = ClientRequestProcessor::generate_new_auth_token(data1, key); + let token2 = ClientRequestProcessor::generate_new_auth_token(data2, key); assert_ne!(token1.value, token2.value); } diff --git a/src/provider/mod.rs b/src/provider/mod.rs index eab56f964b..4e3533f617 100644 --- a/src/provider/mod.rs +++ b/src/provider/mod.rs @@ -91,7 +91,7 @@ impl ServiceProvider { } // TODO: FIGURE OUT HOW TO SET READ_DEADLINES IN TOKIO - async fn process_client_socket_connection(mut socket: tokio::net::TcpStream, processing_data: Arc>) { + async fn process_client_socket_connection(mut socket: tokio::net::TcpStream, processing_data: Arc>, secret_key: Scalar) { let mut buf = [0; 1024]; // TODO: restore the for loop once we go back to persistent tcp socket connection @@ -102,7 +102,7 @@ impl ServiceProvider { Err(()) } Ok(n) => { - match ClientRequestProcessor::process_client_request(buf[..n].as_ref(), processing_data.as_ref()) { + match ClientRequestProcessor::process_client_request(buf[..n].as_ref(), processing_data.as_ref(), secret_key) { Err(e) => { eprintln!("failed to process client request; err = {:?}", e); Err(()) @@ -150,14 +150,14 @@ impl ServiceProvider { async fn start_client_listening(&self) -> Result<(), Box> { let mut listener = tokio::net::TcpListener::bind(self.client_network_address).await?; let processing_data = ClientProcessingData::new(self.store_dir.clone(), self.registered_clients_ledger.clone()).add_arc_rwlock(); - + let key = self.secret_key.clone(); loop { let (socket, _) = listener.accept().await?; // do note that the underlying data is NOT copied here; arc is incremented and lock is shared // (if I understand it all correctly) let thread_processing_data = processing_data.clone(); tokio::spawn(async move { - ServiceProvider::process_client_socket_connection(socket, thread_processing_data).await + ServiceProvider::process_client_socket_connection(socket, thread_processing_data, key).await }); } }