1 //! OSX specific functionality for keys.
2 use core_foundation::base::TCFType;
3 use core_foundation::data::CFData;
4 use core_foundation::dictionary::CFDictionary;
5 use core_foundation::error::CFError;
6 use core_foundation::string::CFString;
7 use security_framework_sys::item::kSecAttrKeyType;
8 use security_framework_sys::key::*;
9 use std::ptr;
10 
11 use crate::key::SecKey;
12 use crate::os::macos::item::KeyType;
13 
14 /// An extension trait adding OSX specific functionality to `SecKey`.
15 pub trait SecKeyExt {
16     /// Creates a new `SecKey` from a buffer containing key data.
from_data(key_type: KeyType, key_data: &CFData) -> Result<SecKey, CFError>17     fn from_data(key_type: KeyType, key_data: &CFData) -> Result<SecKey, CFError>;
18 }
19 
20 impl SecKeyExt for SecKey {
from_data(key_type: KeyType, key_data: &CFData) -> Result<SecKey, CFError>21     fn from_data(key_type: KeyType, key_data: &CFData) -> Result<SecKey, CFError> {
22         unsafe {
23             let key = CFString::wrap_under_get_rule(kSecAttrKeyType);
24             let dict = CFDictionary::from_CFType_pairs(&[(key, key_type.to_str())]);
25 
26             let mut err = ptr::null_mut();
27             let key = SecKeyCreateFromData(
28                 dict.as_concrete_TypeRef(),
29                 key_data.as_concrete_TypeRef(),
30                 &mut err,
31             );
32             if key.is_null() {
33                 Err(CFError::wrap_under_create_rule(err))
34             } else {
35                 Ok(SecKey::wrap_under_create_rule(key))
36             }
37         }
38     }
39 }
40