@@ -181,6 +181,12 @@ impl IHandshakeState for ResponderAwaitingActOneState {
181
181
let mut read_buffer = self . read_buffer ;
182
182
read_buffer. extend_from_slice ( input) ;
183
183
184
+ // Any payload larger than ACT_ONE_TWO_LENGTH indicates a bad peer since initiator data
185
+ // is required to generate act3 (so it can't come before we transition)
186
+ if read_buffer. len ( ) > ACT_ONE_TWO_LENGTH {
187
+ return Err ( "Act One too large" . to_string ( ) ) ;
188
+ }
189
+
184
190
// In the event of a partial fill, stay in the same state and wait for more data
185
191
if read_buffer. len ( ) < ACT_ONE_TWO_LENGTH {
186
192
return Ok ( (
@@ -238,6 +244,12 @@ impl IHandshakeState for InitiatorAwaitingActTwoState {
238
244
let mut read_buffer = self . read_buffer ;
239
245
read_buffer. extend_from_slice ( input) ;
240
246
247
+ // Any payload larger than ACT_ONE_TWO_LENGTH indicates a bad peer since responder data
248
+ // is required to generate post-authentication messages (so it can't come before we transition)
249
+ if read_buffer. len ( ) > ACT_ONE_TWO_LENGTH {
250
+ return Err ( "Act Two too large" . to_string ( ) ) ;
251
+ }
252
+
241
253
// In the event of a partial fill, stay in the same state and wait for more data
242
254
if read_buffer. len ( ) < ACT_ONE_TWO_LENGTH {
243
255
return Ok ( (
@@ -289,7 +301,7 @@ impl IHandshakeState for InitiatorAwaitingActTwoState {
289
301
290
302
// 7. rn = 0, sn = 0
291
303
// - done by Conduit
292
- let mut conduit = Conduit :: new ( sending_key, receiving_key, chaining_key) ;
304
+ let conduit = Conduit :: new ( sending_key, receiving_key, chaining_key) ;
293
305
294
306
// Send m = 0 || c || t over the network buffer
295
307
let mut act_three = Vec :: with_capacity ( ACT_THREE_LENGTH ) ;
@@ -298,14 +310,6 @@ impl IHandshakeState for InitiatorAwaitingActTwoState {
298
310
act_three. extend ( & authentication_tag) ;
299
311
assert_eq ! ( act_three. len( ) , ACT_THREE_LENGTH ) ;
300
312
301
- // Any remaining data in the read buffer would be encrypted, so transfer ownership
302
- // to the Conduit for future use. In this case, it is unlikely that any valid data
303
- // exists, since the responder doesn't have Act3
304
- if read_buffer. len ( ) > 0 {
305
- conduit. read ( & read_buffer[ ..] ) ;
306
- read_buffer. drain ( ..) ;
307
- }
308
-
309
313
Ok ( (
310
314
Some ( act_three) ,
311
315
HandshakeState :: Complete ( Some ( ( conduit, responder_static_public_key) ) )
@@ -600,18 +604,16 @@ mod test {
600
604
assert_matches ! ( awaiting_act_three_state, ResponderAwaitingActThree ( _) ) ;
601
605
}
602
606
603
- // Responder::AwaitingActOne -> AwaitingActThree
604
- // TODO: Should this fail since we don't expect data > ACT_ONE_TWO_LENGTH and likely indicates
605
- // a bad peer?
607
+ // Responder::AwaitingActOne -> AwaitingActThree (bad peer)
608
+ // Act2 requires data from the initiator. If we receive a payload for act1 that is larger than
609
+ // expected it indicates a bad peer
606
610
#[ test]
607
611
fn awaiting_act_one_to_awaiting_act_three_input_extra_bytes ( ) {
608
612
let test_ctx = TestCtx :: new ( ) ;
609
613
let mut act1 = test_ctx. valid_act1 ;
610
614
act1. extend_from_slice ( & [ 1 ] ) ;
611
- let ( act2, awaiting_act_three_state) = test_ctx. responder . next ( & act1) . unwrap ( ) ;
612
615
613
- assert_eq ! ( act2. unwrap( ) , test_ctx. valid_act2) ;
614
- assert_matches ! ( awaiting_act_three_state, ResponderAwaitingActThree ( _) ) ;
616
+ assert_eq ! ( test_ctx. responder. next( & act1) . err( ) , Some ( String :: from( "Act One too large" ) ) ) ;
615
617
}
616
618
617
619
// Responder::AwaitingActOne -> AwaitingActThree (segmented calls)
@@ -658,36 +660,26 @@ mod test {
658
660
assert_eq ! ( test_ctx. responder. next( & act1) . err( ) , Some ( String :: from( "invalid hmac" ) ) ) ;
659
661
}
660
662
661
- // Initiator::AwaitingActTwo -> Complete
662
- // RFC test vector: transport-initiator successful handshake
663
+ // Initiator::AwaitingActTwo -> Complete (bad peer)
664
+ // Initiator data is required to generate post-authentication messages. This means any extra
665
+ // data indicates a bad peer.
663
666
#[ test]
664
- fn awaiting_act_two_to_complete ( ) {
667
+ fn awaiting_act_two_to_complete_extra_bytes ( ) {
665
668
let test_ctx = TestCtx :: new ( ) ;
666
669
let ( _act1, awaiting_act_two_state) = do_next_or_panic ! ( test_ctx. initiator, & [ ] ) ;
667
- let ( act3, complete_state) = do_next_or_panic ! ( awaiting_act_two_state, & test_ctx. valid_act2) ;
668
-
669
- let ( conduit, remote_pubkey) = if let Complete ( Some ( ( conduit, remote_pubkey) ) ) = complete_state {
670
- ( conduit, remote_pubkey)
671
- } else {
672
- panic ! ( ) ;
673
- } ;
670
+ let mut act2 = test_ctx. valid_act2 ;
671
+ act2. extend_from_slice ( & [ 1 ] ) ;
674
672
675
- assert_eq ! ( act3, test_ctx. valid_act3) ;
676
- assert_eq ! ( remote_pubkey, test_ctx. responder_static_public_key) ;
677
- assert_eq ! ( 0 , conduit. decryptor. read_buffer_length( ) ) ;
673
+ assert_eq ! ( awaiting_act_two_state. next( & act2) . err( ) , Some ( String :: from( "Act Two too large" ) ) ) ;
678
674
}
679
675
680
- // Initiator::AwaitingActTwo -> Complete (with extra data)
681
- // Ensures that any remaining data in the read buffer is transferred to the conduit once
682
- // the handshake is complete
683
- // TODO: Is this valid? Don't we expect peers to need ActThree before sending additional data?
676
+ // Initiator::AwaitingActTwo -> Complete
677
+ // RFC test vector: transport-initiator successful handshake
684
678
#[ test]
685
- fn awaiting_act_two_to_complete_excess_bytes_are_in_conduit ( ) {
679
+ fn awaiting_act_two_to_complete ( ) {
686
680
let test_ctx = TestCtx :: new ( ) ;
687
681
let ( _act1, awaiting_act_two_state) = do_next_or_panic ! ( test_ctx. initiator, & [ ] ) ;
688
- let mut act2 = test_ctx. valid_act2 ;
689
- act2. extend_from_slice ( & [ 1 ; 100 ] ) ;
690
- let ( act3, complete_state) = do_next_or_panic ! ( awaiting_act_two_state, & act2) ;
682
+ let ( act3, complete_state) = do_next_or_panic ! ( awaiting_act_two_state, & test_ctx. valid_act2) ;
691
683
692
684
let ( conduit, remote_pubkey) = if let Complete ( Some ( ( conduit, remote_pubkey) ) ) = complete_state {
693
685
( conduit, remote_pubkey)
@@ -697,7 +689,7 @@ mod test {
697
689
698
690
assert_eq ! ( act3, test_ctx. valid_act3) ;
699
691
assert_eq ! ( remote_pubkey, test_ctx. responder_static_public_key) ;
700
- assert_eq ! ( 100 , conduit. decryptor. read_buffer_length( ) ) ;
692
+ assert_eq ! ( 0 , conduit. decryptor. read_buffer_length( ) ) ;
701
693
}
702
694
703
695
// Initiator::AwaitingActTwo -> Complete (segmented calls)
0 commit comments