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 {
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() {
gml.process_message((from, to, message)).unwrap();
}

View File

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

View File

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

View File

@ -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 requester_public = requester.public(&self.id).ok_or(Error::InsufficientRequesterData)?;
if encrypted_data.author != requester_public {
let requester_address = requester.address(&self.id).ok_or(Error::InsufficientRequesterData)?;
if encrypted_data.author != requester_address {
return Err(Error::AccessDenied);
}
@ -201,8 +201,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 requester: Requester = message.requester.clone().into();
let requestor_public = requester.public(&self.id).ok_or(Error::InsufficientRequesterData)?;
if encrypted_data.author != requestor_public {
let requestor_address = requester.address(&self.id).ok_or(Error::InsufficientRequesterData)?;
if encrypted_data.author != requestor_address {
return Err(Error::AccessDenied);
}

View File

@ -19,6 +19,7 @@ use std::fmt::{Debug, Formatter, Error as FmtError};
use std::time;
use std::sync::Arc;
use parking_lot::{Condvar, Mutex};
use ethereum_types::Address;
use ethkey::{Public, Secret};
use key_server_cluster::{Error, NodeId, SessionId, KeyStorage, DocumentKeyShare, DocumentKeyShareVersion};
use key_server_cluster::math;
@ -77,8 +78,8 @@ struct SessionData {
// === Values, filled when session initialization just starts ===
/// Reference to the node, which has started this session.
master: Option<NodeId>,
/// Public key of the creator of the session.
author: Option<Public>,
/// Address of the creator of the session.
author: Option<Address>,
// === Values, filled when session initialization is completed ===
/// Is zero secret generation session?
@ -262,7 +263,7 @@ impl SessionImpl {
}
/// 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_threshold(threshold, &nodes.set())?;
@ -935,6 +936,7 @@ pub mod tests {
use std::sync::Arc;
use std::collections::{BTreeSet, BTreeMap, VecDeque};
use tokio_core::reactor::Core;
use ethereum_types::Address;
use ethkey::{Random, Generator, Public, KeyPair};
use key_server_cluster::{NodeId, SessionId, Error, KeyStorage, DummyKeyStorage};
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> {
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 master_id = l.master().node().clone();
@ -1074,7 +1076,7 @@ pub mod tests {
#[test]
fn initializes_in_cluster_of_single_node() {
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]
@ -1089,7 +1091,7 @@ pub mod tests {
nonce: Some(0),
});
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]
@ -1103,7 +1105,7 @@ pub mod tests {
#[test]
fn fails_to_initialize_when_already_initialized() {
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);
}
@ -1183,7 +1185,7 @@ pub mod tests {
assert_eq!(l.first_slave().on_initialize_session(m, &message::InitializeSession {
session: sid.into(),
session_nonce: 0,
author: Public::default().into(),
author: Address::default().into(),
nodes: nodes.into_iter().map(|(k, v)| (k.into(), v.into())).collect(),
is_zero: false,
threshold: 0,
@ -1200,7 +1202,7 @@ pub mod tests {
assert_eq!(l.first_slave().on_initialize_session(m, &message::InitializeSession {
session: sid.into(),
session_nonce: 0,
author: Public::default().into(),
author: Address::default().into(),
nodes: nodes.into_iter().map(|(k, v)| (k.into(), v.into())).collect(),
is_zero: false,
threshold: 2,
@ -1343,7 +1345,7 @@ pub mod tests {
let test_cases = [(0, 5), (2, 5), (3, 5)];
for &(threshold, num_nodes) in &test_cases {
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);
// let nodes do initialization + keys dissemination

View File

@ -402,7 +402,7 @@ impl SessionImpl {
session_nonce: n,
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);
// start generation of inversed nonce computation session
@ -414,7 +414,7 @@ impl SessionImpl {
session_nonce: n,
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);
// start generation of zero-secret shares for inversed nonce computation session
@ -426,7 +426,7 @@ impl SessionImpl {
session_nonce: n,
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.state = SessionState::NoncesGenerating;
@ -1054,7 +1054,7 @@ mod tests {
use std::sync::Arc;
use std::collections::{BTreeSet, BTreeMap, VecDeque};
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 key_server_cluster::{NodeId, DummyKeyStorage, SessionId, SessionMeta, Error, KeyStorage};
use key_server_cluster::cluster_sessions::ClusterSession;
@ -1165,7 +1165,7 @@ mod tests {
fn prepare_signing_sessions(threshold: usize, num_nodes: usize) -> (KeyGenerationMessageLoop, MessageLoop) {
// run key generation sessions
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() {
gl.process_message((from, to, message)).unwrap();
}

View File

@ -277,7 +277,7 @@ impl SessionImpl {
}),
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);
let joint_public_and_secret = generation_session
@ -405,7 +405,8 @@ impl SessionImpl {
}),
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.state = SessionState::SessionKeyGeneration;
@ -800,7 +801,7 @@ mod tests {
use std::sync::Arc;
use std::str::FromStr;
use std::collections::{BTreeSet, BTreeMap, VecDeque};
use ethereum_types::H256;
use ethereum_types::{Address, H256};
use ethkey::{self, Random, Generator, Public, Secret, KeyPair};
use acl_storage::DummyAclStorage;
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) {
// run key generation sessions
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() {
gl.process_message((from, to, message)).unwrap();
}
@ -971,7 +972,7 @@ mod tests {
},
access_key: Random.generate().unwrap().secret().clone(),
key_share: Some(DocumentKeyShare {
author: Public::default(),
author: Default::default(),
threshold: 0,
public: Default::default(),
common_point: Some(Random.generate().unwrap().public().clone()),
@ -1025,7 +1026,7 @@ mod tests {
},
access_key: Random.generate().unwrap().secret().clone(),
key_share: Some(DocumentKeyShare {
author: Public::default(),
author: Default::default(),
threshold: 2,
public: Default::default(),
common_point: Some(Random.generate().unwrap().public().clone()),
@ -1113,7 +1114,7 @@ mod tests {
message: GenerationMessage::InitializeSession(InitializeSession {
session: SessionId::default().into(),
session_nonce: 0,
author: Public::default().into(),
author: Address::default().into(),
nodes: BTreeMap::new(),
is_zero: false,
threshold: 1,

View File

@ -26,7 +26,7 @@ use parking_lot::{RwLock, Mutex};
use tokio_io::IoFuture;
use tokio_core::reactor::{Handle, Remote, Interval};
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 key_server_cluster::{Error, NodeId, SessionId, Requester, AclStorage, KeyStorage, KeyServerSet, NodeKeyPair};
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 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),
Err(error) => {
self.data.sessions.generation_sessions.remove(&session.id());

View File

@ -19,7 +19,7 @@ use std::collections::{BTreeSet, BTreeMap};
use ethkey::Secret;
use key_server_cluster::SessionId;
use super::{SerializableH256, SerializablePublic, SerializableSecret, SerializableSignature,
SerializableMessageHash, SerializableRequester};
SerializableMessageHash, SerializableRequester, SerializableAddress};
pub type MessageSessionId = SerializableH256;
pub type MessageNodeId = SerializablePublic;
@ -273,7 +273,7 @@ pub struct InitializeSession {
/// Session-level nonce.
pub session_nonce: u64,
/// Session author.
pub author: SerializablePublic,
pub author: SerializableAddress,
/// All session participants along with their identification numbers.
pub nodes: BTreeMap<MessageNodeId, SerializableSecret>,
/// Is zero secret generation session?
@ -963,7 +963,7 @@ pub struct KeyShareCommon {
/// Key threshold.
pub threshold: usize,
/// Author of key share entry.
pub author: SerializablePublic,
pub author: SerializableAddress,
/// Joint public.
pub joint_public: SerializablePublic,
/// 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_server_set::{is_migration_required, KeyServerSet, KeyServerSetSnapshot, KeyServerSetMigration};
pub use super::serialization::{SerializableSignature, SerializableH256, SerializableSecret, SerializablePublic,
SerializableRequester, SerializableMessageHash};
SerializableRequester, SerializableMessageHash, SerializableAddress};
pub use self::cluster::{ClusterCore, ClusterConfiguration, ClusterClient};
pub use self::cluster_sessions::{ClusterSession, ClusterSessionsListener};
#[cfg(test)]

View File

@ -18,27 +18,27 @@ use std::path::PathBuf;
use std::collections::BTreeMap;
use serde_json;
use tiny_keccak::Keccak;
use ethereum_types::H256;
use ethkey::{Secret, Public};
use ethereum_types::{H256, Address};
use ethkey::{Secret, Public, public_to_address};
use kvdb_rocksdb::{Database, DatabaseIterator};
use types::all::{Error, ServiceConfiguration, ServerKeyId, NodeId};
use serialization::{SerializablePublic, SerializableSecret, SerializableH256};
use serialization::{SerializablePublic, SerializableSecret, SerializableH256, SerializableAddress};
/// Key of version value.
const DB_META_KEY_VERSION: &'static [u8; 7] = b"version";
/// Current db version.
const CURRENT_VERSION: u8 = 2;
const CURRENT_VERSION: u8 = 3;
/// Current type of serialized key shares.
type CurrentSerializableDocumentKeyShare = SerializableDocumentKeyShareV2;
type CurrentSerializableDocumentKeyShare = SerializableDocumentKeyShareV3;
/// 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.
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(test, derive(Default))]
pub struct DocumentKeyShare {
/// Author of the entry.
pub author: Public,
pub author: Address,
/// Decryption threshold (at least threshold + 1 nodes are required to decrypt data).
pub threshold: usize,
/// Server public key.
@ -136,7 +136,8 @@ struct SerializableDocumentKeyShareV2 {
/// Encrypted point.
pub encrypted_point: Option<SerializablePublic>,
/// 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.
#[derive(Serialize, Deserialize)]
@ -149,6 +150,26 @@ struct SerializableDocumentKeyShareVersionV2 {
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 {
/// Create new persistent document encryption keys storage
pub fn new(config: &ServiceConfiguration) -> Result<Self, Error> {
@ -177,7 +198,7 @@ fn upgrade_db(db: Database) -> Result<Database, Error> {
let current_key = CurrentSerializableDocumentKeyShare {
// author is used in separate generation + encrypt 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,
public: Public::default().into(), // addded in v2
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) {
let v1_key = serde_json::from_slice::<SerializableDocumentKeyShareV1>(&db_value).map_err(|e| Error::Database(e.to_string()))?;
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,
public: Public::default().into(), // addded in v2
common_point: v1_key.common_point,
@ -217,7 +238,26 @@ fn upgrade_db(db: Database) -> Result<Database, Error> {
db.write(batch)?;
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))),
}
}
@ -331,9 +371,9 @@ impl DocumentKeyShareVersion {
}
}
impl From<DocumentKeyShare> for SerializableDocumentKeyShareV2 {
impl From<DocumentKeyShare> for SerializableDocumentKeyShareV3 {
fn from(key: DocumentKeyShare) -> Self {
SerializableDocumentKeyShareV2 {
SerializableDocumentKeyShareV3 {
author: key.author.into(),
threshold: key.threshold,
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 {
SerializableDocumentKeyShareVersionV2 {
SerializableDocumentKeyShareVersionV3 {
hash: version.hash.into(),
id_numbers: version.id_numbers.into_iter().map(|(k, v)| (k.into(), v.into())).collect(),
secret_share: version.secret_share.into(),
@ -354,8 +394,8 @@ impl From<DocumentKeyShareVersion> for SerializableDocumentKeyShareVersionV2 {
}
}
impl From<SerializableDocumentKeyShareV2> for DocumentKeyShare {
fn from(key: SerializableDocumentKeyShareV2) -> Self {
impl From<SerializableDocumentKeyShareV3> for DocumentKeyShare {
fn from(key: SerializableDocumentKeyShareV3) -> Self {
DocumentKeyShare {
author: key.author.into(),
threshold: key.threshold,
@ -381,12 +421,13 @@ pub mod tests {
use parking_lot::RwLock;
use serde_json;
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 types::all::{Error, NodeAddress, ServiceConfiguration, ClusterConfiguration, ServerKeyId};
use super::{DB_META_KEY_VERSION, CURRENT_VERSION, KeyStorage, PersistentKeyStorage, DocumentKeyShare,
DocumentKeyShareVersion, SerializableDocumentKeyShareV0, SerializableDocumentKeyShareV1,
CurrentSerializableDocumentKeyShare, upgrade_db};
DocumentKeyShareVersion, CurrentSerializableDocumentKeyShare, upgrade_db, SerializableDocumentKeyShareV0,
SerializableDocumentKeyShareV1, SerializableDocumentKeyShareV2, SerializableDocumentKeyShareVersionV2};
/// In-memory document encryption keys storage
#[derive(Default)]
@ -451,7 +492,7 @@ pub mod tests {
let key1 = ServerKeyId::from(1);
let value1 = DocumentKeyShare {
author: Public::default(),
author: Default::default(),
threshold: 100,
public: Public::default(),
common_point: Some(Random.generate().unwrap().public().clone()),
@ -466,7 +507,7 @@ pub mod tests {
};
let key2 = ServerKeyId::from(2);
let value2 = DocumentKeyShare {
author: Public::default(),
author: Default::default(),
threshold: 200,
public: Public::default(),
common_point: Some(Random.generate().unwrap().public().clone()),
@ -523,7 +564,7 @@ pub mod tests {
// 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!(Public::default(), key.author.clone().into());
assert_eq!(Address::default(), key.author.clone().into());
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));
@ -569,7 +610,55 @@ pub mod tests {
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, "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!(vec![(

View File

@ -191,6 +191,10 @@ impl Requester {
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 {