Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: mnemonic rotation #281

Merged
merged 11 commits into from
Apr 22, 2022
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ For more information, see on mnemonic options, see [Mnemonic](#mnemonic).
5. By default, `tofnd` expects a password from the standard input. Users that don't want to use passwords can use the `--no-password` flag. **Attention: Use `--no-password` only for testing .**
```
A threshold signature scheme daemon

USAGE:
tofnd [FLAGS] [OPTIONS]

Expand Down
2 changes: 1 addition & 1 deletion proto
Submodule proto updated 2 files
+1 −0 common.proto
+1 −0 multisig.proto
4 changes: 2 additions & 2 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const TOFND_HOME_ENV_VAR: &str = "TOFND_HOME";
const DEFAULT_MNEMONIC_CMD: &str = "existing";
const DEFAULT_IP: &str = "0.0.0.0";
const DEFAULT_PORT: u16 = 50051;
const AVAILABLE_MNEMONIC_CMDS: [&str; 4] = ["existing", "create", "import", "export"];
const AVAILABLE_MNEMONIC_CMDS: &[&str] = &["existing", "create", "import", "export", "rotate"];

#[cfg(feature = "malicious")]
mod malicious;
Expand Down Expand Up @@ -92,7 +92,7 @@ pub fn parse_args() -> TofndResult<Config> {
.short('m')
.required(false)
.default_value(DEFAULT_MNEMONIC_CMD)
.possible_values(&AVAILABLE_MNEMONIC_CMDS),
.possible_values(AVAILABLE_MNEMONIC_CMDS),
)
.arg(
Arg::new("directory")
Expand Down
2 changes: 2 additions & 0 deletions src/kv_manager/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub enum KvError {
PutErr(InnerKvError),
#[error("Get Error: {0}")]
GetErr(InnerKvError),
#[error("Delete Error: {0}")]
DeleteErr(InnerKvError),
#[error("Exits Error: {0}")]
ExistsErr(InnerKvError),
}
Expand Down
20 changes: 19 additions & 1 deletion src/kv_manager/kv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::encrypted_sled::{self, Password};

use super::{
error::{KvError::*, KvResult},
sled_bindings::{handle_exists, handle_get, handle_put, handle_reserve},
sled_bindings::{handle_delete, handle_exists, handle_get, handle_put, handle_reserve},
types::{
Command::{self, *},
KeyReservation, DEFAULT_KV_NAME, DEFAULT_KV_PATH,
Expand Down Expand Up @@ -94,6 +94,19 @@ where
resp_rx.await?.map_err(GetErr)
}

/// Deletes an unreserved key
/// Returns [DeleteErr] or [SendErr] on failure.
pub async fn delete(&self, key: &str) -> KvResult<()> {
let (resp_tx, resp_rx) = oneshot::channel();
self.sender
.send(Delete {
key: key.to_string(),
resp: resp_tx,
})
.map_err(|e| SendErr(e.to_string()))?;
resp_rx.await?.map_err(DeleteErr)
}

/// Checks if a key exists in the kvstore
/// Returns [ExistsErr] or [SendErr] on failure.
pub async fn exists(&self, key: &str) -> KvResult<bool> {
Expand Down Expand Up @@ -176,6 +189,11 @@ async fn kv_cmd_handler<V: 'static>(
warn!("receiver dropped");
}
}
Delete { key, resp } => {
if resp.send(handle_delete(&kv, key)).is_err() {
warn!("receiver dropped");
}
}
}
}
info!("kv_manager stop");
Expand Down
28 changes: 24 additions & 4 deletions src/kv_manager/sled_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ use serde::{de::DeserializeOwned, Serialize};
use tofn::sdk::api::{deserialize, serialize};

use super::error::{InnerKvError::*, InnerKvResult};
use super::types::{KeyReservation, DEFAULT_RESERV};
use super::types::{KeyReservation, DEFAULT_RESERVE};

use crate::encrypted_sled;

/// Reserves a key. New's key value is [DEFAULT_RESERV].
/// Reserves a key. New's key value is [DEFAULT_RESERVE].
/// Returns [SledErr] of [LogicalErr] on failure.
pub(super) fn handle_reserve(
kv: &encrypted_sled::Db,
Expand All @@ -24,12 +24,32 @@ pub(super) fn handle_reserve(
}

// try to insert the new key with default value
kv.insert(&key, DEFAULT_RESERV)?;
kv.insert(&key, DEFAULT_RESERVE)?;

// return key reservation
Ok(KeyReservation { key })
}

/// Deletes an unreserved key if it exists.
/// Returns [SledErr] of [LogicalErr] on failure.
pub(super) fn handle_delete(kv: &encrypted_sled::Db, key: String) -> InnerKvResult<()> {
if !kv.contains_key(&key)? {
return Ok(());
}

// check if key holds the default reserve value. If yes, can't delete it.
if kv.get(&key)? == Some(sled::IVec::from(DEFAULT_RESERVE)) {
return Err(LogicalErr(format!(
"can't delete reserved key <{}> in kv store.",
key
)));
}

kv.remove(&key)?;

Ok(())
}

/// Inserts a value to an existing key.
/// Returns [SledErr] of [LogicalErr] on failure.
pub(super) fn handle_put<V>(
Expand All @@ -44,7 +64,7 @@ where
// Explanation of code ugliness: that's the standard way to compare a
// sled retrieved value with a local value:
// https://docs.rs/sled/0.34.6/sled/struct.Tree.html#examples-4
if kv.get(&reservation.key)? != Some(sled::IVec::from(DEFAULT_RESERV)) {
if kv.get(&reservation.key)? != Some(sled::IVec::from(DEFAULT_RESERVE)) {
return Err(LogicalErr(format!(
"did not find reservation for key <{}> in kv store.",
reservation.key
Expand Down
4 changes: 2 additions & 2 deletions src/kv_manager/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use super::{
error::InnerKvError::LogicalErr,
sled_bindings::{handle_exists, handle_get, handle_put, handle_reserve},
types::{KeyReservation, DEFAULT_RESERV},
types::{KeyReservation, DEFAULT_RESERVE},
};
use crate::encrypted_sled;

Expand Down Expand Up @@ -42,7 +42,7 @@ fn reserve_success() {
// get bytes
let default_reserv = kv.get(&key).unwrap().unwrap();
// convert to value type
assert!(default_reserv == DEFAULT_RESERV);
assert!(default_reserv == DEFAULT_RESERVE);

clean_up(kv_name.to_str().unwrap(), kv);
}
Expand Down
6 changes: 5 additions & 1 deletion src/kv_manager/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub const DEFAULT_KV_NAME: &str = "kv";
pub(super) const DEFAULT_KV_PATH: &str = "kvstore";

/// default value for reserved key
pub(super) const DEFAULT_RESERV: &str = "";
pub(super) const DEFAULT_RESERVE: &str = "";

/// Returned from a successful `ReserveKey` command
#[derive(Debug)] // disallow derive Clone, Copy
Expand Down Expand Up @@ -49,4 +49,8 @@ pub(super) enum Command<V> {
key: String, // TODO should be &str except lifetimes...
resp: Responder<bool>,
},
Delete {
key: String,
resp: Responder<()>,
},
}
Loading