2017-04-03 11:13:51 +02:00
// 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/>.
2017-09-14 19:29:01 +02:00
///! Given: two nodes each holding its own `self_key_pair`.
///!
///! Handshake process:
///! 1) both nodes are generating random `KeyPair` (`session_key_pair`), which will be used for channel encryption
///! 2) both nodes are generating random H256 (`confirmation_plain`)
///! 3) both nodes are signing `confirmation_plain` using `session_key_pair` to receive `confirmation_signed_session`
///! 4) nodes exchange with `NodePublicKey` messages, containing: `self_key_pair.public`, `confirmation_plain`, `confirmation_signed_session`
///! 5) both nodes are checking that they're configured to communicate to server with received `message.self_key_pair.public`. Connection is closed otherwise
///! 6) both nodes are recovering peer' `session_key_pair.public` from `message.confirmation_plain` and `message.confirmation_signed_session`
///! 7) both nodes are computing shared session key pair using self' `session_key_pair.secret` && peer' `session_key_pair.public`. All following messages are encrypted using this key_pair.
///! 8) both nodes are signing `message.confirmation_plain` with their own `self_key_pair.private` to receive `confirmation_signed`
///! 9) nodes exchange with `NodePrivateKeySignature` messages, containing `confirmation_signed`
///! 10) both nodes are checking that `confirmation_signed` is actually signed with the owner of peer' `self_key_pair.secret`
///!
///! Result of handshake is:
///! 1) belief, that we are connected to the KS from our KS-set
///! 2) session key pair, which is used to enrypt all connection messages
2017-04-03 11:13:51 +02:00
use std ::io ;
2017-08-09 11:09:40 +02:00
use std ::sync ::Arc ;
2017-04-03 11:13:51 +02:00
use std ::collections ::BTreeSet ;
use futures ::{ Future , Poll , Async } ;
2017-04-08 11:26:16 +02:00
use tokio_io ::{ AsyncRead , AsyncWrite } ;
2017-09-14 19:29:01 +02:00
use ethcrypto ::ecdh ::agree ;
use ethkey ::{ Random , Generator , KeyPair , Public , Signature , verify_public , sign , recover } ;
2017-09-04 16:36:49 +02:00
use bigint ::hash ::H256 ;
2017-08-09 11:09:40 +02:00
use key_server_cluster ::{ NodeId , Error , NodeKeyPair } ;
2017-04-03 11:13:51 +02:00
use key_server_cluster ::message ::{ Message , ClusterMessage , NodePublicKey , NodePrivateKeySignature } ;
use key_server_cluster ::io ::{ write_message , write_encrypted_message , WriteMessage , ReadMessage ,
2017-08-09 11:09:40 +02:00
read_message , read_encrypted_message , fix_shared_key } ;
2017-04-03 11:13:51 +02:00
/// Start handshake procedure with another node from the cluster.
2017-08-09 11:09:40 +02:00
pub fn handshake < A > ( a : A , self_key_pair : Arc < NodeKeyPair > , trusted_nodes : BTreeSet < NodeId > ) -> Handshake < A > where A : AsyncWrite + AsyncRead {
2017-09-14 19:29:01 +02:00
let init_data = Random . generate ( ) . map ( | kp | * kp . secret ( ) . clone ( ) ) . map_err ( Into ::into )
. and_then ( | cp | Random . generate ( ) . map ( | kp | ( cp , kp ) ) . map_err ( Into ::into ) ) ;
handshake_with_init_data ( a , init_data , self_key_pair , trusted_nodes )
2017-04-03 11:13:51 +02:00
}
2017-09-14 19:29:01 +02:00
/// Start handshake procedure with another node from the cluster and given plain confirmation + session key pair.
pub fn handshake_with_init_data < A > ( a : A , init_data : Result < ( H256 , KeyPair ) , Error > , self_key_pair : Arc < NodeKeyPair > , trusted_nodes : BTreeSet < NodeId > ) -> Handshake < A > where A : AsyncWrite + AsyncRead {
let handshake_input_data = init_data
. and_then ( | ( cp , kp ) | sign ( kp . secret ( ) , & cp ) . map ( | sp | ( cp , kp , sp ) ) . map_err ( Into ::into ) )
. and_then ( | ( cp , kp , sp ) | Handshake ::< A > ::make_public_key_message ( self_key_pair . public ( ) . clone ( ) , cp . clone ( ) , sp ) . map ( | msg | ( cp , kp , msg ) ) ) ;
let ( error , cp , kp , state ) = match handshake_input_data {
Ok ( ( cp , kp , msg ) ) = > ( None , cp , Some ( kp ) , HandshakeState ::SendPublicKey ( write_message ( a , msg ) ) ) ,
Err ( err ) = > ( Some ( ( a , Err ( err ) ) ) , Default ::default ( ) , None , HandshakeState ::Finished ) ,
2017-04-03 11:13:51 +02:00
} ;
Handshake {
is_active : true ,
error : error ,
state : state ,
self_key_pair : self_key_pair ,
2017-09-14 19:29:01 +02:00
self_session_key_pair : kp ,
self_confirmation_plain : cp ,
2017-08-07 18:54:05 +02:00
trusted_nodes : Some ( trusted_nodes ) ,
2017-09-14 19:29:01 +02:00
peer_node_id : None ,
peer_session_public : None ,
peer_confirmation_plain : None ,
2017-04-03 11:13:51 +02:00
shared_key : None ,
}
}
/// Wait for handshake procedure to be started by another node from the cluster.
2017-08-09 11:09:40 +02:00
pub fn accept_handshake < A > ( a : A , self_key_pair : Arc < NodeKeyPair > ) -> Handshake < A > where A : AsyncWrite + AsyncRead {
2017-04-03 11:13:51 +02:00
let self_confirmation_plain = Random . generate ( ) . map ( | kp | * kp . secret ( ) . clone ( ) ) . map_err ( Into ::into ) ;
2017-09-14 19:29:01 +02:00
let handshake_input_data = self_confirmation_plain
. and_then ( | cp | Random . generate ( ) . map ( | kp | ( cp , kp ) ) . map_err ( Into ::into ) ) ;
let ( error , cp , kp , state ) = match handshake_input_data {
Ok ( ( cp , kp ) ) = > ( None , cp , Some ( kp ) , HandshakeState ::ReceivePublicKey ( read_message ( a ) ) ) ,
Err ( err ) = > ( Some ( ( a , Err ( err ) ) ) , Default ::default ( ) , None , HandshakeState ::Finished ) ,
2017-04-03 11:13:51 +02:00
} ;
Handshake {
is_active : false ,
error : error ,
state : state ,
self_key_pair : self_key_pair ,
2017-09-14 19:29:01 +02:00
self_session_key_pair : kp ,
self_confirmation_plain : cp ,
2017-08-07 18:54:05 +02:00
trusted_nodes : None ,
2017-09-14 19:29:01 +02:00
peer_node_id : None ,
peer_session_public : None ,
peer_confirmation_plain : None ,
2017-04-03 11:13:51 +02:00
shared_key : None ,
}
}
/// Result of handshake procedure.
2017-09-06 11:09:22 +02:00
#[ derive(Debug, PartialEq) ]
2017-04-03 11:13:51 +02:00
pub struct HandshakeResult {
/// Node id.
pub node_id : NodeId ,
/// Shared key.
2017-04-08 11:26:16 +02:00
pub shared_key : KeyPair ,
2017-04-03 11:13:51 +02:00
}
/// Future handshake procedure.
pub struct Handshake < A > {
is_active : bool ,
error : Option < ( A , Result < HandshakeResult , Error > ) > ,
state : HandshakeState < A > ,
2017-08-09 11:09:40 +02:00
self_key_pair : Arc < NodeKeyPair > ,
2017-09-14 19:29:01 +02:00
self_session_key_pair : Option < KeyPair > ,
2017-04-03 11:13:51 +02:00
self_confirmation_plain : H256 ,
2017-08-07 18:54:05 +02:00
trusted_nodes : Option < BTreeSet < NodeId > > ,
2017-09-14 19:29:01 +02:00
peer_node_id : Option < NodeId > ,
peer_session_public : Option < Public > ,
peer_confirmation_plain : Option < H256 > ,
2017-04-08 11:26:16 +02:00
shared_key : Option < KeyPair > ,
2017-04-03 11:13:51 +02:00
}
/// Active handshake state.
enum HandshakeState < A > {
SendPublicKey ( WriteMessage < A > ) ,
ReceivePublicKey ( ReadMessage < A > ) ,
SendPrivateKeySignature ( WriteMessage < A > ) ,
ReceivePrivateKeySignature ( ReadMessage < A > ) ,
Finished ,
}
2017-04-08 11:26:16 +02:00
impl < A > Handshake < A > where A : AsyncRead + AsyncWrite {
2017-04-03 11:13:51 +02:00
#[ cfg(test) ]
pub fn set_self_confirmation_plain ( & mut self , self_confirmation_plain : H256 ) {
self . self_confirmation_plain = self_confirmation_plain ;
}
2017-09-14 19:29:01 +02:00
#[ cfg(test) ]
pub fn set_self_session_key_pair ( & mut self , self_session_key_pair : KeyPair ) {
self . self_session_key_pair = Some ( self_session_key_pair ) ;
}
pub fn make_public_key_message ( self_node_id : NodeId , confirmation_plain : H256 , confirmation_signed_session : Signature ) -> Result < Message , Error > {
2017-04-03 11:13:51 +02:00
Ok ( Message ::Cluster ( ClusterMessage ::NodePublicKey ( NodePublicKey {
node_id : self_node_id . into ( ) ,
confirmation_plain : confirmation_plain . into ( ) ,
2017-09-14 19:29:01 +02:00
confirmation_signed_session : confirmation_signed_session . into ( ) ,
2017-04-03 11:13:51 +02:00
} ) ) )
}
2017-08-09 11:09:40 +02:00
fn make_private_key_signature_message ( self_key_pair : & NodeKeyPair , confirmation_plain : & H256 ) -> Result < Message , Error > {
2017-04-03 11:13:51 +02:00
Ok ( Message ::Cluster ( ClusterMessage ::NodePrivateKeySignature ( NodePrivateKeySignature {
2017-08-09 11:09:40 +02:00
confirmation_signed : self_key_pair . sign ( confirmation_plain ) ? . into ( ) ,
2017-04-03 11:13:51 +02:00
} ) ) )
}
2017-09-14 19:29:01 +02:00
fn compute_shared_key ( self_session_key_pair : & KeyPair , peer_session_public : & Public ) -> Result < KeyPair , Error > {
agree ( self_session_key_pair . secret ( ) , peer_session_public )
. map_err ( Into ::into )
. and_then ( | s | fix_shared_key ( & s ) )
}
2017-04-03 11:13:51 +02:00
}
2017-04-08 11:26:16 +02:00
impl < A > Future for Handshake < A > where A : AsyncRead + AsyncWrite {
2017-04-03 11:13:51 +02:00
type Item = ( A , Result < HandshakeResult , Error > ) ;
type Error = io ::Error ;
fn poll ( & mut self ) -> Poll < Self ::Item , Self ::Error > {
if let Some ( error_result ) = self . error . take ( ) {
return Ok ( error_result . into ( ) ) ;
}
let ( next , result ) = match self . state {
HandshakeState ::SendPublicKey ( ref mut future ) = > {
let ( stream , _ ) = try_ready! ( future . poll ( ) ) ;
if self . is_active {
( HandshakeState ::ReceivePublicKey (
read_message ( stream )
) , Async ::NotReady )
} else {
2017-09-14 19:29:01 +02:00
let shared_key = Self ::compute_shared_key (
self . self_session_key_pair . as_ref ( ) . expect (
" self_session_key_pair is not filled only when initialization has failed; if initialization has failed, self.error.is_some(); qed " ) ,
self . peer_session_public . as_ref ( ) . expect (
" we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; peer_session_public is filled in ReceivePublicKey; qed " ) ,
) ;
self . shared_key = match shared_key {
2017-04-03 11:13:51 +02:00
Ok ( shared_key ) = > Some ( shared_key ) ,
2017-09-14 19:29:01 +02:00
Err ( err ) = > return Ok ( ( stream , Err ( err ) ) . into ( ) ) ,
2017-04-03 11:13:51 +02:00
} ;
2017-09-14 19:29:01 +02:00
let peer_confirmation_plain = self . peer_confirmation_plain . as_ref ( )
. expect ( " we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; peer_confirmation_plain is filled in ReceivePublicKey; qed " ) ;
let message = match Handshake ::< A > ::make_private_key_signature_message ( & * self . self_key_pair , peer_confirmation_plain ) {
2017-04-03 11:13:51 +02:00
Ok ( message ) = > message ,
Err ( err ) = > return Ok ( ( stream , Err ( err ) ) . into ( ) ) ,
} ;
2017-09-14 19:29:01 +02:00
2017-04-03 11:13:51 +02:00
( HandshakeState ::SendPrivateKeySignature ( write_encrypted_message ( stream ,
self . shared_key . as_ref ( ) . expect ( " filled couple of lines above; qed " ) ,
message ) ) , Async ::NotReady )
}
} ,
HandshakeState ::ReceivePublicKey ( ref mut future ) = > {
let ( stream , message ) = try_ready! ( future . poll ( ) ) ;
let message = match message {
Ok ( message ) = > match message {
Message ::Cluster ( ClusterMessage ::NodePublicKey ( message ) ) = > message ,
_ = > return Ok ( ( stream , Err ( Error ::InvalidMessage ) ) . into ( ) ) ,
} ,
Err ( err ) = > return Ok ( ( stream , Err ( err . into ( ) ) ) . into ( ) ) ,
} ;
2017-08-07 18:54:05 +02:00
if ! self . trusted_nodes . as_ref ( ) . map ( | tn | tn . contains ( & * message . node_id ) ) . unwrap_or ( true ) {
2017-04-03 11:13:51 +02:00
return Ok ( ( stream , Err ( Error ::InvalidNodeId ) ) . into ( ) ) ;
}
2017-09-14 19:29:01 +02:00
self . peer_node_id = Some ( message . node_id . into ( ) ) ;
self . peer_session_public = Some ( match recover ( & message . confirmation_signed_session , & message . confirmation_plain ) {
Ok ( peer_session_public ) = > peer_session_public ,
Err ( err ) = > return Ok ( ( stream , Err ( err . into ( ) ) ) . into ( ) ) ,
} ) ;
self . peer_confirmation_plain = Some ( message . confirmation_plain . into ( ) ) ;
2017-04-03 11:13:51 +02:00
if self . is_active {
2017-09-14 19:29:01 +02:00
let shared_key = Self ::compute_shared_key (
self . self_session_key_pair . as_ref ( ) . expect (
" self_session_key_pair is not filled only when initialization has failed; if initialization has failed, self.error.is_some(); qed " ) ,
self . peer_session_public . as_ref ( ) . expect (
" we are in passive mode; in passive mode SendPublicKey follows ReceivePublicKey; peer_session_public is filled in ReceivePublicKey; qed " ) ,
) ;
self . shared_key = match shared_key {
2017-04-03 11:13:51 +02:00
Ok ( shared_key ) = > Some ( shared_key ) ,
2017-09-14 19:29:01 +02:00
Err ( err ) = > return Ok ( ( stream , Err ( err ) ) . into ( ) ) ,
2017-04-03 11:13:51 +02:00
} ;
2017-09-14 19:29:01 +02:00
let peer_confirmation_plain = self . peer_confirmation_plain . as_ref ( )
. expect ( " filled couple of lines above; qed " ) ;
let message = match Handshake ::< A > ::make_private_key_signature_message ( & * self . self_key_pair , peer_confirmation_plain ) {
2017-04-03 11:13:51 +02:00
Ok ( message ) = > message ,
Err ( err ) = > return Ok ( ( stream , Err ( err ) ) . into ( ) ) ,
} ;
2017-09-14 19:29:01 +02:00
2017-04-03 11:13:51 +02:00
( HandshakeState ::SendPrivateKeySignature ( write_encrypted_message ( stream ,
self . shared_key . as_ref ( ) . expect ( " filled couple of lines above; qed " ) ,
message ) ) , Async ::NotReady )
} else {
2017-09-14 19:29:01 +02:00
let self_session_key_pair = self . self_session_key_pair . as_ref ( )
. expect ( " self_session_key_pair is not filled only when initialization has failed; if initialization has failed, self.error.is_some(); qed " ) ;
let confirmation_signed_session = match sign ( self_session_key_pair . secret ( ) , & self . self_confirmation_plain ) . map_err ( Into ::into ) {
Ok ( confirmation_signed_session ) = > confirmation_signed_session ,
Err ( err ) = > return Ok ( ( stream , Err ( err ) ) . into ( ) ) ,
} ;
let message = match Handshake ::< A > ::make_public_key_message ( self . self_key_pair . public ( ) . clone ( ) , self . self_confirmation_plain . clone ( ) , confirmation_signed_session ) {
2017-04-03 11:13:51 +02:00
Ok ( message ) = > message ,
Err ( err ) = > return Ok ( ( stream , Err ( err ) ) . into ( ) ) ,
} ;
( HandshakeState ::SendPublicKey ( write_message ( stream , message ) ) , Async ::NotReady )
}
} ,
HandshakeState ::SendPrivateKeySignature ( ref mut future ) = > {
let ( stream , _ ) = try_ready! ( future . poll ( ) ) ;
( HandshakeState ::ReceivePrivateKeySignature (
2017-04-08 11:26:16 +02:00
read_encrypted_message ( stream ,
self . shared_key . as_ref ( ) . expect ( " shared_key is filled in Send/ReceivePublicKey; SendPrivateKeySignature follows Send/ReceivePublicKey; qed " ) . clone ( )
)
2017-04-03 11:13:51 +02:00
) , Async ::NotReady )
} ,
HandshakeState ::ReceivePrivateKeySignature ( ref mut future ) = > {
let ( stream , message ) = try_ready! ( future . poll ( ) ) ;
let message = match message {
Ok ( message ) = > match message {
Message ::Cluster ( ClusterMessage ::NodePrivateKeySignature ( message ) ) = > message ,
_ = > return Ok ( ( stream , Err ( Error ::InvalidMessage ) ) . into ( ) ) ,
} ,
Err ( err ) = > return Ok ( ( stream , Err ( err . into ( ) ) ) . into ( ) ) ,
} ;
2017-09-14 19:29:01 +02:00
let peer_public = self . peer_node_id . as_ref ( ) . expect ( " peer_node_id is filled in ReceivePublicKey; ReceivePrivateKeySignature follows ReceivePublicKey; qed " ) ;
if ! verify_public ( peer_public , & * message . confirmation_signed , & self . self_confirmation_plain ) . unwrap_or ( false ) {
2017-04-03 11:13:51 +02:00
return Ok ( ( stream , Err ( Error ::InvalidMessage ) ) . into ( ) ) ;
}
( HandshakeState ::Finished , Async ::Ready ( ( stream , Ok ( HandshakeResult {
2017-09-14 19:29:01 +02:00
node_id : self . peer_node_id . expect ( " peer_node_id is filled in ReceivePublicKey; ReceivePrivateKeySignature follows ReceivePublicKey; qed " ) ,
2017-04-03 11:13:51 +02:00
shared_key : self . shared_key . clone ( ) . expect ( " shared_key is filled in Send/ReceivePublicKey; ReceivePrivateKeySignature follows Send/ReceivePublicKey; qed " ) ,
} ) ) ) )
} ,
HandshakeState ::Finished = > panic! ( " poll Handshake after it's done " ) ,
} ;
self . state = next ;
match result {
// by polling again, we register new future
Async ::NotReady = > self . poll ( ) ,
result = > Ok ( result )
}
}
}
#[ cfg(test) ]
mod tests {
2017-08-09 11:09:40 +02:00
use std ::sync ::Arc ;
2017-04-03 11:13:51 +02:00
use std ::collections ::BTreeSet ;
use futures ::Future ;
use ethkey ::{ Random , Generator , sign } ;
2017-09-04 16:36:49 +02:00
use bigint ::hash ::H256 ;
2017-08-09 11:09:40 +02:00
use key_server_cluster ::PlainNodeKeyPair ;
2017-04-03 11:13:51 +02:00
use key_server_cluster ::io ::message ::tests ::TestIo ;
use key_server_cluster ::message ::{ Message , ClusterMessage , NodePublicKey , NodePrivateKeySignature } ;
2017-09-14 19:29:01 +02:00
use super ::{ handshake_with_init_data , accept_handshake , HandshakeResult } ;
2017-04-03 11:13:51 +02:00
fn prepare_test_io ( ) -> ( H256 , TestIo ) {
2017-09-14 19:29:01 +02:00
let mut io = TestIo ::new ( ) ;
2017-04-03 11:13:51 +02:00
let self_confirmation_plain = * Random . generate ( ) . unwrap ( ) . secret ( ) . clone ( ) ;
let peer_confirmation_plain = * Random . generate ( ) . unwrap ( ) . secret ( ) . clone ( ) ;
2017-09-14 19:29:01 +02:00
let self_confirmation_signed = sign ( io . peer_key_pair ( ) . secret ( ) , & self_confirmation_plain ) . unwrap ( ) ;
let peer_confirmation_signed = sign ( io . peer_session_key_pair ( ) . secret ( ) , & peer_confirmation_plain ) . unwrap ( ) ;
2017-04-03 11:13:51 +02:00
2017-09-14 19:29:01 +02:00
let peer_public = io . peer_key_pair ( ) . public ( ) . clone ( ) ;
2017-04-03 11:13:51 +02:00
io . add_input_message ( Message ::Cluster ( ClusterMessage ::NodePublicKey ( NodePublicKey {
2017-09-14 19:29:01 +02:00
node_id : peer_public . into ( ) ,
2017-04-03 11:13:51 +02:00
confirmation_plain : peer_confirmation_plain . into ( ) ,
2017-09-14 19:29:01 +02:00
confirmation_signed_session : peer_confirmation_signed . into ( ) ,
2017-04-03 11:13:51 +02:00
} ) ) ) ;
2017-04-08 11:26:16 +02:00
io . add_encrypted_input_message ( Message ::Cluster ( ClusterMessage ::NodePrivateKeySignature ( NodePrivateKeySignature {
2017-04-03 11:13:51 +02:00
confirmation_signed : self_confirmation_signed . into ( ) ,
} ) ) ) ;
( self_confirmation_plain , io )
}
#[ test ]
fn active_handshake_works ( ) {
let ( self_confirmation_plain , io ) = prepare_test_io ( ) ;
2017-09-14 19:29:01 +02:00
let trusted_nodes : BTreeSet < _ > = vec! [ io . peer_key_pair ( ) . public ( ) . clone ( ) ] . into_iter ( ) . collect ( ) ;
let self_session_key_pair = io . self_session_key_pair ( ) . clone ( ) ;
let self_key_pair = Arc ::new ( PlainNodeKeyPair ::new ( io . self_key_pair ( ) . clone ( ) ) ) ;
let shared_key = io . shared_key_pair ( ) . clone ( ) ;
2017-04-03 11:13:51 +02:00
2017-09-14 19:29:01 +02:00
let handshake = handshake_with_init_data ( io , Ok ( ( self_confirmation_plain , self_session_key_pair ) ) , self_key_pair , trusted_nodes ) ;
2017-04-03 11:13:51 +02:00
let handshake_result = handshake . wait ( ) . unwrap ( ) ;
assert_eq! ( handshake_result . 1 , Ok ( HandshakeResult {
2017-09-14 19:29:01 +02:00
node_id : handshake_result . 0. peer_key_pair ( ) . public ( ) . clone ( ) ,
2017-04-03 11:13:51 +02:00
shared_key : shared_key ,
} ) ) ;
}
#[ test ]
fn passive_handshake_works ( ) {
let ( self_confirmation_plain , io ) = prepare_test_io ( ) ;
2017-09-14 19:29:01 +02:00
let self_key_pair = Arc ::new ( PlainNodeKeyPair ::new ( io . self_key_pair ( ) . clone ( ) ) ) ;
let self_session_key_pair = io . self_session_key_pair ( ) . clone ( ) ;
let shared_key = io . shared_key_pair ( ) . clone ( ) ;
2017-04-03 11:13:51 +02:00
2017-09-14 19:29:01 +02:00
let mut handshake = accept_handshake ( io , self_key_pair ) ;
2017-04-03 11:13:51 +02:00
handshake . set_self_confirmation_plain ( self_confirmation_plain ) ;
2017-09-14 19:29:01 +02:00
handshake . set_self_session_key_pair ( self_session_key_pair ) ;
2017-04-03 11:13:51 +02:00
let handshake_result = handshake . wait ( ) . unwrap ( ) ;
assert_eq! ( handshake_result . 1 , Ok ( HandshakeResult {
2017-09-14 19:29:01 +02:00
node_id : handshake_result . 0. peer_key_pair ( ) . public ( ) . clone ( ) ,
2017-04-03 11:13:51 +02:00
shared_key : shared_key ,
} ) ) ;
}
}