SecretStore: store key author address in db (#7887)

* SecretStore: ability to identify requester via Public/Address

* SecretStore: store author address instead of public in db
This commit is contained in:
Svyatoslav Nikolsky 2018-03-20 05:03:51 +03:00 committed by Marek Kotewicz
parent d7f690c8ba
commit a91e562021
12 changed files with 158 additions and 62 deletions

View File

@ -1166,7 +1166,7 @@ pub mod tests {
pub fn generate_key(threshold: usize, nodes_ids: BTreeSet<NodeId>) -> GenerationMessageLoop { pub fn generate_key(threshold: usize, nodes_ids: BTreeSet<NodeId>) -> GenerationMessageLoop {
let mut gml = GenerationMessageLoop::with_nodes_ids(nodes_ids); let mut gml = GenerationMessageLoop::with_nodes_ids(nodes_ids);
gml.master().initialize(Public::default(), false, threshold, gml.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).unwrap(); gml.master().initialize(Default::default(), false, threshold, gml.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).unwrap();
while let Some((from, to, message)) = gml.take_message() { while let Some((from, to, message)) = gml.take_message() {
gml.process_message((from, to, message)).unwrap(); gml.process_message((from, to, message)).unwrap();
} }

View File

@ -16,7 +16,7 @@
use std::sync::Arc; use std::sync::Arc;
use std::collections::{BTreeSet, BTreeMap}; use std::collections::{BTreeSet, BTreeMap};
use ethereum_types::H256; use ethereum_types::{H256, Address};
use ethkey::{Public, Secret, Signature}; use ethkey::{Public, Secret, Signature};
use parking_lot::{Mutex, Condvar}; use parking_lot::{Mutex, Condvar};
use key_server_cluster::{Error, SessionId, NodeId, DocumentKeyShare, DocumentKeyShareVersion, KeyStorage}; use key_server_cluster::{Error, SessionId, NodeId, DocumentKeyShare, DocumentKeyShareVersion, KeyStorage};
@ -101,7 +101,7 @@ struct NewKeyShare {
/// NewKeyShare: threshold. /// NewKeyShare: threshold.
pub threshold: usize, pub threshold: usize,
/// NewKeyShare: author. /// NewKeyShare: author.
pub author: Public, pub author: Address,
/// NewKeyShare: joint public. /// NewKeyShare: joint public.
pub joint_public: Public, pub joint_public: Public,
/// NewKeyShare: Common (shared) encryption point. /// NewKeyShare: Common (shared) encryption point.

View File

@ -789,7 +789,7 @@ mod tests {
let common_point: Public = "6962be696e1bcbba8e64cc7fddf140f854835354b5804f3bb95ae5a2799130371b589a131bd39699ac7174ccb35fc4342dab05331202209582fc8f3a40916ab0".into(); let common_point: Public = "6962be696e1bcbba8e64cc7fddf140f854835354b5804f3bb95ae5a2799130371b589a131bd39699ac7174ccb35fc4342dab05331202209582fc8f3a40916ab0".into();
let encrypted_point: Public = "b07031982bde9890e12eff154765f03c56c3ab646ad47431db5dd2d742a9297679c4c65b998557f8008469afd0c43d40b6c5f6c6a1c7354875da4115237ed87a".into(); let encrypted_point: Public = "b07031982bde9890e12eff154765f03c56c3ab646ad47431db5dd2d742a9297679c4c65b998557f8008469afd0c43d40b6c5f6c6a1c7354875da4115237ed87a".into();
let encrypted_datas: Vec<_> = (0..5).map(|i| DocumentKeyShare { let encrypted_datas: Vec<_> = (0..5).map(|i| DocumentKeyShare {
author: Public::default(), author: Default::default(),
threshold: 3, threshold: 3,
public: Default::default(), public: Default::default(),
common_point: Some(common_point.clone()), common_point: Some(common_point.clone()),
@ -882,7 +882,7 @@ mod tests {
}, },
access_key: Random.generate().unwrap().secret().clone(), access_key: Random.generate().unwrap().secret().clone(),
key_share: Some(DocumentKeyShare { key_share: Some(DocumentKeyShare {
author: Public::default(), author: Default::default(),
threshold: 0, threshold: 0,
public: Default::default(), public: Default::default(),
common_point: Some(Random.generate().unwrap().public().clone()), common_point: Some(Random.generate().unwrap().public().clone()),
@ -936,7 +936,7 @@ mod tests {
}, },
access_key: Random.generate().unwrap().secret().clone(), access_key: Random.generate().unwrap().secret().clone(),
key_share: Some(DocumentKeyShare { key_share: Some(DocumentKeyShare {
author: Public::default(), author: Default::default(),
threshold: 2, threshold: 2,
public: Default::default(), public: Default::default(),
common_point: Some(Random.generate().unwrap().public().clone()), common_point: Some(Random.generate().unwrap().public().clone()),

View File

@ -157,8 +157,8 @@ impl SessionImpl {
// save encryption data // save encryption data
if let Some(mut encrypted_data) = self.encrypted_data.clone() { if let Some(mut encrypted_data) = self.encrypted_data.clone() {
// check that the requester is the author of the encrypted data // check that the requester is the author of the encrypted data
let requester_public = requester.public(&self.id).ok_or(Error::InsufficientRequesterData)?; let requester_address = requester.address(&self.id).ok_or(Error::InsufficientRequesterData)?;
if encrypted_data.author != requester_public { if encrypted_data.author != requester_address {
return Err(Error::AccessDenied); return Err(Error::AccessDenied);
} }
@ -201,8 +201,8 @@ impl SessionImpl {
// check that the requester is the author of the encrypted data // check that the requester is the author of the encrypted data
if let Some(mut encrypted_data) = self.encrypted_data.clone() { if let Some(mut encrypted_data) = self.encrypted_data.clone() {
let requester: Requester = message.requester.clone().into(); let requester: Requester = message.requester.clone().into();
let requestor_public = requester.public(&self.id).ok_or(Error::InsufficientRequesterData)?; let requestor_address = requester.address(&self.id).ok_or(Error::InsufficientRequesterData)?;
if encrypted_data.author != requestor_public { if encrypted_data.author != requestor_address {
return Err(Error::AccessDenied); return Err(Error::AccessDenied);
} }

View File

@ -19,6 +19,7 @@ use std::fmt::{Debug, Formatter, Error as FmtError};
use std::time; use std::time;
use std::sync::Arc; use std::sync::Arc;
use parking_lot::{Condvar, Mutex}; use parking_lot::{Condvar, Mutex};
use ethereum_types::Address;
use ethkey::{Public, Secret}; use ethkey::{Public, Secret};
use key_server_cluster::{Error, NodeId, SessionId, KeyStorage, DocumentKeyShare, DocumentKeyShareVersion}; use key_server_cluster::{Error, NodeId, SessionId, KeyStorage, DocumentKeyShare, DocumentKeyShareVersion};
use key_server_cluster::math; use key_server_cluster::math;
@ -77,8 +78,8 @@ struct SessionData {
// === Values, filled when session initialization just starts === // === Values, filled when session initialization just starts ===
/// Reference to the node, which has started this session. /// Reference to the node, which has started this session.
master: Option<NodeId>, master: Option<NodeId>,
/// Public key of the creator of the session. /// Address of the creator of the session.
author: Option<Public>, author: Option<Address>,
// === Values, filled when session initialization is completed === // === Values, filled when session initialization is completed ===
/// Is zero secret generation session? /// Is zero secret generation session?
@ -262,7 +263,7 @@ impl SessionImpl {
} }
/// Start new session initialization. This must be called on master node. /// Start new session initialization. This must be called on master node.
pub fn initialize(&self, author: Public, is_zero: bool, threshold: usize, nodes: InitializationNodes) -> Result<(), Error> { pub fn initialize(&self, author: Address, is_zero: bool, threshold: usize, nodes: InitializationNodes) -> Result<(), Error> {
check_cluster_nodes(self.node(), &nodes.set())?; check_cluster_nodes(self.node(), &nodes.set())?;
check_threshold(threshold, &nodes.set())?; check_threshold(threshold, &nodes.set())?;
@ -935,6 +936,7 @@ pub mod tests {
use std::sync::Arc; use std::sync::Arc;
use std::collections::{BTreeSet, BTreeMap, VecDeque}; use std::collections::{BTreeSet, BTreeMap, VecDeque};
use tokio_core::reactor::Core; use tokio_core::reactor::Core;
use ethereum_types::Address;
use ethkey::{Random, Generator, Public, KeyPair}; use ethkey::{Random, Generator, Public, KeyPair};
use key_server_cluster::{NodeId, SessionId, Error, KeyStorage, DummyKeyStorage}; use key_server_cluster::{NodeId, SessionId, Error, KeyStorage, DummyKeyStorage};
use key_server_cluster::message::{self, Message, GenerationMessage}; use key_server_cluster::message::{self, Message, GenerationMessage};
@ -1063,7 +1065,7 @@ pub mod tests {
fn make_simple_cluster(threshold: usize, num_nodes: usize) -> Result<(SessionId, NodeId, NodeId, MessageLoop), Error> { fn make_simple_cluster(threshold: usize, num_nodes: usize) -> Result<(SessionId, NodeId, NodeId, MessageLoop), Error> {
let l = MessageLoop::new(num_nodes); let l = MessageLoop::new(num_nodes);
l.master().initialize(Public::default(), false, threshold, l.nodes.keys().cloned().collect::<BTreeSet<_>>().into())?; l.master().initialize(Default::default(), false, threshold, l.nodes.keys().cloned().collect::<BTreeSet<_>>().into())?;
let session_id = l.session_id.clone(); let session_id = l.session_id.clone();
let master_id = l.master().node().clone(); let master_id = l.master().node().clone();
@ -1074,7 +1076,7 @@ pub mod tests {
#[test] #[test]
fn initializes_in_cluster_of_single_node() { fn initializes_in_cluster_of_single_node() {
let l = MessageLoop::new(1); let l = MessageLoop::new(1);
assert!(l.master().initialize(Public::default(), false, 0, l.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).is_ok()); assert!(l.master().initialize(Default::default(), false, 0, l.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).is_ok());
} }
#[test] #[test]
@ -1089,7 +1091,7 @@ pub mod tests {
nonce: Some(0), nonce: Some(0),
}); });
let cluster_nodes: BTreeSet<_> = (0..2).map(|_| math::generate_random_point().unwrap()).collect(); let cluster_nodes: BTreeSet<_> = (0..2).map(|_| math::generate_random_point().unwrap()).collect();
assert_eq!(session.initialize(Public::default(), false, 0, cluster_nodes.into()).unwrap_err(), Error::InvalidNodesConfiguration); assert_eq!(session.initialize(Default::default(), false, 0, cluster_nodes.into()).unwrap_err(), Error::InvalidNodesConfiguration);
} }
#[test] #[test]
@ -1103,7 +1105,7 @@ pub mod tests {
#[test] #[test]
fn fails_to_initialize_when_already_initialized() { fn fails_to_initialize_when_already_initialized() {
let (_, _, _, l) = make_simple_cluster(0, 2).unwrap(); let (_, _, _, l) = make_simple_cluster(0, 2).unwrap();
assert_eq!(l.master().initialize(Public::default(), false, 0, l.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).unwrap_err(), assert_eq!(l.master().initialize(Default::default(), false, 0, l.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).unwrap_err(),
Error::InvalidStateForRequest); Error::InvalidStateForRequest);
} }
@ -1183,7 +1185,7 @@ pub mod tests {
assert_eq!(l.first_slave().on_initialize_session(m, &message::InitializeSession { assert_eq!(l.first_slave().on_initialize_session(m, &message::InitializeSession {
session: sid.into(), session: sid.into(),
session_nonce: 0, session_nonce: 0,
author: Public::default().into(), author: Address::default().into(),
nodes: nodes.into_iter().map(|(k, v)| (k.into(), v.into())).collect(), nodes: nodes.into_iter().map(|(k, v)| (k.into(), v.into())).collect(),
is_zero: false, is_zero: false,
threshold: 0, threshold: 0,
@ -1200,7 +1202,7 @@ pub mod tests {
assert_eq!(l.first_slave().on_initialize_session(m, &message::InitializeSession { assert_eq!(l.first_slave().on_initialize_session(m, &message::InitializeSession {
session: sid.into(), session: sid.into(),
session_nonce: 0, session_nonce: 0,
author: Public::default().into(), author: Address::default().into(),
nodes: nodes.into_iter().map(|(k, v)| (k.into(), v.into())).collect(), nodes: nodes.into_iter().map(|(k, v)| (k.into(), v.into())).collect(),
is_zero: false, is_zero: false,
threshold: 2, threshold: 2,
@ -1343,7 +1345,7 @@ pub mod tests {
let test_cases = [(0, 5), (2, 5), (3, 5)]; let test_cases = [(0, 5), (2, 5), (3, 5)];
for &(threshold, num_nodes) in &test_cases { for &(threshold, num_nodes) in &test_cases {
let mut l = MessageLoop::new(num_nodes); let mut l = MessageLoop::new(num_nodes);
l.master().initialize(Public::default(), false, threshold, l.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).unwrap(); l.master().initialize(Default::default(), false, threshold, l.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).unwrap();
assert_eq!(l.nodes.len(), num_nodes); assert_eq!(l.nodes.len(), num_nodes);
// let nodes do initialization + keys dissemination // let nodes do initialization + keys dissemination

View File

@ -402,7 +402,7 @@ impl SessionImpl {
session_nonce: n, session_nonce: n,
message: m, message: m,
})); }));
sig_nonce_generation_session.initialize(Public::default(), false, key_share.threshold, consensus_group_map.clone().into())?; sig_nonce_generation_session.initialize(Default::default(), false, key_share.threshold, consensus_group_map.clone().into())?;
data.sig_nonce_generation_session = Some(sig_nonce_generation_session); data.sig_nonce_generation_session = Some(sig_nonce_generation_session);
// start generation of inversed nonce computation session // start generation of inversed nonce computation session
@ -414,7 +414,7 @@ impl SessionImpl {
session_nonce: n, session_nonce: n,
message: m, message: m,
})); }));
inv_nonce_generation_session.initialize(Public::default(), false, key_share.threshold, consensus_group_map.clone().into())?; inv_nonce_generation_session.initialize(Default::default(), false, key_share.threshold, consensus_group_map.clone().into())?;
data.inv_nonce_generation_session = Some(inv_nonce_generation_session); data.inv_nonce_generation_session = Some(inv_nonce_generation_session);
// start generation of zero-secret shares for inversed nonce computation session // start generation of zero-secret shares for inversed nonce computation session
@ -426,7 +426,7 @@ impl SessionImpl {
session_nonce: n, session_nonce: n,
message: m, message: m,
})); }));
inv_zero_generation_session.initialize(Public::default(), true, key_share.threshold * 2, consensus_group_map.clone().into())?; inv_zero_generation_session.initialize(Default::default(), true, key_share.threshold * 2, consensus_group_map.clone().into())?;
data.inv_zero_generation_session = Some(inv_zero_generation_session); data.inv_zero_generation_session = Some(inv_zero_generation_session);
data.state = SessionState::NoncesGenerating; data.state = SessionState::NoncesGenerating;
@ -1054,7 +1054,7 @@ mod tests {
use std::sync::Arc; use std::sync::Arc;
use std::collections::{BTreeSet, BTreeMap, VecDeque}; use std::collections::{BTreeSet, BTreeMap, VecDeque};
use ethereum_types::H256; use ethereum_types::H256;
use ethkey::{self, Random, Generator, Public, KeyPair, verify_public}; use ethkey::{self, Random, Generator, KeyPair, verify_public};
use acl_storage::DummyAclStorage; use acl_storage::DummyAclStorage;
use key_server_cluster::{NodeId, DummyKeyStorage, SessionId, SessionMeta, Error, KeyStorage}; use key_server_cluster::{NodeId, DummyKeyStorage, SessionId, SessionMeta, Error, KeyStorage};
use key_server_cluster::cluster_sessions::ClusterSession; use key_server_cluster::cluster_sessions::ClusterSession;
@ -1165,7 +1165,7 @@ mod tests {
fn prepare_signing_sessions(threshold: usize, num_nodes: usize) -> (KeyGenerationMessageLoop, MessageLoop) { fn prepare_signing_sessions(threshold: usize, num_nodes: usize) -> (KeyGenerationMessageLoop, MessageLoop) {
// run key generation sessions // run key generation sessions
let mut gl = KeyGenerationMessageLoop::new(num_nodes); let mut gl = KeyGenerationMessageLoop::new(num_nodes);
gl.master().initialize(Public::default(), false, threshold, gl.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).unwrap(); gl.master().initialize(Default::default(), false, threshold, gl.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).unwrap();
while let Some((from, to, message)) = gl.take_message() { while let Some((from, to, message)) = gl.take_message() {
gl.process_message((from, to, message)).unwrap(); gl.process_message((from, to, message)).unwrap();
} }

View File

@ -277,7 +277,7 @@ impl SessionImpl {
}), }),
nonce: None, nonce: None,
}); });
generation_session.initialize(Public::default(), false, 0, vec![self.core.meta.self_node_id.clone()].into_iter().collect::<BTreeSet<_>>().into())?; generation_session.initialize(Default::default(), false, 0, vec![self.core.meta.self_node_id.clone()].into_iter().collect::<BTreeSet<_>>().into())?;
debug_assert_eq!(generation_session.state(), GenerationSessionState::WaitingForGenerationConfirmation); debug_assert_eq!(generation_session.state(), GenerationSessionState::WaitingForGenerationConfirmation);
let joint_public_and_secret = generation_session let joint_public_and_secret = generation_session
@ -405,7 +405,8 @@ impl SessionImpl {
}), }),
nonce: None, nonce: None,
}); });
generation_session.initialize(Public::default(), false, key_share.threshold, consensus_group.into())?;
generation_session.initialize(Default::default(), false, key_share.threshold, consensus_group.into())?;
data.generation_session = Some(generation_session); data.generation_session = Some(generation_session);
data.state = SessionState::SessionKeyGeneration; data.state = SessionState::SessionKeyGeneration;
@ -800,7 +801,7 @@ mod tests {
use std::sync::Arc; use std::sync::Arc;
use std::str::FromStr; use std::str::FromStr;
use std::collections::{BTreeSet, BTreeMap, VecDeque}; use std::collections::{BTreeSet, BTreeMap, VecDeque};
use ethereum_types::H256; use ethereum_types::{Address, H256};
use ethkey::{self, Random, Generator, Public, Secret, KeyPair}; use ethkey::{self, Random, Generator, Public, Secret, KeyPair};
use acl_storage::DummyAclStorage; use acl_storage::DummyAclStorage;
use key_server_cluster::{NodeId, DummyKeyStorage, DocumentKeyShare, DocumentKeyShareVersion, SessionId, use key_server_cluster::{NodeId, DummyKeyStorage, DocumentKeyShare, DocumentKeyShareVersion, SessionId,
@ -927,7 +928,7 @@ mod tests {
fn prepare_signing_sessions(threshold: usize, num_nodes: usize) -> (KeyGenerationMessageLoop, MessageLoop) { fn prepare_signing_sessions(threshold: usize, num_nodes: usize) -> (KeyGenerationMessageLoop, MessageLoop) {
// run key generation sessions // run key generation sessions
let mut gl = KeyGenerationMessageLoop::new(num_nodes); let mut gl = KeyGenerationMessageLoop::new(num_nodes);
gl.master().initialize(Public::default(), false, threshold, gl.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).unwrap(); gl.master().initialize(Default::default(), false, threshold, gl.nodes.keys().cloned().collect::<BTreeSet<_>>().into()).unwrap();
while let Some((from, to, message)) = gl.take_message() { while let Some((from, to, message)) = gl.take_message() {
gl.process_message((from, to, message)).unwrap(); gl.process_message((from, to, message)).unwrap();
} }
@ -971,7 +972,7 @@ mod tests {
}, },
access_key: Random.generate().unwrap().secret().clone(), access_key: Random.generate().unwrap().secret().clone(),
key_share: Some(DocumentKeyShare { key_share: Some(DocumentKeyShare {
author: Public::default(), author: Default::default(),
threshold: 0, threshold: 0,
public: Default::default(), public: Default::default(),
common_point: Some(Random.generate().unwrap().public().clone()), common_point: Some(Random.generate().unwrap().public().clone()),
@ -1025,7 +1026,7 @@ mod tests {
}, },
access_key: Random.generate().unwrap().secret().clone(), access_key: Random.generate().unwrap().secret().clone(),
key_share: Some(DocumentKeyShare { key_share: Some(DocumentKeyShare {
author: Public::default(), author: Default::default(),
threshold: 2, threshold: 2,
public: Default::default(), public: Default::default(),
common_point: Some(Random.generate().unwrap().public().clone()), common_point: Some(Random.generate().unwrap().public().clone()),
@ -1113,7 +1114,7 @@ mod tests {
message: GenerationMessage::InitializeSession(InitializeSession { message: GenerationMessage::InitializeSession(InitializeSession {
session: SessionId::default().into(), session: SessionId::default().into(),
session_nonce: 0, session_nonce: 0,
author: Public::default().into(), author: Address::default().into(),
nodes: BTreeMap::new(), nodes: BTreeMap::new(),
is_zero: false, is_zero: false,
threshold: 1, threshold: 1,

View File

@ -26,7 +26,7 @@ use parking_lot::{RwLock, Mutex};
use tokio_io::IoFuture; use tokio_io::IoFuture;
use tokio_core::reactor::{Handle, Remote, Interval}; use tokio_core::reactor::{Handle, Remote, Interval};
use tokio_core::net::{TcpListener, TcpStream}; use tokio_core::net::{TcpListener, TcpStream};
use ethkey::{Public, KeyPair, Signature, Random, Generator}; use ethkey::{Public, KeyPair, Signature, Random, Generator, public_to_address};
use ethereum_types::H256; use ethereum_types::H256;
use key_server_cluster::{Error, NodeId, SessionId, Requester, 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, use key_server_cluster::cluster_sessions::{ClusterSession, AdminSession, ClusterSessions, SessionIdWithSubSession,
@ -907,7 +907,7 @@ impl ClusterClient for ClusterClientImpl {
let cluster = create_cluster_view(&self.data, true)?; let cluster = create_cluster_view(&self.data, true)?;
let session = self.data.sessions.generation_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id, None, false, None)?; let session = self.data.sessions.generation_sessions.insert(cluster, self.data.self_key_pair.public().clone(), session_id, None, false, None)?;
match session.initialize(author, false, threshold, connected_nodes.into()) { match session.initialize(public_to_address(&author), false, threshold, connected_nodes.into()) {
Ok(()) => Ok(session), Ok(()) => Ok(session),
Err(error) => { Err(error) => {
self.data.sessions.generation_sessions.remove(&session.id()); self.data.sessions.generation_sessions.remove(&session.id());

View File

@ -19,7 +19,7 @@ use std::collections::{BTreeSet, BTreeMap};
use ethkey::Secret; use ethkey::Secret;
use key_server_cluster::SessionId; use key_server_cluster::SessionId;
use super::{SerializableH256, SerializablePublic, SerializableSecret, SerializableSignature, use super::{SerializableH256, SerializablePublic, SerializableSecret, SerializableSignature,
SerializableMessageHash, SerializableRequester}; SerializableMessageHash, SerializableRequester, SerializableAddress};
pub type MessageSessionId = SerializableH256; pub type MessageSessionId = SerializableH256;
pub type MessageNodeId = SerializablePublic; pub type MessageNodeId = SerializablePublic;
@ -273,7 +273,7 @@ pub struct InitializeSession {
/// Session-level nonce. /// Session-level nonce.
pub session_nonce: u64, pub session_nonce: u64,
/// Session author. /// Session author.
pub author: SerializablePublic, pub author: SerializableAddress,
/// All session participants along with their identification numbers. /// All session participants along with their identification numbers.
pub nodes: BTreeMap<MessageNodeId, SerializableSecret>, pub nodes: BTreeMap<MessageNodeId, SerializableSecret>,
/// Is zero secret generation session? /// Is zero secret generation session?
@ -963,7 +963,7 @@ pub struct KeyShareCommon {
/// Key threshold. /// Key threshold.
pub threshold: usize, pub threshold: usize,
/// Author of key share entry. /// Author of key share entry.
pub author: SerializablePublic, pub author: SerializableAddress,
/// Joint public. /// Joint public.
pub joint_public: SerializablePublic, pub joint_public: SerializablePublic,
/// Common (shared) encryption point. /// Common (shared) encryption point.

View File

@ -26,7 +26,7 @@ pub use super::acl_storage::AclStorage;
pub use super::key_storage::{KeyStorage, DocumentKeyShare, DocumentKeyShareVersion}; pub use super::key_storage::{KeyStorage, DocumentKeyShare, DocumentKeyShareVersion};
pub use super::key_server_set::{is_migration_required, KeyServerSet, KeyServerSetSnapshot, KeyServerSetMigration}; pub use super::key_server_set::{is_migration_required, KeyServerSet, KeyServerSetSnapshot, KeyServerSetMigration};
pub use super::serialization::{SerializableSignature, SerializableH256, SerializableSecret, SerializablePublic, pub use super::serialization::{SerializableSignature, SerializableH256, SerializableSecret, SerializablePublic,
SerializableRequester, SerializableMessageHash}; SerializableRequester, SerializableMessageHash, SerializableAddress};
pub use self::cluster::{ClusterCore, ClusterConfiguration, ClusterClient}; pub use self::cluster::{ClusterCore, ClusterConfiguration, ClusterClient};
pub use self::cluster_sessions::{ClusterSession, ClusterSessionsListener}; pub use self::cluster_sessions::{ClusterSession, ClusterSessionsListener};
#[cfg(test)] #[cfg(test)]

View File

@ -18,27 +18,27 @@ use std::path::PathBuf;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use serde_json; use serde_json;
use tiny_keccak::Keccak; use tiny_keccak::Keccak;
use ethereum_types::H256; use ethereum_types::{H256, Address};
use ethkey::{Secret, Public}; use ethkey::{Secret, Public, public_to_address};
use kvdb_rocksdb::{Database, DatabaseIterator}; use kvdb_rocksdb::{Database, DatabaseIterator};
use types::all::{Error, ServiceConfiguration, ServerKeyId, NodeId}; use types::all::{Error, ServiceConfiguration, ServerKeyId, NodeId};
use serialization::{SerializablePublic, SerializableSecret, SerializableH256}; use serialization::{SerializablePublic, SerializableSecret, SerializableH256, SerializableAddress};
/// Key of version value. /// Key of version value.
const DB_META_KEY_VERSION: &'static [u8; 7] = b"version"; const DB_META_KEY_VERSION: &'static [u8; 7] = b"version";
/// Current db version. /// Current db version.
const CURRENT_VERSION: u8 = 2; const CURRENT_VERSION: u8 = 3;
/// Current type of serialized key shares. /// Current type of serialized key shares.
type CurrentSerializableDocumentKeyShare = SerializableDocumentKeyShareV2; type CurrentSerializableDocumentKeyShare = SerializableDocumentKeyShareV3;
/// Current type of serialized key shares versions. /// Current type of serialized key shares versions.
type CurrentSerializableDocumentKeyVersion = SerializableDocumentKeyShareVersionV2; type CurrentSerializableDocumentKeyVersion = SerializableDocumentKeyShareVersionV3;
/// Encrypted key share, stored by key storage on the single key server. /// Encrypted key share, stored by key storage on the single key server.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
#[cfg_attr(test, derive(Default))] #[cfg_attr(test, derive(Default))]
pub struct DocumentKeyShare { pub struct DocumentKeyShare {
/// Author of the entry. /// Author of the entry.
pub author: Public, pub author: Address,
/// Decryption threshold (at least threshold + 1 nodes are required to decrypt data). /// Decryption threshold (at least threshold + 1 nodes are required to decrypt data).
pub threshold: usize, pub threshold: usize,
/// Server public key. /// Server public key.
@ -136,7 +136,8 @@ struct SerializableDocumentKeyShareV2 {
/// Encrypted point. /// Encrypted point.
pub encrypted_point: Option<SerializablePublic>, pub encrypted_point: Option<SerializablePublic>,
/// Versions. /// Versions.
pub versions: Vec<SerializableDocumentKeyShareVersionV2>} pub versions: Vec<SerializableDocumentKeyShareVersionV2>
}
/// V2 of encrypted key share version, as it is stored by key storage on the single key server. /// V2 of encrypted key share version, as it is stored by key storage on the single key server.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
@ -149,6 +150,26 @@ struct SerializableDocumentKeyShareVersionV2 {
pub secret_share: SerializableSecret, pub secret_share: SerializableSecret,
} }
/// V3 of encrypted key share, as it is stored by key storage on the single key server.
#[derive(Serialize, Deserialize)]
struct SerializableDocumentKeyShareV3 {
/// Author of the entry.
pub author: SerializableAddress,
/// Decryption threshold (at least threshold + 1 nodes are required to decrypt data).
pub threshold: usize,
/// Server public.
pub public: SerializablePublic,
/// Common (shared) encryption point.
pub common_point: Option<SerializablePublic>,
/// Encrypted point.
pub encrypted_point: Option<SerializablePublic>,
/// Versions.
pub versions: Vec<SerializableDocumentKeyShareVersionV3>
}
/// V3 of encrypted key share version, as it is stored by key storage on the single key server.
type SerializableDocumentKeyShareVersionV3 = SerializableDocumentKeyShareVersionV2;
impl PersistentKeyStorage { impl PersistentKeyStorage {
/// Create new persistent document encryption keys storage /// Create new persistent document encryption keys storage
pub fn new(config: &ServiceConfiguration) -> Result<Self, Error> { pub fn new(config: &ServiceConfiguration) -> Result<Self, Error> {
@ -177,7 +198,7 @@ fn upgrade_db(db: Database) -> Result<Database, Error> {
let current_key = CurrentSerializableDocumentKeyShare { let current_key = CurrentSerializableDocumentKeyShare {
// author is used in separate generation + encrypt sessions. // author is used in separate generation + encrypt sessions.
// in v0 there have been only simultaneous GenEnc sessions. // in v0 there have been only simultaneous GenEnc sessions.
author: Public::default().into(), // added in v1 author: Address::default().into(), // added in v1
threshold: v0_key.threshold, threshold: v0_key.threshold,
public: Public::default().into(), // addded in v2 public: Public::default().into(), // addded in v2
common_point: Some(v0_key.common_point), common_point: Some(v0_key.common_point),
@ -200,7 +221,7 @@ fn upgrade_db(db: Database) -> Result<Database, Error> {
for (db_key, db_value) in db.iter(None).into_iter().flat_map(|inner| inner).filter(|&(ref k, _)| **k != *DB_META_KEY_VERSION) { for (db_key, db_value) in db.iter(None).into_iter().flat_map(|inner| inner).filter(|&(ref k, _)| **k != *DB_META_KEY_VERSION) {
let v1_key = serde_json::from_slice::<SerializableDocumentKeyShareV1>(&db_value).map_err(|e| Error::Database(e.to_string()))?; let v1_key = serde_json::from_slice::<SerializableDocumentKeyShareV1>(&db_value).map_err(|e| Error::Database(e.to_string()))?;
let current_key = CurrentSerializableDocumentKeyShare { let current_key = CurrentSerializableDocumentKeyShare {
author: v1_key.author, // added in v1 author: public_to_address(&v1_key.author).into(), // added in v1 + changed in v3
threshold: v1_key.threshold, threshold: v1_key.threshold,
public: Public::default().into(), // addded in v2 public: Public::default().into(), // addded in v2
common_point: v1_key.common_point, common_point: v1_key.common_point,
@ -217,7 +238,26 @@ fn upgrade_db(db: Database) -> Result<Database, Error> {
db.write(batch)?; db.write(batch)?;
Ok(db) Ok(db)
} }
2 => Ok(db), 2 => {
let mut batch = db.transaction();
batch.put(None, DB_META_KEY_VERSION, &[CURRENT_VERSION]);
for (db_key, db_value) in db.iter(None).into_iter().flat_map(|inner| inner).filter(|&(ref k, _)| **k != *DB_META_KEY_VERSION) {
let v2_key = serde_json::from_slice::<SerializableDocumentKeyShareV2>(&db_value).map_err(|e| Error::Database(e.to_string()))?;
let current_key = CurrentSerializableDocumentKeyShare {
author: public_to_address(&v2_key.author).into(), // changed in v3
threshold: v2_key.threshold,
public: v2_key.public,
common_point: v2_key.common_point,
encrypted_point: v2_key.encrypted_point,
versions: v2_key.versions,
};
let db_value = serde_json::to_vec(&current_key).map_err(|e| Error::Database(e.to_string()))?;
batch.put(None, &*db_key, &*db_value);
}
db.write(batch)?;
Ok(db)
},
3 => Ok(db),
_ => Err(Error::Database(format!("unsupported SecretStore database version: {}", version))), _ => Err(Error::Database(format!("unsupported SecretStore database version: {}", version))),
} }
} }
@ -331,9 +371,9 @@ impl DocumentKeyShareVersion {
} }
} }
impl From<DocumentKeyShare> for SerializableDocumentKeyShareV2 { impl From<DocumentKeyShare> for SerializableDocumentKeyShareV3 {
fn from(key: DocumentKeyShare) -> Self { fn from(key: DocumentKeyShare) -> Self {
SerializableDocumentKeyShareV2 { SerializableDocumentKeyShareV3 {
author: key.author.into(), author: key.author.into(),
threshold: key.threshold, threshold: key.threshold,
public: key.public.into(), public: key.public.into(),
@ -344,9 +384,9 @@ impl From<DocumentKeyShare> for SerializableDocumentKeyShareV2 {
} }
} }
impl From<DocumentKeyShareVersion> for SerializableDocumentKeyShareVersionV2 { impl From<DocumentKeyShareVersion> for SerializableDocumentKeyShareVersionV3 {
fn from(version: DocumentKeyShareVersion) -> Self { fn from(version: DocumentKeyShareVersion) -> Self {
SerializableDocumentKeyShareVersionV2 { SerializableDocumentKeyShareVersionV3 {
hash: version.hash.into(), hash: version.hash.into(),
id_numbers: version.id_numbers.into_iter().map(|(k, v)| (k.into(), v.into())).collect(), id_numbers: version.id_numbers.into_iter().map(|(k, v)| (k.into(), v.into())).collect(),
secret_share: version.secret_share.into(), secret_share: version.secret_share.into(),
@ -354,8 +394,8 @@ impl From<DocumentKeyShareVersion> for SerializableDocumentKeyShareVersionV2 {
} }
} }
impl From<SerializableDocumentKeyShareV2> for DocumentKeyShare { impl From<SerializableDocumentKeyShareV3> for DocumentKeyShare {
fn from(key: SerializableDocumentKeyShareV2) -> Self { fn from(key: SerializableDocumentKeyShareV3) -> Self {
DocumentKeyShare { DocumentKeyShare {
author: key.author.into(), author: key.author.into(),
threshold: key.threshold, threshold: key.threshold,
@ -381,12 +421,13 @@ pub mod tests {
use parking_lot::RwLock; use parking_lot::RwLock;
use serde_json; use serde_json;
use self::tempdir::TempDir; use self::tempdir::TempDir;
use ethkey::{Random, Generator, Public, Secret}; use ethereum_types::{Address, H256};
use ethkey::{Random, Generator, Public, Secret, public_to_address};
use kvdb_rocksdb::Database; use kvdb_rocksdb::Database;
use types::all::{Error, NodeAddress, ServiceConfiguration, ClusterConfiguration, ServerKeyId}; use types::all::{Error, NodeAddress, ServiceConfiguration, ClusterConfiguration, ServerKeyId};
use super::{DB_META_KEY_VERSION, CURRENT_VERSION, KeyStorage, PersistentKeyStorage, DocumentKeyShare, use super::{DB_META_KEY_VERSION, CURRENT_VERSION, KeyStorage, PersistentKeyStorage, DocumentKeyShare,
DocumentKeyShareVersion, SerializableDocumentKeyShareV0, SerializableDocumentKeyShareV1, DocumentKeyShareVersion, CurrentSerializableDocumentKeyShare, upgrade_db, SerializableDocumentKeyShareV0,
CurrentSerializableDocumentKeyShare, upgrade_db}; SerializableDocumentKeyShareV1, SerializableDocumentKeyShareV2, SerializableDocumentKeyShareVersionV2};
/// In-memory document encryption keys storage /// In-memory document encryption keys storage
#[derive(Default)] #[derive(Default)]
@ -451,7 +492,7 @@ pub mod tests {
let key1 = ServerKeyId::from(1); let key1 = ServerKeyId::from(1);
let value1 = DocumentKeyShare { let value1 = DocumentKeyShare {
author: Public::default(), author: Default::default(),
threshold: 100, threshold: 100,
public: Public::default(), public: Public::default(),
common_point: Some(Random.generate().unwrap().public().clone()), common_point: Some(Random.generate().unwrap().public().clone()),
@ -466,7 +507,7 @@ pub mod tests {
}; };
let key2 = ServerKeyId::from(2); let key2 = ServerKeyId::from(2);
let value2 = DocumentKeyShare { let value2 = DocumentKeyShare {
author: Public::default(), author: Default::default(),
threshold: 200, threshold: 200,
public: Public::default(), public: Public::default(),
common_point: Some(Random.generate().unwrap().public().clone()), common_point: Some(Random.generate().unwrap().public().clone()),
@ -523,7 +564,7 @@ pub mod tests {
// check upgrade // check upgrade
assert_eq!(db.get(None, DB_META_KEY_VERSION).unwrap().unwrap()[0], CURRENT_VERSION); assert_eq!(db.get(None, DB_META_KEY_VERSION).unwrap().unwrap()[0], CURRENT_VERSION);
let key = serde_json::from_slice::<CurrentSerializableDocumentKeyShare>(&db.get(None, &[7]).unwrap().map(|key| key.to_vec()).unwrap()).unwrap(); let key = serde_json::from_slice::<CurrentSerializableDocumentKeyShare>(&db.get(None, &[7]).unwrap().map(|key| key.to_vec()).unwrap()).unwrap();
assert_eq!(Public::default(), key.author.clone().into()); assert_eq!(Address::default(), key.author.clone().into());
assert_eq!(777, key.threshold); assert_eq!(777, key.threshold);
assert_eq!(Some("99e82b163b062d55a64085bacfd407bb55f194ba5fb7a1af9c34b84435455520f1372e0e650a4f91aed0058cb823f62146ccb5599c8d13372c300dea866b69fc".parse::<Public>().unwrap()), key.common_point.clone().map(Into::into)); assert_eq!(Some("99e82b163b062d55a64085bacfd407bb55f194ba5fb7a1af9c34b84435455520f1372e0e650a4f91aed0058cb823f62146ccb5599c8d13372c300dea866b69fc".parse::<Public>().unwrap()), key.common_point.clone().map(Into::into));
assert_eq!(Some("7e05df9dd077ec21ed4bc45c9fe9e0a43d65fa4be540630de615ced5e95cf5c3003035eb713317237d7667feeeb64335525158f5f7411f67aca9645169ea554c".parse::<Public>().unwrap()), key.encrypted_point.clone().map(Into::into)); assert_eq!(Some("7e05df9dd077ec21ed4bc45c9fe9e0a43d65fa4be540630de615ced5e95cf5c3003035eb713317237d7667feeeb64335525158f5f7411f67aca9645169ea554c".parse::<Public>().unwrap()), key.encrypted_point.clone().map(Into::into));
@ -569,7 +610,55 @@ pub mod tests {
assert_eq!(777, key.threshold); assert_eq!(777, key.threshold);
assert_eq!(Some("99e82b163b062d55a64085bacfd407bb55f194ba5fb7a1af9c34b84435455520f1372e0e650a4f91aed0058cb823f62146ccb5599c8d13372c300dea866b69fc".parse::<Public>().unwrap()), key.common_point.clone().map(Into::into)); assert_eq!(Some("99e82b163b062d55a64085bacfd407bb55f194ba5fb7a1af9c34b84435455520f1372e0e650a4f91aed0058cb823f62146ccb5599c8d13372c300dea866b69fc".parse::<Public>().unwrap()), key.common_point.clone().map(Into::into));
assert_eq!(Some("7e05df9dd077ec21ed4bc45c9fe9e0a43d65fa4be540630de615ced5e95cf5c3003035eb713317237d7667feeeb64335525158f5f7411f67aca9645169ea554c".parse::<Public>().unwrap()), key.encrypted_point.clone().map(Into::into)); assert_eq!(Some("7e05df9dd077ec21ed4bc45c9fe9e0a43d65fa4be540630de615ced5e95cf5c3003035eb713317237d7667feeeb64335525158f5f7411f67aca9645169ea554c".parse::<Public>().unwrap()), key.encrypted_point.clone().map(Into::into));
assert_eq!(key.author, "b486d3840218837b035c66196ecb15e6b067ca20101e11bd5e626288ab6806ecc70b8307012626bd512bad1559112d11d21025cef48cc7a1d2f3976da08f36c8".into()); assert_eq!(key.author.0, public_to_address(&"b486d3840218837b035c66196ecb15e6b067ca20101e11bd5e626288ab6806ecc70b8307012626bd512bad1559112d11d21025cef48cc7a1d2f3976da08f36c8".into()));
assert_eq!(key.versions.len(), 1);
assert_eq!(vec![(
"b486d3840218837b035c66196ecb15e6b067ca20101e11bd5e626288ab6806ecc70b8307012626bd512bad1559112d11d21025cef48cc7a1d2f3976da08f36c8".parse::<Public>().unwrap(),
"281b6bf43cb86d0dc7b98e1b7def4a80f3ce16d28d2308f934f116767306f06c".parse::<Secret>().unwrap(),
)], key.versions[0].id_numbers.clone().into_iter().map(|(k, v)| (k.into(), v.into())).collect::<Vec<(Public, Secret)>>());
assert_eq!("00125d85a05e5e63e214cb60fe63f132eec8a103aa29266b7e6e6c5b7597230b".parse::<Secret>().unwrap(), key.versions[0].secret_share.clone().into());
}
#[test]
fn upgrade_db_from_2() {
let tempdir = TempDir::new("").unwrap();
let db = Database::open_default(&tempdir.path().display().to_string()).unwrap();
// prepare v2 database
{
let key = serde_json::to_vec(&SerializableDocumentKeyShareV2 {
author: "b486d3840218837b035c66196ecb15e6b067ca20101e11bd5e626288ab6806ecc70b8307012626bd512bad1559112d11d21025cef48cc7a1d2f3976da08f36c8".into(),
threshold: 777,
common_point: Some("99e82b163b062d55a64085bacfd407bb55f194ba5fb7a1af9c34b84435455520f1372e0e650a4f91aed0058cb823f62146ccb5599c8d13372c300dea866b69fc".into()),
encrypted_point: Some("7e05df9dd077ec21ed4bc45c9fe9e0a43d65fa4be540630de615ced5e95cf5c3003035eb713317237d7667feeeb64335525158f5f7411f67aca9645169ea554c".into()),
public: "b486d3840218837b035c66196ecb15e6b067ca20101e11bd5e626288ab6806ecc70b8307012626bd512bad1559112d11d21025cef48cc7a1d2f3976da08f36c8".into(),
versions: vec![SerializableDocumentKeyShareVersionV2 {
hash: "281b6bf43cb86d0dc7b98e1b7def4a80f3ce16d28d2308f934f116767306f06c".parse::<H256>().unwrap().into(),
id_numbers: vec![(
"b486d3840218837b035c66196ecb15e6b067ca20101e11bd5e626288ab6806ecc70b8307012626bd512bad1559112d11d21025cef48cc7a1d2f3976da08f36c8".into(),
"281b6bf43cb86d0dc7b98e1b7def4a80f3ce16d28d2308f934f116767306f06c".parse::<Secret>().unwrap().into(),
)].into_iter().collect(),
secret_share: "00125d85a05e5e63e214cb60fe63f132eec8a103aa29266b7e6e6c5b7597230b".parse::<Secret>().unwrap().into(),
}],
}).unwrap();
let mut batch = db.transaction();
batch.put(None, DB_META_KEY_VERSION, &[2]);
batch.put(None, &[7], &key);
db.write(batch).unwrap();
}
// upgrade database
let db = upgrade_db(db).unwrap();
// check upgrade
assert_eq!(db.get(None, DB_META_KEY_VERSION).unwrap().unwrap()[0], CURRENT_VERSION);
let key = serde_json::from_slice::<CurrentSerializableDocumentKeyShare>(&db.get(None, &[7]).unwrap().map(|key| key.to_vec()).unwrap()).unwrap();
assert_eq!(777, key.threshold);
assert_eq!(Some("99e82b163b062d55a64085bacfd407bb55f194ba5fb7a1af9c34b84435455520f1372e0e650a4f91aed0058cb823f62146ccb5599c8d13372c300dea866b69fc".parse::<Public>().unwrap()), key.common_point.clone().map(Into::into));
assert_eq!(Some("7e05df9dd077ec21ed4bc45c9fe9e0a43d65fa4be540630de615ced5e95cf5c3003035eb713317237d7667feeeb64335525158f5f7411f67aca9645169ea554c".parse::<Public>().unwrap()), key.encrypted_point.clone().map(Into::into));
assert_eq!(key.author.0, public_to_address(&"b486d3840218837b035c66196ecb15e6b067ca20101e11bd5e626288ab6806ecc70b8307012626bd512bad1559112d11d21025cef48cc7a1d2f3976da08f36c8".parse().unwrap()));
assert_eq!(key.versions.len(), 1); assert_eq!(key.versions.len(), 1);
assert_eq!(vec![( assert_eq!(vec![(

View File

@ -191,6 +191,10 @@ impl Requester {
Requester::Address(_) => None, Requester::Address(_) => None,
} }
} }
pub fn address(&self, server_key_id: &ServerKeyId) -> Option<ethkey::Address> {
self.public(server_key_id).map(|p| ethkey::public_to_address(&p))
}
} }
impl From<ethkey::Signature> for Requester { impl From<ethkey::Signature> for Requester {