Skip to content

Commit

Permalink
SecKey: Add SecKeyCopyKeyExchangeResult()
Browse files Browse the repository at this point in the history
  • Loading branch information
crashdump committed Dec 11, 2024
1 parent 9f00f41 commit 0712259
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 1 deletion.
5 changes: 5 additions & 0 deletions security-framework-sys/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions security-framework-sys/src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))]
Expand Down
49 changes: 48 additions & 1 deletion security-framework/src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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<Vec<u8>, 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(&params);

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(&[(
Expand Down

0 comments on commit 0712259

Please sign in to comment.