SecretStore: ability to identify requester via Public/Address (#7886)
This commit is contained in:
parent
249f81cbc5
commit
a6915778bb
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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)?))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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) })
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 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())
|
||||
}
|
||||
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()),
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user