1 //! OSX specific functionality for items.
2 
3 use core_foundation::base::TCFType;
4 use core_foundation::string::CFString;
5 use core_foundation_sys::string::CFStringRef;
6 use security_framework_sys::item::*;
7 
8 use crate::item::ItemSearchOptions;
9 use crate::os::macos::keychain::SecKeychain;
10 use crate::ItemSearchOptionsInternals;
11 
12 /// Types of `SecKey`s.
13 #[derive(Debug, Copy, Clone)]
14 pub struct KeyType(CFStringRef);
15 
16 #[allow(missing_docs)]
17 impl KeyType {
18     #[inline(always)]
rsa() -> Self19     pub fn rsa() -> Self {
20         unsafe { Self(kSecAttrKeyTypeRSA) }
21     }
22 
23     #[inline(always)]
dsa() -> Self24     pub fn dsa() -> Self {
25         unsafe { Self(kSecAttrKeyTypeDSA) }
26     }
27 
28     #[inline(always)]
aes() -> Self29     pub fn aes() -> Self {
30         unsafe { Self(kSecAttrKeyTypeAES) }
31     }
32 
33     #[inline(always)]
des() -> Self34     pub fn des() -> Self {
35         unsafe { Self(kSecAttrKeyTypeDES) }
36     }
37 
38     #[inline(always)]
triple_des() -> Self39     pub fn triple_des() -> Self {
40         unsafe { Self(kSecAttrKeyType3DES) }
41     }
42 
43     #[inline(always)]
rc4() -> Self44     pub fn rc4() -> Self {
45         unsafe { Self(kSecAttrKeyTypeRC4) }
46     }
47 
48     #[inline(always)]
cast() -> Self49     pub fn cast() -> Self {
50         unsafe { Self(kSecAttrKeyTypeCAST) }
51     }
52 
53     #[cfg(feature = "OSX_10_9")]
54     #[inline(always)]
ec() -> Self55     pub fn ec() -> Self {
56         unsafe { Self(kSecAttrKeyTypeEC) }
57     }
58 
to_str(self) -> CFString59     pub(crate) fn to_str(self) -> CFString {
60         unsafe { CFString::wrap_under_get_rule(self.0) }
61     }
62 }
63 
64 /// An extension trait adding OSX specific functionality to `ItemSearchOptions`.
65 pub trait ItemSearchOptionsExt {
66     /// Search within the specified keychains.
67     ///
68     /// If this is not called, the default keychain will be searched.
keychains(&mut self, keychains: &[SecKeychain]) -> &mut Self69     fn keychains(&mut self, keychains: &[SecKeychain]) -> &mut Self;
70 }
71 
72 impl ItemSearchOptionsExt for ItemSearchOptions {
73     #[inline(always)]
keychains(&mut self, keychains: &[SecKeychain]) -> &mut Self74     fn keychains(&mut self, keychains: &[SecKeychain]) -> &mut Self {
75         ItemSearchOptionsInternals::keychains(self, keychains)
76     }
77 }
78 
79 #[cfg(test)]
80 mod test {
81     use crate::item::*;
82     use crate::os::macos::certificate::SecCertificateExt;
83     use crate::os::macos::item::ItemSearchOptionsExt;
84     use crate::os::macos::test::keychain;
85     use tempdir::TempDir;
86 
87     #[test]
find_certificate()88     fn find_certificate() {
89         let dir = p!(TempDir::new("find_certificate"));
90         let keychain = keychain(dir.path());
91         let results = p!(ItemSearchOptions::new()
92             .keychains(&[keychain])
93             .class(ItemClass::certificate())
94             .search());
95         assert_eq!(1, results.len());
96         let certificate = match results[0] {
97             SearchResult::Ref(Reference::Certificate(ref cert)) => cert,
98             _ => panic!("expected certificate"),
99         };
100         assert_eq!("foobar.com", p!(certificate.common_name()));
101     }
102 }
103