@@ -675,6 +675,7 @@ pub enum KeyExchangeError {
675675 NoValidAlgorithm ,
676676 InvalidFixedKeyLength ,
677677 NoCookies ,
678+ CookiesTooBig ,
678679 Io ( std:: io:: Error ) ,
679680 Tls ( tls_utils:: Error ) ,
680681 Certificate ( tls_utils:: Error ) ,
@@ -704,6 +705,7 @@ impl Display for KeyExchangeError {
704705 "The length of a fixed key does not match the algorithm used"
705706 ) ,
706707 Self :: NoCookies => write ! ( f, "Missing cookies" ) ,
708+ Self :: CookiesTooBig => write ! ( f, "Server returned cookies that are too large" ) ,
707709 Self :: Io ( e) => write ! ( f, "{e}" ) ,
708710 Self :: Tls ( e) => write ! ( f, "{e}" ) ,
709711 Self :: Certificate ( e) => write ! ( f, "{e}" ) ,
@@ -756,6 +758,7 @@ impl KeyExchangeError {
756758 | NoValidAlgorithm
757759 | InvalidFixedKeyLength
758760 | NoCookies
761+ | CookiesTooBig
759762 | Tls ( _)
760763 | Certificate ( _)
761764 | DnsName ( _)
@@ -964,6 +967,9 @@ pub struct KeyExchangeResultDecoder {
964967}
965968
966969impl KeyExchangeResultDecoder {
970+ // Chosen such that we can get new cookies if the need arises. In practice, the cookie should never be this big.
971+ const MAX_COOKIE_SIZE : usize = 350 ;
972+
967973 pub fn step_with_slice (
968974 mut self ,
969975 bytes : & [ u8 ] ,
@@ -1027,6 +1033,9 @@ impl KeyExchangeResultDecoder {
10271033 Continue ( state)
10281034 }
10291035 NewCookie { cookie_data } => {
1036+ if cookie_data. len ( ) > Self :: MAX_COOKIE_SIZE {
1037+ return ControlFlow :: Break ( Err ( KeyExchangeError :: CookiesTooBig ) ) ;
1038+ }
10301039 state. cookies . store ( cookie_data) ;
10311040 Continue ( state)
10321041 }
@@ -2507,6 +2516,22 @@ mod test {
25072516 ]
25082517 }
25092518
2519+ fn nts_oversized_cookie ( ) -> [ NtsRecord ; 4 ] {
2520+ [
2521+ NtsRecord :: NextProtocol {
2522+ protocol_ids : vec ! [ 0 ] ,
2523+ } ,
2524+ NtsRecord :: AeadAlgorithm {
2525+ critical : false ,
2526+ algorithm_ids : vec ! [ 15 ] ,
2527+ } ,
2528+ NtsRecord :: NewCookie {
2529+ cookie_data : vec ! [ 0 ; 2048 ] ,
2530+ } ,
2531+ NtsRecord :: EndOfMessage ,
2532+ ]
2533+ }
2534+
25102535 #[ test]
25112536 fn test_nts_time_nl_response ( ) {
25122537 let state = client_decode_records ( nts_time_nl_records ( ) . as_slice ( ) ) . unwrap ( ) ;
@@ -2516,6 +2541,12 @@ mod test {
25162541 assert_eq ! ( state. cookies. gap( ) , 0 ) ;
25172542 }
25182543
2544+ #[ test]
2545+ fn reject_oversized_cookie ( ) {
2546+ let result = client_decode_records ( nts_oversized_cookie ( ) . as_slice ( ) ) ;
2547+ assert ! ( matches!( result, Err ( KeyExchangeError :: CookiesTooBig ) ) ) ;
2548+ }
2549+
25192550 #[ test]
25202551 fn test_decode_nts_time_nl_response ( ) {
25212552 let mut decoder = NtsRecord :: decoder ( ) ;
0 commit comments