NodeKeyPAir trait
This commit is contained in:
parent
b31b067743
commit
45f2b82411
@ -26,7 +26,7 @@ use super::acl_storage::AclStorage;
|
|||||||
use super::key_storage::KeyStorage;
|
use super::key_storage::KeyStorage;
|
||||||
use super::key_server_set::KeyServerSet;
|
use super::key_server_set::KeyServerSet;
|
||||||
use key_server_cluster::{math, ClusterCore};
|
use key_server_cluster::{math, ClusterCore};
|
||||||
use traits::{ServerKeyGenerator, DocumentKeyServer, MessageSigner, KeyServer};
|
use traits::{ServerKeyGenerator, DocumentKeyServer, MessageSigner, KeyServer, NodeKeyPair};
|
||||||
use types::all::{Error, Public, RequestSignature, ServerKeyId, EncryptedDocumentKey, EncryptedDocumentKeyShadow,
|
use types::all::{Error, Public, RequestSignature, ServerKeyId, EncryptedDocumentKey, EncryptedDocumentKeyShadow,
|
||||||
ClusterConfiguration, MessageHash, EncryptedMessageSignature};
|
ClusterConfiguration, MessageHash, EncryptedMessageSignature};
|
||||||
use key_server_cluster::{ClusterClient, ClusterConfiguration as NetClusterConfiguration};
|
use key_server_cluster::{ClusterClient, ClusterConfiguration as NetClusterConfiguration};
|
||||||
@ -45,9 +45,9 @@ pub struct KeyServerCore {
|
|||||||
|
|
||||||
impl KeyServerImpl {
|
impl KeyServerImpl {
|
||||||
/// Create new key server instance
|
/// Create new key server instance
|
||||||
pub fn new(config: &ClusterConfiguration, key_server_set: Arc<KeyServerSet>, acl_storage: Arc<AclStorage>, key_storage: Arc<KeyStorage>) -> Result<Self, Error> {
|
pub fn new(config: &ClusterConfiguration, key_server_set: Arc<KeyServerSet>, self_key_pair: Arc<NodeKeyPair>, acl_storage: Arc<AclStorage>, key_storage: Arc<KeyStorage>) -> Result<Self, Error> {
|
||||||
Ok(KeyServerImpl {
|
Ok(KeyServerImpl {
|
||||||
data: Arc::new(Mutex::new(KeyServerCore::new(config, key_server_set, acl_storage, key_storage)?)),
|
data: Arc::new(Mutex::new(KeyServerCore::new(config, key_server_set, self_key_pair, acl_storage, key_storage)?)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,10 +144,10 @@ impl MessageSigner for KeyServerImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl KeyServerCore {
|
impl KeyServerCore {
|
||||||
pub fn new(config: &ClusterConfiguration, key_server_set: Arc<KeyServerSet>, acl_storage: Arc<AclStorage>, key_storage: Arc<KeyStorage>) -> Result<Self, Error> {
|
pub fn new(config: &ClusterConfiguration, key_server_set: Arc<KeyServerSet>, self_key_pair: Arc<NodeKeyPair>, acl_storage: Arc<AclStorage>, key_storage: Arc<KeyStorage>) -> Result<Self, Error> {
|
||||||
let config = NetClusterConfiguration {
|
let config = NetClusterConfiguration {
|
||||||
threads: config.threads,
|
threads: config.threads,
|
||||||
self_key_pair: ethkey::KeyPair::from_secret_slice(&config.self_private)?,
|
self_key_pair: self_key_pair,
|
||||||
listen_address: (config.listener_address.address.clone(), config.listener_address.port),
|
listen_address: (config.listener_address.address.clone(), config.listener_address.port),
|
||||||
key_server_set: key_server_set,
|
key_server_set: key_server_set,
|
||||||
allow_connecting_to_higher_nodes: config.allow_connecting_to_higher_nodes,
|
allow_connecting_to_higher_nodes: config.allow_connecting_to_higher_nodes,
|
||||||
@ -198,6 +198,7 @@ pub mod tests {
|
|||||||
use ethkey::{self, Secret, Random, Generator};
|
use ethkey::{self, Secret, Random, Generator};
|
||||||
use acl_storage::tests::DummyAclStorage;
|
use acl_storage::tests::DummyAclStorage;
|
||||||
use key_storage::tests::DummyKeyStorage;
|
use key_storage::tests::DummyKeyStorage;
|
||||||
|
use node_key_pair::PlainNodeKeyPair;
|
||||||
use key_server_set::tests::MapKeyServerSet;
|
use key_server_set::tests::MapKeyServerSet;
|
||||||
use key_server_cluster::math;
|
use key_server_cluster::math;
|
||||||
use util::H256;
|
use util::H256;
|
||||||
@ -244,7 +245,7 @@ pub mod tests {
|
|||||||
let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect();
|
let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect();
|
||||||
let configs: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration {
|
let configs: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration {
|
||||||
threads: 1,
|
threads: 1,
|
||||||
self_private: (***key_pairs[i].secret()).into(),
|
// self_key_pair: Arc::new(PlainNodeKeyPair::new(key_pairs[i].clone())),
|
||||||
listener_address: NodeAddress {
|
listener_address: NodeAddress {
|
||||||
address: "127.0.0.1".into(),
|
address: "127.0.0.1".into(),
|
||||||
port: start_port + (i as u16),
|
port: start_port + (i as u16),
|
||||||
@ -259,8 +260,11 @@ pub mod tests {
|
|||||||
let key_servers_set: BTreeMap<Public, SocketAddr> = configs[0].nodes.iter()
|
let key_servers_set: BTreeMap<Public, SocketAddr> = configs[0].nodes.iter()
|
||||||
.map(|(k, a)| (k.clone(), format!("{}:{}", a.address, a.port).parse().unwrap()))
|
.map(|(k, a)| (k.clone(), format!("{}:{}", a.address, a.port).parse().unwrap()))
|
||||||
.collect();
|
.collect();
|
||||||
let key_servers: Vec<_> = configs.into_iter().map(|cfg|
|
let key_servers: Vec<_> = configs.into_iter().enumerate().map(|(i, cfg)|
|
||||||
KeyServerImpl::new(&cfg, Arc::new(MapKeyServerSet::new(key_servers_set.clone())), Arc::new(DummyAclStorage::default()), Arc::new(DummyKeyStorage::default())).unwrap()
|
KeyServerImpl::new(&cfg, Arc::new(MapKeyServerSet::new(key_servers_set.clone())),
|
||||||
|
Arc::new(PlainNodeKeyPair::new(key_pairs[i].clone())),
|
||||||
|
Arc::new(DummyAclStorage::default()),
|
||||||
|
Arc::new(DummyKeyStorage::default())).unwrap()
|
||||||
).collect();
|
).collect();
|
||||||
|
|
||||||
// wait until connections are established. It is fast => do not bother with events here
|
// wait until connections are established. It is fast => do not bother with events here
|
||||||
|
@ -28,7 +28,7 @@ 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};
|
||||||
use util::H256;
|
use util::H256;
|
||||||
use key_server_cluster::{Error, NodeId, SessionId, AclStorage, KeyStorage, KeyServerSet};
|
use key_server_cluster::{Error, NodeId, SessionId, AclStorage, KeyStorage, KeyServerSet, NodeKeyPair};
|
||||||
use key_server_cluster::cluster_sessions::{ClusterSession, ClusterSessions, GenerationSessionWrapper, EncryptionSessionWrapper,
|
use key_server_cluster::cluster_sessions::{ClusterSession, ClusterSessions, GenerationSessionWrapper, EncryptionSessionWrapper,
|
||||||
DecryptionSessionWrapper, SigningSessionWrapper};
|
DecryptionSessionWrapper, SigningSessionWrapper};
|
||||||
use key_server_cluster::message::{self, Message, ClusterMessage, GenerationMessage, EncryptionMessage, DecryptionMessage,
|
use key_server_cluster::message::{self, Message, ClusterMessage, GenerationMessage, EncryptionMessage, DecryptionMessage,
|
||||||
@ -99,7 +99,7 @@ pub struct ClusterConfiguration {
|
|||||||
/// Allow connecting to 'higher' nodes.
|
/// Allow connecting to 'higher' nodes.
|
||||||
pub allow_connecting_to_higher_nodes: bool,
|
pub allow_connecting_to_higher_nodes: bool,
|
||||||
/// KeyPair this node holds.
|
/// KeyPair this node holds.
|
||||||
pub self_key_pair: KeyPair,
|
pub self_key_pair: Arc<NodeKeyPair>,
|
||||||
/// Interface to listen to.
|
/// Interface to listen to.
|
||||||
pub listen_address: (String, u16),
|
pub listen_address: (String, u16),
|
||||||
/// Cluster nodes set.
|
/// Cluster nodes set.
|
||||||
@ -146,7 +146,7 @@ pub struct ClusterData {
|
|||||||
/// Handle to the cpu thread pool.
|
/// Handle to the cpu thread pool.
|
||||||
pool: CpuPool,
|
pool: CpuPool,
|
||||||
/// KeyPair this node holds.
|
/// KeyPair this node holds.
|
||||||
self_key_pair: KeyPair,
|
self_key_pair: Arc<NodeKeyPair>,
|
||||||
/// Connections data.
|
/// Connections data.
|
||||||
connections: ClusterConnections,
|
connections: ClusterConnections,
|
||||||
/// Active sessions data.
|
/// Active sessions data.
|
||||||
@ -989,7 +989,7 @@ pub mod tests {
|
|||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use tokio_core::reactor::Core;
|
use tokio_core::reactor::Core;
|
||||||
use ethkey::{Random, Generator, Public};
|
use ethkey::{Random, Generator, Public};
|
||||||
use key_server_cluster::{NodeId, SessionId, Error, DummyAclStorage, DummyKeyStorage, MapKeyServerSet};
|
use key_server_cluster::{NodeId, SessionId, Error, DummyAclStorage, DummyKeyStorage, MapKeyServerSet, PlainNodeKeyPair};
|
||||||
use key_server_cluster::message::Message;
|
use key_server_cluster::message::Message;
|
||||||
use key_server_cluster::cluster::{Cluster, ClusterCore, ClusterConfiguration};
|
use key_server_cluster::cluster::{Cluster, ClusterCore, ClusterConfiguration};
|
||||||
use key_server_cluster::generation_session::{Session as GenerationSession, SessionState as GenerationSessionState};
|
use key_server_cluster::generation_session::{Session as GenerationSession, SessionState as GenerationSessionState};
|
||||||
@ -1068,7 +1068,7 @@ pub mod tests {
|
|||||||
let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect();
|
let key_pairs: Vec<_> = (0..num_nodes).map(|_| Random.generate().unwrap()).collect();
|
||||||
let cluster_params: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration {
|
let cluster_params: Vec<_> = (0..num_nodes).map(|i| ClusterConfiguration {
|
||||||
threads: 1,
|
threads: 1,
|
||||||
self_key_pair: key_pairs[i].clone(),
|
self_key_pair: Arc::new(PlainNodeKeyPair::new(key_pairs[i].clone())),
|
||||||
listen_address: ("127.0.0.1".to_owned(), ports_begin + i as u16),
|
listen_address: ("127.0.0.1".to_owned(), ports_begin + i as u16),
|
||||||
key_server_set: Arc::new(MapKeyServerSet::new(key_pairs.iter().enumerate()
|
key_server_set: Arc::new(MapKeyServerSet::new(key_pairs.iter().enumerate()
|
||||||
.map(|(j, kp)| (kp.public().clone(), format!("127.0.0.1:{}", ports_begin + j as u16).parse().unwrap()))
|
.map(|(j, kp)| (kp.public().clone(), format!("127.0.0.1:{}", ports_begin + j as u16).parse().unwrap()))
|
||||||
|
@ -15,24 +15,25 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use futures::{Future, Poll, Async};
|
use futures::{Future, Poll, Async};
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use ethkey::{Random, Generator, KeyPair, Secret, sign, verify_public};
|
use ethkey::{Random, Generator, KeyPair, verify_public};
|
||||||
use util::H256;
|
use util::H256;
|
||||||
use key_server_cluster::{NodeId, Error};
|
use key_server_cluster::{NodeId, Error, NodeKeyPair};
|
||||||
use key_server_cluster::message::{Message, ClusterMessage, NodePublicKey, NodePrivateKeySignature};
|
use key_server_cluster::message::{Message, ClusterMessage, NodePublicKey, NodePrivateKeySignature};
|
||||||
use key_server_cluster::io::{write_message, write_encrypted_message, WriteMessage, ReadMessage,
|
use key_server_cluster::io::{write_message, write_encrypted_message, WriteMessage, ReadMessage,
|
||||||
read_message, read_encrypted_message, compute_shared_key};
|
read_message, read_encrypted_message, fix_shared_key};
|
||||||
|
|
||||||
/// Start handshake procedure with another node from the cluster.
|
/// Start handshake procedure with another node from the cluster.
|
||||||
pub fn handshake<A>(a: A, self_key_pair: KeyPair, trusted_nodes: BTreeSet<NodeId>) -> Handshake<A> where A: AsyncWrite + AsyncRead {
|
pub fn handshake<A>(a: A, self_key_pair: Arc<NodeKeyPair>, trusted_nodes: BTreeSet<NodeId>) -> Handshake<A> where A: AsyncWrite + AsyncRead {
|
||||||
let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into);
|
let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into);
|
||||||
handshake_with_plain_confirmation(a, self_confirmation_plain, self_key_pair, trusted_nodes)
|
handshake_with_plain_confirmation(a, self_confirmation_plain, self_key_pair, trusted_nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start handshake procedure with another node from the cluster and given plain confirmation.
|
/// Start handshake procedure with another node from the cluster and given plain confirmation.
|
||||||
pub fn handshake_with_plain_confirmation<A>(a: A, self_confirmation_plain: Result<H256, Error>, self_key_pair: KeyPair, trusted_nodes: BTreeSet<NodeId>) -> Handshake<A> where A: AsyncWrite + AsyncRead {
|
pub fn handshake_with_plain_confirmation<A>(a: A, self_confirmation_plain: Result<H256, Error>, self_key_pair: Arc<NodeKeyPair>, trusted_nodes: BTreeSet<NodeId>) -> Handshake<A> where A: AsyncWrite + AsyncRead {
|
||||||
let (error, state) = match self_confirmation_plain.clone()
|
let (error, state) = match self_confirmation_plain.clone()
|
||||||
.and_then(|c| Handshake::<A>::make_public_key_message(self_key_pair.public().clone(), c)) {
|
.and_then(|c| Handshake::<A>::make_public_key_message(self_key_pair.public().clone(), c)) {
|
||||||
Ok(message) => (None, HandshakeState::SendPublicKey(write_message(a, message))),
|
Ok(message) => (None, HandshakeState::SendPublicKey(write_message(a, message))),
|
||||||
@ -53,7 +54,7 @@ pub fn handshake_with_plain_confirmation<A>(a: A, self_confirmation_plain: Resul
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for handshake procedure to be started by another node from the cluster.
|
/// Wait for handshake procedure to be started by another node from the cluster.
|
||||||
pub fn accept_handshake<A>(a: A, self_key_pair: KeyPair) -> Handshake<A> where A: AsyncWrite + AsyncRead {
|
pub fn accept_handshake<A>(a: A, self_key_pair: Arc<NodeKeyPair>) -> Handshake<A> where A: AsyncWrite + AsyncRead {
|
||||||
let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into);
|
let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into);
|
||||||
let (error, state) = match self_confirmation_plain.clone() {
|
let (error, state) = match self_confirmation_plain.clone() {
|
||||||
Ok(_) => (None, HandshakeState::ReceivePublicKey(read_message(a))),
|
Ok(_) => (None, HandshakeState::ReceivePublicKey(read_message(a))),
|
||||||
@ -87,7 +88,7 @@ pub struct Handshake<A> {
|
|||||||
is_active: bool,
|
is_active: bool,
|
||||||
error: Option<(A, Result<HandshakeResult, Error>)>,
|
error: Option<(A, Result<HandshakeResult, Error>)>,
|
||||||
state: HandshakeState<A>,
|
state: HandshakeState<A>,
|
||||||
self_key_pair: KeyPair,
|
self_key_pair: Arc<NodeKeyPair>,
|
||||||
self_confirmation_plain: H256,
|
self_confirmation_plain: H256,
|
||||||
trusted_nodes: Option<BTreeSet<NodeId>>,
|
trusted_nodes: Option<BTreeSet<NodeId>>,
|
||||||
other_node_id: Option<NodeId>,
|
other_node_id: Option<NodeId>,
|
||||||
@ -117,9 +118,9 @@ impl<A> Handshake<A> where A: AsyncRead + AsyncWrite {
|
|||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_private_key_signature_message(secret: &Secret, confirmation_plain: &H256) -> Result<Message, Error> {
|
fn make_private_key_signature_message(self_key_pair: &NodeKeyPair, confirmation_plain: &H256) -> Result<Message, Error> {
|
||||||
Ok(Message::Cluster(ClusterMessage::NodePrivateKeySignature(NodePrivateKeySignature {
|
Ok(Message::Cluster(ClusterMessage::NodePrivateKeySignature(NodePrivateKeySignature {
|
||||||
confirmation_signed: sign(secret, confirmation_plain)?.into(),
|
confirmation_signed: self_key_pair.sign(confirmation_plain)?.into(),
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,15 +143,15 @@ impl<A> Future for Handshake<A> where A: AsyncRead + AsyncWrite {
|
|||||||
read_message(stream)
|
read_message(stream)
|
||||||
), Async::NotReady)
|
), Async::NotReady)
|
||||||
} else {
|
} else {
|
||||||
self.shared_key = match compute_shared_key(self.self_key_pair.secret(),
|
self.shared_key = match self.self_key_pair.compute_shared_key(
|
||||||
self.other_node_id.as_ref().expect("we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; other_node_id is filled in ReceivePublicKey; qed")
|
self.other_node_id.as_ref().expect("we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; other_node_id is filled in ReceivePublicKey; qed")
|
||||||
) {
|
).map_err(Into::into).and_then(|sk| fix_shared_key(sk.secret())) {
|
||||||
Ok(shared_key) => Some(shared_key),
|
Ok(shared_key) => Some(shared_key),
|
||||||
Err(err) => return Ok((stream, Err(err)).into()),
|
Err(err) => return Ok((stream, Err(err.into())).into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = match Handshake::<A>::make_private_key_signature_message(
|
let message = match Handshake::<A>::make_private_key_signature_message(
|
||||||
self.self_key_pair.secret(),
|
&*self.self_key_pair,
|
||||||
self.other_confirmation_plain.as_ref().expect("we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; other_confirmation_plain is filled in ReceivePublicKey; qed")
|
self.other_confirmation_plain.as_ref().expect("we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; other_confirmation_plain is filled in ReceivePublicKey; qed")
|
||||||
) {
|
) {
|
||||||
Ok(message) => message,
|
Ok(message) => message,
|
||||||
@ -179,15 +180,15 @@ impl<A> Future for Handshake<A> where A: AsyncRead + AsyncWrite {
|
|||||||
self.other_node_id = Some(message.node_id.into());
|
self.other_node_id = Some(message.node_id.into());
|
||||||
self.other_confirmation_plain = Some(message.confirmation_plain.into());
|
self.other_confirmation_plain = Some(message.confirmation_plain.into());
|
||||||
if self.is_active {
|
if self.is_active {
|
||||||
self.shared_key = match compute_shared_key(self.self_key_pair.secret(),
|
self.shared_key = match self.self_key_pair.compute_shared_key(
|
||||||
self.other_node_id.as_ref().expect("filled couple of lines above; qed")
|
self.other_node_id.as_ref().expect("filled couple of lines above; qed")
|
||||||
) {
|
).map_err(Into::into).and_then(|sk| fix_shared_key(sk.secret())) {
|
||||||
Ok(shared_key) => Some(shared_key),
|
Ok(shared_key) => Some(shared_key),
|
||||||
Err(err) => return Ok((stream, Err(err)).into()),
|
Err(err) => return Ok((stream, Err(err.into())).into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let message = match Handshake::<A>::make_private_key_signature_message(
|
let message = match Handshake::<A>::make_private_key_signature_message(
|
||||||
self.self_key_pair.secret(),
|
&*self.self_key_pair,
|
||||||
self.other_confirmation_plain.as_ref().expect("filled couple of lines above; qed")
|
self.other_confirmation_plain.as_ref().expect("filled couple of lines above; qed")
|
||||||
) {
|
) {
|
||||||
Ok(message) => message,
|
Ok(message) => message,
|
||||||
@ -248,11 +249,14 @@ impl<A> Future for Handshake<A> where A: AsyncRead + AsyncWrite {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::sync::Arc;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use ethkey::{Random, Generator, sign};
|
use ethkey::{Random, Generator, sign};
|
||||||
|
use ethcrypto::ecdh::agree;
|
||||||
use util::H256;
|
use util::H256;
|
||||||
use key_server_cluster::io::message::compute_shared_key;
|
use key_server_cluster::PlainNodeKeyPair;
|
||||||
|
use key_server_cluster::io::message::fix_shared_key;
|
||||||
use key_server_cluster::io::message::tests::TestIo;
|
use key_server_cluster::io::message::tests::TestIo;
|
||||||
use key_server_cluster::message::{Message, ClusterMessage, NodePublicKey, NodePrivateKeySignature};
|
use key_server_cluster::message::{Message, ClusterMessage, NodePublicKey, NodePrivateKeySignature};
|
||||||
use super::{handshake_with_plain_confirmation, accept_handshake, HandshakeResult};
|
use super::{handshake_with_plain_confirmation, accept_handshake, HandshakeResult};
|
||||||
@ -283,9 +287,9 @@ mod tests {
|
|||||||
let (self_confirmation_plain, io) = prepare_test_io();
|
let (self_confirmation_plain, io) = prepare_test_io();
|
||||||
let self_key_pair = io.self_key_pair().clone();
|
let self_key_pair = io.self_key_pair().clone();
|
||||||
let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect();
|
let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect();
|
||||||
let shared_key = compute_shared_key(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap();
|
let shared_key = fix_shared_key(&agree(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap()).unwrap();
|
||||||
|
|
||||||
let handshake = handshake_with_plain_confirmation(io, Ok(self_confirmation_plain), self_key_pair, trusted_nodes);
|
let handshake = handshake_with_plain_confirmation(io, Ok(self_confirmation_plain), Arc::new(PlainNodeKeyPair::new(self_key_pair)), trusted_nodes);
|
||||||
let handshake_result = handshake.wait().unwrap();
|
let handshake_result = handshake.wait().unwrap();
|
||||||
assert_eq!(handshake_result.1, Ok(HandshakeResult {
|
assert_eq!(handshake_result.1, Ok(HandshakeResult {
|
||||||
node_id: handshake_result.0.peer_public().clone(),
|
node_id: handshake_result.0.peer_public().clone(),
|
||||||
@ -298,9 +302,9 @@ mod tests {
|
|||||||
let (self_confirmation_plain, io) = prepare_test_io();
|
let (self_confirmation_plain, io) = prepare_test_io();
|
||||||
let self_key_pair = io.self_key_pair().clone();
|
let self_key_pair = io.self_key_pair().clone();
|
||||||
let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect();
|
let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect();
|
||||||
let shared_key = compute_shared_key(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap();
|
let shared_key = fix_shared_key(&agree(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap()).unwrap();
|
||||||
|
|
||||||
let mut handshake = accept_handshake(io, self_key_pair);
|
let mut handshake = accept_handshake(io, Arc::new(PlainNodeKeyPair::new(self_key_pair)));
|
||||||
handshake.set_self_confirmation_plain(self_confirmation_plain);
|
handshake.set_self_confirmation_plain(self_confirmation_plain);
|
||||||
|
|
||||||
let handshake_result = handshake.wait().unwrap();
|
let handshake_result = handshake.wait().unwrap();
|
||||||
|
@ -19,9 +19,8 @@ use std::u16;
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use ethcrypto::ecdh::agree;
|
|
||||||
use ethcrypto::ecies::{encrypt_single_message, decrypt_single_message};
|
use ethcrypto::ecies::{encrypt_single_message, decrypt_single_message};
|
||||||
use ethkey::{Public, Secret, KeyPair};
|
use ethkey::{Secret, KeyPair};
|
||||||
use ethkey::math::curve_order;
|
use ethkey::math::curve_order;
|
||||||
use util::{H256, U256};
|
use util::{H256, U256};
|
||||||
use key_server_cluster::Error;
|
use key_server_cluster::Error;
|
||||||
@ -154,12 +153,11 @@ pub fn decrypt_message(key: &KeyPair, payload: Vec<u8>) -> Result<Vec<u8>, Error
|
|||||||
Ok(decrypt_single_message(key.secret(), &payload)?)
|
Ok(decrypt_single_message(key.secret(), &payload)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute shared encryption key.
|
/// Fix shared encryption key.
|
||||||
pub fn compute_shared_key(self_secret: &Secret, other_public: &Public) -> Result<KeyPair, Error> {
|
pub fn fix_shared_key(shared_secret: &Secret) -> Result<KeyPair, Error> {
|
||||||
// secret key created in agree function is invalid, as it is not calculated mod EC.field.n
|
// secret key created in agree function is invalid, as it is not calculated mod EC.field.n
|
||||||
// => let's do it manually
|
// => let's do it manually
|
||||||
let shared_secret = agree(self_secret, other_public)?;
|
let shared_secret: H256 = (**shared_secret).into();
|
||||||
let shared_secret: H256 = (*shared_secret).into();
|
|
||||||
let shared_secret: U256 = shared_secret.into();
|
let shared_secret: U256 = shared_secret.into();
|
||||||
let shared_secret: H256 = (shared_secret % curve_order()).into();
|
let shared_secret: H256 = (shared_secret % curve_order()).into();
|
||||||
let shared_key_pair = KeyPair::from_secret_slice(&*shared_secret)?;
|
let shared_key_pair = KeyPair::from_secret_slice(&*shared_secret)?;
|
||||||
@ -204,8 +202,9 @@ pub mod tests {
|
|||||||
use futures::Poll;
|
use futures::Poll;
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use ethkey::{KeyPair, Public};
|
use ethkey::{KeyPair, Public};
|
||||||
|
use ethcrypto::ecdh::agree;
|
||||||
use key_server_cluster::message::Message;
|
use key_server_cluster::message::Message;
|
||||||
use super::{MESSAGE_HEADER_SIZE, MessageHeader, compute_shared_key, encrypt_message, serialize_message,
|
use super::{MESSAGE_HEADER_SIZE, MessageHeader, fix_shared_key, encrypt_message, serialize_message,
|
||||||
serialize_header, deserialize_header};
|
serialize_header, deserialize_header};
|
||||||
|
|
||||||
pub struct TestIo {
|
pub struct TestIo {
|
||||||
@ -217,7 +216,7 @@ pub mod tests {
|
|||||||
|
|
||||||
impl TestIo {
|
impl TestIo {
|
||||||
pub fn new(self_key_pair: KeyPair, peer_public: Public) -> Self {
|
pub fn new(self_key_pair: KeyPair, peer_public: Public) -> Self {
|
||||||
let shared_key_pair = compute_shared_key(self_key_pair.secret(), &peer_public).unwrap();
|
let shared_key_pair = fix_shared_key(&agree(self_key_pair.secret(), &peer_public).unwrap()).unwrap();
|
||||||
TestIo {
|
TestIo {
|
||||||
self_key_pair: self_key_pair,
|
self_key_pair: self_key_pair,
|
||||||
peer_public: peer_public,
|
peer_public: peer_public,
|
||||||
|
@ -26,7 +26,7 @@ mod write_message;
|
|||||||
pub use self::deadline::{deadline, Deadline, DeadlineStatus};
|
pub use self::deadline::{deadline, Deadline, DeadlineStatus};
|
||||||
pub use self::handshake::{handshake, accept_handshake, Handshake, HandshakeResult};
|
pub use self::handshake::{handshake, accept_handshake, Handshake, HandshakeResult};
|
||||||
pub use self::message::{MessageHeader, SerializedMessage, serialize_message, deserialize_message,
|
pub use self::message::{MessageHeader, SerializedMessage, serialize_message, deserialize_message,
|
||||||
encrypt_message, compute_shared_key};
|
encrypt_message, fix_shared_key};
|
||||||
pub use self::read_header::{read_header, ReadHeader};
|
pub use self::read_header::{read_header, ReadHeader};
|
||||||
pub use self::read_payload::{read_payload, read_encrypted_payload, ReadPayload};
|
pub use self::read_payload::{read_payload, read_encrypted_payload, ReadPayload};
|
||||||
pub use self::read_message::{read_message, read_encrypted_message, ReadMessage};
|
pub use self::read_message::{read_message, read_encrypted_message, ReadMessage};
|
||||||
|
@ -20,6 +20,7 @@ use ethkey;
|
|||||||
use ethcrypto;
|
use ethcrypto;
|
||||||
use super::types::all::ServerKeyId;
|
use super::types::all::ServerKeyId;
|
||||||
|
|
||||||
|
pub use super::traits::NodeKeyPair;
|
||||||
pub use super::types::all::{NodeId, EncryptedDocumentKeyShadow};
|
pub use super::types::all::{NodeId, EncryptedDocumentKeyShadow};
|
||||||
pub use super::acl_storage::AclStorage;
|
pub use super::acl_storage::AclStorage;
|
||||||
pub use super::key_storage::{KeyStorage, DocumentKeyShare};
|
pub use super::key_storage::{KeyStorage, DocumentKeyShare};
|
||||||
@ -30,6 +31,8 @@ pub use self::generation_session::Session as GenerationSession;
|
|||||||
pub use self::encryption_session::Session as EncryptionSession;
|
pub use self::encryption_session::Session as EncryptionSession;
|
||||||
pub use self::decryption_session::Session as DecryptionSession;
|
pub use self::decryption_session::Session as DecryptionSession;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub use super::node_key_pair::PlainNodeKeyPair;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub use super::key_storage::tests::DummyKeyStorage;
|
pub use super::key_storage::tests::DummyKeyStorage;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -15,18 +15,18 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use futures::{Future, Poll};
|
use futures::{Future, Poll};
|
||||||
use tokio_core::reactor::Handle;
|
use tokio_core::reactor::Handle;
|
||||||
use tokio_core::net::TcpStream;
|
use tokio_core::net::TcpStream;
|
||||||
use ethkey::KeyPair;
|
use key_server_cluster::{Error, NodeKeyPair};
|
||||||
use key_server_cluster::Error;
|
|
||||||
use key_server_cluster::io::{accept_handshake, Handshake, Deadline, deadline};
|
use key_server_cluster::io::{accept_handshake, Handshake, Deadline, deadline};
|
||||||
use key_server_cluster::net::Connection;
|
use key_server_cluster::net::Connection;
|
||||||
|
|
||||||
/// Create future for accepting incoming connection.
|
/// Create future for accepting incoming connection.
|
||||||
pub fn accept_connection(address: SocketAddr, stream: TcpStream, handle: &Handle, self_key_pair: KeyPair) -> Deadline<AcceptConnection> {
|
pub fn accept_connection(address: SocketAddr, stream: TcpStream, handle: &Handle, self_key_pair: Arc<NodeKeyPair>) -> Deadline<AcceptConnection> {
|
||||||
let accept = AcceptConnection {
|
let accept = AcceptConnection {
|
||||||
handshake: accept_handshake(stream, self_key_pair),
|
handshake: accept_handshake(stream, self_key_pair),
|
||||||
address: address,
|
address: address,
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -21,13 +22,12 @@ use std::net::SocketAddr;
|
|||||||
use futures::{Future, Poll, Async};
|
use futures::{Future, Poll, Async};
|
||||||
use tokio_core::reactor::Handle;
|
use tokio_core::reactor::Handle;
|
||||||
use tokio_core::net::{TcpStream, TcpStreamNew};
|
use tokio_core::net::{TcpStream, TcpStreamNew};
|
||||||
use ethkey::KeyPair;
|
use key_server_cluster::{Error, NodeId, NodeKeyPair};
|
||||||
use key_server_cluster::{Error, NodeId};
|
|
||||||
use key_server_cluster::io::{handshake, Handshake, Deadline, deadline};
|
use key_server_cluster::io::{handshake, Handshake, Deadline, deadline};
|
||||||
use key_server_cluster::net::Connection;
|
use key_server_cluster::net::Connection;
|
||||||
|
|
||||||
/// Create future for connecting to other node.
|
/// Create future for connecting to other node.
|
||||||
pub fn connect(address: &SocketAddr, handle: &Handle, self_key_pair: KeyPair, trusted_nodes: BTreeSet<NodeId>) -> Deadline<Connect> {
|
pub fn connect(address: &SocketAddr, handle: &Handle, self_key_pair: Arc<NodeKeyPair>, trusted_nodes: BTreeSet<NodeId>) -> Deadline<Connect> {
|
||||||
let connect = Connect {
|
let connect = Connect {
|
||||||
state: ConnectState::TcpConnect(TcpStream::connect(address, handle)),
|
state: ConnectState::TcpConnect(TcpStream::connect(address, handle)),
|
||||||
address: address.clone(),
|
address: address.clone(),
|
||||||
@ -48,7 +48,7 @@ enum ConnectState {
|
|||||||
pub struct Connect {
|
pub struct Connect {
|
||||||
state: ConnectState,
|
state: ConnectState,
|
||||||
address: SocketAddr,
|
address: SocketAddr,
|
||||||
self_key_pair: KeyPair,
|
self_key_pair: Arc<NodeKeyPair>,
|
||||||
trusted_nodes: BTreeSet<NodeId>,
|
trusted_nodes: BTreeSet<NodeId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ pub mod tests {
|
|||||||
data_path: path.as_str().to_owned(),
|
data_path: path.as_str().to_owned(),
|
||||||
cluster_config: ClusterConfiguration {
|
cluster_config: ClusterConfiguration {
|
||||||
threads: 1,
|
threads: 1,
|
||||||
self_private: (**Random.generate().unwrap().secret().clone()).into(),
|
//self_private: (**Random.generate().unwrap().secret().clone()).into(),
|
||||||
listener_address: NodeAddress {
|
listener_address: NodeAddress {
|
||||||
address: "0.0.0.0".to_owned(),
|
address: "0.0.0.0".to_owned(),
|
||||||
port: 8083,
|
port: 8083,
|
||||||
|
@ -59,22 +59,24 @@ mod key_server;
|
|||||||
mod key_storage;
|
mod key_storage;
|
||||||
mod serialization;
|
mod serialization;
|
||||||
mod key_server_set;
|
mod key_server_set;
|
||||||
|
mod node_key_pair;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ethcore::client::Client;
|
use ethcore::client::Client;
|
||||||
|
|
||||||
pub use types::all::{ServerKeyId, EncryptedDocumentKey, RequestSignature, Public,
|
pub use types::all::{ServerKeyId, EncryptedDocumentKey, RequestSignature, Public,
|
||||||
Error, NodeAddress, ServiceConfiguration, ClusterConfiguration};
|
Error, NodeAddress, ServiceConfiguration, ClusterConfiguration};
|
||||||
pub use traits::{KeyServer};
|
pub use traits::{NodeKeyPair, KeyServer};
|
||||||
|
pub use self::node_key_pair::{PlainNodeKeyPair, KeyStoreNodeKeyPair};
|
||||||
|
|
||||||
/// Start new key server instance
|
/// Start new key server instance
|
||||||
pub fn start(client: Arc<Client>, config: ServiceConfiguration) -> Result<Box<KeyServer>, Error> {
|
pub fn start(client: Arc<Client>, self_key_pair: Arc<NodeKeyPair>, config: ServiceConfiguration) -> Result<Box<KeyServer>, Error> {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
let acl_storage = acl_storage::OnChainAclStorage::new(&client);
|
let acl_storage = acl_storage::OnChainAclStorage::new(&client);
|
||||||
let key_server_set = key_server_set::OnChainKeyServerSet::new(&client, config.cluster_config.nodes.clone())?;
|
let key_server_set = key_server_set::OnChainKeyServerSet::new(&client, config.cluster_config.nodes.clone())?;
|
||||||
let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?);
|
let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?);
|
||||||
let key_server = key_server::KeyServerImpl::new(&config.cluster_config, key_server_set, acl_storage, key_storage)?;
|
let key_server = key_server::KeyServerImpl::new(&config.cluster_config, key_server_set, self_key_pair, acl_storage, key_storage)?;
|
||||||
let listener = http_listener::KeyServerHttpListener::start(&config.listener_address, key_server)?;
|
let listener = http_listener::KeyServerHttpListener::start(&config.listener_address, key_server)?;
|
||||||
Ok(Box::new(listener))
|
Ok(Box::new(listener))
|
||||||
}
|
}
|
||||||
|
67
secret_store/src/node_key_pair.rs
Normal file
67
secret_store/src/node_key_pair.rs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
use ethcrypto::ecdh::agree;
|
||||||
|
use ethkey::{KeyPair, Public, Signature, Error as EthKeyError, sign};
|
||||||
|
use ethcore::account_provider::AccountProvider;
|
||||||
|
use util::H256;
|
||||||
|
use traits::NodeKeyPair;
|
||||||
|
|
||||||
|
pub struct PlainNodeKeyPair {
|
||||||
|
key_pair: KeyPair,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct KeyStoreNodeKeyPair {
|
||||||
|
_account_provider: Arc<AccountProvider>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PlainNodeKeyPair {
|
||||||
|
pub fn new(key_pair: KeyPair) -> Self {
|
||||||
|
PlainNodeKeyPair {
|
||||||
|
key_pair: key_pair,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NodeKeyPair for PlainNodeKeyPair {
|
||||||
|
fn public(&self) -> &Public {
|
||||||
|
self.key_pair.public()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sign(&self, data: &H256) -> Result<Signature, EthKeyError> {
|
||||||
|
sign(self.key_pair.secret(), data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_shared_key(&self, peer_public: &Public) -> Result<KeyPair, EthKeyError> {
|
||||||
|
agree(self.key_pair.secret(), peer_public).map_err(|e| EthKeyError::Custom(e.into()))
|
||||||
|
.and_then(KeyPair::from_secret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NodeKeyPair for KeyStoreNodeKeyPair {
|
||||||
|
fn public(&self) -> &Public {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sign(&self, _data: &H256) -> Result<Signature, EthKeyError> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_shared_key(&self, _peer_public: &Public) -> Result<KeyPair, EthKeyError> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
@ -14,9 +14,21 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use ethkey::{KeyPair, Signature, Error as EthKeyError};
|
||||||
|
use util::H256;
|
||||||
use types::all::{Error, Public, ServerKeyId, MessageHash, EncryptedMessageSignature, RequestSignature, EncryptedDocumentKey,
|
use types::all::{Error, Public, ServerKeyId, MessageHash, EncryptedMessageSignature, RequestSignature, EncryptedDocumentKey,
|
||||||
EncryptedDocumentKeyShadow};
|
EncryptedDocumentKeyShadow};
|
||||||
|
|
||||||
|
/// Node key pair.
|
||||||
|
pub trait NodeKeyPair: Send + Sync {
|
||||||
|
/// Public portion of key.
|
||||||
|
fn public(&self) -> &Public;
|
||||||
|
/// Sign data with node key.
|
||||||
|
fn sign(&self, data: &H256) -> Result<Signature, EthKeyError>;
|
||||||
|
/// Compute shared key to encrypt channel between two nodes.
|
||||||
|
fn compute_shared_key(&self, peer_public: &Public) -> Result<KeyPair, EthKeyError>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Server key (SK) generator.
|
/// Server key (SK) generator.
|
||||||
pub trait ServerKeyGenerator {
|
pub trait ServerKeyGenerator {
|
||||||
/// Generate new SK.
|
/// Generate new SK.
|
||||||
|
@ -83,8 +83,6 @@ pub struct ServiceConfiguration {
|
|||||||
pub struct ClusterConfiguration {
|
pub struct ClusterConfiguration {
|
||||||
/// Number of threads reserved by cluster.
|
/// Number of threads reserved by cluster.
|
||||||
pub threads: usize,
|
pub threads: usize,
|
||||||
/// Private key this node holds.
|
|
||||||
pub self_private: Vec<u8>, // holds ethkey::Secret
|
|
||||||
/// This node address.
|
/// This node address.
|
||||||
pub listener_address: NodeAddress,
|
pub listener_address: NodeAddress,
|
||||||
/// All cluster nodes addresses.
|
/// All cluster nodes addresses.
|
||||||
|
Loading…
Reference in New Issue
Block a user