From eb895fbb3199cd81c887c3048ba2c2090f927ac6 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Tue, 25 Jul 2017 17:54:32 +0300 Subject: [PATCH] completed KeyStoreNodeKeyPair --- Cargo.lock | 1 + ethcore/src/account_provider/mod.rs | 7 +++++++ ethstore/Cargo.toml | 1 + ethstore/src/account/safe_account.rs | 9 ++++++++- ethstore/src/ethstore.rs | 12 ++++++++++++ ethstore/src/lib.rs | 1 + ethstore/src/secret_store.rs | 2 ++ secret_store/src/key_server.rs | 1 - secret_store/src/node_key_pair.rs | 5 +++-- 9 files changed, 35 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae33d7590..0c049c948 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -794,6 +794,7 @@ name = "ethstore" version = "0.1.0" dependencies = [ "ethcore-bigint 0.1.3", + "ethcore-util 1.8.0", "ethcrypto 0.1.0", "ethkey 0.2.0", "itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/src/account_provider/mod.rs b/ethcore/src/account_provider/mod.rs index 769db692c..752cec964 100755 --- a/ethcore/src/account_provider/mod.rs +++ b/ethcore/src/account_provider/mod.rs @@ -702,6 +702,13 @@ impl AccountProvider { Ok(self.sstore.decrypt(&account, &password, shared_mac, message)?) } + /// Agree on shared key. + pub fn agree(&self, address: Address, password: Option, other_public: &Public) -> Result { + let account = self.sstore.account_ref(&address)?; + let password = password.map(Ok).unwrap_or_else(|| self.password(&account))?; + Ok(self.sstore.agree(&account, &password, other_public)?) + } + /// Returns the underlying `SecretStore` reference if one exists. pub fn list_geth_accounts(&self, testnet: bool) -> Vec
{ self.sstore.list_geth_accounts(testnet).into_iter().map(|a| Address::from(a).into()).collect() diff --git a/ethstore/Cargo.toml b/ethstore/Cargo.toml index 117332022..9d8d2fce5 100755 --- a/ethstore/Cargo.toml +++ b/ethstore/Cargo.toml @@ -19,6 +19,7 @@ itertools = "0.5" parking_lot = "0.4" ethcrypto = { path = "../ethcrypto" } ethcore-bigint = { path = "../util/bigint" } +ethcore-util = { path = "../util" } smallvec = "0.4" parity-wordlist = "1.0" tempdir = "0.3" diff --git a/ethstore/src/account/safe_account.rs b/ethstore/src/account/safe_account.rs index e0512fe8d..478b796e6 100755 --- a/ethstore/src/account/safe_account.rs +++ b/ethstore/src/account/safe_account.rs @@ -14,7 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use ethkey::{KeyPair, sign, Address, Signature, Message, Public}; +use ethkey::{KeyPair, sign, Address, Signature, Message, Public, Secret}; +use crypto::ecdh::agree; use {json, Error, crypto}; use account::Version; use super::crypto::Crypto; @@ -135,6 +136,12 @@ impl SafeAccount { crypto::ecies::decrypt(&secret, shared_mac, message).map_err(From::from) } + /// Agree on shared key. + pub fn agree(&self, password: &str, other: &Public) -> Result { + let secret = self.crypto.secret(password)?; + agree(&secret, other).map_err(From::from) + } + /// Derive public key. pub fn public(&self, password: &str) -> Result { let secret = self.crypto.secret(password)?; diff --git a/ethstore/src/ethstore.rs b/ethstore/src/ethstore.rs index 246671990..d32fa9f62 100755 --- a/ethstore/src/ethstore.rs +++ b/ethstore/src/ethstore.rs @@ -97,6 +97,10 @@ impl SimpleSecretStore for EthStore { self.store.sign_derived(account_ref, password, derivation, message) } + fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result { + self.store.agree(account, password, other) + } + fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result, Error> { let account = self.get(account)?; account.decrypt(password, shared_mac, message) @@ -509,6 +513,14 @@ impl SimpleSecretStore for EthMultiStore { Err(Error::InvalidPassword) } + fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result { + let accounts = self.get_matching(account, password)?; + for account in accounts { + return account.agree(password, other); + } + Err(Error::InvalidPassword) + } + fn create_vault(&self, name: &str, password: &str) -> Result<(), Error> { let is_vault_created = { // lock border let mut vaults = self.vaults.lock(); diff --git a/ethstore/src/lib.rs b/ethstore/src/lib.rs index 65935f89c..311e9e73a 100755 --- a/ethstore/src/lib.rs +++ b/ethstore/src/lib.rs @@ -35,6 +35,7 @@ extern crate ethcore_bigint as bigint; extern crate ethcrypto as crypto; extern crate ethkey as _ethkey; extern crate parity_wordlist; +extern crate ethcore_util as util; #[macro_use] extern crate log; diff --git a/ethstore/src/secret_store.rs b/ethstore/src/secret_store.rs index 2deae023e..e364245b7 100755 --- a/ethstore/src/secret_store.rs +++ b/ethstore/src/secret_store.rs @@ -60,6 +60,8 @@ pub trait SimpleSecretStore: Send + Sync { fn sign_derived(&self, account_ref: &StoreAccountRef, password: &str, derivation: Derivation, message: &Message) -> Result; /// Decrypt a messages with given account. fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result, Error>; + /// Agree on shared key. + fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result; /// Returns all accounts in this secret store. fn accounts(&self) -> Result, Error>; diff --git a/secret_store/src/key_server.rs b/secret_store/src/key_server.rs index 0944dd37c..6526bff68 100644 --- a/secret_store/src/key_server.rs +++ b/secret_store/src/key_server.rs @@ -245,7 +245,6 @@ pub mod tests { let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect(); let configs: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration { threads: 1, -// self_key_pair: Arc::new(PlainNodeKeyPair::new(key_pairs[i].clone())), listener_address: NodeAddress { address: "127.0.0.1".into(), port: start_port + (i as u16), diff --git a/secret_store/src/node_key_pair.rs b/secret_store/src/node_key_pair.rs index 556625079..ce6c88a07 100644 --- a/secret_store/src/node_key_pair.rs +++ b/secret_store/src/node_key_pair.rs @@ -77,7 +77,8 @@ impl NodeKeyPair for KeyStoreNodeKeyPair { .map_err(|e| EthKeyError::Custom(format!("{}", e))) } - fn compute_shared_key(&self, _peer_public: &Public) -> Result { - unimplemented!() + fn compute_shared_key(&self, peer_public: &Public) -> Result { + KeyPair::from_secret(self.account_provider.agree(self.address.clone(), Some(self.password.clone()), peer_public) + .map_err(|e| EthKeyError::Custom(format!("{}", e)))?) } }