SecretStore: ability to identify requester via Public/Address (#7886)

This commit is contained in:
Svyatoslav Nikolsky 2018-03-19 08:42:40 +03:00 committed by Marek Kotewicz
parent 249f81cbc5
commit a6915778bb
14 changed files with 327 additions and 505 deletions

View File

@ -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<EncryptedDocumentKeyShadow, Error> {
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

View File

@ -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<Signature>) -> Result<Self, Error> {
pub fn new(params: SessionParams, requester: Option<Requester>) -> Result<Self, Error> {
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

View File

@ -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);
}

View File

@ -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<Signature>) -> Result<Self, Error> {
pub fn new(params: SessionParams, requester: Option<Requester>) -> Result<Self, Error> {
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

View File

@ -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<Signature>) -> Result<Self, Error> {
pub fn new(params: SessionParams, requester: Option<Requester>) -> Result<Self, Error> {
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

View File

@ -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<Arc<GenerationSession>, Error>;
/// Start new encryption session.
fn new_encryption_session(&self, session_id: SessionId, requestor_signature: Signature, common_point: Public, encrypted_point: Public) -> Result<Arc<EncryptionSession>, Error>;
fn new_encryption_session(&self, session_id: SessionId, requester: Requester, common_point: Public, encrypted_point: Public) -> Result<Arc<EncryptionSession>, Error>;
/// Start new decryption session.
fn new_decryption_session(&self, session_id: SessionId, requestor_signature: Signature, version: Option<H256>, is_shadow_decryption: bool) -> Result<Arc<DecryptionSession>, Error>;
/// Start new signing session.
fn new_schnorr_signing_session(&self, session_id: SessionId, requestor_signature: Signature, version: Option<H256>, message_hash: H256) -> Result<Arc<SchnorrSigningSession>, Error>;
fn new_decryption_session(&self, session_id: SessionId, requester: Requester, version: Option<H256>, is_shadow_decryption: bool) -> Result<Arc<DecryptionSession>, Error>;
/// Start new Schnorr signing session.
fn new_schnorr_signing_session(&self, session_id: SessionId, requester: Requester, version: Option<H256>, message_hash: H256) -> Result<Arc<SchnorrSigningSession>, Error>;
/// Start new ECDSA session.
fn new_ecdsa_signing_session(&self, session_id: SessionId, requestor_signature: Signature, version: Option<H256>, message_hash: H256) -> Result<Arc<EcdsaSigningSession>, Error>;
fn new_ecdsa_signing_session(&self, session_id: SessionId, requester: Requester, version: Option<H256>, message_hash: H256) -> Result<Arc<EcdsaSigningSession>, Error>;
/// Start new key version negotiation session.
fn new_key_version_negotiation_session(&self, session_id: SessionId) -> Result<Arc<KeyVersionNegotiationSession<KeyVersionNegotiationSessionTransport>>, 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<Arc<EncryptionSession>, Error> {
fn new_encryption_session(&self, session_id: SessionId, requester: Requester, common_point: Public, encrypted_point: Public) -> Result<Arc<EncryptionSession>, 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<H256>, is_shadow_decryption: bool) -> Result<Arc<DecryptionSession>, Error> {
fn new_decryption_session(&self, session_id: SessionId, requester: Requester, version: Option<H256>, is_shadow_decryption: bool) -> Result<Arc<DecryptionSession>, 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<H256>, message_hash: H256) -> Result<Arc<SchnorrSigningSession>, Error> {
fn new_schnorr_signing_session(&self, session_id: SessionId, requester: Requester, version: Option<H256>, message_hash: H256) -> Result<Arc<SchnorrSigningSession>, 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<H256>, message_hash: H256) -> Result<Arc<EcdsaSigningSession>, Error> {
fn new_ecdsa_signing_session(&self, session_id: SessionId, requester: Requester, version: Option<H256>, message_hash: H256) -> Result<Arc<EcdsaSigningSession>, 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<Arc<GenerationSession>, Error> { unimplemented!("test-only") }
fn new_encryption_session(&self, _session_id: SessionId, _requestor_signature: Signature, _common_point: Public, _encrypted_point: Public) -> Result<Arc<EncryptionSession>, Error> { unimplemented!("test-only") }
fn new_decryption_session(&self, _session_id: SessionId, _requestor_signature: Signature, _version: Option<H256>, _is_shadow_decryption: bool) -> Result<Arc<DecryptionSession>, Error> { unimplemented!("test-only") }
fn new_schnorr_signing_session(&self, _session_id: SessionId, _requestor_signature: Signature, _version: Option<H256>, _message_hash: H256) -> Result<Arc<SchnorrSigningSession>, Error> { unimplemented!("test-only") }
fn new_ecdsa_signing_session(&self, _session_id: SessionId, _requestor_signature: Signature, _version: Option<H256>, _message_hash: H256) -> Result<Arc<EcdsaSigningSession>, Error> { unimplemented!("test-only") }
fn new_encryption_session(&self, _session_id: SessionId, _requester: Requester, _common_point: Public, _encrypted_point: Public) -> Result<Arc<EncryptionSession>, Error> { unimplemented!("test-only") }
fn new_decryption_session(&self, _session_id: SessionId, _requester: Requester, _version: Option<H256>, _is_shadow_decryption: bool) -> Result<Arc<DecryptionSession>, Error> { unimplemented!("test-only") }
fn new_schnorr_signing_session(&self, _session_id: SessionId, _requester: Requester, _version: Option<H256>, _message_hash: H256) -> Result<Arc<SchnorrSigningSession>, Error> { unimplemented!("test-only") }
fn new_ecdsa_signing_session(&self, _session_id: SessionId, _requester: Requester, _version: Option<H256>, _message_hash: H256) -> Result<Arc<EcdsaSigningSession>, Error> { unimplemented!("test-only") }
fn new_key_version_negotiation_session(&self, _session_id: SessionId) -> Result<Arc<KeyVersionNegotiationSession<KeyVersionNegotiationSessionTransport>>, Error> { unimplemented!("test-only") }
fn new_servers_set_change_session(&self, _session_id: Option<SessionId>, _migration_id: Option<H256>, _new_nodes_set: BTreeSet<NodeId>, _old_set_signature: Signature, _new_set_signature: Signature) -> Result<Arc<AdminSession>, 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();

View File

@ -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<EncryptionSessionImpl, EncryptionSessionCreator, ()>,
/// Decryption sessions.
pub decryption_sessions: ClusterSessionsContainer<DecryptionSessionImpl, DecryptionSessionCreator, Signature>,
pub decryption_sessions: ClusterSessionsContainer<DecryptionSessionImpl, DecryptionSessionCreator, Requester>,
/// Schnorr signing sessions.
pub schnorr_signing_sessions: ClusterSessionsContainer<SchnorrSigningSessionImpl, SchnorrSigningSessionCreator, Signature>,
pub schnorr_signing_sessions: ClusterSessionsContainer<SchnorrSigningSessionImpl, SchnorrSigningSessionCreator, Requester>,
/// ECDSA signing sessions.
pub ecdsa_signing_sessions: ClusterSessionsContainer<EcdsaSigningSessionImpl, EcdsaSigningSessionCreator, Signature>,
pub ecdsa_signing_sessions: ClusterSessionsContainer<EcdsaSigningSessionImpl, EcdsaSigningSessionCreator, Requester>,
/// Key version negotiation sessions.
pub negotiation_sessions: ClusterSessionsContainer<KeyVersionNegotiationSessionImpl<VersionNegotiationTransport>, KeyVersionNegotiationSessionCreator, ()>,
/// Administrative sessions.

View File

@ -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<SessionCreatorCore>,
}
impl ClusterSessionCreator<DecryptionSessionImpl, Signature> for DecryptionSessionCreator {
fn creation_data_from_message(message: &Message) -> Result<Option<Signature>, Error> {
impl ClusterSessionCreator<DecryptionSessionImpl, Requester> for DecryptionSessionCreator {
fn creation_data_from_message(message: &Message) -> Result<Option<Requester>, 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<DecryptionSessionImpl, Signature> for DecryptionSessi
}))
}
fn create(&self, cluster: Arc<Cluster>, master: NodeId, nonce: Option<u64>, id: SessionIdWithSubSession, requester_signature: Option<Signature>) -> Result<Arc<DecryptionSessionImpl>, Error> {
fn create(&self, cluster: Arc<Cluster>, master: NodeId, nonce: Option<u64>, id: SessionIdWithSubSession, requester: Option<Requester>) -> Result<Arc<DecryptionSessionImpl>, 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<DecryptionSessionImpl, Signature> 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<SessionCreatorCore>,
}
impl ClusterSessionCreator<SchnorrSigningSessionImpl, Signature> for SchnorrSigningSessionCreator {
fn creation_data_from_message(message: &Message) -> Result<Option<Signature>, Error> {
impl ClusterSessionCreator<SchnorrSigningSessionImpl, Requester> for SchnorrSigningSessionCreator {
fn creation_data_from_message(message: &Message) -> Result<Option<Requester>, 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<SchnorrSigningSessionImpl, Signature> for SchnorrSign
}))
}
fn create(&self, cluster: Arc<Cluster>, master: NodeId, nonce: Option<u64>, id: SessionIdWithSubSession, requester_signature: Option<Signature>) -> Result<Arc<SchnorrSigningSessionImpl>, Error> {
fn create(&self, cluster: Arc<Cluster>, master: NodeId, nonce: Option<u64>, id: SessionIdWithSubSession, requester: Option<Requester>) -> Result<Arc<SchnorrSigningSessionImpl>, 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<SchnorrSigningSessionImpl, Signature> 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<SessionCreatorCore>,
}
impl ClusterSessionCreator<EcdsaSigningSessionImpl, Signature> for EcdsaSigningSessionCreator {
fn creation_data_from_message(message: &Message) -> Result<Option<Signature>, Error> {
impl ClusterSessionCreator<EcdsaSigningSessionImpl, Requester> for EcdsaSigningSessionCreator {
fn creation_data_from_message(message: &Message) -> Result<Option<Requester>, 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<EcdsaSigningSessionImpl, Signature> for EcdsaSigningS
}))
}
fn create(&self, cluster: Arc<Cluster>, master: NodeId, nonce: Option<u64>, id: SessionIdWithSubSession, requester_signature: Option<Signature>) -> Result<Arc<EcdsaSigningSessionImpl>, Error> {
fn create(&self, cluster: Arc<Cluster>, master: NodeId, nonce: Option<u64>, id: SessionIdWithSubSession, requester: Option<Requester>) -> Result<Arc<EcdsaSigningSessionImpl>, 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<EcdsaSigningSessionImpl, Signature> for EcdsaSigningS
acl_storage: self.core.acl_storage.clone(),
cluster: cluster,
nonce: nonce,
}, requester_signature)?))
}, requester)?))
}
}

View File

@ -15,8 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
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<ConsensusExecutor, ConsensusTransport, ComputationExecutor, ComputationTran
}
impl<ConsensusExecutor, ConsensusTransport, ComputationExecutor, ComputationTransport> ConsensusSession<ConsensusExecutor, ConsensusTransport, ComputationExecutor, ComputationTransport>
where ConsensusExecutor: JobExecutor<PartialJobRequest=Signature, PartialJobResponse=bool, JobResponse=BTreeSet<NodeId>>,
where ConsensusExecutor: JobExecutor<PartialJobRequest=Requester, PartialJobResponse=bool, JobResponse=BTreeSet<NodeId>>,
ConsensusTransport: JobTransport<PartialJobRequest=ConsensusExecutor::PartialJobRequest, PartialJobResponse=ConsensusExecutor::PartialJobResponse>,
ComputationExecutor: JobExecutor,
ComputationTransport: JobTransport<PartialJobRequest=ComputationExecutor::PartialJobRequest, PartialJobResponse=ComputationExecutor::PartialJobResponse> {
@ -351,7 +350,7 @@ impl<ConsensusExecutor, ConsensusTransport, ComputationExecutor, ComputationTran
let consensus_result = match message {
&ConsensusMessage::InitializeConsensusSession(ref message) =>
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<ConsensusExecutor, ConsensusTransport, ComputationExecutor, ComputationTran
#[cfg(test)]
mod tests {
use std::sync::Arc;
use ethkey::{Signature, KeyPair, Random, Generator, sign};
use key_server_cluster::{Error, NodeId, SessionId, DummyAclStorage};
use ethkey::{KeyPair, Random, Generator, sign};
use key_server_cluster::{Error, NodeId, SessionId, Requester, DummyAclStorage};
use key_server_cluster::message::{ConsensusMessage, InitializeConsensusSession, ConfirmConsensusInitialization};
use key_server_cluster::jobs::job_session::tests::{make_master_session_meta, make_slave_session_meta, SquaredSumJobExecutor, DummyJobTransport};
use key_server_cluster::jobs::key_access_job::KeyAccessJob;
use super::{ConsensusSession, ConsensusSessionParams, ConsensusSessionState};
type SquaredSumConsensusSession = ConsensusSession<KeyAccessJob, DummyJobTransport<Signature, bool>, SquaredSumJobExecutor, DummyJobTransport<u32, u32>>;
type SquaredSumConsensusSession = ConsensusSession<KeyAccessJob, DummyJobTransport<Requester, bool>, SquaredSumJobExecutor, DummyJobTransport<u32, u32>>;
fn make_master_consensus_session(threshold: usize, requester: Option<KeyPair>, acl_storage: Option<DummyAclStorage>) -> 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();

View File

@ -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<AclStorage>,
/// Requester signature.
signature: Option<Signature>,
/// Requester data.
requester: Option<Requester>,
}
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<AclStorage>, signature: Signature) -> Self {
pub fn new_on_master(id: SessionId, acl_storage: Arc<AclStorage>, 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<Option<Public>, 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<NodeId>;
fn prepare_partial_request(&self, _node: &NodeId, _nodes: &BTreeSet<NodeId>) -> Result<Signature, Error> {
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<NodeId>) -> Result<Requester, Error> {
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<JobPartialRequestAction<bool>, Error> {
fn process_partial_request(&mut self, partial_request: Requester) -> Result<JobPartialRequestAction<bool>, 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) })
}

View File

@ -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

View File

@ -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<ethkey::Error> 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"),
}
}
}

View File

@ -15,17 +15,104 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
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<T> From<T> for $name where $other: From<T> {
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<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 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<D>(deserializer: D) -> Result<Self, D::Error> 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<E>(self, value: &str) -> Result<Self::Value, E> 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<E>(self, value: String) -> Result<Self::Value, E> 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<SerializableBytes>,
}
/// Serializable Bytes.
#[derive(Clone, Debug, PartialEq)]
pub struct SerializableBytes(pub Bytes);
impl<T> From<T> for SerializableBytes where Bytes: From<T> {
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<Bytes> 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<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 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<D>(deserializer: D) -> Result<Self, D::Error>
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<SerializableRequester> 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<T> From<T> for SerializableSignature where Signature: From<T> {
fn from(s: T) -> SerializableSignature {
SerializableSignature(s.into())
impl From<Requester> 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()),
}
}
impl Into<Signature> 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<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 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<D>(deserializer: D) -> Result<Self, D::Error> 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<E>(self, value: &str) -> Result<Self::Value, E> 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<E>(self, value: String) -> Result<Self::Value, E> where E: SerdeError {
self.visit_str(value.as_ref())
}
}
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<T> From<T> for SerializableH256 where H256: From<T> {
fn from(s: T) -> SerializableH256 {
SerializableH256(s.into())
}
}
impl Into<H256> 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<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 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<D>(deserializer: D) -> Result<Self, D::Error> 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<E>(self, value: &str) -> Result<Self::Value, E> 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<E>(self, value: String) -> Result<Self::Value, E> where E: SerdeError {
self.visit_str(value.as_ref())
}
}
deserializer.deserialize_any(HashVisitor)
}
}
impl PartialEq<SerializableH256> 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<Ordering> {
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<T> From<T> for SerializableSecret where Secret: From<T> {
fn from(s: T) -> SerializableSecret {
SerializableSecret(s.into())
}
}
impl Into<Secret> 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<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 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<D>(deserializer: D) -> Result<Self, D::Error> 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<E>(self, value: &str) -> Result<Self::Value, E> 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<E>(self, value: String) -> Result<Self::Value, E> 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<T> From<T> for SerializablePublic where Public: From<T> {
fn from(p: T) -> SerializablePublic {
SerializablePublic(p.into())
}
}
impl Into<Public> 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<Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl Serialize for SerializablePublic {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 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<D>(deserializer: D) -> Result<Self, D::Error> 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<E>(self, value: &str) -> Result<Self::Value, E> 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<E>(self, value: String) -> Result<Self::Value, E> where E: SerdeError {
self.visit_str(value.as_ref())
}
}
deserializer.deserialize_any(HashVisitor)
}
}

View File

@ -117,6 +117,17 @@ pub struct EncryptedDocumentKeyShadow {
pub decrypt_shadows: Option<Vec<Vec<u8>>>,
}
/// 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<String> 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<Public> {
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<ethkey::Signature> for Requester {
fn from(signature: ethkey::Signature) -> Requester {
Requester::Signature(signature)
}
}