Skip to content

Commit 9f00f41

Browse files
authored
Merge pull request #217 from olvrlrnz/sec-key-support-encrypt-decrypt
SecKey: Add support for encryption and decryption
2 parents f35b6ac + 55fe4fe commit 9f00f41

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

security-framework-sys/src/item.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ extern "C" {
2828
pub static kSecAttrLabel: CFStringRef;
2929
pub static kSecAttrIsPermanent: CFStringRef;
3030
pub static kSecAttrPublicKeyHash: CFStringRef;
31+
pub static kSecAttrSerialNumber: CFStringRef;
3132
pub static kSecPrivateKeyAttrs: CFStringRef;
3233
pub static kSecPublicKeyAttrs: CFStringRef;
3334

security-framework-sys/src/key.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@ extern "C" {
6060
error: *mut CFErrorRef,
6161
) -> core_foundation_sys::base::Boolean;
6262

63+
#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))]
64+
pub fn SecKeyCreateEncryptedData(
65+
key: SecKeyRef,
66+
algorithm: SecKeyAlgorithm,
67+
plaintext: CFDataRef,
68+
error: *mut CFErrorRef,
69+
) -> CFDataRef;
70+
71+
#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))]
72+
pub fn SecKeyCreateDecryptedData(
73+
key: SecKeyRef,
74+
algorithm: SecKeyAlgorithm,
75+
ciphertext: CFDataRef,
76+
error: *mut CFErrorRef,
77+
) -> CFDataRef;
78+
6379
#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))]
6480
pub fn SecKeyIsAlgorithmSupported(
6581
key: SecKeyRef,

security-framework/src/item.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ pub struct ItemSearchOptions {
137137
account: Option<CFString>,
138138
access_group: Option<CFString>,
139139
pub_key_hash: Option<CFData>,
140+
serial_number: Option<CFData>,
140141
app_label: Option<CFData>,
141142
}
142143

@@ -272,6 +273,15 @@ impl ItemSearchOptions {
272273
self
273274
}
274275

276+
/// Search for a certificate with the given serial number.
277+
///
278+
/// This is only compatible with [`ItemClass::certificate`].
279+
#[inline(always)]
280+
pub fn serial_number(&mut self, serial_number: &[u8]) -> &mut Self {
281+
self.serial_number = Some(CFData::from_buffer(serial_number));
282+
self
283+
}
284+
275285
/// Search for a key with the given public key hash.
276286
///
277287
/// This is only compatible with [`ItemClass::key`], to search for a
@@ -399,6 +409,13 @@ impl ItemSearchOptions {
399409
);
400410
}
401411

412+
if let Some(ref serial_number) = self.serial_number {
413+
params.add(
414+
&kSecAttrSerialNumber.to_void(),
415+
&serial_number.to_void(),
416+
);
417+
}
418+
402419
if let Some(ref app_label) = self.app_label {
403420
params.add(
404421
&kSecAttrApplicationLabel.to_void(),

security-framework/src/key.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use security_framework_sys::key::{
4343
SecKeyCopyAttributes, SecKeyCopyExternalRepresentation,
4444
SecKeyCreateSignature, SecKeyCreateRandomKey,
4545
SecKeyCopyPublicKey,
46+
SecKeyCreateDecryptedData, SecKeyCreateEncryptedData,
4647
};
4748
#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))]
4849
use security_framework_sys::item::kSecAttrApplicationLabel;
@@ -195,6 +196,40 @@ impl SecKey {
195196
Some(unsafe { SecKey::wrap_under_create_rule(pub_seckey) })
196197
}
197198

199+
#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))]
200+
/// Encrypts a block of data using a public key and specified algorithm
201+
pub fn encrypt_data(&self, algorithm: Algorithm, input: &[u8]) -> Result<Vec<u8>, CFError> {
202+
let mut error: CFErrorRef = std::ptr::null_mut();
203+
204+
let output = unsafe {
205+
SecKeyCreateEncryptedData(self.as_concrete_TypeRef(), algorithm.into(), CFData::from_buffer(input).as_concrete_TypeRef(), &mut error)
206+
};
207+
208+
if !error.is_null() {
209+
Err(unsafe { CFError::wrap_under_create_rule(error) })
210+
} else {
211+
let output = unsafe { CFData::wrap_under_create_rule(output) };
212+
Ok(output.to_vec())
213+
}
214+
}
215+
216+
#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))]
217+
/// Decrypts a block of data using a private key and specified algorithm
218+
pub fn decrypt_data(&self, algorithm: Algorithm, input: &[u8]) -> Result<Vec<u8>, CFError> {
219+
let mut error: CFErrorRef = std::ptr::null_mut();
220+
221+
let output = unsafe {
222+
SecKeyCreateDecryptedData(self.as_concrete_TypeRef(), algorithm.into(), CFData::from_buffer(input).as_concrete_TypeRef(), &mut error)
223+
};
224+
225+
if !error.is_null() {
226+
Err(unsafe { CFError::wrap_under_create_rule(error) })
227+
} else {
228+
let output = unsafe { CFData::wrap_under_create_rule(output) };
229+
Ok(output.to_vec())
230+
}
231+
}
232+
198233
#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))]
199234
/// Creates the cryptographic signature for a block of data using a private
200235
/// key and specified algorithm.

0 commit comments

Comments
 (0)