@@ -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