From a6915778bb21ce3828ed577b1129df4c49a23755 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 19 Mar 2018 08:42:40 +0300 Subject: [PATCH] SecretStore: ability to identify requester via Public/Address (#7886) --- secret_store/src/key_server.rs | 15 +- .../client_sessions/decryption_session.rs | 62 ++- .../client_sessions/encryption_session.rs | 15 +- .../client_sessions/signing_session_ecdsa.rs | 26 +- .../signing_session_schnorr.rs | 37 +- .../src/key_server_cluster/cluster.rs | 54 ++- .../key_server_cluster/cluster_sessions.rs | 10 +- .../cluster_sessions_creator.rs | 40 +- .../jobs/consensus_session.rs | 22 +- .../key_server_cluster/jobs/key_access_job.rs | 40 +- .../src/key_server_cluster/message.rs | 21 +- secret_store/src/key_server_cluster/mod.rs | 8 +- secret_store/src/serialization.rs | 449 +++++------------- secret_store/src/types/all.rs | 33 ++ 14 files changed, 327 insertions(+), 505 deletions(-) diff --git a/secret_store/src/key_server.rs b/secret_store/src/key_server.rs index bafcea3e7..181df0caa 100644 --- a/secret_store/src/key_server.rs +++ b/secret_store/src/key_server.rs @@ -85,7 +85,8 @@ impl ServerKeyGenerator for KeyServerImpl { impl DocumentKeyServer for KeyServerImpl { fn store_document_key(&self, key_id: &ServerKeyId, signature: &RequestSignature, common_point: Public, encrypted_document_key: Public) -> Result<(), Error> { // store encrypted key - let encryption_session = self.data.lock().cluster.new_encryption_session(key_id.clone(), signature.clone(), common_point, encrypted_document_key)?; + let encryption_session = self.data.lock().cluster.new_encryption_session(key_id.clone(), + signature.clone().into(), common_point, encrypted_document_key)?; encryption_session.wait(None).map_err(Into::into) } @@ -116,7 +117,8 @@ impl DocumentKeyServer for KeyServerImpl { .map_err(|_| Error::BadSignature)?; // decrypt document key - let decryption_session = self.data.lock().cluster.new_decryption_session(key_id.clone(), signature.clone(), None, false)?; + let decryption_session = self.data.lock().cluster.new_decryption_session(key_id.clone(), + signature.clone().into(), None, false)?; let document_key = decryption_session.wait()?.decrypted_secret; // encrypt document key with requestor public key @@ -126,7 +128,8 @@ impl DocumentKeyServer for KeyServerImpl { } fn restore_document_key_shadow(&self, key_id: &ServerKeyId, signature: &RequestSignature) -> Result { - let decryption_session = self.data.lock().cluster.new_decryption_session(key_id.clone(), signature.clone(), None, true)?; + let decryption_session = self.data.lock().cluster.new_decryption_session(key_id.clone(), + signature.clone().into(), None, true)?; decryption_session.wait().map_err(Into::into) } } @@ -138,7 +141,8 @@ impl MessageSigner for KeyServerImpl { .map_err(|_| Error::BadSignature)?; // sign message - let signing_session = self.data.lock().cluster.new_schnorr_signing_session(key_id.clone(), signature.clone(), None, message)?; + let signing_session = self.data.lock().cluster.new_schnorr_signing_session(key_id.clone(), + signature.clone().into(), None, message)?; let message_signature = signing_session.wait()?; // compose two message signature components into single one @@ -158,7 +162,8 @@ impl MessageSigner for KeyServerImpl { .map_err(|_| Error::BadSignature)?; // sign message - let signing_session = self.data.lock().cluster.new_ecdsa_signing_session(key_id.clone(), signature.clone(), None, message)?; + let signing_session = self.data.lock().cluster.new_ecdsa_signing_session(key_id.clone(), + signature.clone().into(), None, message)?; let message_signature = signing_session.wait()?; // encrypt combined signature with requestor public key diff --git a/secret_store/src/key_server_cluster/client_sessions/decryption_session.rs b/secret_store/src/key_server_cluster/client_sessions/decryption_session.rs index ad1fe2f2e..502a07bbc 100644 --- a/secret_store/src/key_server_cluster/client_sessions/decryption_session.rs +++ b/secret_store/src/key_server_cluster/client_sessions/decryption_session.rs @@ -18,8 +18,9 @@ use std::collections::BTreeSet; use std::sync::Arc; use parking_lot::{Mutex, Condvar}; use ethereum_types::H256; -use ethkey::{Secret, Signature}; -use key_server_cluster::{Error, AclStorage, DocumentKeyShare, NodeId, SessionId, EncryptedDocumentKeyShadow, SessionMeta}; +use ethkey::Secret; +use key_server_cluster::{Error, AclStorage, DocumentKeyShare, NodeId, SessionId, Requester, + EncryptedDocumentKeyShadow, SessionMeta}; use key_server_cluster::cluster::Cluster; use key_server_cluster::cluster_sessions::{SessionIdWithSubSession, ClusterSession}; use key_server_cluster::message::{Message, DecryptionMessage, DecryptionConsensusMessage, RequestPartialDecryption, @@ -141,7 +142,7 @@ enum DelegationStatus { impl SessionImpl { /// Create new decryption session. - pub fn new(params: SessionParams, requester_signature: Option) -> Result { + pub fn new(params: SessionParams, requester: Option) -> Result { debug_assert_eq!(params.meta.threshold, params.key_share.as_ref().map(|ks| ks.threshold).unwrap_or_default()); // check that common_point and encrypted_point are already set @@ -161,8 +162,8 @@ impl SessionImpl { }; let consensus_session = ConsensusSession::new(ConsensusSessionParams { meta: params.meta.clone(), - consensus_executor: match requester_signature { - Some(requester_signature) => KeyAccessJob::new_on_master(params.meta.id.clone(), params.acl_storage.clone(), requester_signature), + consensus_executor: match requester { + Some(requester) => KeyAccessJob::new_on_master(params.meta.id.clone(), params.acl_storage.clone(), requester), None => KeyAccessJob::new_on_slave(params.meta.id.clone(), params.acl_storage.clone()), }, consensus_transport: consensus_transport, @@ -234,7 +235,7 @@ impl SessionImpl { session: self.core.meta.id.clone().into(), sub_session: self.core.access_key.clone().into(), session_nonce: self.core.nonce, - requestor_signature: data.consensus_session.consensus_job().executor().requester_signature() + requester: data.consensus_session.consensus_job().executor().requester() .expect("signature is passed to master node on creation; session can be delegated from master node only; qed") .clone().into(), version: version.into(), @@ -318,7 +319,7 @@ impl SessionImpl { return Err(Error::InvalidStateForRequest); } - data.consensus_session.consensus_job_mut().executor_mut().set_requester_signature(message.requestor_signature.clone().into()); + data.consensus_session.consensus_job_mut().executor_mut().set_requester(message.requester.clone().into()); data.delegation_status = Some(DelegationStatus::DelegatedFrom(sender.clone(), message.session_nonce)); } @@ -393,8 +394,12 @@ impl SessionImpl { let mut data = self.data.lock(); let key_version = key_share.version(data.version.as_ref().ok_or(Error::InvalidMessage)?) .map_err(|e| Error::KeyStorage(e.into()))?.hash.clone(); - let requester = data.consensus_session.consensus_job().executor().requester()?.ok_or(Error::InvalidStateForRequest)?.clone(); - let decryption_job = DecryptionJob::new_on_slave(self.core.meta.self_node_id.clone(), self.core.access_key.clone(), requester, key_share.clone(), key_version)?; + let requester_public = data.consensus_session.consensus_job().executor().requester() + .ok_or(Error::InvalidStateForRequest)? + .public(&self.core.meta.id) + .ok_or(Error::InsufficientRequesterData)?; + let decryption_job = DecryptionJob::new_on_slave(self.core.meta.self_node_id.clone(), self.core.access_key.clone(), + requester_public.clone(), key_share.clone(), key_version)?; let decryption_transport = self.core.decryption_transport(false); // respond to request @@ -409,7 +414,7 @@ impl SessionImpl { if message.is_broadcast_session { let consensus_group: BTreeSet<_> = message.nodes.iter().cloned().map(Into::into).collect(); let broadcast_decryption_job = DecryptionJob::new_on_master(self.core.meta.self_node_id.clone(), - self.core.access_key.clone(), requester, key_share.clone(), key_version, + self.core.access_key.clone(), requester_public, key_share.clone(), key_version, message.is_shadow_decryption, message.is_broadcast_session)?; Self::create_broadcast_decryption_job(&self.core, &mut *data, consensus_group, broadcast_decryption_job, message.request_id.clone().into())?; @@ -537,10 +542,11 @@ impl SessionImpl { }; let key_version = key_share.version(version).map_err(|e| Error::KeyStorage(e.into()))?.hash.clone(); - let requester = data.consensus_session.consensus_job().executor().requester()?.ok_or(Error::InvalidStateForRequest)?.clone(); + let requester = data.consensus_session.consensus_job().executor().requester().ok_or(Error::InvalidStateForRequest)?.clone(); + let requester_public = requester.public(&core.meta.id).ok_or(Error::InsufficientRequesterData)?; let consensus_group = data.consensus_session.select_consensus_group()?.clone(); let decryption_job = DecryptionJob::new_on_master(core.meta.self_node_id.clone(), - core.access_key.clone(), requester, key_share.clone(), key_version, + core.access_key.clone(), requester_public.clone(), key_share.clone(), key_version, is_shadow_decryption, is_broadcast_session)?; let decryption_request_id = decryption_job.request_id().clone().expect("TODO"); let decryption_transport = core.decryption_transport(false); @@ -549,7 +555,7 @@ impl SessionImpl { // ...and prepare decryption job session if we need to broadcast result if data.is_broadcast_session.expect("TODO") { let broadcast_decryption_job = DecryptionJob::new_on_master(core.meta.self_node_id.clone(), - core.access_key.clone(), requester, key_share.clone(), key_version, is_shadow_decryption, is_broadcast_session)?; + core.access_key.clone(), requester_public, key_share.clone(), key_version, is_shadow_decryption, is_broadcast_session)?; Self::create_broadcast_decryption_job(&core, data, consensus_group, broadcast_decryption_job, decryption_request_id)?; } @@ -675,10 +681,10 @@ impl SessionCore { } impl JobTransport for DecryptionConsensusTransport { - type PartialJobRequest=Signature; + type PartialJobRequest=Requester; type PartialJobResponse=bool; - fn send_partial_request(&self, node: &NodeId, request: Signature) -> Result<(), Error> { + fn send_partial_request(&self, node: &NodeId, request: Requester) -> Result<(), Error> { let version = self.version.as_ref() .expect("send_partial_request is called on initialized master node only; version is filled in before initialization starts on master node; qed"); self.cluster.send(node, Message::Decryption(DecryptionMessage::DecryptionConsensusMessage(DecryptionConsensusMessage { @@ -686,7 +692,7 @@ impl JobTransport for DecryptionConsensusTransport { sub_session: self.access_key.clone().into(), session_nonce: self.nonce, message: ConsensusMessage::InitializeConsensusSession(InitializeConsensusSession { - requestor_signature: request.into(), + requester: request.into(), version: version.clone().into(), }) }))) @@ -746,7 +752,8 @@ mod tests { use std::collections::{BTreeMap, VecDeque}; use acl_storage::DummyAclStorage; use ethkey::{self, KeyPair, Random, Generator, Public, Secret}; - use key_server_cluster::{NodeId, DocumentKeyShare, DocumentKeyShareVersion, SessionId, Error, EncryptedDocumentKeyShadow, SessionMeta}; + use key_server_cluster::{NodeId, DocumentKeyShare, DocumentKeyShareVersion, SessionId, Requester, + Error, EncryptedDocumentKeyShadow, SessionMeta}; use key_server_cluster::cluster::tests::DummyCluster; use key_server_cluster::cluster_sessions::ClusterSession; use key_server_cluster::decryption_session::{SessionImpl, SessionParams}; @@ -815,7 +822,7 @@ mod tests { acl_storage: acl_storages[i].clone(), cluster: clusters[i].clone(), nonce: 0, - }, if i == 0 { signature.clone() } else { None }).unwrap()).collect(); + }, if i == 0 { signature.clone().map(Into::into) } else { None }).unwrap()).collect(); (requester, clusters, acl_storages, sessions) } @@ -889,7 +896,7 @@ mod tests { acl_storage: Arc::new(DummyAclStorage::default()), cluster: Arc::new(DummyCluster::new(self_node_id.clone())), nonce: 0, - }, Some(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap())) { + }, Some(Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()))) { Ok(_) => (), _ => panic!("unexpected"), } @@ -910,7 +917,7 @@ mod tests { acl_storage: Arc::new(DummyAclStorage::default()), cluster: Arc::new(DummyCluster::new(self_node_id.clone())), nonce: 0, - }, Some(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap())).unwrap(); + }, Some(Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()))).unwrap(); assert_eq!(session.initialize(Default::default(), false, false), Err(Error::InvalidMessage)); } @@ -943,7 +950,7 @@ mod tests { acl_storage: Arc::new(DummyAclStorage::default()), cluster: Arc::new(DummyCluster::new(self_node_id.clone())), nonce: 0, - }, Some(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap())).unwrap(); + }, Some(Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()))).unwrap(); assert_eq!(session.initialize(Default::default(), false, false), Err(Error::ConsensusUnreachable)); } @@ -963,7 +970,8 @@ mod tests { sub_session: sessions[0].access_key().clone().into(), session_nonce: 0, message: message::ConsensusMessage::InitializeConsensusSession(message::InitializeConsensusSession { - requestor_signature: ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap().into(), + requester: Requester::Signature(ethkey::sign( + Random.generate().unwrap().secret(), &SessionId::default()).unwrap()).into(), version: Default::default(), }), }).unwrap_err(), Error::InvalidMessage); @@ -977,7 +985,8 @@ mod tests { sub_session: sessions[0].access_key().clone().into(), session_nonce: 0, message: message::ConsensusMessage::InitializeConsensusSession(message::InitializeConsensusSession { - requestor_signature: ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap().into(), + requester: Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), + &SessionId::default()).unwrap()).into(), version: Default::default(), }), }).unwrap(), ()); @@ -1000,7 +1009,8 @@ mod tests { sub_session: sessions[0].access_key().clone().into(), session_nonce: 0, message: message::ConsensusMessage::InitializeConsensusSession(message::InitializeConsensusSession { - requestor_signature: ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap().into(), + requester: Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), + &SessionId::default()).unwrap()).into(), version: Default::default(), }), }).unwrap(), ()); @@ -1263,8 +1273,8 @@ mod tests { // let's say node1 doesn't have a share && delegates decryption request to node0 // initially session is created on node1 => node1 is master for itself, but for other nodes node0 is still master sessions[1].core.meta.master_node_id = sessions[1].core.meta.self_node_id.clone(); - sessions[1].data.lock().consensus_session.consensus_job_mut().executor_mut().set_requester_signature( - sessions[0].data.lock().consensus_session.consensus_job().executor().requester_signature().unwrap().clone() + sessions[1].data.lock().consensus_session.consensus_job_mut().executor_mut().set_requester( + sessions[0].data.lock().consensus_session.consensus_job().executor().requester().unwrap().clone() ); // now let's try to do a decryption diff --git a/secret_store/src/key_server_cluster/client_sessions/encryption_session.rs b/secret_store/src/key_server_cluster/client_sessions/encryption_session.rs index 22aa8d40e..18b8c53ff 100644 --- a/secret_store/src/key_server_cluster/client_sessions/encryption_session.rs +++ b/secret_store/src/key_server_cluster/client_sessions/encryption_session.rs @@ -19,8 +19,8 @@ use std::fmt::{Debug, Formatter, Error as FmtError}; use std::time; use std::sync::Arc; use parking_lot::{Condvar, Mutex}; -use ethkey::{self, Public, Signature}; -use key_server_cluster::{Error, NodeId, SessionId, KeyStorage, DocumentKeyShare}; +use ethkey::Public; +use key_server_cluster::{Error, NodeId, SessionId, Requester, KeyStorage, DocumentKeyShare}; use key_server_cluster::cluster::Cluster; use key_server_cluster::cluster_sessions::ClusterSession; use key_server_cluster::message::{Message, EncryptionMessage, InitializeEncryptionSession, @@ -137,7 +137,7 @@ impl SessionImpl { /// Start new session initialization. This must be called on master node. - pub fn initialize(&self, requestor_signature: Signature, common_point: Public, encrypted_point: Public) -> Result<(), Error> { + pub fn initialize(&self, requester: Requester, common_point: Public, encrypted_point: Public) -> Result<(), Error> { let mut data = self.data.lock(); // check state @@ -157,8 +157,8 @@ impl SessionImpl { // save encryption data if let Some(mut encrypted_data) = self.encrypted_data.clone() { // check that the requester is the author of the encrypted data - let requestor_public = ethkey::recover(&requestor_signature, &self.id)?; - if encrypted_data.author != requestor_public { + let requester_public = requester.public(&self.id).ok_or(Error::InsufficientRequesterData)?; + if encrypted_data.author != requester_public { return Err(Error::AccessDenied); } @@ -173,7 +173,7 @@ impl SessionImpl { self.cluster.broadcast(Message::Encryption(EncryptionMessage::InitializeEncryptionSession(InitializeEncryptionSession { session: self.id.clone().into(), session_nonce: self.nonce, - requestor_signature: requestor_signature.into(), + requester: requester.into(), common_point: common_point.into(), encrypted_point: encrypted_point.into(), }))) @@ -200,7 +200,8 @@ impl SessionImpl { // check that the requester is the author of the encrypted data if let Some(mut encrypted_data) = self.encrypted_data.clone() { - let requestor_public = ethkey::recover(&message.requestor_signature.clone().into(), &self.id)?; + let requester: Requester = message.requester.clone().into(); + let requestor_public = requester.public(&self.id).ok_or(Error::InsufficientRequesterData)?; if encrypted_data.author != requestor_public { return Err(Error::AccessDenied); } diff --git a/secret_store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs b/secret_store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs index 9bb063840..cd97a1c17 100644 --- a/secret_store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs +++ b/secret_store/src/key_server_cluster/client_sessions/signing_session_ecdsa.rs @@ -20,7 +20,7 @@ use std::sync::Arc; use parking_lot::{Mutex, Condvar}; use ethkey::{Public, Secret, Signature, sign}; use ethereum_types::H256; -use key_server_cluster::{Error, NodeId, SessionId, SessionMeta, AclStorage, DocumentKeyShare}; +use key_server_cluster::{Error, NodeId, SessionId, SessionMeta, AclStorage, DocumentKeyShare, Requester}; use key_server_cluster::cluster::{Cluster}; use key_server_cluster::cluster_sessions::{SessionIdWithSubSession, ClusterSession}; use key_server_cluster::generation_session::{SessionImpl as GenerationSession, SessionParams as GenerationSessionParams, @@ -170,7 +170,7 @@ enum DelegationStatus { impl SessionImpl { /// Create new signing session. - pub fn new(params: SessionParams, requester_signature: Option) -> Result { + pub fn new(params: SessionParams, requester: Option) -> Result { debug_assert_eq!(params.meta.threshold, params.key_share.as_ref().map(|ks| ks.threshold).unwrap_or_default()); let consensus_transport = SigningConsensusTransport { @@ -188,8 +188,8 @@ impl SessionImpl { self_node_id: params.meta.self_node_id, threshold: params.meta.threshold * 2, }, - consensus_executor: match requester_signature { - Some(requester_signature) => KeyAccessJob::new_on_master(params.meta.id.clone(), params.acl_storage.clone(), requester_signature), + consensus_executor: match requester { + Some(requester) => KeyAccessJob::new_on_master(params.meta.id.clone(), params.acl_storage.clone(), requester), None => KeyAccessJob::new_on_slave(params.meta.id.clone(), params.acl_storage.clone()), }, consensus_transport: consensus_transport, @@ -240,8 +240,8 @@ impl SessionImpl { session: self.core.meta.id.clone().into(), sub_session: self.core.access_key.clone().into(), session_nonce: self.core.nonce, - requestor_signature: data.consensus_session.consensus_job().executor().requester_signature() - .expect("signature is passed to master node on creation; session can be delegated from master node only; qed") + requester: data.consensus_session.consensus_job().executor().requester() + .expect("requester is passed to master node on creation; session can be delegated from master node only; qed") .clone().into(), version: version.into(), message_hash: message_hash.into(), @@ -331,7 +331,7 @@ impl SessionImpl { return Err(Error::InvalidStateForRequest); } - data.consensus_session.consensus_job_mut().executor_mut().set_requester_signature(message.requestor_signature.clone().into()); + data.consensus_session.consensus_job_mut().executor_mut().set_requester(message.requester.clone().into()); data.delegation_status = Some(DelegationStatus::DelegatedFrom(sender.clone(), message.session_nonce)); } @@ -994,10 +994,10 @@ impl SessionCore { } impl JobTransport for SigningConsensusTransport { - type PartialJobRequest=Signature; + type PartialJobRequest=Requester; type PartialJobResponse=bool; - fn send_partial_request(&self, node: &NodeId, request: Signature) -> Result<(), Error> { + fn send_partial_request(&self, node: &NodeId, request: Requester) -> Result<(), Error> { let version = self.version.as_ref() .expect("send_partial_request is called on initialized master node only; version is filled in before initialization starts on master node; qed"); self.cluster.send(node, Message::EcdsaSigning(EcdsaSigningMessage::EcdsaSigningConsensusMessage(EcdsaSigningConsensusMessage { @@ -1005,7 +1005,7 @@ impl JobTransport for SigningConsensusTransport { sub_session: self.access_key.clone().into(), session_nonce: self.nonce, message: ConsensusMessage::InitializeConsensusSession(InitializeConsensusSession { - requestor_signature: request.into(), + requester: request.into(), version: version.clone().into(), }) }))) @@ -1104,7 +1104,7 @@ mod tests { acl_storage: acl_storage, cluster: cluster.clone(), nonce: 0, - }, if i == 0 { signature.clone() } else { None }).unwrap(); + }, if i == 0 { signature.clone().map(Into::into) } else { None }).unwrap(); nodes.insert(gl_node_id.clone(), Node { node_id: gl_node_id.clone(), cluster: cluster, key_storage: gl_node.key_storage.clone(), session: session }); } @@ -1261,8 +1261,8 @@ mod tests { sl.nodes[&requested_node].key_storage.remove(&Default::default()).unwrap(); sl.nodes.get_mut(&requested_node).unwrap().session.core.key_share = None; sl.nodes.get_mut(&requested_node).unwrap().session.core.meta.master_node_id = sl.nodes[&requested_node].session.core.meta.self_node_id.clone(); - sl.nodes[&requested_node].session.data.lock().consensus_session.consensus_job_mut().executor_mut().set_requester_signature( - sl.nodes[&actual_master].session.data.lock().consensus_session.consensus_job().executor().requester_signature().unwrap().clone() + sl.nodes[&requested_node].session.data.lock().consensus_session.consensus_job_mut().executor_mut().set_requester( + sl.nodes[&actual_master].session.data.lock().consensus_session.consensus_job().executor().requester().unwrap().clone() ); // now let's try to do a decryption diff --git a/secret_store/src/key_server_cluster/client_sessions/signing_session_schnorr.rs b/secret_store/src/key_server_cluster/client_sessions/signing_session_schnorr.rs index ae3e0289f..625565ac5 100644 --- a/secret_store/src/key_server_cluster/client_sessions/signing_session_schnorr.rs +++ b/secret_store/src/key_server_cluster/client_sessions/signing_session_schnorr.rs @@ -17,9 +17,9 @@ use std::collections::BTreeSet; use std::sync::Arc; use parking_lot::{Mutex, Condvar}; -use ethkey::{Public, Secret, Signature}; +use ethkey::{Public, Secret}; use ethereum_types::H256; -use key_server_cluster::{Error, NodeId, SessionId, SessionMeta, AclStorage, DocumentKeyShare}; +use key_server_cluster::{Error, NodeId, SessionId, Requester, SessionMeta, AclStorage, DocumentKeyShare}; use key_server_cluster::cluster::{Cluster}; use key_server_cluster::cluster_sessions::{SessionIdWithSubSession, ClusterSession}; use key_server_cluster::generation_session::{SessionImpl as GenerationSession, SessionParams as GenerationSessionParams, @@ -160,7 +160,7 @@ enum DelegationStatus { impl SessionImpl { /// Create new signing session. - pub fn new(params: SessionParams, requester_signature: Option) -> Result { + pub fn new(params: SessionParams, requester: Option) -> Result { debug_assert_eq!(params.meta.threshold, params.key_share.as_ref().map(|ks| ks.threshold).unwrap_or_default()); let consensus_transport = SigningConsensusTransport { @@ -172,8 +172,8 @@ impl SessionImpl { }; let consensus_session = ConsensusSession::new(ConsensusSessionParams { meta: params.meta.clone(), - consensus_executor: match requester_signature { - Some(requester_signature) => KeyAccessJob::new_on_master(params.meta.id.clone(), params.acl_storage.clone(), requester_signature), + consensus_executor: match requester { + Some(requester) => KeyAccessJob::new_on_master(params.meta.id.clone(), params.acl_storage.clone(), requester), None => KeyAccessJob::new_on_slave(params.meta.id.clone(), params.acl_storage.clone()), }, consensus_transport: consensus_transport, @@ -227,8 +227,8 @@ impl SessionImpl { session: self.core.meta.id.clone().into(), sub_session: self.core.access_key.clone().into(), session_nonce: self.core.nonce, - requestor_signature: data.consensus_session.consensus_job().executor().requester_signature() - .expect("signature is passed to master node on creation; session can be delegated from master node only; qed") + requester: data.consensus_session.consensus_job().executor().requester() + .expect("requester is passed to master node on creation; session can be delegated from master node only; qed") .clone().into(), version: version.into(), message_hash: message_hash.into(), @@ -333,7 +333,7 @@ impl SessionImpl { return Err(Error::InvalidStateForRequest); } - data.consensus_session.consensus_job_mut().executor_mut().set_requester_signature(message.requestor_signature.clone().into()); + data.consensus_session.consensus_job_mut().executor_mut().set_requester(message.requester.clone().into()); data.delegation_status = Some(DelegationStatus::DelegatedFrom(sender.clone(), message.session_nonce)); } @@ -740,10 +740,10 @@ impl SessionCore { } impl JobTransport for SigningConsensusTransport { - type PartialJobRequest=Signature; + type PartialJobRequest=Requester; type PartialJobResponse=bool; - fn send_partial_request(&self, node: &NodeId, request: Signature) -> Result<(), Error> { + fn send_partial_request(&self, node: &NodeId, request: Requester) -> Result<(), Error> { let version = self.version.as_ref() .expect("send_partial_request is called on initialized master node only; version is filled in before initialization starts on master node; qed"); self.cluster.send(node, Message::SchnorrSigning(SchnorrSigningMessage::SchnorrSigningConsensusMessage(SchnorrSigningConsensusMessage { @@ -751,7 +751,7 @@ impl JobTransport for SigningConsensusTransport { sub_session: self.access_key.clone().into(), session_nonce: self.nonce, message: ConsensusMessage::InitializeConsensusSession(InitializeConsensusSession { - requestor_signature: request.into(), + requester: request.into(), version: version.clone().into(), }) }))) @@ -803,7 +803,8 @@ mod tests { use ethereum_types::H256; use ethkey::{self, Random, Generator, Public, Secret, KeyPair}; use acl_storage::DummyAclStorage; - use key_server_cluster::{NodeId, DummyKeyStorage, DocumentKeyShare, DocumentKeyShareVersion, SessionId, SessionMeta, Error, KeyStorage}; + use key_server_cluster::{NodeId, DummyKeyStorage, DocumentKeyShare, DocumentKeyShareVersion, SessionId, + Requester, SessionMeta, Error, KeyStorage}; use key_server_cluster::cluster_sessions::ClusterSession; use key_server_cluster::cluster::tests::DummyCluster; use key_server_cluster::generation_session::tests::MessageLoop as KeyGenerationMessageLoop; @@ -853,7 +854,7 @@ mod tests { acl_storage: acl_storage, cluster: cluster.clone(), nonce: 0, - }, if i == 0 { signature.clone() } else { None }).unwrap(); + }, if i == 0 { signature.clone().map(Into::into) } else { None }).unwrap(); nodes.insert(gl_node_id.clone(), Node { node_id: gl_node_id.clone(), cluster: cluster, key_storage: gl_node.key_storage.clone(), session: session }); } @@ -984,7 +985,7 @@ mod tests { acl_storage: Arc::new(DummyAclStorage::default()), cluster: Arc::new(DummyCluster::new(self_node_id.clone())), nonce: 0, - }, Some(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap())) { + }, Some(Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()))) { Ok(_) => (), _ => panic!("unexpected"), } @@ -1005,7 +1006,7 @@ mod tests { acl_storage: Arc::new(DummyAclStorage::default()), cluster: Arc::new(DummyCluster::new(self_node_id.clone())), nonce: 0, - }, Some(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap())).unwrap(); + }, Some(Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()))).unwrap(); assert_eq!(session.initialize(Default::default(), Default::default()), Err(Error::InvalidMessage)); } @@ -1038,7 +1039,7 @@ mod tests { acl_storage: Arc::new(DummyAclStorage::default()), cluster: Arc::new(DummyCluster::new(self_node_id.clone())), nonce: 0, - }, Some(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap())).unwrap(); + }, Some(Requester::Signature(ethkey::sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()))).unwrap(); assert_eq!(session.initialize(Default::default(), Default::default()), Err(Error::ConsensusUnreachable)); } @@ -1231,8 +1232,8 @@ mod tests { sl.nodes[&requested_node].key_storage.remove(&Default::default()).unwrap(); sl.nodes.get_mut(&requested_node).unwrap().session.core.key_share = None; sl.nodes.get_mut(&requested_node).unwrap().session.core.meta.master_node_id = sl.nodes[&requested_node].session.core.meta.self_node_id.clone(); - sl.nodes[&requested_node].session.data.lock().consensus_session.consensus_job_mut().executor_mut().set_requester_signature( - sl.nodes[&actual_master].session.data.lock().consensus_session.consensus_job().executor().requester_signature().unwrap().clone() + sl.nodes[&requested_node].session.data.lock().consensus_session.consensus_job_mut().executor_mut().set_requester( + sl.nodes[&actual_master].session.data.lock().consensus_session.consensus_job().executor().requester().unwrap().clone() ); // now let's try to do a decryption diff --git a/secret_store/src/key_server_cluster/cluster.rs b/secret_store/src/key_server_cluster/cluster.rs index 52d7f6b16..62e0dce6a 100644 --- a/secret_store/src/key_server_cluster/cluster.rs +++ b/secret_store/src/key_server_cluster/cluster.rs @@ -28,7 +28,7 @@ use tokio_core::reactor::{Handle, Remote, Interval}; use tokio_core::net::{TcpListener, TcpStream}; use ethkey::{Public, KeyPair, Signature, Random, Generator}; use ethereum_types::H256; -use key_server_cluster::{Error, NodeId, SessionId, AclStorage, KeyStorage, KeyServerSet, NodeKeyPair}; +use key_server_cluster::{Error, NodeId, SessionId, Requester, AclStorage, KeyStorage, KeyServerSet, NodeKeyPair}; use key_server_cluster::cluster_sessions::{ClusterSession, AdminSession, ClusterSessions, SessionIdWithSubSession, ClusterSessionsContainer, SERVERS_SET_CHANGE_SESSION_ID, create_cluster_view, AdminSessionCreationData, ClusterSessionsListener}; use key_server_cluster::cluster_sessions_creator::{ClusterSessionCreator, IntoSessionId}; @@ -68,13 +68,13 @@ pub trait ClusterClient: Send + Sync { /// Start new generation session. fn new_generation_session(&self, session_id: SessionId, author: Public, threshold: usize) -> Result, Error>; /// Start new encryption session. - fn new_encryption_session(&self, session_id: SessionId, requestor_signature: Signature, common_point: Public, encrypted_point: Public) -> Result, Error>; + fn new_encryption_session(&self, session_id: SessionId, requester: Requester, common_point: Public, encrypted_point: Public) -> Result, Error>; /// Start new decryption session. - fn new_decryption_session(&self, session_id: SessionId, requestor_signature: Signature, version: Option, is_shadow_decryption: bool) -> Result, Error>; - /// Start new signing session. - fn new_schnorr_signing_session(&self, session_id: SessionId, requestor_signature: Signature, version: Option, message_hash: H256) -> Result, Error>; + fn new_decryption_session(&self, session_id: SessionId, requester: Requester, version: Option, is_shadow_decryption: bool) -> Result, Error>; + /// Start new Schnorr signing session. + fn new_schnorr_signing_session(&self, session_id: SessionId, requester: Requester, version: Option, message_hash: H256) -> Result, Error>; /// Start new ECDSA session. - fn new_ecdsa_signing_session(&self, session_id: SessionId, requestor_signature: Signature, version: Option, message_hash: H256) -> Result, Error>; + fn new_ecdsa_signing_session(&self, session_id: SessionId, requester: Requester, version: Option, message_hash: H256) -> Result, Error>; /// Start new key version negotiation session. fn new_key_version_negotiation_session(&self, session_id: SessionId) -> Result>, Error>; /// Start new servers set change session. @@ -916,13 +916,13 @@ impl ClusterClient for ClusterClientImpl { } } - fn new_encryption_session(&self, session_id: SessionId, requestor_signature: Signature, common_point: Public, encrypted_point: Public) -> Result, Error> { + fn new_encryption_session(&self, session_id: SessionId, requester: Requester, common_point: Public, encrypted_point: Public) -> Result, Error> { let mut connected_nodes = self.data.connections.connected_nodes(); connected_nodes.insert(self.data.self_key_pair.public().clone()); let cluster = create_cluster_view(&self.data, true)?; let session = self.data.sessions.encryption_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id, None, false, None)?; - match session.initialize(requestor_signature, common_point, encrypted_point) { + match session.initialize(requester, common_point, encrypted_point) { Ok(()) => Ok(session), Err(error) => { self.data.sessions.encryption_sessions.remove(&session.id()); @@ -931,14 +931,15 @@ impl ClusterClient for ClusterClientImpl { } } - fn new_decryption_session(&self, session_id: SessionId, requestor_signature: Signature, version: Option, is_shadow_decryption: bool) -> Result, Error> { + fn new_decryption_session(&self, session_id: SessionId, requester: Requester, version: Option, is_shadow_decryption: bool) -> Result, Error> { let mut connected_nodes = self.data.connections.connected_nodes(); connected_nodes.insert(self.data.self_key_pair.public().clone()); let access_key = Random.generate()?.secret().clone(); let session_id = SessionIdWithSubSession::new(session_id, access_key); let cluster = create_cluster_view(&self.data, false)?; - let session = self.data.sessions.decryption_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id.clone(), None, false, Some(requestor_signature))?; + let session = self.data.sessions.decryption_sessions.insert(cluster, self.data.self_key_pair.public().clone(), + session_id.clone(), None, false, Some(requester))?; let initialization_result = match version { Some(version) => session.initialize(version, is_shadow_decryption, false), @@ -960,14 +961,14 @@ impl ClusterClient for ClusterClientImpl { } } - fn new_schnorr_signing_session(&self, session_id: SessionId, requestor_signature: Signature, version: Option, message_hash: H256) -> Result, Error> { + fn new_schnorr_signing_session(&self, session_id: SessionId, requester: Requester, version: Option, message_hash: H256) -> Result, Error> { let mut connected_nodes = self.data.connections.connected_nodes(); connected_nodes.insert(self.data.self_key_pair.public().clone()); let access_key = Random.generate()?.secret().clone(); let session_id = SessionIdWithSubSession::new(session_id, access_key); let cluster = create_cluster_view(&self.data, false)?; - let session = self.data.sessions.schnorr_signing_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id.clone(), None, false, Some(requestor_signature))?; + let session = self.data.sessions.schnorr_signing_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id.clone(), None, false, Some(requester))?; let initialization_result = match version { Some(version) => session.initialize(version, message_hash), @@ -989,14 +990,14 @@ impl ClusterClient for ClusterClientImpl { } } - fn new_ecdsa_signing_session(&self, session_id: SessionId, requestor_signature: Signature, version: Option, message_hash: H256) -> Result, Error> { + fn new_ecdsa_signing_session(&self, session_id: SessionId, requester: Requester, version: Option, message_hash: H256) -> Result, Error> { let mut connected_nodes = self.data.connections.connected_nodes(); connected_nodes.insert(self.data.self_key_pair.public().clone()); let access_key = Random.generate()?.secret().clone(); let session_id = SessionIdWithSubSession::new(session_id, access_key); let cluster = create_cluster_view(&self.data, false)?; - let session = self.data.sessions.ecdsa_signing_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id.clone(), None, false, Some(requestor_signature))?; + let session = self.data.sessions.ecdsa_signing_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id.clone(), None, false, Some(requester))?; let initialization_result = match version { Some(version) => session.initialize(version, message_hash), @@ -1090,7 +1091,8 @@ pub mod tests { use tokio_core::reactor::Core; use ethereum_types::H256; use ethkey::{Random, Generator, Public, Signature, sign}; - use key_server_cluster::{NodeId, SessionId, Error, DummyAclStorage, DummyKeyStorage, MapKeyServerSet, PlainNodeKeyPair, KeyStorage}; + use key_server_cluster::{NodeId, SessionId, Requester, Error, DummyAclStorage, DummyKeyStorage, + MapKeyServerSet, PlainNodeKeyPair, KeyStorage}; use key_server_cluster::message::Message; use key_server_cluster::cluster::{Cluster, ClusterCore, ClusterConfiguration, ClusterClient, ClusterState}; use key_server_cluster::cluster_sessions::{ClusterSession, AdminSession, ClusterSessionsListener}; @@ -1120,10 +1122,10 @@ pub mod tests { impl ClusterClient for DummyClusterClient { fn cluster_state(&self) -> ClusterState { unimplemented!("test-only") } fn new_generation_session(&self, _session_id: SessionId, _author: Public, _threshold: usize) -> Result, Error> { unimplemented!("test-only") } - fn new_encryption_session(&self, _session_id: SessionId, _requestor_signature: Signature, _common_point: Public, _encrypted_point: Public) -> Result, Error> { unimplemented!("test-only") } - fn new_decryption_session(&self, _session_id: SessionId, _requestor_signature: Signature, _version: Option, _is_shadow_decryption: bool) -> Result, Error> { unimplemented!("test-only") } - fn new_schnorr_signing_session(&self, _session_id: SessionId, _requestor_signature: Signature, _version: Option, _message_hash: H256) -> Result, Error> { unimplemented!("test-only") } - fn new_ecdsa_signing_session(&self, _session_id: SessionId, _requestor_signature: Signature, _version: Option, _message_hash: H256) -> Result, Error> { unimplemented!("test-only") } + fn new_encryption_session(&self, _session_id: SessionId, _requester: Requester, _common_point: Public, _encrypted_point: Public) -> Result, Error> { unimplemented!("test-only") } + fn new_decryption_session(&self, _session_id: SessionId, _requester: Requester, _version: Option, _is_shadow_decryption: bool) -> Result, Error> { unimplemented!("test-only") } + fn new_schnorr_signing_session(&self, _session_id: SessionId, _requester: Requester, _version: Option, _message_hash: H256) -> Result, Error> { unimplemented!("test-only") } + fn new_ecdsa_signing_session(&self, _session_id: SessionId, _requester: Requester, _version: Option, _message_hash: H256) -> Result, Error> { unimplemented!("test-only") } fn new_key_version_negotiation_session(&self, _session_id: SessionId) -> Result>, Error> { unimplemented!("test-only") } fn new_servers_set_change_session(&self, _session_id: Option, _migration_id: Option, _new_nodes_set: BTreeSet, _old_set_signature: Signature, _new_set_signature: Signature) -> Result, Error> { unimplemented!("test-only") } @@ -1401,7 +1403,7 @@ pub mod tests { // and try to sign message with generated key let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session0 = clusters[0].client().new_schnorr_signing_session(Default::default(), signature, None, Default::default()).unwrap(); + let session0 = clusters[0].client().new_schnorr_signing_session(Default::default(), signature.into(), None, Default::default()).unwrap(); let session = clusters[0].data.sessions.schnorr_signing_sessions.first().unwrap(); loop_until(&mut core, time::Duration::from_millis(300), || session.is_finished() && (0..3).all(|i| @@ -1410,8 +1412,9 @@ pub mod tests { // and try to sign message with generated key using node that has no key share let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session2 = clusters[2].client().new_schnorr_signing_session(Default::default(), signature, None, Default::default()).unwrap(); + let session2 = clusters[2].client().new_schnorr_signing_session(Default::default(), signature.into(), None, Default::default()).unwrap(); let session = clusters[2].data.sessions.schnorr_signing_sessions.first().unwrap(); + loop_until(&mut core, time::Duration::from_millis(300), || session.is_finished() && (0..3).all(|i| clusters[i].data.sessions.schnorr_signing_sessions.is_empty())); session2.wait().unwrap(); @@ -1421,8 +1424,9 @@ pub mod tests { // and try to sign message with generated key let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session1 = clusters[0].client().new_schnorr_signing_session(Default::default(), signature, None, Default::default()).unwrap(); + let session1 = clusters[0].client().new_schnorr_signing_session(Default::default(), signature.into(), None, Default::default()).unwrap(); let session = clusters[0].data.sessions.schnorr_signing_sessions.first().unwrap(); + loop_until(&mut core, time::Duration::from_millis(300), || session.is_finished()); session1.wait().unwrap_err(); } @@ -1448,7 +1452,7 @@ pub mod tests { // and try to sign message with generated key let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session0 = clusters[0].client().new_ecdsa_signing_session(Default::default(), signature, None, H256::random()).unwrap(); + let session0 = clusters[0].client().new_ecdsa_signing_session(Default::default(), signature.into(), None, H256::random()).unwrap(); let session = clusters[0].data.sessions.ecdsa_signing_sessions.first().unwrap(); loop_until(&mut core, time::Duration::from_millis(1000), || session.is_finished() && (0..3).all(|i| @@ -1457,7 +1461,7 @@ pub mod tests { // and try to sign message with generated key using node that has no key share let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session2 = clusters[2].client().new_ecdsa_signing_session(Default::default(), signature, None, H256::random()).unwrap(); + let session2 = clusters[2].client().new_ecdsa_signing_session(Default::default(), signature.into(), None, H256::random()).unwrap(); let session = clusters[2].data.sessions.ecdsa_signing_sessions.first().unwrap(); loop_until(&mut core, time::Duration::from_millis(1000), || session.is_finished() && (0..3).all(|i| clusters[i].data.sessions.ecdsa_signing_sessions.is_empty())); @@ -1468,7 +1472,7 @@ pub mod tests { // and try to sign message with generated key let signature = sign(Random.generate().unwrap().secret(), &Default::default()).unwrap(); - let session1 = clusters[0].client().new_ecdsa_signing_session(Default::default(), signature, None, H256::random()).unwrap(); + let session1 = clusters[0].client().new_ecdsa_signing_session(Default::default(), signature.into(), None, H256::random()).unwrap(); let session = clusters[0].data.sessions.ecdsa_signing_sessions.first().unwrap(); loop_until(&mut core, time::Duration::from_millis(1000), || session.is_finished()); session1.wait().unwrap_err(); diff --git a/secret_store/src/key_server_cluster/cluster_sessions.rs b/secret_store/src/key_server_cluster/cluster_sessions.rs index a1db7d919..86e38a879 100644 --- a/secret_store/src/key_server_cluster/cluster_sessions.rs +++ b/secret_store/src/key_server_cluster/cluster_sessions.rs @@ -20,8 +20,8 @@ use std::sync::atomic::AtomicBool; use std::collections::{VecDeque, BTreeMap, BTreeSet}; use parking_lot::{Mutex, RwLock, Condvar}; use ethereum_types::H256; -use ethkey::{Secret, Signature}; -use key_server_cluster::{Error, NodeId, SessionId}; +use ethkey::Secret; +use key_server_cluster::{Error, NodeId, SessionId, Requester}; use key_server_cluster::cluster::{Cluster, ClusterData, ClusterConfiguration, ClusterView}; use key_server_cluster::connection_trigger::ServersSetChangeSessionCreatorConnector; use key_server_cluster::message::{self, Message}; @@ -126,11 +126,11 @@ pub struct ClusterSessions { /// Encryption sessions. pub encryption_sessions: ClusterSessionsContainer, /// Decryption sessions. - pub decryption_sessions: ClusterSessionsContainer, + pub decryption_sessions: ClusterSessionsContainer, /// Schnorr signing sessions. - pub schnorr_signing_sessions: ClusterSessionsContainer, + pub schnorr_signing_sessions: ClusterSessionsContainer, /// ECDSA signing sessions. - pub ecdsa_signing_sessions: ClusterSessionsContainer, + pub ecdsa_signing_sessions: ClusterSessionsContainer, /// Key version negotiation sessions. pub negotiation_sessions: ClusterSessionsContainer, KeyVersionNegotiationSessionCreator, ()>, /// Administrative sessions. diff --git a/secret_store/src/key_server_cluster/cluster_sessions_creator.rs b/secret_store/src/key_server_cluster/cluster_sessions_creator.rs index 00ea08014..86e40853e 100644 --- a/secret_store/src/key_server_cluster/cluster_sessions_creator.rs +++ b/secret_store/src/key_server_cluster/cluster_sessions_creator.rs @@ -18,8 +18,8 @@ use std::sync::Arc; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::collections::BTreeMap; use parking_lot::RwLock; -use ethkey::{Public, Signature}; -use key_server_cluster::{Error, NodeId, SessionId, AclStorage, KeyStorage, DocumentKeyShare, SessionMeta}; +use ethkey::Public; +use key_server_cluster::{Error, NodeId, SessionId, Requester, AclStorage, KeyStorage, DocumentKeyShare, SessionMeta}; use key_server_cluster::cluster::{Cluster, ClusterConfiguration}; use key_server_cluster::connection_trigger::ServersSetChangeSessionCreatorConnector; use key_server_cluster::cluster_sessions::{ClusterSession, SessionIdWithSubSession, AdminSession, AdminSessionCreationData}; @@ -202,14 +202,14 @@ pub struct DecryptionSessionCreator { pub core: Arc, } -impl ClusterSessionCreator for DecryptionSessionCreator { - fn creation_data_from_message(message: &Message) -> Result, Error> { +impl ClusterSessionCreator for DecryptionSessionCreator { + fn creation_data_from_message(message: &Message) -> Result, Error> { match *message { Message::Decryption(DecryptionMessage::DecryptionConsensusMessage(ref message)) => match &message.message { - &ConsensusMessage::InitializeConsensusSession(ref message) => Ok(Some(message.requestor_signature.clone().into())), + &ConsensusMessage::InitializeConsensusSession(ref message) => Ok(Some(message.requester.clone().into())), _ => Err(Error::InvalidMessage), }, - Message::Decryption(DecryptionMessage::DecryptionSessionDelegation(ref message)) => Ok(Some(message.requestor_signature.clone().into())), + Message::Decryption(DecryptionMessage::DecryptionSessionDelegation(ref message)) => Ok(Some(message.requester.clone().into())), _ => Err(Error::InvalidMessage), } } @@ -223,7 +223,7 @@ impl ClusterSessionCreator for DecryptionSessi })) } - fn create(&self, cluster: Arc, master: NodeId, nonce: Option, id: SessionIdWithSubSession, requester_signature: Option) -> Result, Error> { + fn create(&self, cluster: Arc, master: NodeId, nonce: Option, id: SessionIdWithSubSession, requester: Option) -> Result, Error> { let encrypted_data = self.core.read_key_share(&id.id)?; let nonce = self.core.check_session_nonce(&master, nonce)?; Ok(Arc::new(DecryptionSessionImpl::new(DecryptionSessionParams { @@ -238,7 +238,7 @@ impl ClusterSessionCreator for DecryptionSessi acl_storage: self.core.acl_storage.clone(), cluster: cluster, nonce: nonce, - }, requester_signature)?)) + }, requester)?)) } } @@ -248,14 +248,14 @@ pub struct SchnorrSigningSessionCreator { pub core: Arc, } -impl ClusterSessionCreator for SchnorrSigningSessionCreator { - fn creation_data_from_message(message: &Message) -> Result, Error> { +impl ClusterSessionCreator for SchnorrSigningSessionCreator { + fn creation_data_from_message(message: &Message) -> Result, Error> { match *message { Message::SchnorrSigning(SchnorrSigningMessage::SchnorrSigningConsensusMessage(ref message)) => match &message.message { - &ConsensusMessage::InitializeConsensusSession(ref message) => Ok(Some(message.requestor_signature.clone().into())), + &ConsensusMessage::InitializeConsensusSession(ref message) => Ok(Some(message.requester.clone().into())), _ => Err(Error::InvalidMessage), }, - Message::SchnorrSigning(SchnorrSigningMessage::SchnorrSigningSessionDelegation(ref message)) => Ok(Some(message.requestor_signature.clone().into())), + Message::SchnorrSigning(SchnorrSigningMessage::SchnorrSigningSessionDelegation(ref message)) => Ok(Some(message.requester.clone().into())), _ => Err(Error::InvalidMessage), } } @@ -269,7 +269,7 @@ impl ClusterSessionCreator for SchnorrSign })) } - fn create(&self, cluster: Arc, master: NodeId, nonce: Option, id: SessionIdWithSubSession, requester_signature: Option) -> Result, Error> { + fn create(&self, cluster: Arc, master: NodeId, nonce: Option, id: SessionIdWithSubSession, requester: Option) -> Result, Error> { let encrypted_data = self.core.read_key_share(&id.id)?; let nonce = self.core.check_session_nonce(&master, nonce)?; Ok(Arc::new(SchnorrSigningSessionImpl::new(SchnorrSigningSessionParams { @@ -284,7 +284,7 @@ impl ClusterSessionCreator for SchnorrSign acl_storage: self.core.acl_storage.clone(), cluster: cluster, nonce: nonce, - }, requester_signature)?)) + }, requester)?)) } } @@ -294,14 +294,14 @@ pub struct EcdsaSigningSessionCreator { pub core: Arc, } -impl ClusterSessionCreator for EcdsaSigningSessionCreator { - fn creation_data_from_message(message: &Message) -> Result, Error> { +impl ClusterSessionCreator for EcdsaSigningSessionCreator { + fn creation_data_from_message(message: &Message) -> Result, Error> { match *message { Message::EcdsaSigning(EcdsaSigningMessage::EcdsaSigningConsensusMessage(ref message)) => match &message.message { - &ConsensusMessage::InitializeConsensusSession(ref message) => Ok(Some(message.requestor_signature.clone().into())), + &ConsensusMessage::InitializeConsensusSession(ref message) => Ok(Some(message.requester.clone().into())), _ => Err(Error::InvalidMessage), }, - Message::EcdsaSigning(EcdsaSigningMessage::EcdsaSigningSessionDelegation(ref message)) => Ok(Some(message.requestor_signature.clone().into())), + Message::EcdsaSigning(EcdsaSigningMessage::EcdsaSigningSessionDelegation(ref message)) => Ok(Some(message.requester.clone().into())), _ => Err(Error::InvalidMessage), } } @@ -315,7 +315,7 @@ impl ClusterSessionCreator for EcdsaSigningS })) } - fn create(&self, cluster: Arc, master: NodeId, nonce: Option, id: SessionIdWithSubSession, requester_signature: Option) -> Result, Error> { + fn create(&self, cluster: Arc, master: NodeId, nonce: Option, id: SessionIdWithSubSession, requester: Option) -> Result, Error> { let encrypted_data = self.core.read_key_share(&id.id)?; let nonce = self.core.check_session_nonce(&master, nonce)?; Ok(Arc::new(EcdsaSigningSessionImpl::new(EcdsaSigningSessionParams { @@ -330,7 +330,7 @@ impl ClusterSessionCreator for EcdsaSigningS acl_storage: self.core.acl_storage.clone(), cluster: cluster, nonce: nonce, - }, requester_signature)?)) + }, requester)?)) } } diff --git a/secret_store/src/key_server_cluster/jobs/consensus_session.rs b/secret_store/src/key_server_cluster/jobs/consensus_session.rs index d57b57e5f..42de71b54 100644 --- a/secret_store/src/key_server_cluster/jobs/consensus_session.rs +++ b/secret_store/src/key_server_cluster/jobs/consensus_session.rs @@ -15,8 +15,7 @@ // along with Parity. If not, see . use std::collections::BTreeSet; -use ethkey::Signature; -use key_server_cluster::{Error, NodeId, SessionMeta}; +use key_server_cluster::{Error, NodeId, SessionMeta, Requester}; use key_server_cluster::message::ConsensusMessage; use key_server_cluster::jobs::job_session::{JobSession, JobSessionState, JobTransport, JobExecutor}; @@ -342,7 +341,7 @@ impl ConsensusSession - where ConsensusExecutor: JobExecutor>, + where ConsensusExecutor: JobExecutor>, ConsensusTransport: JobTransport, ComputationExecutor: JobExecutor, ComputationTransport: JobTransport { @@ -351,7 +350,7 @@ impl - self.consensus_job.on_partial_request(sender, message.requestor_signature.clone().into()), + self.consensus_job.on_partial_request(sender, message.requester.clone().into()), &ConsensusMessage::ConfirmConsensusInitialization(ref message) => self.consensus_job.on_partial_response(sender, message.is_confirmed), }; @@ -362,20 +361,21 @@ impl, SquaredSumJobExecutor, DummyJobTransport>; + type SquaredSumConsensusSession = ConsensusSession, SquaredSumJobExecutor, DummyJobTransport>; fn make_master_consensus_session(threshold: usize, requester: Option, acl_storage: Option) -> SquaredSumConsensusSession { let secret = requester.map(|kp| kp.secret().clone()).unwrap_or(Random.generate().unwrap().secret().clone()); SquaredSumConsensusSession::new(ConsensusSessionParams { meta: make_master_session_meta(threshold), - consensus_executor: KeyAccessJob::new_on_master(SessionId::default(), Arc::new(acl_storage.unwrap_or(DummyAclStorage::default())), sign(&secret, &SessionId::default()).unwrap()), + consensus_executor: KeyAccessJob::new_on_master(SessionId::default(), Arc::new(acl_storage.unwrap_or(DummyAclStorage::default())), + sign(&secret, &SessionId::default()).unwrap().into()), consensus_transport: DummyJobTransport::default(), }).unwrap() } @@ -502,7 +502,7 @@ mod tests { let mut session = make_slave_consensus_session(0, None); assert_eq!(session.state(), ConsensusSessionState::WaitingForInitialization); session.on_consensus_message(&NodeId::from(1), &ConsensusMessage::InitializeConsensusSession(InitializeConsensusSession { - requestor_signature: sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap().into(), + requester: Requester::Signature(sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()).into(), version: Default::default(), })).unwrap(); assert_eq!(session.state(), ConsensusSessionState::ConsensusEstablished); @@ -515,7 +515,7 @@ mod tests { let mut session = make_slave_consensus_session(0, None); assert_eq!(session.state(), ConsensusSessionState::WaitingForInitialization); session.on_consensus_message(&NodeId::from(1), &ConsensusMessage::InitializeConsensusSession(InitializeConsensusSession { - requestor_signature: sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap().into(), + requester: Requester::Signature(sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()).into(), version: Default::default(), })).unwrap(); assert_eq!(session.state(), ConsensusSessionState::ConsensusEstablished); @@ -545,7 +545,7 @@ mod tests { fn consessus_session_completion_is_accepted() { let mut session = make_slave_consensus_session(0, None); session.on_consensus_message(&NodeId::from(1), &ConsensusMessage::InitializeConsensusSession(InitializeConsensusSession { - requestor_signature: sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap().into(), + requester: Requester::Signature(sign(Random.generate().unwrap().secret(), &SessionId::default()).unwrap()).into(), version: Default::default(), })).unwrap(); session.on_session_completed(&NodeId::from(1)).unwrap(); diff --git a/secret_store/src/key_server_cluster/jobs/key_access_job.rs b/secret_store/src/key_server_cluster/jobs/key_access_job.rs index a42a76aa6..2cb686e6c 100644 --- a/secret_store/src/key_server_cluster/jobs/key_access_job.rs +++ b/secret_store/src/key_server_cluster/jobs/key_access_job.rs @@ -16,8 +16,7 @@ use std::sync::Arc; use std::collections::{BTreeSet, BTreeMap}; -use ethkey::{Public, Signature, recover}; -use key_server_cluster::{Error, NodeId, SessionId, AclStorage}; +use key_server_cluster::{Error, NodeId, SessionId, Requester, AclStorage}; use key_server_cluster::jobs::job_session::{JobPartialResponseAction, JobPartialRequestAction, JobExecutor}; /// Purpose of this job is to construct set of nodes, which have agreed to provide access to the given key for the given requestor. @@ -28,8 +27,8 @@ pub struct KeyAccessJob { has_key_share: bool, /// ACL storage. acl_storage: Arc, - /// Requester signature. - signature: Option, + /// Requester data. + requester: Option, } impl KeyAccessJob { @@ -38,16 +37,16 @@ impl KeyAccessJob { id: id, has_key_share: true, acl_storage: acl_storage, - signature: None, + requester: None, } } - pub fn new_on_master(id: SessionId, acl_storage: Arc, signature: Signature) -> Self { + pub fn new_on_master(id: SessionId, acl_storage: Arc, requester: Requester) -> Self { KeyAccessJob { id: id, has_key_share: true, acl_storage: acl_storage, - signature: Some(signature), + requester: Some(requester), } } @@ -55,38 +54,31 @@ impl KeyAccessJob { self.has_key_share = has_key_share; } - pub fn set_requester_signature(&mut self, signature: Signature) { - self.signature = Some(signature); + pub fn set_requester(&mut self, requester: Requester) { + self.requester = Some(requester); } - pub fn requester_signature(&self) -> Option<&Signature> { - self.signature.as_ref() - } - - pub fn requester(&self) -> Result, Error> { - match self.signature.as_ref() { - Some(signature) => Ok(Some(recover(signature, &self.id)?)), - None => Ok(None), - } + pub fn requester(&self) -> Option<&Requester> { + self.requester.as_ref() } } impl JobExecutor for KeyAccessJob { - type PartialJobRequest = Signature; + type PartialJobRequest = Requester; type PartialJobResponse = bool; type JobResponse = BTreeSet; - fn prepare_partial_request(&self, _node: &NodeId, _nodes: &BTreeSet) -> Result { - Ok(self.signature.as_ref().expect("prepare_partial_request is only called on master nodes; new_on_master fills the signature; qed").clone()) + fn prepare_partial_request(&self, _node: &NodeId, _nodes: &BTreeSet) -> Result { + Ok(self.requester.as_ref().expect("prepare_partial_request is only called on master nodes; new_on_master fills the signature; qed").clone()) } - fn process_partial_request(&mut self, partial_request: Signature) -> Result, Error> { + fn process_partial_request(&mut self, partial_request: Requester) -> Result, Error> { if !self.has_key_share { return Ok(JobPartialRequestAction::Reject(false)); } - self.signature = Some(partial_request.clone()); - self.acl_storage.check(&recover(&partial_request, &self.id)?, &self.id) + self.requester = Some(partial_request.clone()); + self.acl_storage.check(&partial_request.public(&self.id).ok_or(Error::InsufficientRequesterData)?, &self.id) .map_err(|_| Error::AccessDenied) .map(|is_confirmed| if is_confirmed { JobPartialRequestAction::Respond(true) } else { JobPartialRequestAction::Reject(false) }) } diff --git a/secret_store/src/key_server_cluster/message.rs b/secret_store/src/key_server_cluster/message.rs index e0675af24..999ed625f 100644 --- a/secret_store/src/key_server_cluster/message.rs +++ b/secret_store/src/key_server_cluster/message.rs @@ -18,7 +18,8 @@ use std::fmt; use std::collections::{BTreeSet, BTreeMap}; use ethkey::Secret; use key_server_cluster::SessionId; -use super::{SerializableH256, SerializablePublic, SerializableSecret, SerializableSignature, SerializableMessageHash}; +use super::{SerializableH256, SerializablePublic, SerializableSecret, SerializableSignature, + SerializableMessageHash, SerializableRequester}; pub type MessageSessionId = SerializableH256; pub type MessageNodeId = SerializablePublic; @@ -362,8 +363,8 @@ pub struct InitializeEncryptionSession { pub session: MessageSessionId, /// Session-level nonce. pub session_nonce: u64, - /// Requestor signature. - pub requestor_signature: SerializableSignature, + /// Requester. + pub requester: SerializableRequester, /// Common point. pub common_point: SerializablePublic, /// Encrypted data. @@ -393,8 +394,8 @@ pub struct EncryptionSessionError { /// Node is asked to be part of consensus group. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct InitializeConsensusSession { - /// Requestor signature. - pub requestor_signature: SerializableSignature, + /// Requester. + pub requester: SerializableRequester, /// Key version. pub version: SerializableH256, } @@ -529,8 +530,8 @@ pub struct SchnorrSigningSessionDelegation { pub sub_session: SerializableSecret, /// Session-level nonce. pub session_nonce: u64, - /// Requestor signature. - pub requestor_signature: SerializableSignature, + /// Requester. + pub requester: SerializableRequester, /// Key version. pub version: SerializableH256, /// Message hash. @@ -683,7 +684,7 @@ pub struct EcdsaSigningSessionDelegation { /// Session-level nonce. pub session_nonce: u64, /// Requestor signature. - pub requestor_signature: SerializableSignature, + pub requester: SerializableRequester, /// Key version. pub version: SerializableH256, /// Message hash. @@ -787,8 +788,8 @@ pub struct DecryptionSessionDelegation { pub sub_session: SerializableSecret, /// Session-level nonce. pub session_nonce: u64, - /// Requestor signature. - pub requestor_signature: SerializableSignature, + /// Requester. + pub requester: SerializableRequester, /// Key version. pub version: SerializableH256, /// Is shadow decryption requested? When true, decryption result diff --git a/secret_store/src/key_server_cluster/mod.rs b/secret_store/src/key_server_cluster/mod.rs index 5f5cb2bb9..97c7d414b 100644 --- a/secret_store/src/key_server_cluster/mod.rs +++ b/secret_store/src/key_server_cluster/mod.rs @@ -21,11 +21,12 @@ use ethcrypto; use super::types::all::ServerKeyId; pub use super::traits::NodeKeyPair; -pub use super::types::all::{NodeId, EncryptedDocumentKeyShadow}; +pub use super::types::all::{NodeId, Requester, EncryptedDocumentKeyShadow}; pub use super::acl_storage::AclStorage; pub use super::key_storage::{KeyStorage, DocumentKeyShare, DocumentKeyShareVersion}; pub use super::key_server_set::{is_migration_required, KeyServerSet, KeyServerSetSnapshot, KeyServerSetMigration}; -pub use super::serialization::{SerializableSignature, SerializableH256, SerializableSecret, SerializablePublic, SerializableMessageHash}; +pub use super::serialization::{SerializableSignature, SerializableH256, SerializableSecret, SerializablePublic, + SerializableRequester, SerializableMessageHash}; pub use self::cluster::{ClusterCore, ClusterConfiguration, ClusterClient}; pub use self::cluster_sessions::{ClusterSession, ClusterSessionsListener}; #[cfg(test)] @@ -113,6 +114,8 @@ pub enum Error { ExclusiveSessionActive, /// Can't start exclusive session, because there are other active sessions. HasActiveSessions, + /// Insufficient requester data. + InsufficientRequesterData, } impl From for Error { @@ -161,6 +164,7 @@ impl fmt::Display for Error { Error::AccessDenied => write!(f, "Access denied"), Error::ExclusiveSessionActive => write!(f, "Exclusive session active"), Error::HasActiveSessions => write!(f, "Unable to start exclusive session"), + Error::InsufficientRequesterData => write!(f, "Insufficient requester data"), } } } diff --git a/secret_store/src/serialization.rs b/secret_store/src/serialization.rs index 3831b67ca..95f679096 100644 --- a/secret_store/src/serialization.rs +++ b/secret_store/src/serialization.rs @@ -15,17 +15,104 @@ // along with Parity. If not, see . use std::fmt; -use std::cmp::{Ord, PartialOrd, Ordering}; use std::ops::Deref; use rustc_hex::{ToHex, FromHex}; use serde::{Serialize, Deserialize, Serializer, Deserializer}; use serde::de::{Visitor, Error as SerdeError}; use ethkey::{Public, Secret, Signature}; -use ethereum_types::H256; +use ethereum_types::{H160, H256}; use bytes::Bytes; +use types::all::Requester; + +macro_rules! impl_bytes_deserialize { + ($name: ident, $value: expr, true) => { + $value[2..].from_hex().map($name).map_err(SerdeError::custom) + }; + ($name: ident, $value: expr, false) => { + $value[2..].parse().map($name).map_err(SerdeError::custom) + } +} + +macro_rules! impl_bytes { + ($name: ident, $other: ident, $from_hex: ident, ($($trait: ident),*)) => { + #[derive(Clone, Debug, PartialEq, Eq, $($trait,)*)] + pub struct $name(pub $other); + + impl From for $name where $other: From { + fn from(s: T) -> $name { + $name(s.into()) + } + } + + impl Into<$other> for $name { + fn into(self) -> $other { + self.0 + } + } + + impl Deref for $name { + type Target = $other; + + fn deref(&self) -> &$other { + &self.0 + } + } + + impl Serialize for $name { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + let mut serialized = "0x".to_owned(); + serialized.push_str(self.0.to_hex().as_ref()); + serializer.serialize_str(serialized.as_ref()) + } + } + + impl<'a> Deserialize<'a> for $name { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { + struct HexBytesVisitor; + + impl<'b> Visitor<'b> for HexBytesVisitor { + type Value = $name; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a hex-encoded bytes string") + } + + fn visit_str(self, value: &str) -> Result where E: SerdeError { + if value.len() >= 2 && &value[0..2] == "0x" && value.len() & 1 == 0 { + impl_bytes_deserialize!($name, value, $from_hex) + } else { + Err(SerdeError::custom("invalid format")) + } + } + + fn visit_string(self, value: String) -> Result where E: SerdeError { + self.visit_str(value.as_ref()) + } + } + + deserializer.deserialize_any(HexBytesVisitor) + } + } + } +} /// Serializable message hash. pub type SerializableMessageHash = SerializableH256; +/// Serializable address; +pub type SerializableAddress = SerializableH160; + +/// Serializable Bytes. +impl_bytes!(SerializableBytes, Bytes, true, (Default)); +/// Serializable H256. +impl_bytes!(SerializableH256, H256, false, (Default, PartialOrd, Ord)); +/// Serializable H160. +impl_bytes!(SerializableH160, H160, false, (Default)); +/// Serializable H512 (aka Public). +impl_bytes!(SerializablePublic, Public, false, (Default, PartialOrd, Ord)); +/// Serializable Secret. +impl_bytes!(SerializableSecret, Secret, false, ()); +/// Serializable Signature. +impl_bytes!(SerializableSignature, Signature, false, ()); /// Serializable shadow decryption result. #[derive(Clone, Debug, Serialize, Deserialize)] @@ -38,350 +125,34 @@ pub struct SerializableEncryptedDocumentKeyShadow { pub decrypt_shadows: Vec, } -/// Serializable Bytes. -#[derive(Clone, Debug, PartialEq)] -pub struct SerializableBytes(pub Bytes); - -impl From for SerializableBytes where Bytes: From { - fn from(s: T) -> SerializableBytes { - SerializableBytes(s.into()) - } +/// Serializable requester identification data. +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum SerializableRequester { + /// Requested with server key id signature. + Signature(SerializableSignature), + /// Requested with public key. + Public(SerializablePublic), + /// Requested with verified address. + Address(SerializableAddress), } -impl Into for SerializableBytes { - fn into(self) -> Bytes { - self.0 - } -} - -impl Deref for SerializableBytes { - type Target = Bytes; - - fn deref(&self) -> &Bytes { - &self.0 - } -} - -impl Serialize for SerializableBytes { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - let mut serialized = "0x".to_owned(); - serialized.push_str(self.0.to_hex().as_ref()); - serializer.serialize_str(serialized.as_ref()) - } -} - -impl<'a> Deserialize<'a> for SerializableBytes { - fn deserialize(deserializer: D) -> Result - where D: Deserializer<'a> - { - let s = String::deserialize(deserializer)?; - if s.len() >= 2 && &s[0..2] == "0x" && s.len() & 1 == 0 { - let data = s[2..].from_hex().map_err(SerdeError::custom)?; - Ok(SerializableBytes(data)) - } else { - Err(SerdeError::custom("invalid format")) +impl From for Requester { + fn from(requester: SerializableRequester) -> Requester { + match requester { + SerializableRequester::Signature(signature) => Requester::Signature(signature.into()), + SerializableRequester::Public(public) => Requester::Public(public.into()), + SerializableRequester::Address(address) => Requester::Address(address.into()), } } } -/// Serializable Signature. -#[derive(Clone, Debug)] -pub struct SerializableSignature(pub Signature); - -impl From for SerializableSignature where Signature: From { - fn from(s: T) -> SerializableSignature { - SerializableSignature(s.into()) - } -} - -impl Into for SerializableSignature { - fn into(self) -> Signature { - self.0 - } -} - -impl Deref for SerializableSignature { - type Target = Signature; - - fn deref(&self) -> &Signature { - &self.0 - } -} - -impl Serialize for SerializableSignature { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - let mut serialized = "0x".to_owned(); - serialized.push_str(self.0.to_hex().as_ref()); - serializer.serialize_str(serialized.as_ref()) - } -} - -impl<'a> Deserialize<'a> for SerializableSignature { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { - struct HashVisitor; - - impl<'b> Visitor<'b> for HashVisitor { - type Value = SerializableSignature; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "a hex-encoded Signature") - } - - fn visit_str(self, value: &str) -> Result where E: SerdeError { - if value.len() >= 2 && &value[0..2] == "0x" && value.len() & 1 == 0 { - value[2..].parse().map(|s| SerializableSignature(s)).map_err(SerdeError::custom) - } else { - Err(SerdeError::custom("invalid format")) - } - } - - fn visit_string(self, value: String) -> Result where E: SerdeError { - self.visit_str(value.as_ref()) - } +impl From for SerializableRequester { + fn from(requester: Requester) -> SerializableRequester { + match requester { + Requester::Signature(signature) => SerializableRequester::Signature(signature.into()), + Requester::Public(public) => SerializableRequester::Public(public.into()), + Requester::Address(address) => SerializableRequester::Address(address.into()), } - - deserializer.deserialize_any(HashVisitor) - } -} - -/// Serializable H256. -#[derive(Clone, Debug)] -pub struct SerializableH256(pub H256); - -impl Default for SerializableH256 { - fn default() -> Self { - SerializableH256(Default::default()) - } -} - -impl From for SerializableH256 where H256: From { - fn from(s: T) -> SerializableH256 { - SerializableH256(s.into()) - } -} - -impl Into for SerializableH256 { - fn into(self) -> H256 { - self.0 - } -} - -impl Deref for SerializableH256 { - type Target = H256; - - fn deref(&self) -> &H256 { - &self.0 - } -} - -impl Serialize for SerializableH256 { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - let mut serialized = "0x".to_owned(); - serialized.push_str(self.0.to_hex().as_ref()); - serializer.serialize_str(serialized.as_ref()) - } -} - -impl<'a> Deserialize<'a> for SerializableH256 { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { - struct HashVisitor; - - impl<'b> Visitor<'b> for HashVisitor { - type Value = SerializableH256; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "a hex-encoded H256") - } - - fn visit_str(self, value: &str) -> Result where E: SerdeError { - if value.len() >= 2 && &value[0..2] == "0x" && value.len() & 1 == 0 { - value[2..].parse().map(|s| SerializableH256(s)).map_err(SerdeError::custom) - } else { - Err(SerdeError::custom("invalid format")) - } - } - - fn visit_string(self, value: String) -> Result where E: SerdeError { - self.visit_str(value.as_ref()) - } - } - - deserializer.deserialize_any(HashVisitor) - } -} - -impl PartialEq for SerializableH256 { - fn eq(&self, other: &Self) -> bool { - self.0.eq(&other.0) - } -} - -impl Eq for SerializableH256 { -} - -impl PartialOrd for SerializableH256 { - fn partial_cmp(&self, other: &Self) -> Option { - self.0.partial_cmp(&other.0) - } -} - -impl Ord for SerializableH256 { - fn cmp(&self, other: &Self) -> Ordering { - self.0.cmp(&other.0) - } -} - -/// Serializable EC scalar/secret key. -#[derive(Clone, Debug, PartialEq)] -pub struct SerializableSecret(pub Secret); - -impl From for SerializableSecret where Secret: From { - fn from(s: T) -> SerializableSecret { - SerializableSecret(s.into()) - } -} - -impl Into for SerializableSecret { - fn into(self) -> Secret { - self.0 - } -} - -impl Deref for SerializableSecret { - type Target = Secret; - - fn deref(&self) -> &Secret { - &self.0 - } -} - -impl AsRef<[u8]> for SerializableSecret { - #[inline] - fn as_ref(&self) -> &[u8] { - &*self.0 - } -} - -impl Serialize for SerializableSecret { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - let mut serialized = "0x".to_owned(); - serialized.push_str(self.0.to_hex().as_ref()); - serializer.serialize_str(serialized.as_ref()) - } -} - -impl<'a> Deserialize<'a> for SerializableSecret { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { - struct HashVisitor; - - impl<'b> Visitor<'b> for HashVisitor { - type Value = SerializableSecret; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "a hex-encoded EC scalar") - } - - fn visit_str(self, value: &str) -> Result where E: SerdeError { - if value.len() >= 2 && &value[0..2] == "0x" && value.len() & 1 == 0 { - value[2..].parse().map(|s| SerializableSecret(s)).map_err(SerdeError::custom) - } else { - Err(SerdeError::custom("invalid format")) - } - } - - fn visit_string(self, value: String) -> Result where E: SerdeError { - self.visit_str(value.as_ref()) - } - } - - deserializer.deserialize_any(HashVisitor) - } -} - -/// Serializable EC point/public key. -#[derive(Clone, Debug)] -pub struct SerializablePublic(pub Public); - -impl From for SerializablePublic where Public: From { - fn from(p: T) -> SerializablePublic { - SerializablePublic(p.into()) - } -} - -impl Into for SerializablePublic { - fn into(self) -> Public { - self.0 - } -} - -impl Deref for SerializablePublic { - type Target = Public; - - fn deref(&self) -> &Public { - &self.0 - } -} - -impl AsRef<[u8]> for SerializablePublic { - #[inline] - fn as_ref(&self) -> &[u8] { - &*self.0 - } -} - -impl Eq for SerializablePublic { } - -impl PartialEq for SerializablePublic { - fn eq(&self, other: &SerializablePublic) -> bool { - self.0.eq(&other.0) - } -} - -impl Ord for SerializablePublic { - fn cmp(&self, other: &SerializablePublic) -> Ordering { - self.0.cmp(&other.0) - } -} - -impl PartialOrd for SerializablePublic { - fn partial_cmp(&self, other: &SerializablePublic) -> Option { - self.0.partial_cmp(&other.0) - } -} - -impl Serialize for SerializablePublic { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - let mut serialized = "0x".to_owned(); - serialized.push_str(self.0.to_hex().as_ref()); - serializer.serialize_str(serialized.as_ref()) - } -} - -impl<'a> Deserialize<'a> for SerializablePublic { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { - struct HashVisitor; - - impl<'b> Visitor<'b> for HashVisitor { - type Value = SerializablePublic; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "a hex-encoded EC point") - } - - fn visit_str(self, value: &str) -> Result where E: SerdeError { - if value.len() >= 2 && &value[0..2] == "0x" && value.len() & 1 == 0 { - value[2..].parse().map(|s| SerializablePublic(s)).map_err(SerdeError::custom) - } else { - Err(SerdeError::custom("invalid format")) - } - } - - fn visit_string(self, value: String) -> Result where E: SerdeError { - self.visit_str(value.as_ref()) - } - } - - deserializer.deserialize_any(HashVisitor) } } diff --git a/secret_store/src/types/all.rs b/secret_store/src/types/all.rs index 0ce90383c..f1afd3da2 100644 --- a/secret_store/src/types/all.rs +++ b/secret_store/src/types/all.rs @@ -117,6 +117,17 @@ pub struct EncryptedDocumentKeyShadow { pub decrypt_shadows: Option>>, } +/// Requester identification data. +#[derive(Debug, Clone)] +pub enum Requester { + /// Requested with server key id signature. + Signature(ethkey::Signature), + /// Requested with public key. + Public(ethkey::Public), + /// Requested with verified address. + Address(ethereum_types::Address), +} + impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { match *self { @@ -165,3 +176,25 @@ impl Into for Error { format!("{}", self) } } + +impl Default for Requester { + fn default() -> Self { + Requester::Signature(Default::default()) + } +} + +impl Requester { + pub fn public(&self, server_key_id: &ServerKeyId) -> Option { + match *self { + Requester::Signature(ref signature) => ethkey::recover(signature, server_key_id).ok(), + Requester::Public(ref public) => Some(public.clone()), + Requester::Address(_) => None, + } + } +} + +impl From for Requester { + fn from(signature: ethkey::Signature) -> Requester { + Requester::Signature(signature) + } +}