@@ -187,6 +187,77 @@ async fn test_kex_done_with_ecdh_nistp256() {
187187 . unwrap ( ) ;
188188}
189189
190+ #[ tokio:: test]
191+ async fn test_kex_done_with_dh_gex_sha256_and_rfc4419_minimum ( ) {
192+ let _ = env_logger:: try_init ( ) ;
193+
194+ let client_key = PrivateKey :: random ( & mut OsRng , ssh_key:: Algorithm :: Ed25519 ) . unwrap ( ) ;
195+
196+ let mut server_config = server:: Config :: default ( ) ;
197+ server_config. inactivity_timeout = None ;
198+ server_config. auth_rejection_time = std:: time:: Duration :: from_secs ( 3 ) ;
199+ server_config
200+ . keys
201+ . push ( PrivateKey :: random ( & mut OsRng , ssh_key:: Algorithm :: Ed25519 ) . unwrap ( ) ) ;
202+ server_config. preferred = {
203+ let mut p = Preferred :: default ( ) ;
204+ p. kex = Cow :: Borrowed ( & [ kex:: DH_GEX_SHA256 ] ) ;
205+ p
206+ } ;
207+ let server_config = Arc :: new ( server_config) ;
208+
209+ let socket = tokio:: net:: TcpListener :: bind ( "127.0.0.1:0" ) . await . unwrap ( ) ;
210+ let addr = socket. local_addr ( ) . unwrap ( ) ;
211+
212+ tokio:: spawn ( async move {
213+ let ( socket, _) = socket. accept ( ) . await . unwrap ( ) ;
214+ server:: run_stream ( server_config, socket, TestServer { } )
215+ . await
216+ . unwrap ( ) ;
217+ } ) ;
218+
219+ let captured_secret: Arc < Mutex < Option < Vec < u8 > > > > = Arc :: new ( Mutex :: new ( None ) ) ;
220+ let captured_names: Arc < Mutex < Option < Names > > > = Arc :: new ( Mutex :: new ( None ) ) ;
221+
222+ let mut client_config = client:: Config :: default ( ) ;
223+ client_config. preferred = {
224+ let mut p = Preferred :: default ( ) ;
225+ p. kex = Cow :: Borrowed ( & [ kex:: DH_GEX_SHA256 ] ) ;
226+ p
227+ } ;
228+ client_config. gex = client:: GexParams :: for_client_config ( 2048 , 4097 , 8192 ) . unwrap ( ) ;
229+ let client_config = Arc :: new ( client_config) ;
230+
231+ let client = TestClientWithKexCapture {
232+ shared_secret : captured_secret. clone ( ) ,
233+ negotiated_cipher : captured_names. clone ( ) ,
234+ } ;
235+
236+ let mut session = client:: connect ( client_config, addr, client) . await . unwrap ( ) ;
237+
238+ let authenticated = session
239+ . authenticate_publickey (
240+ std:: env:: var ( "USER" ) . unwrap_or ( "user" . to_owned ( ) ) ,
241+ PrivateKeyWithHashAlg :: new ( Arc :: new ( client_key) , None ) ,
242+ )
243+ . await
244+ . unwrap ( )
245+ . success ( ) ;
246+ assert ! ( authenticated) ;
247+
248+ let secret = captured_secret. lock ( ) . unwrap ( ) ;
249+ assert ! ( secret. is_some( ) , "Shared secret should be captured" ) ;
250+ assert ! ( !secret. as_ref( ) . unwrap( ) . is_empty( ) ) ;
251+
252+ let kex_alg = captured_names. lock ( ) . unwrap ( ) ;
253+ assert_eq ! ( kex_alg. as_ref( ) . unwrap( ) . kex, kex:: DH_GEX_SHA256 ) ;
254+
255+ session
256+ . disconnect ( Disconnect :: ByApplication , "" , "" )
257+ . await
258+ . unwrap ( ) ;
259+ }
260+
190261/// Test that kex_done is called on rekey
191262#[ tokio:: test]
192263async fn test_kex_done_on_rekey ( ) {
0 commit comments