From 0712259d30c0cf3ab492a991a7a9b82287638f23 Mon Sep 17 00:00:00 2001 From: Adrien P Date: Tue, 10 Dec 2024 13:04:12 +0400 Subject: [PATCH] SecKey: Add SecKeyCopyKeyExchangeResult() --- security-framework-sys/src/item.rs | 5 +++ security-framework-sys/src/key.rs | 9 ++++++ security-framework/src/key.rs | 49 +++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/security-framework-sys/src/item.rs b/security-framework-sys/src/item.rs index d7dcb67c..afdbdfce 100644 --- a/security-framework-sys/src/item.rs +++ b/security-framework-sys/src/item.rs @@ -68,6 +68,11 @@ extern "C" { pub static kSecAttrAccessGroup: CFStringRef; pub static kSecAttrAccessGroupToken: CFStringRef; + #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] + pub static kSecKeyKeyExchangeParameterRequestedSize: CFStringRef; + #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] + pub static kSecKeyKeyExchangeParameterSharedInfo: CFStringRef; + pub static kSecAttrAuthenticationType: CFStringRef; pub static kSecAttrComment: CFStringRef; pub static kSecAttrDescription: CFStringRef; diff --git a/security-framework-sys/src/key.rs b/security-framework-sys/src/key.rs index d43a027f..f5026d7c 100644 --- a/security-framework-sys/src/key.rs +++ b/security-framework-sys/src/key.rs @@ -82,6 +82,15 @@ extern "C" { operation: SecKeyOperationType, algorithm: SecKeyAlgorithm, ) -> core_foundation_sys::base::Boolean; + + #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] + pub fn SecKeyCopyKeyExchangeResult( + privateKey: SecKeyRef, + algorithm: SecKeyAlgorithm, + publicKey: SecKeyRef, + parameters: CFDictionaryRef, + error: *mut CFErrorRef, + ) -> CFDataRef; } #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] diff --git a/security-framework/src/key.rs b/security-framework/src/key.rs index 322373bb..ecef81dd 100644 --- a/security-framework/src/key.rs +++ b/security-framework/src/key.rs @@ -19,7 +19,8 @@ use core_foundation::error::{CFError, CFErrorRef}; use security_framework_sys::{ item::{kSecAttrKeyTypeRSA, kSecValueRef}, - keychain_item::SecItemDelete + keychain_item::SecItemDelete, + key::SecKeyCopyKeyExchangeResult }; #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] use security_framework_sys::{item::{ @@ -276,6 +277,52 @@ impl SecKey { Ok(valid != 0) } + /// Performs the Diffie-Hellman style of key exchange. + #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] + pub fn key_exchange( + &self, + algorithm: Algorithm, + public_key: &SecKey, + requested_size: usize, + shared_info: Option<&[u8]>, + ) -> Result, CFError> { + use core_foundation::data::CFData; + use security_framework_sys::item::{kSecKeyKeyExchangeParameterRequestedSize, kSecKeyKeyExchangeParameterSharedInfo}; + + unsafe { + let mut params = vec![( + CFString::wrap_under_get_rule(kSecKeyKeyExchangeParameterRequestedSize), + CFNumber::from(requested_size as i64).into_CFType(), + )]; + + if let Some(shared_info) = shared_info { + params.push(( + CFString::wrap_under_get_rule(kSecKeyKeyExchangeParameterSharedInfo), + CFData::from_buffer(shared_info).as_CFType(), + )) + }; + + let parameters = CFDictionary::from_CFType_pairs(¶ms); + + let mut error: CFErrorRef = std::ptr::null_mut(); + + let output = SecKeyCopyKeyExchangeResult( + self.as_concrete_TypeRef(), + algorithm.into(), + public_key.as_concrete_TypeRef(), + parameters.as_concrete_TypeRef(), + &mut error, + ); + + if !error.is_null() { + Err(CFError::wrap_under_create_rule(error)) + } else { + let output = CFData::wrap_under_create_rule(output); + Ok(output.to_vec()) + } + } + } + /// Translates to `SecItemDelete`, passing in the `SecKeyRef` pub fn delete(&self) -> Result<(), Error> { let query = CFMutableDictionary::from_CFType_pairs(&[(