SecretStore: encrypt messages using private key from key store (#6146)
* do not cache ACL storage contract * when error comes before initialization * initial KeyServerSet commit * update_nodes_set in maintain * do not connect to self * fixed connection establishing * removed println * improved KeyServerSet tracing * moved parsing to KeyServerSet * re-read only when blockchain is changed * do not try to connect if not a part of cluster * improved logging * fixed tests * NodeKeyPAir trait * fixed parity to use new trait * continue integrating with parity * updated parity for NodeKeyPair * completed KeyStoreNodeKeyPair * removed comment * removed dependency && style
This commit is contained in:
		
							parent
							
								
									d209100a60
								
							
						
					
					
						commit
						33ba5b63f3
					
				@ -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)?;
 | 
				
			||||||
@ -697,6 +702,13 @@ impl AccountProvider {
 | 
				
			|||||||
		Ok(self.sstore.decrypt(&account, &password, shared_mac, message)?)
 | 
							Ok(self.sstore.decrypt(&account, &password, shared_mac, message)?)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Agree on shared key.
 | 
				
			||||||
 | 
						pub fn agree(&self, address: Address, password: Option<String>, other_public: &Public) -> Result<Secret, SignError> {
 | 
				
			||||||
 | 
							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.
 | 
						/// Returns the underlying `SecretStore` reference if one exists.
 | 
				
			||||||
	pub fn list_geth_accounts(&self, testnet: bool) -> Vec<Address> {
 | 
						pub fn list_geth_accounts(&self, testnet: bool) -> Vec<Address> {
 | 
				
			||||||
		self.sstore.list_geth_accounts(testnet).into_iter().map(|a| Address::from(a).into()).collect()
 | 
							self.sstore.list_geth_accounts(testnet).into_iter().map(|a| Address::from(a).into()).collect()
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,8 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 {json, Error, crypto};
 | 
				
			||||||
use account::Version;
 | 
					use account::Version;
 | 
				
			||||||
use super::crypto::Crypto;
 | 
					use super::crypto::Crypto;
 | 
				
			||||||
@ -135,6 +136,12 @@ impl SafeAccount {
 | 
				
			|||||||
		crypto::ecies::decrypt(&secret, shared_mac, message).map_err(From::from)
 | 
							crypto::ecies::decrypt(&secret, shared_mac, message).map_err(From::from)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Agree on shared key.
 | 
				
			||||||
 | 
						pub fn agree(&self, password: &str, other: &Public) -> Result<Secret, Error> {
 | 
				
			||||||
 | 
							let secret = self.crypto.secret(password)?;
 | 
				
			||||||
 | 
							agree(&secret, other).map_err(From::from)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Derive public key.
 | 
						/// Derive public key.
 | 
				
			||||||
	pub fn public(&self, password: &str) -> Result<Public, Error> {
 | 
						pub fn public(&self, password: &str) -> Result<Public, Error> {
 | 
				
			||||||
		let secret = self.crypto.secret(password)?;
 | 
							let secret = self.crypto.secret(password)?;
 | 
				
			||||||
 | 
				
			|||||||
@ -97,6 +97,10 @@ impl SimpleSecretStore for EthStore {
 | 
				
			|||||||
		self.store.sign_derived(account_ref, password, derivation, message)
 | 
							self.store.sign_derived(account_ref, password, derivation, message)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result<Secret, Error> {
 | 
				
			||||||
 | 
							self.store.agree(account, password, other)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
 | 
						fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
 | 
				
			||||||
		let account = self.get(account)?;
 | 
							let account = self.get(account)?;
 | 
				
			||||||
		account.decrypt(password, shared_mac, message)
 | 
							account.decrypt(password, shared_mac, message)
 | 
				
			||||||
@ -495,18 +499,26 @@ impl SimpleSecretStore for EthMultiStore {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	fn sign(&self, account: &StoreAccountRef, password: &str, message: &Message) -> Result<Signature, Error> {
 | 
						fn sign(&self, account: &StoreAccountRef, password: &str, message: &Message) -> Result<Signature, Error> {
 | 
				
			||||||
		let accounts = self.get_matching(account, password)?;
 | 
							let accounts = self.get_matching(account, password)?;
 | 
				
			||||||
		for account in accounts {
 | 
							match accounts.first() {
 | 
				
			||||||
			return account.sign(password, message);
 | 
								Some(ref account) => account.sign(password, message),
 | 
				
			||||||
 | 
								None => Err(Error::InvalidPassword),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Err(Error::InvalidPassword)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
 | 
						fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
 | 
				
			||||||
		let accounts = self.get_matching(account, password)?;
 | 
							let accounts = self.get_matching(account, password)?;
 | 
				
			||||||
		for account in accounts {
 | 
							match accounts.first() {
 | 
				
			||||||
			return account.decrypt(password, shared_mac, message);
 | 
								Some(ref account) => account.decrypt(password, shared_mac, message),
 | 
				
			||||||
 | 
								None => Err(Error::InvalidPassword),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result<Secret, Error> {
 | 
				
			||||||
 | 
							let accounts = self.get_matching(account, password)?;
 | 
				
			||||||
 | 
							match accounts.first() {
 | 
				
			||||||
 | 
								Some(ref account) => account.agree(password, other),
 | 
				
			||||||
 | 
								None => Err(Error::InvalidPassword),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Err(Error::InvalidPassword)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn create_vault(&self, name: &str, password: &str) -> Result<(), Error> {
 | 
						fn create_vault(&self, name: &str, password: &str) -> Result<(), Error> {
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,8 @@ pub trait SimpleSecretStore: Send + Sync {
 | 
				
			|||||||
	fn sign_derived(&self, account_ref: &StoreAccountRef, password: &str, derivation: Derivation, message: &Message) -> Result<Signature, Error>;
 | 
						fn sign_derived(&self, account_ref: &StoreAccountRef, password: &str, derivation: Derivation, message: &Message) -> Result<Signature, Error>;
 | 
				
			||||||
	/// Decrypt a messages with given account.
 | 
						/// Decrypt a messages with given account.
 | 
				
			||||||
	fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error>;
 | 
						fn decrypt(&self, account: &StoreAccountRef, password: &str, shared_mac: &[u8], message: &[u8]) -> Result<Vec<u8>, Error>;
 | 
				
			||||||
 | 
						/// Agree on shared key.
 | 
				
			||||||
 | 
						fn agree(&self, account: &StoreAccountRef, password: &str, other: &Public) -> Result<Secret, Error>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Returns all accounts in this secret store.
 | 
						/// Returns all accounts in this secret store.
 | 
				
			||||||
	fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error>;
 | 
						fn accounts(&self) -> Result<Vec<StoreAccountRef>, Error>;
 | 
				
			||||||
 | 
				
			|||||||
@ -41,7 +41,7 @@ use ethcore_logger::Config as LogConfig;
 | 
				
			|||||||
use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path};
 | 
					use dir::{self, Directories, default_hypervisor_path, default_local_path, default_data_path};
 | 
				
			||||||
use dapps::Configuration as DappsConfiguration;
 | 
					use dapps::Configuration as DappsConfiguration;
 | 
				
			||||||
use ipfs::Configuration as IpfsConfiguration;
 | 
					use ipfs::Configuration as IpfsConfiguration;
 | 
				
			||||||
use secretstore::Configuration as SecretStoreConfiguration;
 | 
					use secretstore::{Configuration as SecretStoreConfiguration, NodeSecretKey};
 | 
				
			||||||
use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack};
 | 
					use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack};
 | 
				
			||||||
use run::RunCmd;
 | 
					use run::RunCmd;
 | 
				
			||||||
use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, DataFormat};
 | 
					use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, DataFormat};
 | 
				
			||||||
@ -993,10 +993,13 @@ impl Configuration {
 | 
				
			|||||||
		self.interface(&self.args.flag_secretstore_http_interface)
 | 
							self.interface(&self.args.flag_secretstore_http_interface)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn secretstore_self_secret(&self) -> Result<Option<Secret>, 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(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),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -507,7 +507,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));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -734,6 +734,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)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -17,9 +17,20 @@
 | 
				
			|||||||
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)]
 | 
				
			||||||
 | 
					/// This node secret key.
 | 
				
			||||||
 | 
					pub enum NodeSecretKey {
 | 
				
			||||||
 | 
						/// Stored as plain text in configuration file.
 | 
				
			||||||
 | 
						Plain(Secret),
 | 
				
			||||||
 | 
						/// Stored as account in key store.
 | 
				
			||||||
 | 
						KeyStore(Address),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, PartialEq, Clone)]
 | 
					#[derive(Debug, PartialEq, Clone)]
 | 
				
			||||||
/// Secret store configuration
 | 
					/// Secret store configuration
 | 
				
			||||||
@ -27,7 +38,7 @@ pub struct Configuration {
 | 
				
			|||||||
	/// Is secret store functionality enabled?
 | 
						/// Is secret store functionality enabled?
 | 
				
			||||||
	pub enabled: bool,
 | 
						pub enabled: bool,
 | 
				
			||||||
	/// This node secret.
 | 
						/// This node secret.
 | 
				
			||||||
	pub self_secret: Option<Secret>,
 | 
						pub self_secret: Option<NodeSecretKey>,
 | 
				
			||||||
	/// Other nodes IDs + addresses.
 | 
						/// Other nodes IDs + addresses.
 | 
				
			||||||
	pub nodes: BTreeMap<Public, (String, u16)>,
 | 
						pub nodes: BTreeMap<Public, (String, u16)>,
 | 
				
			||||||
	/// Interface to listen to
 | 
						/// Interface to listen to
 | 
				
			||||||
@ -43,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"))]
 | 
				
			||||||
@ -65,9 +80,10 @@ mod server {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[cfg(feature="secretstore")]
 | 
					#[cfg(feature="secretstore")]
 | 
				
			||||||
mod server {
 | 
					mod server {
 | 
				
			||||||
 | 
						use std::sync::Arc;
 | 
				
			||||||
	use ethcore_secretstore;
 | 
						use ethcore_secretstore;
 | 
				
			||||||
	use ethkey::KeyPair;
 | 
						use ethkey::KeyPair;
 | 
				
			||||||
	use super::{Configuration, Dependencies};
 | 
						use super::{Configuration, Dependencies, NodeSecretKey};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Key server
 | 
						/// Key server
 | 
				
			||||||
	pub struct KeyServer {
 | 
						pub struct KeyServer {
 | 
				
			||||||
@ -76,8 +92,31 @@ mod server {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	impl KeyServer {
 | 
						impl KeyServer {
 | 
				
			||||||
		/// Create new key server
 | 
							/// Create new key server
 | 
				
			||||||
		pub fn new(conf: Configuration, deps: Dependencies) -> Result<Self, String> {
 | 
							pub fn new(mut conf: Configuration, deps: Dependencies) -> Result<Self, String> {
 | 
				
			||||||
			let self_secret = conf.self_secret.ok_or("self secret is required when using secretstore")?;
 | 
								let self_secret: Arc<ethcore_secretstore::NodeKeyPair> = match conf.self_secret.take() {
 | 
				
			||||||
 | 
									Some(NodeSecretKey::Plain(secret)) => Arc::new(ethcore_secretstore::PlainNodeKeyPair::new(
 | 
				
			||||||
 | 
										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()),
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			let mut conf = ethcore_secretstore::ServiceConfiguration {
 | 
								let mut conf = ethcore_secretstore::ServiceConfiguration {
 | 
				
			||||||
				listener_address: ethcore_secretstore::NodeAddress {
 | 
									listener_address: ethcore_secretstore::NodeAddress {
 | 
				
			||||||
					address: conf.http_interface.clone(),
 | 
										address: conf.http_interface.clone(),
 | 
				
			||||||
@ -86,7 +125,6 @@ mod server {
 | 
				
			|||||||
				data_path: conf.data_path.clone(),
 | 
									data_path: conf.data_path.clone(),
 | 
				
			||||||
				cluster_config: ethcore_secretstore::ClusterConfiguration {
 | 
									cluster_config: ethcore_secretstore::ClusterConfiguration {
 | 
				
			||||||
					threads: 4,
 | 
										threads: 4,
 | 
				
			||||||
					self_private: (**self_secret).into(),
 | 
					 | 
				
			||||||
					listener_address: ethcore_secretstore::NodeAddress {
 | 
										listener_address: ethcore_secretstore::NodeAddress {
 | 
				
			||||||
						address: conf.interface.clone(),
 | 
											address: conf.interface.clone(),
 | 
				
			||||||
						port: conf.port,
 | 
											port: conf.port,
 | 
				
			||||||
@ -99,11 +137,9 @@ mod server {
 | 
				
			|||||||
				},
 | 
									},
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			let self_key_pair = KeyPair::from_secret(self_secret.clone())
 | 
								conf.cluster_config.nodes.insert(self_secret.public().clone(), conf.cluster_config.listener_address.clone());
 | 
				
			||||||
				.map_err(|e| format!("valid secret is required when using secretstore. Error: {}", e))?;
 | 
					 | 
				
			||||||
			conf.cluster_config.nodes.insert(self_key_pair.public().clone(), conf.cluster_config.listener_address.clone());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			let key_server = ethcore_secretstore::start(deps.client, conf)
 | 
								let key_server = ethcore_secretstore::start(deps.client, self_secret, conf)
 | 
				
			||||||
				.map_err(Into::<String>::into)?;
 | 
									.map_err(Into::<String>::into)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Ok(KeyServer {
 | 
								Ok(KeyServer {
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,7 @@ use super::acl_storage::AclStorage;
 | 
				
			|||||||
use super::key_storage::KeyStorage;
 | 
					use super::key_storage::KeyStorage;
 | 
				
			||||||
use super::key_server_set::KeyServerSet;
 | 
					use super::key_server_set::KeyServerSet;
 | 
				
			||||||
use key_server_cluster::{math, ClusterCore};
 | 
					use key_server_cluster::{math, ClusterCore};
 | 
				
			||||||
use traits::{ServerKeyGenerator, DocumentKeyServer, MessageSigner, KeyServer};
 | 
					use traits::{ServerKeyGenerator, DocumentKeyServer, MessageSigner, KeyServer, NodeKeyPair};
 | 
				
			||||||
use types::all::{Error, Public, RequestSignature, ServerKeyId, EncryptedDocumentKey, EncryptedDocumentKeyShadow,
 | 
					use types::all::{Error, Public, RequestSignature, ServerKeyId, EncryptedDocumentKey, EncryptedDocumentKeyShadow,
 | 
				
			||||||
	ClusterConfiguration, MessageHash, EncryptedMessageSignature};
 | 
						ClusterConfiguration, MessageHash, EncryptedMessageSignature};
 | 
				
			||||||
use key_server_cluster::{ClusterClient, ClusterConfiguration as NetClusterConfiguration};
 | 
					use key_server_cluster::{ClusterClient, ClusterConfiguration as NetClusterConfiguration};
 | 
				
			||||||
@ -45,9 +45,9 @@ pub struct KeyServerCore {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl KeyServerImpl {
 | 
					impl KeyServerImpl {
 | 
				
			||||||
	/// Create new key server instance
 | 
						/// Create new key server instance
 | 
				
			||||||
	pub fn new(config: &ClusterConfiguration, key_server_set: Arc<KeyServerSet>, acl_storage: Arc<AclStorage>, key_storage: Arc<KeyStorage>) -> Result<Self, Error> {
 | 
						pub fn new(config: &ClusterConfiguration, key_server_set: Arc<KeyServerSet>, self_key_pair: Arc<NodeKeyPair>, acl_storage: Arc<AclStorage>, key_storage: Arc<KeyStorage>) -> Result<Self, Error> {
 | 
				
			||||||
		Ok(KeyServerImpl {
 | 
							Ok(KeyServerImpl {
 | 
				
			||||||
			data: Arc::new(Mutex::new(KeyServerCore::new(config, key_server_set, acl_storage, key_storage)?)),
 | 
								data: Arc::new(Mutex::new(KeyServerCore::new(config, key_server_set, self_key_pair, acl_storage, key_storage)?)),
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -144,10 +144,10 @@ impl MessageSigner for KeyServerImpl {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl KeyServerCore {
 | 
					impl KeyServerCore {
 | 
				
			||||||
	pub fn new(config: &ClusterConfiguration, key_server_set: Arc<KeyServerSet>, acl_storage: Arc<AclStorage>, key_storage: Arc<KeyStorage>) -> Result<Self, Error> {
 | 
						pub fn new(config: &ClusterConfiguration, key_server_set: Arc<KeyServerSet>, self_key_pair: Arc<NodeKeyPair>, acl_storage: Arc<AclStorage>, key_storage: Arc<KeyStorage>) -> Result<Self, Error> {
 | 
				
			||||||
		let config = NetClusterConfiguration {
 | 
							let config = NetClusterConfiguration {
 | 
				
			||||||
			threads: config.threads,
 | 
								threads: config.threads,
 | 
				
			||||||
			self_key_pair: ethkey::KeyPair::from_secret_slice(&config.self_private)?,
 | 
								self_key_pair: self_key_pair,
 | 
				
			||||||
			listen_address: (config.listener_address.address.clone(), config.listener_address.port),
 | 
								listen_address: (config.listener_address.address.clone(), config.listener_address.port),
 | 
				
			||||||
			key_server_set: key_server_set,
 | 
								key_server_set: key_server_set,
 | 
				
			||||||
			allow_connecting_to_higher_nodes: config.allow_connecting_to_higher_nodes,
 | 
								allow_connecting_to_higher_nodes: config.allow_connecting_to_higher_nodes,
 | 
				
			||||||
@ -198,6 +198,7 @@ pub mod tests {
 | 
				
			|||||||
	use ethkey::{self, Secret, Random, Generator};
 | 
						use ethkey::{self, Secret, Random, Generator};
 | 
				
			||||||
	use acl_storage::tests::DummyAclStorage;
 | 
						use acl_storage::tests::DummyAclStorage;
 | 
				
			||||||
	use key_storage::tests::DummyKeyStorage;
 | 
						use key_storage::tests::DummyKeyStorage;
 | 
				
			||||||
 | 
						use node_key_pair::PlainNodeKeyPair;
 | 
				
			||||||
	use key_server_set::tests::MapKeyServerSet;
 | 
						use key_server_set::tests::MapKeyServerSet;
 | 
				
			||||||
	use key_server_cluster::math;
 | 
						use key_server_cluster::math;
 | 
				
			||||||
	use util::H256;
 | 
						use util::H256;
 | 
				
			||||||
@ -244,7 +245,6 @@ pub mod tests {
 | 
				
			|||||||
		let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect();
 | 
							let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect();
 | 
				
			||||||
		let configs: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration {
 | 
							let configs: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration {
 | 
				
			||||||
				threads: 1,
 | 
									threads: 1,
 | 
				
			||||||
				self_private: (***key_pairs[i].secret()).into(),
 | 
					 | 
				
			||||||
				listener_address: NodeAddress {
 | 
									listener_address: NodeAddress {
 | 
				
			||||||
					address: "127.0.0.1".into(),
 | 
										address: "127.0.0.1".into(),
 | 
				
			||||||
					port: start_port + (i as u16),
 | 
										port: start_port + (i as u16),
 | 
				
			||||||
@ -259,8 +259,11 @@ pub mod tests {
 | 
				
			|||||||
		let key_servers_set: BTreeMap<Public, SocketAddr> = configs[0].nodes.iter()
 | 
							let key_servers_set: BTreeMap<Public, SocketAddr> = configs[0].nodes.iter()
 | 
				
			||||||
			.map(|(k, a)| (k.clone(), format!("{}:{}", a.address, a.port).parse().unwrap()))
 | 
								.map(|(k, a)| (k.clone(), format!("{}:{}", a.address, a.port).parse().unwrap()))
 | 
				
			||||||
			.collect();
 | 
								.collect();
 | 
				
			||||||
		let key_servers: Vec<_> = configs.into_iter().map(|cfg|
 | 
							let key_servers: Vec<_> = configs.into_iter().enumerate().map(|(i, cfg)|
 | 
				
			||||||
			KeyServerImpl::new(&cfg, Arc::new(MapKeyServerSet::new(key_servers_set.clone())), Arc::new(DummyAclStorage::default()), Arc::new(DummyKeyStorage::default())).unwrap()
 | 
								KeyServerImpl::new(&cfg, Arc::new(MapKeyServerSet::new(key_servers_set.clone())),
 | 
				
			||||||
 | 
									Arc::new(PlainNodeKeyPair::new(key_pairs[i].clone())),
 | 
				
			||||||
 | 
									Arc::new(DummyAclStorage::default()),
 | 
				
			||||||
 | 
									Arc::new(DummyKeyStorage::default())).unwrap()
 | 
				
			||||||
		).collect();
 | 
							).collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// wait until connections are established. It is fast => do not bother with events here
 | 
							// wait until connections are established. It is fast => do not bother with events here
 | 
				
			||||||
 | 
				
			|||||||
@ -28,7 +28,7 @@ use tokio_core::reactor::{Handle, Remote, Interval};
 | 
				
			|||||||
use tokio_core::net::{TcpListener, TcpStream};
 | 
					use tokio_core::net::{TcpListener, TcpStream};
 | 
				
			||||||
use ethkey::{Public, KeyPair, Signature, Random, Generator};
 | 
					use ethkey::{Public, KeyPair, Signature, Random, Generator};
 | 
				
			||||||
use util::H256;
 | 
					use util::H256;
 | 
				
			||||||
use key_server_cluster::{Error, NodeId, SessionId, AclStorage, KeyStorage, KeyServerSet};
 | 
					use key_server_cluster::{Error, NodeId, SessionId, AclStorage, KeyStorage, KeyServerSet, NodeKeyPair};
 | 
				
			||||||
use key_server_cluster::cluster_sessions::{ClusterSession, ClusterSessions, GenerationSessionWrapper, EncryptionSessionWrapper,
 | 
					use key_server_cluster::cluster_sessions::{ClusterSession, ClusterSessions, GenerationSessionWrapper, EncryptionSessionWrapper,
 | 
				
			||||||
	DecryptionSessionWrapper, SigningSessionWrapper};
 | 
						DecryptionSessionWrapper, SigningSessionWrapper};
 | 
				
			||||||
use key_server_cluster::message::{self, Message, ClusterMessage, GenerationMessage, EncryptionMessage, DecryptionMessage,
 | 
					use key_server_cluster::message::{self, Message, ClusterMessage, GenerationMessage, EncryptionMessage, DecryptionMessage,
 | 
				
			||||||
@ -99,7 +99,7 @@ pub struct ClusterConfiguration {
 | 
				
			|||||||
	/// Allow connecting to 'higher' nodes.
 | 
						/// Allow connecting to 'higher' nodes.
 | 
				
			||||||
	pub allow_connecting_to_higher_nodes: bool,
 | 
						pub allow_connecting_to_higher_nodes: bool,
 | 
				
			||||||
	/// KeyPair this node holds.
 | 
						/// KeyPair this node holds.
 | 
				
			||||||
	pub self_key_pair: KeyPair,
 | 
						pub self_key_pair: Arc<NodeKeyPair>,
 | 
				
			||||||
	/// Interface to listen to.
 | 
						/// Interface to listen to.
 | 
				
			||||||
	pub listen_address: (String, u16),
 | 
						pub listen_address: (String, u16),
 | 
				
			||||||
	/// Cluster nodes set.
 | 
						/// Cluster nodes set.
 | 
				
			||||||
@ -146,7 +146,7 @@ pub struct ClusterData {
 | 
				
			|||||||
	/// Handle to the cpu thread pool.
 | 
						/// Handle to the cpu thread pool.
 | 
				
			||||||
	pool: CpuPool,
 | 
						pool: CpuPool,
 | 
				
			||||||
	/// KeyPair this node holds.
 | 
						/// KeyPair this node holds.
 | 
				
			||||||
	self_key_pair: KeyPair,
 | 
						self_key_pair: Arc<NodeKeyPair>,
 | 
				
			||||||
	/// Connections data.
 | 
						/// Connections data.
 | 
				
			||||||
	connections: ClusterConnections,
 | 
						connections: ClusterConnections,
 | 
				
			||||||
	/// Active sessions data.
 | 
						/// Active sessions data.
 | 
				
			||||||
@ -989,7 +989,7 @@ pub mod tests {
 | 
				
			|||||||
	use parking_lot::Mutex;
 | 
						use parking_lot::Mutex;
 | 
				
			||||||
	use tokio_core::reactor::Core;
 | 
						use tokio_core::reactor::Core;
 | 
				
			||||||
	use ethkey::{Random, Generator, Public};
 | 
						use ethkey::{Random, Generator, Public};
 | 
				
			||||||
	use key_server_cluster::{NodeId, SessionId, Error, DummyAclStorage, DummyKeyStorage, MapKeyServerSet};
 | 
						use key_server_cluster::{NodeId, SessionId, Error, DummyAclStorage, DummyKeyStorage, MapKeyServerSet, PlainNodeKeyPair};
 | 
				
			||||||
	use key_server_cluster::message::Message;
 | 
						use key_server_cluster::message::Message;
 | 
				
			||||||
	use key_server_cluster::cluster::{Cluster, ClusterCore, ClusterConfiguration};
 | 
						use key_server_cluster::cluster::{Cluster, ClusterCore, ClusterConfiguration};
 | 
				
			||||||
	use key_server_cluster::generation_session::{Session as GenerationSession, SessionState as GenerationSessionState};
 | 
						use key_server_cluster::generation_session::{Session as GenerationSession, SessionState as GenerationSessionState};
 | 
				
			||||||
@ -1068,7 +1068,7 @@ pub mod tests {
 | 
				
			|||||||
		let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect();
 | 
							let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect();
 | 
				
			||||||
		let cluster_params: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration {
 | 
							let cluster_params: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration {
 | 
				
			||||||
			threads: 1,
 | 
								threads: 1,
 | 
				
			||||||
			self_key_pair: key_pairs[i].clone(),
 | 
								self_key_pair: Arc::new(PlainNodeKeyPair::new(key_pairs[i].clone())),
 | 
				
			||||||
			listen_address: ("127.0.0.1".to_owned(), ports_begin + i as u16),
 | 
								listen_address: ("127.0.0.1".to_owned(), ports_begin + i as u16),
 | 
				
			||||||
			key_server_set: Arc::new(MapKeyServerSet::new(key_pairs.iter().enumerate()
 | 
								key_server_set: Arc::new(MapKeyServerSet::new(key_pairs.iter().enumerate()
 | 
				
			||||||
				.map(|(j, kp)| (kp.public().clone(), format!("127.0.0.1:{}", ports_begin + j as u16).parse().unwrap()))
 | 
									.map(|(j, kp)| (kp.public().clone(), format!("127.0.0.1:{}", ports_begin + j as u16).parse().unwrap()))
 | 
				
			||||||
 | 
				
			|||||||
@ -15,24 +15,25 @@
 | 
				
			|||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use std::io;
 | 
					use std::io;
 | 
				
			||||||
 | 
					use std::sync::Arc;
 | 
				
			||||||
use std::collections::BTreeSet;
 | 
					use std::collections::BTreeSet;
 | 
				
			||||||
use futures::{Future, Poll, Async};
 | 
					use futures::{Future, Poll, Async};
 | 
				
			||||||
use tokio_io::{AsyncRead, AsyncWrite};
 | 
					use tokio_io::{AsyncRead, AsyncWrite};
 | 
				
			||||||
use ethkey::{Random, Generator, KeyPair, Secret, sign, verify_public};
 | 
					use ethkey::{Random, Generator, KeyPair, verify_public};
 | 
				
			||||||
use util::H256;
 | 
					use util::H256;
 | 
				
			||||||
use key_server_cluster::{NodeId, Error};
 | 
					use key_server_cluster::{NodeId, Error, NodeKeyPair};
 | 
				
			||||||
use key_server_cluster::message::{Message, ClusterMessage, NodePublicKey, NodePrivateKeySignature};
 | 
					use key_server_cluster::message::{Message, ClusterMessage, NodePublicKey, NodePrivateKeySignature};
 | 
				
			||||||
use key_server_cluster::io::{write_message, write_encrypted_message, WriteMessage, ReadMessage,
 | 
					use key_server_cluster::io::{write_message, write_encrypted_message, WriteMessage, ReadMessage,
 | 
				
			||||||
	read_message, read_encrypted_message, compute_shared_key};
 | 
						read_message, read_encrypted_message, fix_shared_key};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Start handshake procedure with another node from the cluster.
 | 
					/// Start handshake procedure with another node from the cluster.
 | 
				
			||||||
pub fn handshake<A>(a: A, self_key_pair: KeyPair, trusted_nodes: BTreeSet<NodeId>) -> Handshake<A> where A: AsyncWrite + AsyncRead {
 | 
					pub fn handshake<A>(a: A, self_key_pair: Arc<NodeKeyPair>, trusted_nodes: BTreeSet<NodeId>) -> Handshake<A> where A: AsyncWrite + AsyncRead {
 | 
				
			||||||
	let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into);
 | 
						let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into);
 | 
				
			||||||
	handshake_with_plain_confirmation(a, self_confirmation_plain, self_key_pair, trusted_nodes)
 | 
						handshake_with_plain_confirmation(a, self_confirmation_plain, self_key_pair, trusted_nodes)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Start handshake procedure with another node from the cluster and given plain confirmation.
 | 
					/// Start handshake procedure with another node from the cluster and given plain confirmation.
 | 
				
			||||||
pub fn handshake_with_plain_confirmation<A>(a: A, self_confirmation_plain: Result<H256, Error>, self_key_pair: KeyPair, trusted_nodes: BTreeSet<NodeId>) -> Handshake<A> where A: AsyncWrite + AsyncRead {
 | 
					pub fn handshake_with_plain_confirmation<A>(a: A, self_confirmation_plain: Result<H256, Error>, self_key_pair: Arc<NodeKeyPair>, trusted_nodes: BTreeSet<NodeId>) -> Handshake<A> where A: AsyncWrite + AsyncRead {
 | 
				
			||||||
	let (error, state) = match self_confirmation_plain.clone()
 | 
						let (error, state) = match self_confirmation_plain.clone()
 | 
				
			||||||
		.and_then(|c| Handshake::<A>::make_public_key_message(self_key_pair.public().clone(), c)) {
 | 
							.and_then(|c| Handshake::<A>::make_public_key_message(self_key_pair.public().clone(), c)) {
 | 
				
			||||||
		Ok(message) => (None, HandshakeState::SendPublicKey(write_message(a, message))),
 | 
							Ok(message) => (None, HandshakeState::SendPublicKey(write_message(a, message))),
 | 
				
			||||||
@ -53,7 +54,7 @@ pub fn handshake_with_plain_confirmation<A>(a: A, self_confirmation_plain: Resul
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Wait for handshake procedure to be started by another node from the cluster.
 | 
					/// Wait for handshake procedure to be started by another node from the cluster.
 | 
				
			||||||
pub fn accept_handshake<A>(a: A, self_key_pair: KeyPair) -> Handshake<A> where A: AsyncWrite + AsyncRead {
 | 
					pub fn accept_handshake<A>(a: A, self_key_pair: Arc<NodeKeyPair>) -> Handshake<A> where A: AsyncWrite + AsyncRead {
 | 
				
			||||||
	let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into);
 | 
						let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into);
 | 
				
			||||||
	let (error, state) = match self_confirmation_plain.clone() {
 | 
						let (error, state) = match self_confirmation_plain.clone() {
 | 
				
			||||||
		Ok(_) => (None, HandshakeState::ReceivePublicKey(read_message(a))),
 | 
							Ok(_) => (None, HandshakeState::ReceivePublicKey(read_message(a))),
 | 
				
			||||||
@ -87,7 +88,7 @@ pub struct Handshake<A> {
 | 
				
			|||||||
	is_active: bool,
 | 
						is_active: bool,
 | 
				
			||||||
	error: Option<(A, Result<HandshakeResult, Error>)>,
 | 
						error: Option<(A, Result<HandshakeResult, Error>)>,
 | 
				
			||||||
	state: HandshakeState<A>,
 | 
						state: HandshakeState<A>,
 | 
				
			||||||
	self_key_pair: KeyPair,
 | 
						self_key_pair: Arc<NodeKeyPair>,
 | 
				
			||||||
	self_confirmation_plain: H256,
 | 
						self_confirmation_plain: H256,
 | 
				
			||||||
	trusted_nodes: Option<BTreeSet<NodeId>>,
 | 
						trusted_nodes: Option<BTreeSet<NodeId>>,
 | 
				
			||||||
	other_node_id: Option<NodeId>,
 | 
						other_node_id: Option<NodeId>,
 | 
				
			||||||
@ -117,9 +118,9 @@ impl<A> Handshake<A> where A: AsyncRead + AsyncWrite {
 | 
				
			|||||||
		})))
 | 
							})))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn make_private_key_signature_message(secret: &Secret, confirmation_plain: &H256) -> Result<Message, Error> {
 | 
						fn make_private_key_signature_message(self_key_pair: &NodeKeyPair, confirmation_plain: &H256) -> Result<Message, Error> {
 | 
				
			||||||
		Ok(Message::Cluster(ClusterMessage::NodePrivateKeySignature(NodePrivateKeySignature {
 | 
							Ok(Message::Cluster(ClusterMessage::NodePrivateKeySignature(NodePrivateKeySignature {
 | 
				
			||||||
			confirmation_signed: sign(secret, confirmation_plain)?.into(),
 | 
								confirmation_signed: self_key_pair.sign(confirmation_plain)?.into(),
 | 
				
			||||||
		})))
 | 
							})))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -142,15 +143,15 @@ impl<A> Future for Handshake<A> where A: AsyncRead + AsyncWrite {
 | 
				
			|||||||
						read_message(stream)
 | 
											read_message(stream)
 | 
				
			||||||
					), Async::NotReady)
 | 
										), Async::NotReady)
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					self.shared_key = match compute_shared_key(self.self_key_pair.secret(),
 | 
										self.shared_key = match self.self_key_pair.compute_shared_key(
 | 
				
			||||||
						self.other_node_id.as_ref().expect("we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; other_node_id is filled in ReceivePublicKey; qed")
 | 
											self.other_node_id.as_ref().expect("we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; other_node_id is filled in ReceivePublicKey; qed")
 | 
				
			||||||
					) {
 | 
										).map_err(Into::into).and_then(|sk| fix_shared_key(sk.secret())) {
 | 
				
			||||||
						Ok(shared_key) => Some(shared_key),
 | 
											Ok(shared_key) => Some(shared_key),
 | 
				
			||||||
						Err(err) => return Ok((stream, Err(err)).into()),
 | 
											Err(err) => return Ok((stream, Err(err.into())).into()),
 | 
				
			||||||
					};
 | 
										};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					let message = match Handshake::<A>::make_private_key_signature_message(
 | 
										let message = match Handshake::<A>::make_private_key_signature_message(
 | 
				
			||||||
						self.self_key_pair.secret(),
 | 
											&*self.self_key_pair,
 | 
				
			||||||
						self.other_confirmation_plain.as_ref().expect("we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; other_confirmation_plain is filled in ReceivePublicKey; qed")
 | 
											self.other_confirmation_plain.as_ref().expect("we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; other_confirmation_plain is filled in ReceivePublicKey; qed")
 | 
				
			||||||
					) {
 | 
										) {
 | 
				
			||||||
						Ok(message) => message,
 | 
											Ok(message) => message,
 | 
				
			||||||
@ -179,15 +180,15 @@ impl<A> Future for Handshake<A> where A: AsyncRead + AsyncWrite {
 | 
				
			|||||||
				self.other_node_id = Some(message.node_id.into());
 | 
									self.other_node_id = Some(message.node_id.into());
 | 
				
			||||||
				self.other_confirmation_plain = Some(message.confirmation_plain.into());
 | 
									self.other_confirmation_plain = Some(message.confirmation_plain.into());
 | 
				
			||||||
				if self.is_active {
 | 
									if self.is_active {
 | 
				
			||||||
					self.shared_key = match compute_shared_key(self.self_key_pair.secret(),
 | 
										self.shared_key = match self.self_key_pair.compute_shared_key(
 | 
				
			||||||
						self.other_node_id.as_ref().expect("filled couple of lines above; qed")
 | 
											self.other_node_id.as_ref().expect("filled couple of lines above; qed")
 | 
				
			||||||
					) {
 | 
										).map_err(Into::into).and_then(|sk| fix_shared_key(sk.secret())) {
 | 
				
			||||||
						Ok(shared_key) => Some(shared_key),
 | 
											Ok(shared_key) => Some(shared_key),
 | 
				
			||||||
						Err(err) => return Ok((stream, Err(err)).into()),
 | 
											Err(err) => return Ok((stream, Err(err.into())).into()),
 | 
				
			||||||
					};
 | 
										};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					let message = match Handshake::<A>::make_private_key_signature_message(
 | 
										let message = match Handshake::<A>::make_private_key_signature_message(
 | 
				
			||||||
						self.self_key_pair.secret(),
 | 
											&*self.self_key_pair,
 | 
				
			||||||
						self.other_confirmation_plain.as_ref().expect("filled couple of lines above; qed")
 | 
											self.other_confirmation_plain.as_ref().expect("filled couple of lines above; qed")
 | 
				
			||||||
					) {
 | 
										) {
 | 
				
			||||||
						Ok(message) => message,
 | 
											Ok(message) => message,
 | 
				
			||||||
@ -248,11 +249,14 @@ impl<A> Future for Handshake<A> where A: AsyncRead + AsyncWrite {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod tests {
 | 
					mod tests {
 | 
				
			||||||
 | 
						use std::sync::Arc;
 | 
				
			||||||
	use std::collections::BTreeSet;
 | 
						use std::collections::BTreeSet;
 | 
				
			||||||
	use futures::Future;
 | 
						use futures::Future;
 | 
				
			||||||
	use ethkey::{Random, Generator, sign};
 | 
						use ethkey::{Random, Generator, sign};
 | 
				
			||||||
 | 
						use ethcrypto::ecdh::agree;
 | 
				
			||||||
	use util::H256;
 | 
						use util::H256;
 | 
				
			||||||
	use key_server_cluster::io::message::compute_shared_key;
 | 
						use key_server_cluster::PlainNodeKeyPair;
 | 
				
			||||||
 | 
						use key_server_cluster::io::message::fix_shared_key;
 | 
				
			||||||
	use key_server_cluster::io::message::tests::TestIo;
 | 
						use key_server_cluster::io::message::tests::TestIo;
 | 
				
			||||||
	use key_server_cluster::message::{Message, ClusterMessage, NodePublicKey, NodePrivateKeySignature};
 | 
						use key_server_cluster::message::{Message, ClusterMessage, NodePublicKey, NodePrivateKeySignature};
 | 
				
			||||||
	use super::{handshake_with_plain_confirmation, accept_handshake, HandshakeResult};
 | 
						use super::{handshake_with_plain_confirmation, accept_handshake, HandshakeResult};
 | 
				
			||||||
@ -283,9 +287,9 @@ mod tests {
 | 
				
			|||||||
		let (self_confirmation_plain, io) = prepare_test_io();
 | 
							let (self_confirmation_plain, io) = prepare_test_io();
 | 
				
			||||||
		let self_key_pair = io.self_key_pair().clone();
 | 
							let self_key_pair = io.self_key_pair().clone();
 | 
				
			||||||
		let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect();
 | 
							let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect();
 | 
				
			||||||
		let shared_key = compute_shared_key(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap();
 | 
							let shared_key = fix_shared_key(&agree(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap()).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let handshake = handshake_with_plain_confirmation(io, Ok(self_confirmation_plain), self_key_pair, trusted_nodes);
 | 
							let handshake = handshake_with_plain_confirmation(io, Ok(self_confirmation_plain), Arc::new(PlainNodeKeyPair::new(self_key_pair)), trusted_nodes);
 | 
				
			||||||
		let handshake_result = handshake.wait().unwrap();
 | 
							let handshake_result = handshake.wait().unwrap();
 | 
				
			||||||
		assert_eq!(handshake_result.1, Ok(HandshakeResult {
 | 
							assert_eq!(handshake_result.1, Ok(HandshakeResult {
 | 
				
			||||||
			node_id: handshake_result.0.peer_public().clone(),
 | 
								node_id: handshake_result.0.peer_public().clone(),
 | 
				
			||||||
@ -298,9 +302,9 @@ mod tests {
 | 
				
			|||||||
		let (self_confirmation_plain, io) = prepare_test_io();
 | 
							let (self_confirmation_plain, io) = prepare_test_io();
 | 
				
			||||||
		let self_key_pair = io.self_key_pair().clone();
 | 
							let self_key_pair = io.self_key_pair().clone();
 | 
				
			||||||
		let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect();
 | 
							let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect();
 | 
				
			||||||
		let shared_key = compute_shared_key(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap();
 | 
							let shared_key = fix_shared_key(&agree(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap()).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let mut handshake = accept_handshake(io, self_key_pair);
 | 
							let mut handshake = accept_handshake(io, Arc::new(PlainNodeKeyPair::new(self_key_pair)));
 | 
				
			||||||
		handshake.set_self_confirmation_plain(self_confirmation_plain);
 | 
							handshake.set_self_confirmation_plain(self_confirmation_plain);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let handshake_result = handshake.wait().unwrap();
 | 
							let handshake_result = handshake.wait().unwrap();
 | 
				
			||||||
 | 
				
			|||||||
@ -19,9 +19,8 @@ use std::u16;
 | 
				
			|||||||
use std::ops::Deref;
 | 
					use std::ops::Deref;
 | 
				
			||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
 | 
					use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
 | 
				
			||||||
use serde_json;
 | 
					use serde_json;
 | 
				
			||||||
use ethcrypto::ecdh::agree;
 | 
					 | 
				
			||||||
use ethcrypto::ecies::{encrypt_single_message, decrypt_single_message};
 | 
					use ethcrypto::ecies::{encrypt_single_message, decrypt_single_message};
 | 
				
			||||||
use ethkey::{Public, Secret, KeyPair};
 | 
					use ethkey::{Secret, KeyPair};
 | 
				
			||||||
use ethkey::math::curve_order;
 | 
					use ethkey::math::curve_order;
 | 
				
			||||||
use util::{H256, U256};
 | 
					use util::{H256, U256};
 | 
				
			||||||
use key_server_cluster::Error;
 | 
					use key_server_cluster::Error;
 | 
				
			||||||
@ -154,12 +153,11 @@ pub fn decrypt_message(key: &KeyPair, payload: Vec<u8>) -> Result<Vec<u8>, Error
 | 
				
			|||||||
	Ok(decrypt_single_message(key.secret(), &payload)?)
 | 
						Ok(decrypt_single_message(key.secret(), &payload)?)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Compute shared encryption key.
 | 
					/// Fix shared encryption key.
 | 
				
			||||||
pub fn compute_shared_key(self_secret: &Secret, other_public: &Public) -> Result<KeyPair, Error> {
 | 
					pub fn fix_shared_key(shared_secret: &Secret) -> Result<KeyPair, Error> {
 | 
				
			||||||
	// secret key created in agree function is invalid, as it is not calculated mod EC.field.n
 | 
						// secret key created in agree function is invalid, as it is not calculated mod EC.field.n
 | 
				
			||||||
	// => let's do it manually
 | 
						// => let's do it manually
 | 
				
			||||||
	let shared_secret = agree(self_secret, other_public)?;
 | 
						let shared_secret: H256 = (**shared_secret).into();
 | 
				
			||||||
	let shared_secret: H256 = (*shared_secret).into();
 | 
					 | 
				
			||||||
	let shared_secret: U256 = shared_secret.into();
 | 
						let shared_secret: U256 = shared_secret.into();
 | 
				
			||||||
	let shared_secret: H256 = (shared_secret % curve_order()).into();
 | 
						let shared_secret: H256 = (shared_secret % curve_order()).into();
 | 
				
			||||||
	let shared_key_pair = KeyPair::from_secret_slice(&*shared_secret)?;
 | 
						let shared_key_pair = KeyPair::from_secret_slice(&*shared_secret)?;
 | 
				
			||||||
@ -204,8 +202,9 @@ pub mod tests {
 | 
				
			|||||||
	use futures::Poll;
 | 
						use futures::Poll;
 | 
				
			||||||
	use tokio_io::{AsyncRead, AsyncWrite};
 | 
						use tokio_io::{AsyncRead, AsyncWrite};
 | 
				
			||||||
	use ethkey::{KeyPair, Public};
 | 
						use ethkey::{KeyPair, Public};
 | 
				
			||||||
 | 
						use ethcrypto::ecdh::agree;
 | 
				
			||||||
	use key_server_cluster::message::Message;
 | 
						use key_server_cluster::message::Message;
 | 
				
			||||||
	use super::{MESSAGE_HEADER_SIZE, MessageHeader, compute_shared_key, encrypt_message, serialize_message,
 | 
						use super::{MESSAGE_HEADER_SIZE, MessageHeader, fix_shared_key, encrypt_message, serialize_message,
 | 
				
			||||||
		serialize_header, deserialize_header};
 | 
							serialize_header, deserialize_header};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pub struct TestIo {
 | 
						pub struct TestIo {
 | 
				
			||||||
@ -217,7 +216,7 @@ pub mod tests {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	impl TestIo {
 | 
						impl TestIo {
 | 
				
			||||||
		pub fn new(self_key_pair: KeyPair, peer_public: Public) -> Self {
 | 
							pub fn new(self_key_pair: KeyPair, peer_public: Public) -> Self {
 | 
				
			||||||
			let shared_key_pair = compute_shared_key(self_key_pair.secret(), &peer_public).unwrap();
 | 
								let shared_key_pair = fix_shared_key(&agree(self_key_pair.secret(), &peer_public).unwrap()).unwrap();
 | 
				
			||||||
			TestIo {
 | 
								TestIo {
 | 
				
			||||||
				self_key_pair: self_key_pair,
 | 
									self_key_pair: self_key_pair,
 | 
				
			||||||
				peer_public: peer_public,
 | 
									peer_public: peer_public,
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,7 @@ mod write_message;
 | 
				
			|||||||
pub use self::deadline::{deadline, Deadline, DeadlineStatus};
 | 
					pub use self::deadline::{deadline, Deadline, DeadlineStatus};
 | 
				
			||||||
pub use self::handshake::{handshake, accept_handshake, Handshake, HandshakeResult};
 | 
					pub use self::handshake::{handshake, accept_handshake, Handshake, HandshakeResult};
 | 
				
			||||||
pub use self::message::{MessageHeader, SerializedMessage, serialize_message, deserialize_message,
 | 
					pub use self::message::{MessageHeader, SerializedMessage, serialize_message, deserialize_message,
 | 
				
			||||||
	encrypt_message, compute_shared_key};
 | 
						encrypt_message, fix_shared_key};
 | 
				
			||||||
pub use self::read_header::{read_header, ReadHeader};
 | 
					pub use self::read_header::{read_header, ReadHeader};
 | 
				
			||||||
pub use self::read_payload::{read_payload, read_encrypted_payload, ReadPayload};
 | 
					pub use self::read_payload::{read_payload, read_encrypted_payload, ReadPayload};
 | 
				
			||||||
pub use self::read_message::{read_message, read_encrypted_message, ReadMessage};
 | 
					pub use self::read_message::{read_message, read_encrypted_message, ReadMessage};
 | 
				
			||||||
 | 
				
			|||||||
@ -20,6 +20,7 @@ use ethkey;
 | 
				
			|||||||
use ethcrypto;
 | 
					use ethcrypto;
 | 
				
			||||||
use super::types::all::ServerKeyId;
 | 
					use super::types::all::ServerKeyId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub use super::traits::NodeKeyPair;
 | 
				
			||||||
pub use super::types::all::{NodeId, EncryptedDocumentKeyShadow};
 | 
					pub use super::types::all::{NodeId, EncryptedDocumentKeyShadow};
 | 
				
			||||||
pub use super::acl_storage::AclStorage;
 | 
					pub use super::acl_storage::AclStorage;
 | 
				
			||||||
pub use super::key_storage::{KeyStorage, DocumentKeyShare};
 | 
					pub use super::key_storage::{KeyStorage, DocumentKeyShare};
 | 
				
			||||||
@ -30,6 +31,8 @@ pub use self::generation_session::Session as GenerationSession;
 | 
				
			|||||||
pub use self::encryption_session::Session as EncryptionSession;
 | 
					pub use self::encryption_session::Session as EncryptionSession;
 | 
				
			||||||
pub use self::decryption_session::Session as DecryptionSession;
 | 
					pub use self::decryption_session::Session as DecryptionSession;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					pub use super::node_key_pair::PlainNodeKeyPair;
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
pub use super::key_storage::tests::DummyKeyStorage;
 | 
					pub use super::key_storage::tests::DummyKeyStorage;
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
				
			|||||||
@ -15,18 +15,18 @@
 | 
				
			|||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use std::io;
 | 
					use std::io;
 | 
				
			||||||
 | 
					use std::sync::Arc;
 | 
				
			||||||
use std::net::SocketAddr;
 | 
					use std::net::SocketAddr;
 | 
				
			||||||
use std::time::Duration;
 | 
					use std::time::Duration;
 | 
				
			||||||
use futures::{Future, Poll};
 | 
					use futures::{Future, Poll};
 | 
				
			||||||
use tokio_core::reactor::Handle;
 | 
					use tokio_core::reactor::Handle;
 | 
				
			||||||
use tokio_core::net::TcpStream;
 | 
					use tokio_core::net::TcpStream;
 | 
				
			||||||
use ethkey::KeyPair;
 | 
					use key_server_cluster::{Error, NodeKeyPair};
 | 
				
			||||||
use key_server_cluster::Error;
 | 
					 | 
				
			||||||
use key_server_cluster::io::{accept_handshake, Handshake, Deadline, deadline};
 | 
					use key_server_cluster::io::{accept_handshake, Handshake, Deadline, deadline};
 | 
				
			||||||
use key_server_cluster::net::Connection;
 | 
					use key_server_cluster::net::Connection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Create future for accepting incoming connection.
 | 
					/// Create future for accepting incoming connection.
 | 
				
			||||||
pub fn accept_connection(address: SocketAddr, stream: TcpStream, handle: &Handle, self_key_pair: KeyPair) -> Deadline<AcceptConnection> {
 | 
					pub fn accept_connection(address: SocketAddr, stream: TcpStream, handle: &Handle, self_key_pair: Arc<NodeKeyPair>) -> Deadline<AcceptConnection> {
 | 
				
			||||||
	let accept = AcceptConnection {
 | 
						let accept = AcceptConnection {
 | 
				
			||||||
		handshake: accept_handshake(stream, self_key_pair),
 | 
							handshake: accept_handshake(stream, self_key_pair),
 | 
				
			||||||
		address: address,
 | 
							address: address,
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,7 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use std::sync::Arc;
 | 
				
			||||||
use std::collections::BTreeSet;
 | 
					use std::collections::BTreeSet;
 | 
				
			||||||
use std::io;
 | 
					use std::io;
 | 
				
			||||||
use std::time::Duration;
 | 
					use std::time::Duration;
 | 
				
			||||||
@ -21,13 +22,12 @@ use std::net::SocketAddr;
 | 
				
			|||||||
use futures::{Future, Poll, Async};
 | 
					use futures::{Future, Poll, Async};
 | 
				
			||||||
use tokio_core::reactor::Handle;
 | 
					use tokio_core::reactor::Handle;
 | 
				
			||||||
use tokio_core::net::{TcpStream, TcpStreamNew};
 | 
					use tokio_core::net::{TcpStream, TcpStreamNew};
 | 
				
			||||||
use ethkey::KeyPair;
 | 
					use key_server_cluster::{Error, NodeId, NodeKeyPair};
 | 
				
			||||||
use key_server_cluster::{Error, NodeId};
 | 
					 | 
				
			||||||
use key_server_cluster::io::{handshake, Handshake, Deadline, deadline};
 | 
					use key_server_cluster::io::{handshake, Handshake, Deadline, deadline};
 | 
				
			||||||
use key_server_cluster::net::Connection;
 | 
					use key_server_cluster::net::Connection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Create future for connecting to other node.
 | 
					/// Create future for connecting to other node.
 | 
				
			||||||
pub fn connect(address: &SocketAddr, handle: &Handle, self_key_pair: KeyPair, trusted_nodes: BTreeSet<NodeId>) -> Deadline<Connect> {
 | 
					pub fn connect(address: &SocketAddr, handle: &Handle, self_key_pair: Arc<NodeKeyPair>, trusted_nodes: BTreeSet<NodeId>) -> Deadline<Connect> {
 | 
				
			||||||
	let connect = Connect {
 | 
						let connect = Connect {
 | 
				
			||||||
		state: ConnectState::TcpConnect(TcpStream::connect(address, handle)),
 | 
							state: ConnectState::TcpConnect(TcpStream::connect(address, handle)),
 | 
				
			||||||
		address: address.clone(),
 | 
							address: address.clone(),
 | 
				
			||||||
@ -48,7 +48,7 @@ enum ConnectState {
 | 
				
			|||||||
pub struct Connect {
 | 
					pub struct Connect {
 | 
				
			||||||
	state: ConnectState,
 | 
						state: ConnectState,
 | 
				
			||||||
	address: SocketAddr,
 | 
						address: SocketAddr,
 | 
				
			||||||
	self_key_pair: KeyPair,
 | 
						self_key_pair: Arc<NodeKeyPair>,
 | 
				
			||||||
	trusted_nodes: BTreeSet<NodeId>,
 | 
						trusted_nodes: BTreeSet<NodeId>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -241,7 +241,6 @@ pub mod tests {
 | 
				
			|||||||
			data_path: path.as_str().to_owned(),
 | 
								data_path: path.as_str().to_owned(),
 | 
				
			||||||
			cluster_config: ClusterConfiguration {
 | 
								cluster_config: ClusterConfiguration {
 | 
				
			||||||
				threads: 1,
 | 
									threads: 1,
 | 
				
			||||||
				self_private: (**Random.generate().unwrap().secret().clone()).into(),
 | 
					 | 
				
			||||||
				listener_address: NodeAddress {
 | 
									listener_address: NodeAddress {
 | 
				
			||||||
					address: "0.0.0.0".to_owned(),
 | 
										address: "0.0.0.0".to_owned(),
 | 
				
			||||||
					port: 8083,
 | 
										port: 8083,
 | 
				
			||||||
 | 
				
			|||||||
@ -59,22 +59,24 @@ mod key_server;
 | 
				
			|||||||
mod key_storage;
 | 
					mod key_storage;
 | 
				
			||||||
mod serialization;
 | 
					mod serialization;
 | 
				
			||||||
mod key_server_set;
 | 
					mod key_server_set;
 | 
				
			||||||
 | 
					mod node_key_pair;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use std::sync::Arc;
 | 
					use std::sync::Arc;
 | 
				
			||||||
use ethcore::client::Client;
 | 
					use ethcore::client::Client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub use types::all::{ServerKeyId, EncryptedDocumentKey, RequestSignature, Public,
 | 
					pub use types::all::{ServerKeyId, EncryptedDocumentKey, RequestSignature, Public,
 | 
				
			||||||
	Error, NodeAddress, ServiceConfiguration, ClusterConfiguration};
 | 
						Error, NodeAddress, ServiceConfiguration, ClusterConfiguration};
 | 
				
			||||||
pub use traits::{KeyServer};
 | 
					pub use traits::{NodeKeyPair, KeyServer};
 | 
				
			||||||
 | 
					pub use self::node_key_pair::{PlainNodeKeyPair, KeyStoreNodeKeyPair};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Start new key server instance
 | 
					/// Start new key server instance
 | 
				
			||||||
pub fn start(client: Arc<Client>, config: ServiceConfiguration) -> Result<Box<KeyServer>, Error> {
 | 
					pub fn start(client: Arc<Client>, self_key_pair: Arc<NodeKeyPair>, config: ServiceConfiguration) -> Result<Box<KeyServer>, Error> {
 | 
				
			||||||
	use std::sync::Arc;
 | 
						use std::sync::Arc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let acl_storage = acl_storage::OnChainAclStorage::new(&client);
 | 
						let acl_storage = acl_storage::OnChainAclStorage::new(&client);
 | 
				
			||||||
	let key_server_set = key_server_set::OnChainKeyServerSet::new(&client, config.cluster_config.nodes.clone())?;
 | 
						let key_server_set = key_server_set::OnChainKeyServerSet::new(&client, config.cluster_config.nodes.clone())?;
 | 
				
			||||||
	let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?);
 | 
						let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?);
 | 
				
			||||||
	let key_server = key_server::KeyServerImpl::new(&config.cluster_config, key_server_set, acl_storage, key_storage)?;
 | 
						let key_server = key_server::KeyServerImpl::new(&config.cluster_config, key_server_set, self_key_pair, acl_storage, key_storage)?;
 | 
				
			||||||
	let listener = http_listener::KeyServerHttpListener::start(&config.listener_address, key_server)?;
 | 
						let listener = http_listener::KeyServerHttpListener::start(&config.listener_address, key_server)?;
 | 
				
			||||||
	Ok(Box::new(listener))
 | 
						Ok(Box::new(listener))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										84
									
								
								secret_store/src/node_key_pair.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								secret_store/src/node_key_pair.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					// Copyright 2015-2017 Parity Technologies (UK) Ltd.
 | 
				
			||||||
 | 
					// This file is part of Parity.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					// it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					// the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					// (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parity is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					// GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use std::sync::Arc;
 | 
				
			||||||
 | 
					use ethcrypto::ecdh::agree;
 | 
				
			||||||
 | 
					use ethkey::{KeyPair, Public, Signature, Error as EthKeyError, sign};
 | 
				
			||||||
 | 
					use ethcore::account_provider::AccountProvider;
 | 
				
			||||||
 | 
					use util::{Address, H256};
 | 
				
			||||||
 | 
					use traits::NodeKeyPair;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct PlainNodeKeyPair {
 | 
				
			||||||
 | 
						key_pair: KeyPair,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct KeyStoreNodeKeyPair {
 | 
				
			||||||
 | 
						account_provider: Arc<AccountProvider>,
 | 
				
			||||||
 | 
						address: Address,
 | 
				
			||||||
 | 
						public: Public,
 | 
				
			||||||
 | 
						password: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl PlainNodeKeyPair {
 | 
				
			||||||
 | 
						pub fn new(key_pair: KeyPair) -> Self {
 | 
				
			||||||
 | 
							PlainNodeKeyPair {
 | 
				
			||||||
 | 
								key_pair: key_pair,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl NodeKeyPair for PlainNodeKeyPair {
 | 
				
			||||||
 | 
						fn public(&self) -> &Public {
 | 
				
			||||||
 | 
							self.key_pair.public()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn sign(&self, data: &H256) -> Result<Signature, EthKeyError> {
 | 
				
			||||||
 | 
							sign(self.key_pair.secret(), data)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn compute_shared_key(&self, peer_public: &Public) -> Result<KeyPair, EthKeyError> {
 | 
				
			||||||
 | 
							agree(self.key_pair.secret(), peer_public).map_err(|e| EthKeyError::Custom(e.into()))
 | 
				
			||||||
 | 
								.and_then(KeyPair::from_secret)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 {
 | 
				
			||||||
 | 
						fn public(&self) -> &Public {
 | 
				
			||||||
 | 
							&self.public
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn sign(&self, data: &H256) -> Result<Signature, EthKeyError> {
 | 
				
			||||||
 | 
							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> {
 | 
				
			||||||
 | 
							KeyPair::from_secret(self.account_provider.agree(self.address.clone(), Some(self.password.clone()), peer_public)
 | 
				
			||||||
 | 
								.map_err(|e| EthKeyError::Custom(format!("{}", e)))?)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -14,9 +14,21 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use ethkey::{KeyPair, Signature, Error as EthKeyError};
 | 
				
			||||||
 | 
					use util::H256;
 | 
				
			||||||
use types::all::{Error, Public, ServerKeyId, MessageHash, EncryptedMessageSignature, RequestSignature, EncryptedDocumentKey,
 | 
					use types::all::{Error, Public, ServerKeyId, MessageHash, EncryptedMessageSignature, RequestSignature, EncryptedDocumentKey,
 | 
				
			||||||
	EncryptedDocumentKeyShadow};
 | 
						EncryptedDocumentKeyShadow};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Node key pair.
 | 
				
			||||||
 | 
					pub trait NodeKeyPair: Send + Sync {
 | 
				
			||||||
 | 
						/// Public portion of key.
 | 
				
			||||||
 | 
						fn public(&self) -> &Public;
 | 
				
			||||||
 | 
						/// Sign data with node key.
 | 
				
			||||||
 | 
						fn sign(&self, data: &H256) -> Result<Signature, EthKeyError>;
 | 
				
			||||||
 | 
						/// Compute shared key to encrypt channel between two nodes.
 | 
				
			||||||
 | 
						fn compute_shared_key(&self, peer_public: &Public) -> Result<KeyPair, EthKeyError>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Server key (SK) generator.
 | 
					/// Server key (SK) generator.
 | 
				
			||||||
pub trait ServerKeyGenerator {
 | 
					pub trait ServerKeyGenerator {
 | 
				
			||||||
	/// Generate new SK.
 | 
						/// Generate new SK.
 | 
				
			||||||
 | 
				
			|||||||
@ -83,8 +83,6 @@ pub struct ServiceConfiguration {
 | 
				
			|||||||
pub struct ClusterConfiguration {
 | 
					pub struct ClusterConfiguration {
 | 
				
			||||||
	/// Number of threads reserved by cluster.
 | 
						/// Number of threads reserved by cluster.
 | 
				
			||||||
	pub threads: usize,
 | 
						pub threads: usize,
 | 
				
			||||||
	/// Private key this node holds.
 | 
					 | 
				
			||||||
	pub self_private: Vec<u8>, // holds ethkey::Secret
 | 
					 | 
				
			||||||
	/// This node address.
 | 
						/// This node address.
 | 
				
			||||||
	pub listener_address: NodeAddress,
 | 
						pub listener_address: NodeAddress,
 | 
				
			||||||
	/// All cluster nodes addresses.
 | 
						/// All cluster nodes addresses.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user