mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
[Floonet] Encrypt private slate data upon storage in DB (#2189)
* xor encrypt stored nonce and blind sum in transaction data * rustfmt * stop doc tests splatting wallet files throughout
This commit is contained in:
parent
a42250445d
commit
7812a9e892
2 changed files with 68 additions and 6 deletions
|
@ -99,6 +99,7 @@ where
|
|||
/// use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
|
||||
///
|
||||
/// let mut wallet_config = WalletConfig::default();
|
||||
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
|
||||
///
|
||||
/// // A NodeClient must first be created to handle communication between
|
||||
/// // the wallet and the node.
|
||||
|
@ -148,6 +149,7 @@ where
|
|||
/// # use wallet::libwallet::api::APIOwner;
|
||||
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
|
||||
/// # let mut wallet_config = WalletConfig::default();
|
||||
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
|
||||
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
|
||||
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
|
||||
/// # Arc::new(Mutex::new(
|
||||
|
@ -203,6 +205,7 @@ where
|
|||
/// # use wallet::libwallet::api::APIOwner;
|
||||
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
|
||||
/// # let mut wallet_config = WalletConfig::default();
|
||||
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
|
||||
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
|
||||
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
|
||||
/// # Arc::new(Mutex::new(
|
||||
|
@ -256,6 +259,7 @@ where
|
|||
/// # use wallet::libwallet::api::APIOwner;
|
||||
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
|
||||
/// # let mut wallet_config = WalletConfig::default();
|
||||
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
|
||||
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
|
||||
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
|
||||
/// # Arc::new(Mutex::new(
|
||||
|
@ -313,6 +317,7 @@ where
|
|||
/// # use wallet::libwallet::api::APIOwner;
|
||||
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
|
||||
/// # let mut wallet_config = WalletConfig::default();
|
||||
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
|
||||
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
|
||||
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
|
||||
/// # Arc::new(Mutex::new(
|
||||
|
@ -389,6 +394,7 @@ where
|
|||
/// # use wallet::libwallet::api::APIOwner;
|
||||
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
|
||||
/// # let mut wallet_config = WalletConfig::default();
|
||||
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
|
||||
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
|
||||
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
|
||||
/// # Arc::new(Mutex::new(
|
||||
|
@ -462,6 +468,7 @@ where
|
|||
/// # use wallet::libwallet::api::APIOwner;
|
||||
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
|
||||
/// # let mut wallet_config = WalletConfig::default();
|
||||
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
|
||||
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
|
||||
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
|
||||
/// # Arc::new(Mutex::new(
|
||||
|
@ -575,6 +582,7 @@ where
|
|||
/// # use wallet::libwallet::api::APIOwner;
|
||||
/// # use wallet::{LMDBBackend, HTTPNodeClient, WalletBackend, WalletConfig};
|
||||
/// # let mut wallet_config = WalletConfig::default();
|
||||
/// # wallet_config.data_file_dir = "test_output/doc/wallet1".to_owned();
|
||||
/// # let node_client = HTTPNodeClient::new(&wallet_config.check_node_api_http_addr, None);
|
||||
/// # let mut wallet:Arc<Mutex<WalletBackend<HTTPNodeClient, ExtKeychain>>> =
|
||||
/// # Arc::new(Mutex::new(
|
||||
|
|
|
@ -26,6 +26,8 @@ use serde_json;
|
|||
use failure::ResultExt;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::blake2::blake2b::Blake2b;
|
||||
|
||||
use crate::keychain::{ChildNumber, ExtKeychain, Identifier, Keychain};
|
||||
use crate::store::{self, option_to_not_found, to_key, to_key_u64};
|
||||
|
||||
|
@ -35,6 +37,7 @@ use crate::libwallet::types::*;
|
|||
use crate::libwallet::{internal, Error, ErrorKind};
|
||||
use crate::types::{WalletConfig, WalletSeed};
|
||||
use crate::util;
|
||||
use crate::util::secp::constants::SECRET_KEY_SIZE;
|
||||
use crate::util::secp::pedersen;
|
||||
|
||||
pub const DB_DIR: &'static str = "db";
|
||||
|
@ -62,6 +65,39 @@ pub fn wallet_db_exists(config: WalletConfig) -> bool {
|
|||
db_path.exists()
|
||||
}
|
||||
|
||||
/// Helper to derive XOR keys for storing private transaction keys in the DB
|
||||
/// (blind_xor_key, nonce_xor_key)
|
||||
fn private_ctx_xor_keys<K>(
|
||||
keychain: &K,
|
||||
slate_id: &[u8],
|
||||
) -> Result<([u8; SECRET_KEY_SIZE], [u8; SECRET_KEY_SIZE]), Error>
|
||||
where
|
||||
K: Keychain,
|
||||
{
|
||||
let root_key = keychain.derive_key(0, &K::root_key_id())?;
|
||||
|
||||
// derive XOR values for storing secret values in DB
|
||||
// h(root_key|slate_id|"blind")
|
||||
let mut hasher = Blake2b::new(SECRET_KEY_SIZE);
|
||||
hasher.update(&root_key.0[..]);
|
||||
hasher.update(&slate_id[..]);
|
||||
hasher.update(&"blind".as_bytes()[..]);
|
||||
let blind_xor_key = hasher.finalize();
|
||||
let mut ret_blind = [0; SECRET_KEY_SIZE];
|
||||
ret_blind.copy_from_slice(&blind_xor_key.as_bytes()[0..SECRET_KEY_SIZE]);
|
||||
|
||||
// h(root_key|slate_id|"nonce")
|
||||
let mut hasher = Blake2b::new(SECRET_KEY_SIZE);
|
||||
hasher.update(&root_key.0[..]);
|
||||
hasher.update(&slate_id[..]);
|
||||
hasher.update(&"nonce".as_bytes()[..]);
|
||||
let nonce_xor_key = hasher.finalize();
|
||||
let mut ret_nonce = [0; SECRET_KEY_SIZE];
|
||||
ret_nonce.copy_from_slice(&nonce_xor_key.as_bytes()[0..SECRET_KEY_SIZE]);
|
||||
|
||||
Ok((ret_blind, ret_nonce))
|
||||
}
|
||||
|
||||
pub struct LMDBBackend<C, K> {
|
||||
db: store::Store,
|
||||
config: WalletConfig,
|
||||
|
@ -232,11 +268,19 @@ where
|
|||
|
||||
fn get_private_context(&mut self, slate_id: &[u8]) -> Result<Context, Error> {
|
||||
let ctx_key = to_key(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec());
|
||||
option_to_not_found(
|
||||
let (blind_xor_key, nonce_xor_key) = private_ctx_xor_keys(self.keychain(), slate_id)?;
|
||||
|
||||
let mut ctx: Context = option_to_not_found(
|
||||
self.db.get_ser(&ctx_key),
|
||||
&format!("Slate id: {:x?}", slate_id.to_vec()),
|
||||
)
|
||||
.map_err(|e| e.into())
|
||||
)?;
|
||||
|
||||
for i in 0..SECRET_KEY_SIZE {
|
||||
ctx.sec_key.0[i] = ctx.sec_key.0[i] ^ blind_xor_key[i];
|
||||
ctx.sec_nonce.0[i] = ctx.sec_nonce.0[i] ^ nonce_xor_key[i];
|
||||
}
|
||||
|
||||
Ok(ctx)
|
||||
}
|
||||
|
||||
fn acct_path_iter<'a>(&'a self) -> Box<dyn Iterator<Item = AcctPathMapping> + 'a> {
|
||||
|
@ -501,11 +545,21 @@ where
|
|||
self.save(out.clone())
|
||||
}
|
||||
|
||||
//TODO: Keys stored unencrypted in DB.. not good
|
||||
// should store keys as derivation paths instead
|
||||
fn save_private_context(&mut self, slate_id: &[u8], ctx: &Context) -> Result<(), Error> {
|
||||
let ctx_key = to_key(PRIVATE_TX_CONTEXT_PREFIX, &mut slate_id.to_vec());
|
||||
self.db.borrow().as_ref().unwrap().put_ser(&ctx_key, &ctx)?;
|
||||
let (blind_xor_key, nonce_xor_key) = private_ctx_xor_keys(self.keychain(), slate_id)?;
|
||||
|
||||
let mut s_ctx = ctx.clone();
|
||||
for i in 0..SECRET_KEY_SIZE {
|
||||
s_ctx.sec_key.0[i] = s_ctx.sec_key.0[i] ^ blind_xor_key[i];
|
||||
s_ctx.sec_nonce.0[i] = s_ctx.sec_nonce.0[i] ^ nonce_xor_key[i];
|
||||
}
|
||||
|
||||
self.db
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.put_ser(&ctx_key, &s_ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue