updated parity for NodeKeyPair

This commit is contained in:
Svyatoslav Nikolsky 2017-07-25 16:30:24 +03:00
parent 9e30d85fdc
commit 2e9df2c39d
5 changed files with 62 additions and 10 deletions

View File

@ -519,6 +519,11 @@ impl AccountProvider {
} }
} }
/// Returns account public key.
pub fn account_public(&self, address: Address, password: &str) -> Result<Public, Error> {
self.sstore.public(&self.sstore.account_ref(&address)?, password)
}
/// Returns each account along with name and meta. /// Returns each account along with name and meta.
pub fn set_account_name(&self, address: Address, name: String) -> Result<(), Error> { pub fn set_account_name(&self, address: Address, name: String) -> Result<(), Error> {
self.sstore.set_name(&self.sstore.account_ref(&address)?, name)?; self.sstore.set_name(&self.sstore.account_ref(&address)?, name)?;

View File

@ -997,8 +997,11 @@ impl Configuration {
fn secretstore_self_secret(&self) -> Result<Option<NodeSecretKey>, String> { fn secretstore_self_secret(&self) -> Result<Option<NodeSecretKey>, String> {
match self.args.flag_secretstore_secret { match self.args.flag_secretstore_secret {
Some(ref s) => Ok(Some(NodeSecretKey::Plain(s.parse() Some(ref s) if s.len() == 64 => Ok(Some(NodeSecretKey::Plain(s.parse()
.map_err(|e| format!("Invalid secret store secret: {}. Error: {:?}", s, e))?))), .map_err(|e| format!("Invalid secret store secret: {}. Error: {:?}", s, e))?))),
Some(ref s) if s.len() == 40 => Ok(Some(NodeSecretKey::KeyStore(s.parse()
.map_err(|e| format!("Invalid secret store secret address: {}. Error: {:?}", s, e))?))),
Some(_) => Err(format!("Invalid secret store secret. Must be either existing account address, or hex-encoded private key")),
None => Ok(None), None => Ok(None),
} }
} }

View File

@ -489,7 +489,7 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
} }
// Attempt to sign in the engine signer. // Attempt to sign in the engine signer.
if !passwords.into_iter().any(|p| miner.set_engine_signer(engine_signer, p).is_ok()) { if !passwords.iter().any(|p| miner.set_engine_signer(engine_signer, (*p).clone()).is_ok()) {
return Err(format!("No valid password for the consensus signer {}. {}", engine_signer, VERIFY_PASSWORD_HINT)); return Err(format!("No valid password for the consensus signer {}. {}", engine_signer, VERIFY_PASSWORD_HINT));
} }
} }
@ -705,6 +705,8 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R
// secret store key server // secret store key server
let secretstore_deps = secretstore::Dependencies { let secretstore_deps = secretstore::Dependencies {
client: client.clone(), client: client.clone(),
account_provider: account_provider,
accounts_passwords: &passwords,
}; };
let secretstore_key_server = secretstore::start(cmd.secretstore_conf.clone(), secretstore_deps)?; let secretstore_key_server = secretstore::start(cmd.secretstore_conf.clone(), secretstore_deps)?;

View File

@ -17,15 +17,19 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::sync::Arc; use std::sync::Arc;
use dir::default_data_path; use dir::default_data_path;
use ethcore::account_provider::AccountProvider;
use ethcore::client::Client; use ethcore::client::Client;
use ethkey::{Secret, Public}; use ethkey::{Secret, Public};
use helpers::replace_home; use helpers::replace_home;
use util::Address;
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
/// This node secret key. /// This node secret key.
pub enum NodeSecretKey { pub enum NodeSecretKey {
/// Stored as plain text in configuration file. /// Stored as plain text in configuration file.
Plain(Secret), Plain(Secret),
/// Stored as account in key store.
KeyStore(Address),
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
@ -50,9 +54,13 @@ pub struct Configuration {
} }
/// Secret store dependencies /// Secret store dependencies
pub struct Dependencies { pub struct Dependencies<'a> {
/// Blockchain client. /// Blockchain client.
pub client: Arc<Client>, pub client: Arc<Client>,
/// Account provider.
pub account_provider: Arc<AccountProvider>,
/// Passed accounts passwords.
pub accounts_passwords: &'a [String],
} }
#[cfg(not(feature = "secretstore"))] #[cfg(not(feature = "secretstore"))]
@ -73,7 +81,7 @@ mod server {
#[cfg(feature="secretstore")] #[cfg(feature="secretstore")]
mod server { mod server {
use std::sync::Arc; use std::sync::Arc;
use ethcore_secretstore::{self, NodeKeyPair}; use ethcore_secretstore;
use ethkey::KeyPair; use ethkey::KeyPair;
use super::{Configuration, Dependencies, NodeSecretKey}; use super::{Configuration, Dependencies, NodeSecretKey};
@ -85,9 +93,27 @@ mod server {
impl KeyServer { impl KeyServer {
/// Create new key server /// Create new key server
pub fn new(mut conf: Configuration, deps: Dependencies) -> Result<Self, String> { pub fn new(mut conf: Configuration, deps: Dependencies) -> Result<Self, String> {
let self_secret = match conf.self_secret.take() { let self_secret: Arc<ethcore_secretstore::NodeKeyPair> = match conf.self_secret.take() {
Some(NodeSecretKey::Plain(secret)) => Arc::new(ethcore_secretstore::PlainNodeKeyPair::new( Some(NodeSecretKey::Plain(secret)) => Arc::new(ethcore_secretstore::PlainNodeKeyPair::new(
KeyPair::from_secret(secret).map_err(|e| format!("invalid secret: {}", e))?)), KeyPair::from_secret(secret).map_err(|e| format!("invalid secret: {}", e))?)),
Some(NodeSecretKey::KeyStore(account)) => {
// Check if account exists
if !deps.account_provider.has_account(account.clone()).unwrap_or(false) {
return Err(format!("Account {} passed as secret store node key is not found", account));
}
// Check if any passwords have been read from the password file(s)
if deps.accounts_passwords.is_empty() {
return Err(format!("No password found for the secret store node account {}", account));
}
// Attempt to sign in the engine signer.
let password = deps.accounts_passwords.iter()
.find(|p| deps.account_provider.sign(account.clone(), Some((*p).clone()), Default::default()).is_ok())
.ok_or(format!("No valid password for the secret store node account {}", account))?;
Arc::new(ethcore_secretstore::KeyStoreNodeKeyPair::new(deps.account_provider, account, password.clone())
.map_err(|e| format!("{}", e))?)
},
None => return Err("self secret is required when using secretstore".into()), None => return Err("self secret is required when using secretstore".into()),
}; };

View File

@ -18,7 +18,7 @@ use std::sync::Arc;
use ethcrypto::ecdh::agree; use ethcrypto::ecdh::agree;
use ethkey::{KeyPair, Public, Signature, Error as EthKeyError, sign}; use ethkey::{KeyPair, Public, Signature, Error as EthKeyError, sign};
use ethcore::account_provider::AccountProvider; use ethcore::account_provider::AccountProvider;
use util::H256; use util::{Address, H256};
use traits::NodeKeyPair; use traits::NodeKeyPair;
pub struct PlainNodeKeyPair { pub struct PlainNodeKeyPair {
@ -26,7 +26,10 @@ pub struct PlainNodeKeyPair {
} }
pub struct KeyStoreNodeKeyPair { pub struct KeyStoreNodeKeyPair {
_account_provider: Arc<AccountProvider>, account_provider: Arc<AccountProvider>,
address: Address,
public: Public,
password: String,
} }
impl PlainNodeKeyPair { impl PlainNodeKeyPair {
@ -52,13 +55,26 @@ impl NodeKeyPair for PlainNodeKeyPair {
} }
} }
impl KeyStoreNodeKeyPair {
pub fn new(account_provider: Arc<AccountProvider>, address: Address, password: String) -> Result<Self, EthKeyError> {
let public = account_provider.account_public(address.clone(), &password).map_err(|e| EthKeyError::Custom(format!("{}", e)))?;
Ok(KeyStoreNodeKeyPair {
account_provider: account_provider,
address: address,
public: public,
password: password,
})
}
}
impl NodeKeyPair for KeyStoreNodeKeyPair { impl NodeKeyPair for KeyStoreNodeKeyPair {
fn public(&self) -> &Public { fn public(&self) -> &Public {
unimplemented!() &self.public
} }
fn sign(&self, _data: &H256) -> Result<Signature, EthKeyError> { fn sign(&self, data: &H256) -> Result<Signature, EthKeyError> {
unimplemented!() self.account_provider.sign(self.address.clone(), Some(self.password.clone()), data.clone())
.map_err(|e| EthKeyError::Custom(format!("{}", e)))
} }
fn compute_shared_key(&self, _peer_public: &Public) -> Result<KeyPair, EthKeyError> { fn compute_shared_key(&self, _peer_public: &Public) -> Result<KeyPair, EthKeyError> {