From 80f7ae678aab4a2c61fc638eb7cc5b9c96f4ffbf Mon Sep 17 00:00:00 2001 From: hashmap Date: Fri, 28 Dec 2018 23:12:59 +0100 Subject: [PATCH] Implement zeroing memory for wallet password (#2229) Testing ergonomics, if this approach is acceptable I'll implement it for other sensitive parts. --- Cargo.lock | 7 +++++++ util/Cargo.toml | 1 + util/src/lib.rs | 2 +- util/src/types.rs | 24 ++++++++++++++++++++++++ wallet/src/lmdb_wallet.rs | 5 +++-- 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c942ff751..d1af5f825 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -926,6 +926,7 @@ dependencies = [ "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "zip 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2871,6 +2872,11 @@ dependencies = [ "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "zeroize" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "zip" version = "0.4.2" @@ -3178,4 +3184,5 @@ dependencies = [ "checksum xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12ea8eda4b1eb72f02d148402e23832d56a33f55d8c1b2d5bcdde91d79d47cb1" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" "checksum yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95acf0db5515d07da9965ec0e0ba6cc2d825e2caeb7303b66ca441729801254e" +"checksum zeroize 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f36215ad2c05d1444c2807b7284667080f34e05660c335b20d3e2524f7b1dbde" "checksum zip 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "36b9e08fb518a65cf7e08a1e482573eb87a2f4f8c6619316612a3c1f162fe822" diff --git a/util/Cargo.toml b/util/Cargo.toml index 03a6b5851..1d45e6782 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -22,6 +22,7 @@ log = "0.4" walkdir = "2" zip = { version = "0.4", default-features = false } parking_lot = {version = "0.6"} +zeroize = "0.5.1" [dependencies.grin_secp256k1zkp] git = "https://github.com/mimblewimble/rust-secp256k1-zkp" diff --git a/util/src/lib.rs b/util/src/lib.rs index ba5ed0e0d..08b7cf98d 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -43,7 +43,7 @@ pub mod secp_static; pub use crate::secp_static::static_secp_instance; pub mod types; -pub use crate::types::{LogLevel, LoggingConfig}; +pub use crate::types::{LogLevel, LoggingConfig, ZeroingString}; pub mod macros; diff --git a/util/src/types.rs b/util/src/types.rs index 477fbc034..b0f78cef2 100644 --- a/util/src/types.rs +++ b/util/src/types.rs @@ -64,3 +64,27 @@ impl Default for LoggingConfig { } } } + +use std::ops::Deref; +use zeroize::Zeroize; +pub struct ZeroingString(String); + +impl Drop for ZeroingString { + fn drop(&mut self) { + self.0.zeroize(); + } +} + +impl From<&str> for ZeroingString { + fn from(s: &str) -> Self { + ZeroingString(String::from(s)) + } +} + +impl Deref for ZeroingString { + type Target = str; + + fn deref(&self) -> &str { + &self.0 + } +} diff --git a/wallet/src/lmdb_wallet.rs b/wallet/src/lmdb_wallet.rs index 564bb4dd8..dbc34ae92 100644 --- a/wallet/src/lmdb_wallet.rs +++ b/wallet/src/lmdb_wallet.rs @@ -39,6 +39,7 @@ use crate::types::{WalletConfig, WalletSeed}; use crate::util; use crate::util::secp::constants::SECRET_KEY_SIZE; use crate::util::secp::pedersen; +use crate::util::ZeroingString; pub const DB_DIR: &'static str = "db"; pub const TX_SAVE_DIR: &'static str = "saved_txs"; @@ -102,7 +103,7 @@ pub struct LMDBBackend { db: store::Store, config: WalletConfig, /// passphrase: TODO better ways of dealing with this other than storing - passphrase: String, + passphrase: ZeroingString, /// Keychain pub keychain: Option, /// Parent path to use by default for output operations @@ -144,7 +145,7 @@ impl LMDBBackend { let res = LMDBBackend { db: store, config: config.clone(), - passphrase: String::from(passphrase), + passphrase: ZeroingString::from(passphrase), keychain: None, parent_key_id: LMDBBackend::::default_path(), w2n_client: n_client,