Change SHA256 to HMAC

This commit is contained in:
aniampio
2019-12-17 17:29:10 +01:00
parent 85d147ef62
commit 671e55f4d5
4 changed files with 38 additions and 23 deletions
Generated
+1
View File
@@ -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)",
+2 -1
View File
@@ -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"
serde_json = "1.0"
hmac = "0.7.1"
+31 -18
View File
@@ -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<Sha256>;
#[derive(Debug)]
pub enum ClientProcessingError {
@@ -57,12 +61,13 @@ impl ClientRequestProcessor {
pub(crate) fn process_client_request(
data: &[u8],
processing_data: &RwLock<ClientProcessingData>,
provider_secret_key: Scalar
) -> Result<Vec<u8>, 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<u8>>) -> Result<RegisterResponse, ClientProcessingError>{
fn register_new_client(req:RegisterRequest, store_dir: &Path, registered_client_ledger: &mut HashMap<[u8; 32], Vec<u8>>, provider_secret_key: Scalar) -> Result<RegisterResponse, ClientProcessingError>{
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<u8>) -> 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<u8>, 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<u8>> = 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<u8>> = 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);
}
+4 -4
View File
@@ -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<RwLock<ClientProcessingData>>) {
async fn process_client_socket_connection(mut socket: tokio::net::TcpStream, processing_data: Arc<RwLock<ClientProcessingData>>, 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<dyn std::error::Error>> {
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
});
}
}