Browse Source

bin/tau: adding encryption

Dastan-glitch 4 years ago
parent
commit
cc18f509e8
3 changed files with 278 additions and 13 deletions
  1. 212 9
      Cargo.lock
  2. 3 0
      bin/tau/taud/Cargo.toml
  3. 63 4
      bin/tau/taud/src/main.rs

+ 212 - 9
Cargo.lock

@@ -23,6 +23,16 @@ version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
 
+[[package]]
+name = "aead"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877"
+dependencies = [
+ "generic-array",
+ "rand_core 0.6.3",
+]
+
 [[package]]
 name = "ahash"
 version = "0.7.6"
@@ -426,7 +436,7 @@ dependencies = [
  "cc",
  "cfg-if 1.0.0",
  "constant_time_eq",
- "digest",
+ "digest 0.10.3",
 ]
 
 [[package]]
@@ -627,6 +637,31 @@ version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
+[[package]]
+name = "chacha20"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91"
+dependencies = [
+ "cfg-if 1.0.0",
+ "cipher",
+ "cpufeatures",
+ "zeroize",
+]
+
+[[package]]
+name = "chacha20poly1305"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a"
+dependencies = [
+ "aead",
+ "chacha20",
+ "cipher",
+ "poly1305",
+ "zeroize",
+]
+
 [[package]]
 name = "chrono"
 version = "0.4.19"
@@ -640,6 +675,15 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "cipher"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
+dependencies = [
+ "generic-array",
+]
+
 [[package]]
 name = "clap"
 version = "2.34.0"
@@ -996,6 +1040,21 @@ dependencies = [
  "crypto_api",
 ]
 
+[[package]]
+name = "crypto_box"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d2bcbd5e4fc3ad3de2d0e75509f870a6fa9f488e0e2c9a8ce49721a52efc4e"
+dependencies = [
+ "chacha20",
+ "chacha20poly1305",
+ "rand_core 0.6.3",
+ "salsa20",
+ "x25519-dalek",
+ "xsalsa20poly1305",
+ "zeroize",
+]
+
 [[package]]
 name = "csv"
 version = "1.1.6"
@@ -1055,6 +1114,19 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "curve25519-dalek"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0"
+dependencies = [
+ "byteorder",
+ "digest 0.9.0",
+ "rand_core 0.5.1",
+ "subtle",
+ "zeroize",
+]
+
 [[package]]
 name = "dao-cli"
 version = "0.3.0"
@@ -1313,6 +1385,15 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
 [[package]]
 name = "digest"
 version = "0.10.3"
@@ -1494,6 +1575,24 @@ version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
 
+[[package]]
+name = "encoding_rs"
+version = "0.8.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "encoding_rs_io"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83"
+dependencies = [
+ "encoding_rs",
+]
+
 [[package]]
 name = "enum-iterator"
 version = "0.7.0"
@@ -1623,7 +1722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b2958d04124b9f27f175eaeb9a9f383d026098aa837eadd8ba22c11f13a05b9e"
 dependencies = [
  "bitvec 0.22.3",
- "rand_core",
+ "rand_core 0.6.3",
  "subtle",
 ]
 
@@ -1964,7 +2063,7 @@ checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89"
 dependencies = [
  "byteorder",
  "ff",
- "rand_core",
+ "rand_core 0.6.3",
  "subtle",
 ]
 
@@ -1999,7 +2098,7 @@ dependencies = [
  "group",
  "pasta_curves",
  "plotters",
- "rand_core",
+ "rand_core 0.6.3",
  "rayon",
  "tabbycat",
 ]
@@ -2558,6 +2657,12 @@ version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
 
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
 [[package]]
 name = "openssl"
 version = "0.10.38"
@@ -2801,6 +2906,17 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "poly1305"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede"
+dependencies = [
+ "cpufeatures",
+ "opaque-debug",
+ "universal-hash",
+]
+
 [[package]]
 name = "ppv-lite86"
 version = "0.2.16"
@@ -2965,7 +3081,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 dependencies = [
  "libc",
  "rand_chacha",
- "rand_core",
+ "rand_core 0.6.3",
 ]
 
 [[package]]
@@ -2975,9 +3091,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
 dependencies = [
  "ppv-lite86",
- "rand_core",
+ "rand_core 0.6.3",
 ]
 
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+
 [[package]]
 name = "rand_core"
 version = "0.6.3"
@@ -2993,7 +3115,7 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
 dependencies = [
- "rand_core",
+ "rand_core 0.6.3",
 ]
 
 [[package]]
@@ -3260,6 +3382,16 @@ version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
 
+[[package]]
+name = "salsa20"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c0fbb5f676da676c260ba276a8f43a8dc67cf02d1438423aeb1c677a7212686"
+dependencies = [
+ "cipher",
+ "zeroize",
+]
+
 [[package]]
 name = "same-file"
 version = "1.0.6"
@@ -3420,7 +3552,7 @@ checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
 dependencies = [
  "cfg-if 1.0.0",
  "cpufeatures",
- "digest",
+ "digest 0.10.3",
 ]
 
 [[package]]
@@ -3431,7 +3563,7 @@ checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676"
 dependencies = [
  "cfg-if 1.0.0",
  "cpufeatures",
- "digest",
+ "digest 0.10.3",
 ]
 
 [[package]]
@@ -3761,6 +3893,18 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "synstructure"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "unicode-xid",
+]
+
 [[package]]
 name = "tabbycat"
 version = "0.1.2"
@@ -3816,9 +3960,12 @@ dependencies = [
  "async-trait",
  "chrono",
  "clap 3.1.12",
+ "crypto_box",
  "ctrlc-async",
  "darkfi",
  "easy-parallel",
+ "encoding_rs",
+ "encoding_rs_io",
  "futures",
  "log",
  "num_cpus",
@@ -4120,6 +4267,16 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
 
+[[package]]
+name = "universal-hash"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05"
+dependencies = [
+ "generic-array",
+ "subtle",
+]
+
 [[package]]
 name = "untrusted"
 version = "0.7.1"
@@ -4657,6 +4814,31 @@ dependencies = [
  "tap",
 ]
 
+[[package]]
+name = "x25519-dalek"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2392b6b94a576b4e2bf3c5b2757d63f10ada8020a2e4d08ac849ebcf6ea8e077"
+dependencies = [
+ "curve25519-dalek",
+ "rand_core 0.5.1",
+ "zeroize",
+]
+
+[[package]]
+name = "xsalsa20poly1305"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e68bcb965d6c650091450b95cea12f07dcd299a01c15e2f9433b0813ea3c0886"
+dependencies = [
+ "aead",
+ "poly1305",
+ "rand_core 0.6.3",
+ "salsa20",
+ "subtle",
+ "zeroize",
+]
+
 [[package]]
 name = "yasna"
 version = "0.5.0"
@@ -4666,6 +4848,27 @@ dependencies = [
  "time 0.3.9",
 ]
 
+[[package]]
+name = "zeroize"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
+dependencies = [
+ "zeroize_derive",
+]
+
+[[package]]
+name = "zeroize_derive"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
 [[package]]
 name = "zkas"
 version = "0.3.0"

+ 3 - 0
bin/tau/taud/Cargo.toml

@@ -26,9 +26,12 @@ rand = "0.8.5"
 chrono = "0.4.19"
 thiserror = "1.0.30"
 ctrlc-async = {version= "3.2.2", default-features = false, features = ["async-std", "termination"]}
+encoding_rs = "0.8.31"
+encoding_rs_io = "0.1.7"
 
 # Encoding and parsing
 serde = {version = "1.0.136", features = ["derive"]}
 serde_json = "1.0.79"
 structopt = "0.3.26"
 structopt-toml = "0.5.0"
+crypto_box = {version = "0.7.2", features = ["std"]}

+ 63 - 4
bin/tau/taud/src/main.rs

@@ -1,10 +1,12 @@
 use async_std::sync::Arc;
+use serde::{Deserialize, Serialize};
 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::{info, warn};
+use log::{error, info, warn};
 use simplelog::{ColorChoice, TermLogger, TerminalMode};
 use smol::future;
 use structopt_toml::StructOptToml;
@@ -17,6 +19,7 @@ use darkfi::{
         cli::{log_config, spawn_config},
         expand_path,
         path::get_config_path,
+        serial::{deserialize, serialize, SerialDecodable, SerialEncodable},
     },
     Error, Result,
 };
@@ -34,8 +37,15 @@ use crate::{
     month_tasks::MonthTasks,
     settings::{Args, CONFIG_FILE, CONFIG_FILE_CONTENTS},
     task_info::TaskInfo,
+    util::{load, save},
 };
 
+#[derive(Debug, Clone, SerialEncodable, SerialDecodable, Serialize, Deserialize)]
+pub struct MsgPayload {
+    nonce: Vec<u8>,
+    payload: Vec<u8>,
+}
+
 async_daemonize!(realmain);
 async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
     let datastore_path = expand_path(&settings.datastore)?;
@@ -44,6 +54,23 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
     create_dir_all(datastore_path.join("month"))?;
     create_dir_all(datastore_path.join("task"))?;
 
+    let mut rng = crypto_box::rand_core::OsRng;
+
+    let secret_key = match load::<[u8; KEY_SIZE]>(&datastore_path.join("secret_key")) {
+        Ok(t) => SecretKey::try_from(t)?,
+        Err(_) => {
+            info!(target: "tau", "generating a new secret key");
+            let secret = SecretKey::generate(&mut rng);
+            let sk_string = secret.as_bytes();
+            save::<[u8; KEY_SIZE]>(&datastore_path.join("secret_key"), sk_string)
+                .map_err(Error::from)?;
+            secret
+        }
+    };
+
+    let public_key = secret_key.public_key();
+    let msg_box = Box::new(&public_key, &secret_key);
+
     //
     // RPC
     //
@@ -69,7 +96,7 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
     //Raft
     //
     let datastore_raft = datastore_path.join("tau.db");
-    let mut raft = Raft::<TaskInfo>::new(net_settings.inbound, datastore_raft)?;
+    let mut raft = Raft::<Vec<u8>>::new(net_settings.inbound, datastore_raft)?;
 
     let raft_sender = raft.get_broadcast();
     let commits = raft.get_commits();
@@ -83,7 +110,15 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
 
         for task in tasks {
             info!(target: "tau", "send local task {:?}", task);
-            initial_sync_raft_sender.send(task).await.map_err(Error::from)?;
+
+            let nonce = crypto_box::generate_nonce(&mut rng);
+            let payload = &serialize(&task)[..];
+            let encrypted_payload = msg_box.encrypt(&nonce, payload).unwrap();
+
+            let msg = MsgPayload { nonce: nonce.to_vec(), payload: encrypted_payload };
+            let ser_msg = serialize(&msg);
+
+            initial_sync_raft_sender.send(ser_msg).await.map_err(Error::from)?;
         }
 
         loop {
@@ -93,12 +128,36 @@ async fn realmain(settings: Args, executor: Arc<Executor<'_>>) -> Result<()> {
                     if let Some(tk) = task {
                         info!(target: "tau", "save the received task {:?}", tk);
                         tk.save(&datastore_path_cloned)?;
-                        raft_sender.send(tk).await.map_err(Error::from)?;
+
+                        let nonce = crypto_box::generate_nonce(&mut rng);
+                        let payload = &serialize(&tk)[..];
+                        let encrypted_payload = msg_box.encrypt(&nonce, payload).unwrap();
+
+                        let msg = MsgPayload {
+                            nonce: nonce.to_vec(),
+                            payload: encrypted_payload,
+                        };
+                        let ser_msg = serialize(&msg);
+
+                        raft_sender.send(ser_msg).await.map_err(Error::from)?;
                     }
                 }
                 task = commits.recv().fuse() => {
                     let task = task.map_err(Error::from)?;
+
+                    let recv: MsgPayload = deserialize(&task)?;
+                    let nonce = recv.nonce.as_slice();
+                    let message = match msg_box.decrypt(nonce.try_into().unwrap(), &recv.payload[..]){
+                        Ok(m) => m,
+                        Err(_) => {
+                            error!("Invalid secret or public key");
+                            vec![]
+                        },
+                    };
+
+                    let task: TaskInfo = deserialize(&message)?;
                     info!(target: "tau", "receive update from the commits {:?}", task);
+                    
                     task.save(&datastore_path_cloned)?;
                 }