@@ -43,10 +43,10 @@ enum KxGroup {
4343}
4444
4545impl KxGroup {
46- fn alg_handle ( self ) -> BCRYPT_ALG_HANDLE {
46+ fn alg_handle ( self ) -> Result < BCRYPT_ALG_HANDLE , Error > {
4747 match self {
48- Self :: SECP256R1 => BCRYPT_ECDH_P256_ALG_HANDLE ,
49- Self :: SECP384R1 => BCRYPT_ECDH_P384_ALG_HANDLE ,
48+ Self :: SECP256R1 => Ok ( BCRYPT_ECDH_P256_ALG_HANDLE ) ,
49+ Self :: SECP384R1 => Ok ( BCRYPT_ECDH_P384_ALG_HANDLE ) ,
5050 Self :: X25519 => alg:: ecdh_x25519 ( ) ,
5151 }
5252 }
@@ -92,7 +92,11 @@ fn cng_supports_x25519() -> bool {
9292 ] ;
9393 let y = [ 0 ; 32 ] ;
9494
95- import_ecdh_public_key ( KxGroup :: X25519 . alg_handle ( ) , & u, & y) . is_ok ( )
95+ let Ok ( handle) = KxGroup :: X25519 . alg_handle ( ) else {
96+ return false ;
97+ } ;
98+
99+ import_ecdh_public_key ( handle, & u, & y) . is_ok ( )
96100}
97101
98102struct EcKeyExchange {
@@ -122,7 +126,7 @@ impl SupportedKxGroup for KxGroup {
122126
123127 unsafe {
124128 BCryptGenerateKeyPair (
125- self . alg_handle ( ) ,
129+ self . alg_handle ( ) ? ,
126130 & mut * key_handle,
127131 self . key_bits ( ) as u32 ,
128132 0 ,
@@ -223,7 +227,7 @@ impl ActiveKeyExchange for EcKeyExchange {
223227 & [ 0 ; 32 ]
224228 } ;
225229
226- let peer_key_handle = import_ecdh_public_key ( self . kx_group . alg_handle ( ) , x, y) ?;
230+ let peer_key_handle = import_ecdh_public_key ( self . kx_group . alg_handle ( ) ? , x, y) ?;
227231
228232 // Now derive the shared secret
229233 let mut secret = Owned :: default ( ) ;
@@ -290,6 +294,12 @@ mod test {
290294 assert_eq ! ( advertises_x25519, super :: cng_supports_x25519( ) ) ;
291295 }
292296
297+ #[ test]
298+ fn x25519_capability_probe_does_not_panic ( ) {
299+ let _supported = std:: panic:: catch_unwind ( super :: cng_supports_x25519)
300+ . expect ( "X25519 capability probing should return false instead of panicking" ) ;
301+ }
302+
293303 #[ test]
294304 fn secp256r1 ( ) {
295305 let test_set = wycheproof:: ecdh:: TestSet :: load ( TestName :: EcdhSecp256r1Ecpoint ) . unwrap ( ) ;
@@ -307,7 +317,8 @@ mod test {
307317 public_key : Vec :: new ( ) ,
308318 } ;
309319 kx. key_handle =
310- import_ecdh_private_key ( kx. kx_group . alg_handle ( ) , & test. private_key ) . unwrap ( ) ;
320+ import_ecdh_private_key ( kx. kx_group . alg_handle ( ) . unwrap ( ) , & test. private_key )
321+ . unwrap ( ) ;
311322
312323 let res = Box :: new ( kx) . complete ( & test. public_key ) ;
313324 let pub_key_uncompressed = test. public_key . first ( ) == Some ( & 0x04 ) ;
@@ -353,7 +364,8 @@ mod test {
353364 key[ 0 ] &= 0xf8 ;
354365 key[ 31 ] &= 0x7f ;
355366 key[ 31 ] |= 0x40 ;
356- kx. key_handle = import_ecdh_private_key ( kx. kx_group . alg_handle ( ) , & key) . unwrap ( ) ;
367+ kx. key_handle =
368+ import_ecdh_private_key ( kx. kx_group . alg_handle ( ) . unwrap ( ) , & key) . unwrap ( ) ;
357369
358370 let res = Box :: new ( kx) . complete ( & test. public_key ) ;
359371
0 commit comments