@@ -19,7 +19,8 @@ use core_foundation::error::{CFError, CFErrorRef};
19
19
20
20
use security_framework_sys:: {
21
21
item:: { kSecAttrKeyTypeRSA, kSecValueRef} ,
22
- keychain_item:: SecItemDelete
22
+ keychain_item:: SecItemDelete ,
23
+ key:: SecKeyCopyKeyExchangeResult
23
24
} ;
24
25
#[ cfg( any( feature = "OSX_10_12" , target_os = "ios" , target_os = "tvos" , target_os = "watchos" , target_os = "visionos" ) ) ]
25
26
use security_framework_sys:: { item:: {
@@ -117,6 +118,15 @@ impl KeyType {
117
118
unsafe { Self ( kSecAttrKeyTypeEC) }
118
119
}
119
120
121
+ #[ inline( always) ]
122
+ #[ must_use]
123
+ pub fn ec_sec_prime_random ( ) -> Self {
124
+ use security_framework_sys:: item:: kSecAttrKeyTypeECSECPrimeRandom;
125
+
126
+ unsafe { Self ( kSecAttrKeyTypeECSECPrimeRandom) }
127
+ }
128
+
129
+
120
130
pub ( crate ) fn to_str ( self ) -> CFString {
121
131
unsafe { CFString :: wrap_under_get_rule ( self . 0 ) }
122
132
}
@@ -276,6 +286,52 @@ impl SecKey {
276
286
Ok ( valid != 0 )
277
287
}
278
288
289
+ /// Performs the Diffie-Hellman style of key exchange.
290
+ #[ cfg( any( feature = "OSX_10_12" , target_os = "ios" , target_os = "tvos" , target_os = "watchos" , target_os = "visionos" ) ) ]
291
+ pub fn key_exchange (
292
+ & self ,
293
+ algorithm : Algorithm ,
294
+ public_key : & SecKey ,
295
+ requested_size : usize ,
296
+ shared_info : Option < & [ u8 ] > ,
297
+ ) -> Result < Vec < u8 > , CFError > {
298
+ use core_foundation:: data:: CFData ;
299
+ use security_framework_sys:: item:: { kSecKeyKeyExchangeParameterRequestedSize, kSecKeyKeyExchangeParameterSharedInfo} ;
300
+
301
+ unsafe {
302
+ let mut params = vec ! [ (
303
+ CFString :: wrap_under_get_rule( kSecKeyKeyExchangeParameterRequestedSize) ,
304
+ CFNumber :: from( requested_size as i64 ) . into_CFType( ) ,
305
+ ) ] ;
306
+
307
+ if let Some ( shared_info) = shared_info {
308
+ params. push ( (
309
+ CFString :: wrap_under_get_rule ( kSecKeyKeyExchangeParameterSharedInfo) ,
310
+ CFData :: from_buffer ( shared_info) . as_CFType ( ) ,
311
+ ) )
312
+ } ;
313
+
314
+ let parameters = CFDictionary :: from_CFType_pairs ( & params) ;
315
+
316
+ let mut error: CFErrorRef = std:: ptr:: null_mut ( ) ;
317
+
318
+ let output = SecKeyCopyKeyExchangeResult (
319
+ self . as_concrete_TypeRef ( ) ,
320
+ algorithm. into ( ) ,
321
+ public_key. as_concrete_TypeRef ( ) ,
322
+ parameters. as_concrete_TypeRef ( ) ,
323
+ & mut error,
324
+ ) ;
325
+
326
+ if !error. is_null ( ) {
327
+ Err ( CFError :: wrap_under_create_rule ( error) )
328
+ } else {
329
+ let output = CFData :: wrap_under_create_rule ( output) ;
330
+ Ok ( output. to_vec ( ) )
331
+ }
332
+ }
333
+ }
334
+
279
335
/// Translates to `SecItemDelete`, passing in the `SecKeyRef`
280
336
pub fn delete ( & self ) -> Result < ( ) , Error > {
281
337
let query = CFMutableDictionary :: from_CFType_pairs ( & [ (
0 commit comments