From a135814891d95dc1e82eff5df0bcb473125b3f5a Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Wed, 18 Sep 2019 12:34:19 +0200 Subject: [PATCH] Persist the provider key Of course we also need to persist the resolver keys --- Cargo.toml | 3 +++ src/config.rs | 16 ++++++++++++++++ src/crypto.rs | 9 ++++++--- src/main.rs | 40 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5ab5fb7..8cebbaf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,9 @@ log = "0.4.8" net2 = "0.2.33" parking_lot = "0.9.0" rand = "0.7.2" +serde = "1.0.101" +serde_derive = "1.0.101" +serde-big-array = "0.1.5" siphasher = "0.3.0" tokio = "=0.2.0-alpha.4" tokio-net = "=0.2.0-alpha.4" diff --git a/src/config.rs b/src/config.rs index e69de29..52aba7a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -0,0 +1,16 @@ +use crate::crypto::*; +use crate::errors::*; + +use bincode; + +#[derive(Serialize, Deserialize, Debug)] +pub struct State { + pub provider_kp: SignKeyPair, +} + +impl State { + pub fn new() -> Self { + let provider_kp = SignKeyPair::new(); + State { provider_kp } + } +} diff --git a/src/crypto.rs b/src/crypto.rs index ceba407..b3544fe 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -27,9 +27,12 @@ impl Signature { } } -#[derive(Derivative)] +big_array! { BigArray; } + +#[derive(Serialize, Deserialize, Derivative)] #[derivative(Default)] pub struct SignSK( + #[serde(with = "BigArray")] #[derivative(Default(value = "[0u8; crypto_sign_SECRETKEYBYTES as usize]"))] [u8; crypto_sign_SECRETKEYBYTES as usize], ); @@ -59,7 +62,7 @@ impl SignSK { } } -#[derive(Debug, Default)] +#[derive(Debug, Serialize, Deserialize, Default)] pub struct SignPK([u8; crypto_sign_PUBLICKEYBYTES as usize]); impl SignPK { @@ -76,7 +79,7 @@ impl SignPK { } } -#[derive(Derivative)] +#[derive(Derivative, Serialize, Deserialize)] #[derivative(Debug, Default)] pub struct SignKeyPair { #[derivative(Debug = "ignore")] diff --git a/src/main.rs b/src/main.rs index 0504bb9..cd03423 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,10 @@ extern crate derivative; extern crate failure; #[macro_use] extern crate log; +#[macro_use] +extern crate serde_derive; +#[macro_use] +extern crate serde_big_array; mod config; mod crypto; @@ -23,6 +27,7 @@ mod dnscrypt_certs; mod errors; mod globals; +use config::*; use crypto::*; use dns::*; use dnscrypt::*; @@ -40,9 +45,12 @@ use parking_lot::Mutex; use rand::prelude::*; use std::collections::vec_deque::VecDeque; use std::convert::TryFrom; +use std::fs::File; +use std::io::prelude::*; use std::mem; use std::net::SocketAddr; use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; +use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::Arc; use std::time::Duration; @@ -360,6 +368,14 @@ fn main() -> Result<(), Error> { .required(true) .help("Address and port to connect from"), ) + .arg( + Arg::with_name("state-file") + .value_name("state-file") + .takes_value(true) + .default_value("dnscrypt-server.state") + .required(true) + .help("File to store the server state"), + ) .get_matches(); let listen_addr = matches @@ -384,7 +400,29 @@ fn main() -> Result<(), Error> { let udp_timeout = Duration::from_secs(10); let tcp_timeout = Duration::from_secs(10); - let provider_kp = SignKeyPair::new(); + let state_file_s = matches.value_of("state-file").unwrap(); + let state_file = PathBuf::from(state_file_s); + + let state = match File::open(&state_file) { + Err(_) => { + println!("No state file found... creating a new provider key"); + let state = State::new(); + let mut fp = File::create(&state_file)?; + let state_bin = bincode::serialize(&state)?; + fp.write_all(&state_bin)?; + state + } + Ok(mut fp) => { + println!( + "State file [{}] found; using existing provider key", + state_file.as_os_str().to_string_lossy() + ); + let mut state_bin = vec![]; + fp.read_to_end(&mut state_bin)?; + bincode::deserialize(&state_bin)? + } + }; + let provider_kp = state.provider_kp; info!("Server address: {}", listen_addr); info!("Provider public key: {}", provider_kp.pk.as_string());