@@ -13,25 +13,42 @@ mod states;
13
13
/// Currently requires explicit ephemeral private key specification.
14
14
pub struct PeerHandshake {
15
15
state : Option < HandshakeState > ,
16
+ ready_for_process : bool
16
17
}
17
18
18
19
impl PeerHandshake {
19
20
/// Instantiate a new handshake with a node identity secret key and an ephemeral private key
20
- pub fn create_and_initialize_outbound ( initiator_static_private_key : & SecretKey , responder_static_public_key : & PublicKey , initiator_ephemeral_private_key : & SecretKey ) -> ( Vec < u8 > , Self ) {
21
+ pub fn new_outbound ( initiator_static_private_key : & SecretKey , responder_static_public_key : & PublicKey , initiator_ephemeral_private_key : & SecretKey ) -> Self {
21
22
let state = HandshakeState :: new_initiator ( initiator_static_private_key, responder_static_public_key, initiator_ephemeral_private_key) ;
22
23
23
- // This transition does not have a failure path
24
- let ( response_vec_opt, next_state) = state. next ( & [ ] ) . unwrap ( ) ;
25
- ( response_vec_opt. unwrap ( ) , Self { state : Some ( next_state) } )
24
+ Self {
25
+ state : Some ( state) ,
26
+ ready_for_process : false
27
+ }
26
28
}
27
29
28
30
/// Instantiate a new handshake in anticipation of a peer's first handshake act
29
31
pub fn new_inbound ( responder_static_private_key : & SecretKey , responder_ephemeral_private_key : & SecretKey ) -> Self {
30
32
Self {
31
- state : Some ( HandshakeState :: new_responder ( responder_static_private_key, responder_ephemeral_private_key) )
33
+ state : Some ( HandshakeState :: new_responder ( responder_static_private_key, responder_ephemeral_private_key) ) ,
34
+ ready_for_process : true
32
35
}
33
36
}
34
37
38
+ /// Initializes the outbound handshake and provides the initial bytes to send to the responder
39
+ pub fn set_up_outbound ( & mut self ) -> Vec < u8 > {
40
+ assert ! ( !self . ready_for_process) ;
41
+ let cur_state = self . state . take ( ) . unwrap ( ) ;
42
+
43
+ // This transition does not have a failure path
44
+ let ( response_vec_opt, next_state) = cur_state. next ( & [ ] ) . unwrap ( ) ;
45
+
46
+ self . state = Some ( next_state) ;
47
+
48
+ self . ready_for_process = true ;
49
+ response_vec_opt. unwrap ( )
50
+ }
51
+
35
52
/// Process act dynamically
36
53
/// # Arguments
37
54
/// `input`: Byte slice received from peer as part of the handshake protocol
@@ -41,6 +58,7 @@ impl PeerHandshake {
41
58
/// `.0`: Byte vector containing the next act to send back to the peer per the handshake protocol
42
59
/// `.1`: Some(Conduit, PublicKey) if the handshake was just processed to completion and messages can now be encrypted and decrypted
43
60
pub fn process_act ( & mut self , input : & [ u8 ] ) -> Result < ( Option < Vec < u8 > > , Option < ( Conduit , PublicKey ) > ) , String > {
61
+ assert ! ( self . ready_for_process) ;
44
62
let cur_state = self . state . take ( ) . unwrap ( ) ;
45
63
46
64
let ( act_opt, mut next_state) = cur_state. next ( input) ?;
@@ -85,7 +103,8 @@ mod test {
85
103
let inbound_static_public_key = PublicKey :: from_secret_key ( & curve, & inbound_static_private_key) ;
86
104
let inbound_ephemeral_private_key = SecretKey :: from_slice ( & [ 0x_22_u8 ; 32 ] ) . unwrap ( ) ;
87
105
88
- let ( act1, outbound_handshake) = PeerHandshake :: create_and_initialize_outbound ( & outbound_static_private_key, & inbound_static_public_key, & outbound_ephemeral_private_key) ;
106
+ let mut outbound_handshake= PeerHandshake :: new_outbound ( & outbound_static_private_key, & inbound_static_public_key, & outbound_ephemeral_private_key) ;
107
+ let act1 = outbound_handshake. set_up_outbound ( ) ;
89
108
let inbound_handshake = PeerHandshake :: new_inbound ( & inbound_static_private_key, & inbound_ephemeral_private_key) ;
90
109
91
110
TestCtx {
@@ -113,17 +132,43 @@ mod test {
113
132
}
114
133
}
115
134
135
+ // Test that the outbound needs to call set_up_outbound() before process_act()
136
+ #[ test]
137
+ #[ should_panic( expected = "assertion failed: self.ready_for_process" ) ]
138
+ fn new_outbound_no_set_up_panics ( ) {
139
+ let curve = secp256k1:: Secp256k1 :: new ( ) ;
140
+
141
+ let outbound_static_private_key = SecretKey :: from_slice ( & [ 0x_11_u8 ; 32 ] ) . unwrap ( ) ;
142
+ let outbound_ephemeral_private_key = SecretKey :: from_slice ( & [ 0x_12_u8 ; 32 ] ) . unwrap ( ) ;
143
+ let inbound_static_private_key = SecretKey :: from_slice ( & [ 0x_21_u8 ; 32 ] ) . unwrap ( ) ;
144
+ let inbound_static_public_key = PublicKey :: from_secret_key ( & curve, & inbound_static_private_key) ;
145
+
146
+ let mut outbound_handshake= PeerHandshake :: new_outbound ( & outbound_static_private_key, & inbound_static_public_key, & outbound_ephemeral_private_key) ;
147
+ outbound_handshake. process_act ( & [ ] ) . unwrap ( ) ;
148
+ }
149
+
150
+ // Test that calling set_up_outbound() on the inbound panics
151
+ #[ test]
152
+ #[ should_panic( expected = "assertion failed: !self.ready_for_process" ) ]
153
+ fn new_inbound_calling_set_up_panics ( ) {
154
+ let inbound_static_private_key = SecretKey :: from_slice ( & [ 0x_21_u8 ; 32 ] ) . unwrap ( ) ;
155
+ let inbound_ephemeral_private_key = SecretKey :: from_slice ( & [ 0x_22_u8 ; 32 ] ) . unwrap ( ) ;
156
+
157
+ let mut inbound_handshake = PeerHandshake :: new_inbound ( & inbound_static_private_key, & inbound_ephemeral_private_key) ;
158
+ inbound_handshake. set_up_outbound ( ) ;
159
+ }
160
+
116
161
// Default Outbound::Uninitiated
117
162
#[ test]
118
- fn peer_handshake_new_outbound ( ) {
163
+ fn new_outbound ( ) {
119
164
let test_ctx = TestCtx :: new ( ) ;
120
165
121
166
assert_matches ! ( test_ctx. outbound_handshake. state, Some ( HandshakeState :: InitiatorAwaitingActTwo ( _) ) ) ;
122
167
}
123
168
124
169
// Default Inbound::AwaitingActOne
125
170
#[ test]
126
- fn peer_handshake_new_inbound ( ) {
171
+ fn new_inbound ( ) {
127
172
let test_ctx = TestCtx :: new ( ) ;
128
173
129
174
assert_matches ! ( test_ctx. inbound_handshake. state, Some ( HandshakeState :: ResponderAwaitingActOne ( _) ) ) ;
0 commit comments