On-chain ACL checker for secretstore (#5015)
* ECDKG protocol prototype * added test for enc/dec math * get rid of decryption_session * added licenses * fix after merge * get rid of unused serde dependency * doc * decryption session [without commutative enc] * failed_dec_session * fixed tests * added commen * added more decryption session tests * helper to localize an issue * more computations to localize error * decryption_session::SessionParams * added tests for EC math to localize problem * secretstore network transport * encryption_session_works_over_network * network errors processing * connecting to KeyServer * licenses * get rid of debug println-s * fixed secretstore args * encryption results are stored in KS database * decryption protocol works over network * enc/dec Session traits * fixing warnings * fix after merge * on-chain ACL checker proto * fixed compilation * fixed compilation * finally fixed <odd>-of-N-scheme * temporary commented test * 1-of-N works in math * scheme 1-of-N works * updated AclStorage with real contract ABI * remove unnecessary unsafety * fixed grumbles * wakeup on access denied * fix after merge * fix after merge * moved contract to native-contracts lib
This commit is contained in:
		
							parent
							
								
									ee4f9da385
								
							
						
					
					
						commit
						abec06f50c
					
				
							
								
								
									
										3
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -635,6 +635,8 @@ name = "ethcore-secretstore" | ||||
| version = "1.0.0" | ||||
| dependencies = [ | ||||
|  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "ethabi 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "ethcore 1.7.0", | ||||
|  "ethcore-devtools 1.7.0", | ||||
|  "ethcore-ipc 1.7.0", | ||||
|  "ethcore-ipc-codegen 1.7.0", | ||||
| @ -646,6 +648,7 @@ dependencies = [ | ||||
|  "futures-cpupool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "hyper 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "native-contracts 0.1.0", | ||||
|  "parking_lot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "serde 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  | ||||
| @ -23,6 +23,7 @@ use std::io::Write; | ||||
| // TODO: `include!` these from files where they're pretty-printed?
 | ||||
| const REGISTRY_ABI: &'static str = r#"[{"constant":true,"inputs":[{"name":"_data","type":"address"}],"name":"canReverse","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"bytes32"}],"name":"setData","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"confirmReverse","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[{"name":"success","type":"bool"}],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"drop","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"getAddress","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"setFee","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_to","type":"address"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"getData","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserved","outputs":[{"name":"reserved","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"drain","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_who","type":"address"}],"name":"proposeReverse","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"hasReverse","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"}],"name":"getUint","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"getReverse","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_data","type":"address"}],"name":"reverse","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"uint256"}],"name":"setUint","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_who","type":"address"}],"name":"confirmReverseAs","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"removeReverse","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_key","type":"string"},{"name":"_value","type":"address"}],"name":"setAddress","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"}]"#; | ||||
| const SERVICE_TRANSACTION_ABI: &'static str = r#"[{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_who","type":"address"}],"name":"certify","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getAddress","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_who","type":"address"}],"name":"revoke","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"delegate","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"getUint","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_new","type":"address"}],"name":"setDelegate","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"}],"name":"certified","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_field","type":"string"}],"name":"get","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"}]"#; | ||||
| const SECRETSTORE_ACL_STORAGE_ABI: &'static str = r#"[{"constant":true,"inputs":[{"name":"user","type":"address"},{"name":"document","type":"bytes32"}],"name":"checkPermissions","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"}]"#; | ||||
| 
 | ||||
| fn build_file(name: &str, abi: &str, filename: &str) { | ||||
| 	let code = ::native_contract_generator::generate_module(name, abi).unwrap(); | ||||
| @ -37,4 +38,5 @@ fn build_file(name: &str, abi: &str, filename: &str) { | ||||
| fn main() { | ||||
| 	build_file("Registry", REGISTRY_ABI, "registry.rs"); | ||||
| 	build_file("ServiceTransactionChecker", SERVICE_TRANSACTION_ABI, "service_transaction.rs"); | ||||
| 	build_file("SecretStoreAclStorage", SECRETSTORE_ACL_STORAGE_ABI, "secretstore_acl_storage.rs"); | ||||
| } | ||||
|  | ||||
| @ -25,6 +25,8 @@ extern crate ethcore_util as util; | ||||
| 
 | ||||
| mod registry; | ||||
| mod service_transaction; | ||||
| mod secretstore_acl_storage; | ||||
| 
 | ||||
| pub use self::registry::Registry; | ||||
| pub use self::service_transaction::ServiceTransactionChecker; | ||||
| pub use self::secretstore_acl_storage::SecretStoreAclStorage; | ||||
|  | ||||
							
								
								
									
										22
									
								
								ethcore/native_contracts/src/secretstore_acl_storage.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								ethcore/native_contracts/src/secretstore_acl_storage.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| // 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/>.
 | ||||
| 
 | ||||
| #![allow(unused_mut, unused_variables, unused_imports)] | ||||
| 
 | ||||
| //! Secret store ACL storage contract.
 | ||||
| // TODO: testing.
 | ||||
| 
 | ||||
| include!(concat!(env!("OUT_DIR"), "/secretstore_acl_storage.rs")); | ||||
| @ -463,7 +463,9 @@ pub fn execute(cmd: RunCmd, can_restart: bool, logger: Arc<RotatingLogger>) -> R | ||||
| 	let signer_server = signer::start(cmd.signer_conf.clone(), signer_deps)?; | ||||
| 
 | ||||
| 	// secret store key server
 | ||||
| 	let secretstore_deps = secretstore::Dependencies { }; | ||||
| 	let secretstore_deps = secretstore::Dependencies { | ||||
| 		client: client.clone(), | ||||
| 	}; | ||||
| 	let secretstore_key_server = secretstore::start(cmd.secretstore_conf.clone(), secretstore_deps); | ||||
| 
 | ||||
| 	// the ipfs server
 | ||||
|  | ||||
| @ -14,7 +14,9 @@ | ||||
| // 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 dir::default_data_path; | ||||
| use ethcore::client::Client; | ||||
| use helpers::replace_home; | ||||
| 
 | ||||
| #[derive(Debug, PartialEq, Clone)] | ||||
| @ -30,10 +32,10 @@ pub struct Configuration { | ||||
| 	pub data_path: String, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, PartialEq, Clone)] | ||||
| /// Secret store dependencies
 | ||||
| pub struct Dependencies { | ||||
| 	// the only dependency will be BlockChainClient
 | ||||
| 	/// Blockchain client.
 | ||||
| 	pub client: Arc<Client>, | ||||
| } | ||||
| 
 | ||||
| #[cfg(not(feature = "secretstore"))] | ||||
| @ -64,7 +66,7 @@ mod server { | ||||
| 
 | ||||
| 	impl KeyServer { | ||||
| 		/// Create new key server
 | ||||
| 		pub fn new(conf: Configuration, _deps: Dependencies) -> Result<Self, String> { | ||||
| 		pub fn new(conf: Configuration, deps: Dependencies) -> Result<Self, String> { | ||||
| 			let key_pairs = vec![ | ||||
| 				ethkey::KeyPair::from_secret("6c26a76e9b31048d170873a791401c7e799a11f0cefc0171cc31a49800967509".parse().unwrap()).unwrap(), | ||||
| 				ethkey::KeyPair::from_secret("7e94018b3731afdb3b4e6f4c3e179475640166da12e1d1b0c7d80729b1a5b452".parse().unwrap()).unwrap(), | ||||
| @ -96,7 +98,7 @@ mod server { | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			let key_server = ethcore_secretstore::start(conf) | ||||
| 			let key_server = ethcore_secretstore::start(deps.client, conf) | ||||
| 				.map_err(Into::<String>::into)?; | ||||
| 
 | ||||
| 			Ok(KeyServer { | ||||
|  | ||||
| @ -24,12 +24,15 @@ tokio-core = "0.1" | ||||
| tokio-service = "0.1" | ||||
| tokio-proto = "0.1" | ||||
| url = "1.0" | ||||
| ethabi = "1.0.0" | ||||
| ethcore = { path = "../ethcore" } | ||||
| ethcore-devtools = { path = "../devtools" } | ||||
| ethcore-util = { path = "../util" } | ||||
| ethcore-ipc = { path = "../ipc/rpc" } | ||||
| ethcore-ipc-nano = { path = "../ipc/nano" } | ||||
| ethcrypto = { path = "../ethcrypto" } | ||||
| ethkey = { path = "../ethkey" } | ||||
| native-contracts = { path = "../ethcore/native_contracts" } | ||||
| 
 | ||||
| [profile.release] | ||||
| debug = true | ||||
|  | ||||
| @ -14,23 +14,76 @@ | ||||
| // 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::collections::{HashMap, HashSet}; | ||||
| use parking_lot::RwLock; | ||||
| use std::sync::Arc; | ||||
| use futures::{future, Future}; | ||||
| use parking_lot::Mutex; | ||||
| use ethkey::public_to_address; | ||||
| use ethcore::client::{Client, BlockChainClient, BlockId}; | ||||
| use native_contracts::SecretStoreAclStorage; | ||||
| use types::all::{Error, DocumentAddress, Public}; | ||||
| 
 | ||||
| const ACL_CHECKER_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_acl_checker"; | ||||
| 
 | ||||
| /// ACL storage of Secret Store
 | ||||
| pub trait AclStorage: Send + Sync { | ||||
| 	/// Check if requestor with `public` key can access document with hash `document`
 | ||||
| 	fn check(&self, public: &Public, document: &DocumentAddress) -> Result<bool, Error>; | ||||
| } | ||||
| 
 | ||||
| /// Dummy ACL storage implementation
 | ||||
| #[derive(Default, Debug)] | ||||
| pub struct DummyAclStorage { | ||||
| 	prohibited: RwLock<HashMap<Public, HashSet<DocumentAddress>>>, | ||||
| /// On-chain ACL storage implementation.
 | ||||
| pub struct OnChainAclStorage { | ||||
| 	/// Blockchain client.
 | ||||
| 	client: Arc<Client>, | ||||
| 	/// On-chain contract.
 | ||||
| 	contract: Mutex<Option<SecretStoreAclStorage>>, | ||||
| } | ||||
| 
 | ||||
| impl DummyAclStorage { | ||||
| impl OnChainAclStorage { | ||||
| 	pub fn new(client: Arc<Client>) -> Self { | ||||
| 		OnChainAclStorage { | ||||
| 			client: client, | ||||
| 			contract: Mutex::new(None), | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl AclStorage for OnChainAclStorage { | ||||
| 	fn check(&self, public: &Public, document: &DocumentAddress) -> Result<bool, Error> { | ||||
| 		let mut contract = self.contract.lock(); | ||||
| 		if !contract.is_some() { | ||||
| 			*contract = self.client.registry_address(ACL_CHECKER_CONTRACT_REGISTRY_NAME.to_owned()) | ||||
| 				.and_then(|contract_addr| { | ||||
| 					trace!(target: "secretstore", "Configuring for ACL checker contract from {}", contract_addr); | ||||
| 
 | ||||
| 					Some(SecretStoreAclStorage::new(contract_addr)) | ||||
| 				}) | ||||
| 		} | ||||
| 		if let Some(ref contract) = *contract { | ||||
| 			let address = public_to_address(&public); | ||||
| 			let do_call = |a, d| future::done(self.client.call_contract(BlockId::Latest, a, d)); | ||||
| 			contract.check_permissions(do_call, address, document.clone()) | ||||
| 				.map_err(|err| Error::Internal(err)) | ||||
| 				.wait() | ||||
| 		} else { | ||||
| 			Err(Error::Internal("ACL checker contract is not configured".to_owned())) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| pub mod tests { | ||||
| 	use std::collections::{HashMap, HashSet}; | ||||
| 	use parking_lot::RwLock; | ||||
| 	use types::all::{Error, DocumentAddress, Public}; | ||||
| 	use super::AclStorage; | ||||
| 
 | ||||
| 	#[derive(Default, Debug)] | ||||
| 	/// Dummy ACL storage implementation
 | ||||
| 	pub struct DummyAclStorage { | ||||
| 		prohibited: RwLock<HashMap<Public, HashSet<DocumentAddress>>>, | ||||
| 	} | ||||
| 
 | ||||
| 	impl DummyAclStorage { | ||||
| 		#[cfg(test)] | ||||
| 		/// Prohibit given requestor access to given document
 | ||||
| 		pub fn prohibit(&self, public: Public, document: DocumentAddress) { | ||||
| @ -39,13 +92,14 @@ impl DummyAclStorage { | ||||
| 				.or_insert_with(Default::default) | ||||
| 				.insert(document); | ||||
| 		} | ||||
| } | ||||
| 	} | ||||
| 
 | ||||
| impl AclStorage for DummyAclStorage { | ||||
| 	impl AclStorage for DummyAclStorage { | ||||
| 		fn check(&self, public: &Public, document: &DocumentAddress) -> Result<bool, Error> { | ||||
| 			Ok(self.prohibited.read() | ||||
| 				.get(public) | ||||
| 				.map(|docs| !docs.contains(document)) | ||||
| 				.unwrap_or(true)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -147,7 +147,7 @@ mod tests { | ||||
| 	use std::sync::Arc; | ||||
| 	use ethcrypto; | ||||
| 	use ethkey::{self, Random, Generator}; | ||||
| 	use acl_storage::DummyAclStorage; | ||||
| 	use acl_storage::tests::DummyAclStorage; | ||||
| 	use key_storage::tests::DummyKeyStorage; | ||||
| 	use types::all::{ClusterConfiguration, NodeAddress, EncryptionConfiguration, DocumentEncryptedKey, DocumentKey}; | ||||
| 	use super::super::{RequestSignature, DocumentAddress}; | ||||
|  | ||||
| @ -220,7 +220,7 @@ impl SessionImpl { | ||||
| 				self.completed.notify_all(); | ||||
| 			}, | ||||
| 			// we can not decrypt data
 | ||||
| 			SessionState::Failed => (), | ||||
| 			SessionState::Failed => self.completed.notify_all(), | ||||
| 			// cannot reach other states
 | ||||
| 			_ => unreachable!("process_initialization_response can change state to WaitingForPartialDecryption or Failed; checked that we are in WaitingForInitializationConfirm state above; qed"), | ||||
| 		} | ||||
| @ -285,7 +285,10 @@ impl SessionImpl { | ||||
| 			SessionState::WaitingForPartialDecryption => | ||||
| 				SessionImpl::start_waiting_for_partial_decryption(self.node().clone(), self.id.clone(), self.access_key.clone(), &self.cluster, &self.encrypted_data, &mut *data), | ||||
| 			// we can not have enough nodes for decryption
 | ||||
| 			SessionState::Failed => Ok(()), | ||||
| 			SessionState::Failed => { | ||||
| 				self.completed.notify_all(); | ||||
| 				Ok(()) | ||||
| 			}, | ||||
| 			// cannot reach other states
 | ||||
| 			_ => unreachable!("process_initialization_response can change state to WaitingForPartialDecryption or Failed; checked that we are in WaitingForInitializationConfirm state above; qed"), | ||||
| 		} | ||||
| @ -480,6 +483,7 @@ fn process_initialization_response(encrypted_data: &DocumentKeyShare, data: &mut | ||||
| 
 | ||||
| 			// check if we still can receive enough confirmations to do a decryption?
 | ||||
| 			if encrypted_data.id_numbers.len() - data.rejected_nodes.len() < encrypted_data.threshold + 1 { | ||||
| 				data.decrypted_secret = Some(Err(Error::AccessDenied)); | ||||
| 				data.state = SessionState::Failed; | ||||
| 			} | ||||
| 		}, | ||||
| @ -503,7 +507,7 @@ fn do_partial_decryption(node: &NodeId, _requestor_public: &Public, participants | ||||
| mod tests { | ||||
| 	use std::sync::Arc; | ||||
| 	use std::collections::BTreeMap; | ||||
| 	use super::super::super::acl_storage::DummyAclStorage; | ||||
| 	use super::super::super::acl_storage::tests::DummyAclStorage; | ||||
| 	use ethkey::{self, Random, Generator, Public, Secret}; | ||||
| 	use key_server_cluster::{NodeId, DocumentKeyShare, SessionId, Error}; | ||||
| 	use key_server_cluster::cluster::tests::DummyCluster; | ||||
|  | ||||
| @ -21,7 +21,7 @@ use ethcrypto; | ||||
| use super::types::all::DocumentAddress; | ||||
| 
 | ||||
| pub use super::types::all::{NodeId, EncryptionConfiguration}; | ||||
| pub use super::acl_storage::{AclStorage, DummyAclStorage}; | ||||
| pub use super::acl_storage::AclStorage; | ||||
| pub use super::key_storage::{KeyStorage, DocumentKeyShare}; | ||||
| pub use super::serialization::{SerializableSignature, SerializableH256, SerializableSecret, SerializablePublic}; | ||||
| pub use self::cluster::{ClusterCore, ClusterConfiguration, ClusterClient}; | ||||
| @ -30,6 +30,8 @@ pub use self::decryption_session::Session as DecryptionSession; | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| pub use super::key_storage::tests::DummyKeyStorage; | ||||
| #[cfg(test)] | ||||
| pub use super::acl_storage::tests::DummyAclStorage; | ||||
| 
 | ||||
| pub type SessionId = DocumentAddress; | ||||
| 
 | ||||
| @ -72,6 +74,8 @@ pub enum Error { | ||||
| 	Serde(String), | ||||
| 	/// Key storage error.
 | ||||
| 	KeyStorage(String), | ||||
| 	/// Acl storage error.
 | ||||
| 	AccessDenied, | ||||
| } | ||||
| 
 | ||||
| impl From<ethkey::Error> for Error { | ||||
| @ -110,6 +114,7 @@ impl fmt::Display for Error { | ||||
| 			Error::Io(ref e) => write!(f, "i/o error {}", e), | ||||
| 			Error::Serde(ref e) => write!(f, "serde error {}", e), | ||||
| 			Error::KeyStorage(ref e) => write!(f, "key storage error {}", e), | ||||
| 			Error::AccessDenied => write!(f, "Access denied"), | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -32,11 +32,14 @@ extern crate tokio_service; | ||||
| extern crate tokio_proto; | ||||
| extern crate url; | ||||
| 
 | ||||
| extern crate ethabi; | ||||
| extern crate ethcore; | ||||
| extern crate ethcore_devtools as devtools; | ||||
| extern crate ethcore_util as util; | ||||
| extern crate ethcore_ipc as ipc; | ||||
| extern crate ethcrypto; | ||||
| extern crate ethkey; | ||||
| extern crate native_contracts; | ||||
| 
 | ||||
| mod key_server_cluster; | ||||
| mod types; | ||||
| @ -52,15 +55,18 @@ mod key_server; | ||||
| mod key_storage; | ||||
| mod serialization; | ||||
| 
 | ||||
| use std::sync::Arc; | ||||
| use ethcore::client::Client; | ||||
| 
 | ||||
| pub use types::all::{DocumentAddress, DocumentKey, DocumentEncryptedKey, RequestSignature, Public, | ||||
| 	Error, NodeAddress, ServiceConfiguration, ClusterConfiguration, EncryptionConfiguration}; | ||||
| pub use traits::{KeyServer}; | ||||
| 
 | ||||
| /// Start new key server instance
 | ||||
| pub fn start(config: ServiceConfiguration) -> Result<Box<KeyServer>, Error> { | ||||
| pub fn start(client: Arc<Client>, config: ServiceConfiguration) -> Result<Box<KeyServer>, Error> { | ||||
| 	use std::sync::Arc; | ||||
| 
 | ||||
| 	let acl_storage = Arc::new(acl_storage::DummyAclStorage::default()); | ||||
| 	let acl_storage = Arc::new(acl_storage::OnChainAclStorage::new(client)); | ||||
| 	let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?); | ||||
| 	let key_server = key_server::KeyServerImpl::new(&config.cluster_config, acl_storage, key_storage)?; | ||||
| 	let listener = http_listener::KeyServerHttpListener::start(config, key_server)?; | ||||
|  | ||||
| @ -119,7 +119,10 @@ impl From<ethkey::Error> for Error { | ||||
| 
 | ||||
| impl From<key_server_cluster::Error> for Error { | ||||
| 	fn from(err: key_server_cluster::Error) -> Self { | ||||
| 		Error::Internal(err.into()) | ||||
| 		match err { | ||||
| 			key_server_cluster::Error::AccessDenied => Error::AccessDenied, | ||||
| 			_ => Error::Internal(err.into()), | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user