diff --git a/bin/tau/taud/Cargo.toml b/bin/tau/taud/Cargo.toml index 762ac32f8..dbc20d182 100644 --- a/bin/tau/taud/Cargo.toml +++ b/bin/tau/taud/Cargo.toml @@ -33,4 +33,4 @@ serde_json = "1.0.79" structopt = "0.3.26" structopt-toml = "0.5.0" crypto_box = {version = "0.7.2", features = ["std"]} -hex = {version = "0.4.3", optional = true} +hex = "0.4.3" diff --git a/bin/tau/taud/src/main.rs b/bin/tau/taud/src/main.rs index a5ddbeb66..1fc3e39b4 100644 --- a/bin/tau/taud/src/main.rs +++ b/bin/tau/taud/src/main.rs @@ -1,11 +1,11 @@ use async_std::sync::Arc; -use std::{fs::create_dir_all, process::exit}; +use std::fs::create_dir_all; use async_executor::Executor; use crypto_box::{aead::Aead, Box, SecretKey, KEY_SIZE}; use easy_parallel::Parallel; use futures::{select, FutureExt}; -use log::{error, info, warn}; +use log::{error, info, warn, debug}; use simplelog::{ColorChoice, TermLogger, TerminalMode}; use smol::future; use structopt_toml::StructOptToml; @@ -45,6 +45,43 @@ pub struct EncryptedTask { payload: Vec, } +fn encrypt_task( + task: &TaskInfo, + secret_key: &SecretKey, + rng: &mut crypto_box::rand_core::OsRng, + ) -> Result { + debug!("start encrypting task"); + let public_key = secret_key.public_key(); + let msg_box = Box::new(&public_key, &secret_key); + + let nonce = crypto_box::generate_nonce(rng); + let payload = &serialize(task)[..]; + let payload = match msg_box.encrypt(&nonce, payload) { + Ok(p) => p, + Err(e) => { + error!("Unable to encrypt task: {}", e); + return Err(Error::OperationFailed) + }, + }; + + let nonce = nonce.to_vec(); + Ok(EncryptedTask { nonce, payload }) +} + +fn decrypt_task(encrypt_task: &EncryptedTask, secret_key: &SecretKey) -> Option { + debug!("start decrypting task"); + let public_key = secret_key.public_key(); + let msg_box = Box::new(&public_key, &secret_key); + + let nonce = encrypt_task.nonce.as_slice(); + let decrypted_task = match msg_box.decrypt(nonce.into(), &encrypt_task.payload[..]) { + Ok(m) => m, + Err(_) => return None + }; + + deserialize(&decrypted_task).ok() +} + async_daemonize!(realmain); async fn realmain(settings: Args, executor: Arc>) -> Result<()> { let datastore_path = expand_path(&settings.datastore)?; @@ -55,41 +92,30 @@ async fn realmain(settings: Args, executor: Arc>) -> Result<()> { let mut rng = crypto_box::rand_core::OsRng; - let secret_key = match settings.key_gen { - true => { - info!(target: "tau", "generating a new secret key"); - let secret = SecretKey::generate(&mut rng); - let sk_string = hex::encode(secret.as_bytes()); - save::(&datastore_path.join("secret_key"), &sk_string)?; - secret - } - false => { - if settings.key.is_some() { - let sk_string = hex::decode(settings.key.unwrap()) - .map_err(|_| Error::DecodeError("Error decoding key from arguments"))?; - - let sk_bytes: [u8; KEY_SIZE] = sk_string - .try_into() - .map_err(|_| Error::ParseFailed("Could not convert key to bytes"))?; - - SecretKey::try_from(sk_bytes)? - } else { - let loaded_key = match load::(&datastore_path.join("secret_key")) { - Ok(key) => key, - Err(_) => { - error!("Could not load secret key from file, please run \"taud --help\" for more information"); - exit(1) - } - }; - let sk_string = hex::decode(loaded_key) - .map_err(|_| Error::DecodeError("Error decoding secret key from file"))?; - - let sk_bytes: [u8; KEY_SIZE] = sk_string - .try_into() - .map_err(|_| Error::ParseFailed("Could not convert key to bytes"))?; - - SecretKey::try_from(sk_bytes)? - } + let secret_key = if settings.key_gen { + info!(target: "tau", "generating a new secret key"); + let secret = SecretKey::generate(&mut rng); + let sk_string = hex::encode(secret.as_bytes()); + save::(&datastore_path.join("secret_key"), &sk_string)?; + secret + } else { + if settings.key.is_some() { + let sk_str = settings.key.unwrap(); + save::(&datastore_path.join("secret_key"), &sk_str)?; + let sk_bytes = hex::decode(sk_str)?; + let sk_bytes: [u8; KEY_SIZE] = sk_bytes.as_slice().try_into()?; + SecretKey::try_from(sk_bytes)? + } else { + let loaded_key = match load::(&datastore_path.join("secret_key")) { + Ok(key) => key, + Err(_) => { + error!("Could not load secret key from file, please run \"taud --help\" for more information"); + return Ok(()) + } + }; + let sk_bytes = hex::decode(loaded_key)?; + let sk_bytes: [u8; KEY_SIZE] = sk_bytes.as_slice().try_into()?; + SecretKey::try_from(sk_bytes)? } }; @@ -131,23 +157,8 @@ async fn realmain(settings: Args, executor: Arc>) -> Result<()> { let tasks = MonthTasks::load_current_open_tasks(&datastore_path)?; for task in tasks { - info!(target: "tau", "send local task {:?}", task); - let public_key = secret_key.public_key(); - let msg_box = Box::new(&public_key, &secret_key); - - let nonce = crypto_box::generate_nonce(&mut rng); - let payload = &serialize(&task)[..]; - let encrypted_payload = match msg_box.encrypt(&nonce, payload) { - Ok(p) => p, - Err(_) => { - error!("Could not encrypt task"); - continue - } - }; - - let encrypted_task = - EncryptedTask { nonce: nonce.to_vec(), payload: encrypted_payload }; - + debug!(target: "tau", "send local task {:?}", task); + let encrypted_task = encrypt_task(&task, &secret_key, &mut rng)?; initial_sync_raft_sender.send(encrypted_task).await.map_err(Error::from)?; } @@ -157,42 +168,20 @@ async fn realmain(settings: Args, executor: Arc>) -> Result<()> { let task = task.map_err(Error::from)?; if let Some(tk) = task { info!(target: "tau", "save the received task {:?}", tk); + let encrypted_task = encrypt_task(&tk, &secret_key,&mut rng)?; tk.save(&datastore_path_cloned)?; - - let public_key = secret_key.public_key(); - let msg_box = Box::new(&public_key, &secret_key); - - let nonce = crypto_box::generate_nonce(&mut rng); - let payload = &serialize(&tk)[..]; - let encrypted_payload = match msg_box.encrypt(&nonce, payload) { - Ok(p) => p, - Err(_) => { - error!("Could not encrypt task"); - continue - } - }; - - let encrypted_task = - EncryptedTask { nonce: nonce.to_vec(), payload: encrypted_payload }; - raft_sender.send(encrypted_task).await.map_err(Error::from)?; } } task = commits.recv().fuse() => { let recv = task.map_err(Error::from)?; + let task = decrypt_task(&recv, &secret_key); - let public_key = secret_key.public_key(); - let msg_box = Box::new(&public_key, &secret_key); + if task.is_none() { + continue + } - let nonce = recv.nonce.as_slice(); - let decrypted_task = match msg_box.decrypt(nonce.try_into().unwrap(), &recv.payload[..]) { - Ok(m) => m, - Err(_) => { - error!("Invalid secret or public key"); - continue - } - }; - let task: TaskInfo = deserialize(&decrypted_task)?; + let task = task.unwrap(); info!(target: "tau", "receive update from the commits {:?}", task); task.save(&datastore_path_cloned)?; }