1- use std:: str;
1+ use std:: { io :: Write , str} ;
22
33use aws_lc_rs:: {
44 agreement:: { self , EphemeralPrivateKey , UnparsedPublicKey , X25519 } ,
@@ -15,6 +15,7 @@ use crate::{
1515} ;
1616
1717pub ( crate ) struct EcdhKeyExchange {
18+ cookie : [ u8 ; 16 ] ,
1819 /// The current session id or `None` if this is the initial key exchange.
1920 session_id : Option < digest:: Digest > ,
2021}
@@ -138,6 +139,30 @@ impl EcdhKeyExchange {
138139 return Err ( ( ) ) ;
139140 }
140141
142+ if std:: env:: var ( "OXISH_ENABLE_KEYLOG" ) . as_deref ( ) == Ok ( "1" ) {
143+ assert ! ( cfg!( debug_assertions) ) ;
144+ eprintln ! ( "Logging shared secret to ssh_keylog file!" ) ;
145+ std:: fs:: OpenOptions :: new ( )
146+ . create ( true )
147+ . append ( true )
148+ . write ( true )
149+ . open ( "ssh_keylog" )
150+ . unwrap ( )
151+ . write_all (
152+ format ! (
153+ "{:032x} SHARED_SECRET {}\n " ,
154+ u128 :: from_be_bytes( self . cookie) ,
155+ shared_secret
156+ . iter( )
157+ . map( |& byte| format!( "{byte:02X}" ) )
158+ . collect:: <Vec <_>>( )
159+ . join( "" )
160+ )
161+ . as_bytes ( ) ,
162+ )
163+ . unwrap ( ) ;
164+ }
165+
141166 // The first exchange hash is used as session id.
142167 let session_id = self . session_id . as_ref ( ) . unwrap_or ( & exchange_hash) ;
143168 let derivation = KeyDerivation {
@@ -325,6 +350,8 @@ impl KeyExchange {
325350 }
326351 } ;
327352
353+ let cookie = key_exchange_init. cookie ;
354+
328355 if let Err ( error) = conn
329356 . stream_write
330357 . write_packet ( & key_exchange_init, |kex_init_payload| {
@@ -354,6 +381,7 @@ impl KeyExchange {
354381 }
355382
356383 Ok ( EcdhKeyExchange {
384+ cookie,
357385 session_id : self . session_id ,
358386 } )
359387 }
0 commit comments