Skip to content

Commit

Permalink
fix: add hidden types and seed words to key manager (#4925)
Browse files Browse the repository at this point in the history
Description
---
We refactor the `key_manager` crate so that hides sensitive data such as mnemonics, encryption and mac keys, etc.

Motivation and Context
---
Tackle issue #4861 and a portion of #4846.

Fixes #4861 

How Has This Been Tested?
---
Add unit tests for `SeedWords`. Also generated need wallet with visible seed words, to the user.
  • Loading branch information
jorgeantonio21 committed Nov 22, 2022
1 parent 4be02b6 commit 0bdb568
Show file tree
Hide file tree
Showing 14 changed files with 549 additions and 268 deletions.
133 changes: 71 additions & 62 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions applications/tari_console_wallet/Cargo.toml
Expand Up @@ -50,6 +50,7 @@ tonic = "0.6.2"
tracing = "0.1.26"
unicode-segmentation = "1.6.0"
unicode-width = "0.1"
zeroize = "1.3.0"

[dependencies.tari_core]
path = "../../base_layer/core"
Expand Down
4 changes: 2 additions & 2 deletions applications/tari_console_wallet/src/init/mod.rs
Expand Up @@ -401,7 +401,7 @@ pub async fn init_wallet(
}
if let Some(file_name) = seed_words_file_name {
let seed_words = wallet.get_seed_words(&MnemonicLanguage::English)?.join(" ");
let _result = fs::write(file_name, seed_words).map_err(|e| {
let _result = fs::write(file_name, seed_words.reveal()).map_err(|e| {
ExitError::new(
ExitCode::WalletError,
&format!("Problem writing seed words to file: {}", e),
Expand Down Expand Up @@ -549,7 +549,7 @@ fn confirm_seed_words(wallet: &mut WalletSqlite) -> Result<(), ExitError> {
println!("WRITE THEM DOWN OR COPY THEM NOW. THIS IS YOUR ONLY CHANCE TO DO SO.");
println!();
println!("=========================");
println!("{}", seed_words.join(" "));
println!("{}", seed_words.join(" ").reveal());
println!("=========================");
println!("\x07"); // beep!

Expand Down
19 changes: 11 additions & 8 deletions applications/tari_console_wallet/src/lib.rs
Expand Up @@ -48,7 +48,8 @@ use tari_common::{
configuration::bootstrap::ApplicationType,
exit_codes::{ExitCode, ExitError},
};
use tari_key_manager::cipher_seed::CipherSeed;
use tari_crypto::tari_utilities::Hidden;
use tari_key_manager::{cipher_seed::CipherSeed, SeedWords};
#[cfg(all(unix, feature = "libtor"))]
use tari_libtor::tor::Tor;
use tari_shutdown::Shutdown;
Expand Down Expand Up @@ -213,13 +214,15 @@ fn get_password(config: &ApplicationConfig, cli: &Cli) -> Option<SafePassword> {
fn get_recovery_seed(boot_mode: WalletBoot, cli: &Cli) -> Result<Option<CipherSeed>, ExitError> {
if matches!(boot_mode, WalletBoot::Recovery) {
let seed = if cli.seed_words.is_some() {
let seed_words: Vec<String> = cli
.seed_words
.clone()
.unwrap()
.split_whitespace()
.map(|v| v.to_string())
.collect();
// need to zeroize first, to clean up memory of cli.seed_words clone
let seed_words: SeedWords = SeedWords::new(
cli.seed_words
.as_ref()
.unwrap()
.split_whitespace()
.map(|s| Hidden::hide(s.to_string()))
.collect(),
);
get_seed_from_seed_words(seed_words)?
} else {
prompt_private_key_from_seed_words()?
Expand Down
11 changes: 7 additions & 4 deletions applications/tari_console_wallet/src/recovery.rs
Expand Up @@ -27,7 +27,8 @@ use futures::FutureExt;
use log::*;
use rustyline::Editor;
use tari_common::exit_codes::{ExitCode, ExitError};
use tari_key_manager::{cipher_seed::CipherSeed, mnemonic::Mnemonic};
use tari_crypto::tari_utilities::Hidden;
use tari_key_manager::{cipher_seed::CipherSeed, mnemonic::Mnemonic, SeedWords};
use tari_shutdown::Shutdown;
use tari_utilities::hex::Hex;
use tari_wallet::{
Expand All @@ -37,6 +38,7 @@ use tari_wallet::{
WalletSqlite,
};
use tokio::sync::broadcast;
use zeroize::Zeroizing;

use crate::wallet_modes::PeerConfig;

Expand All @@ -51,8 +53,9 @@ pub fn prompt_private_key_from_seed_words() -> Result<CipherSeed, ExitError> {
println!("Recovery Mode");
println!();
println!("Type or paste all of your seed words on one line, only separated by spaces.");
let input = rl.readline(">> ").map_err(|e| ExitError::new(ExitCode::IOError, e))?;
let seed_words: Vec<String> = input.split_whitespace().map(str::to_string).collect();
let input = Zeroizing::new(rl.readline(">> ").map_err(|e| ExitError::new(ExitCode::IOError, e))?);
let seed_words: SeedWords =
SeedWords::new(input.split_whitespace().map(|s| Hidden::hide(s.to_string())).collect());

match CipherSeed::from_mnemonic(&seed_words, None) {
Ok(seed) => break Ok(seed),
Expand All @@ -66,7 +69,7 @@ pub fn prompt_private_key_from_seed_words() -> Result<CipherSeed, ExitError> {
}

/// Return seed matching the seed words.
pub fn get_seed_from_seed_words(seed_words: Vec<String>) -> Result<CipherSeed, ExitError> {
pub fn get_seed_from_seed_words(seed_words: SeedWords) -> Result<CipherSeed, ExitError> {
debug!(target: LOG_TARGET, "Return seed derived from the provided seed words");
match CipherSeed::from_mnemonic(&seed_words, None) {
Ok(seed) => Ok(seed),
Expand Down

0 comments on commit 0bdb568

Please sign in to comment.