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 {
rsa() -> Self18     pub fn rsa() -> Self {
19         unsafe { Self(kSecAttrKeyTypeRSA) }
20     }
21 
dsa() -> Self22     pub fn dsa() -> Self {
23         unsafe { Self(kSecAttrKeyTypeDSA) }
24     }
25 
aes() -> Self26     pub fn aes() -> Self {
27         unsafe { Self(kSecAttrKeyTypeAES) }
28     }
29 
des() -> Self30     pub fn des() -> Self {
31         unsafe { Self(kSecAttrKeyTypeDES) }
32     }
33 
triple_des() -> Self34     pub fn triple_des() -> Self {
35         unsafe { Self(kSecAttrKeyType3DES) }
36     }
37 
rc4() -> Self38     pub fn rc4() -> Self {
39         unsafe { Self(kSecAttrKeyTypeRC4) }
40     }
41 
cast() -> Self42     pub fn cast() -> Self {
43         unsafe { Self(kSecAttrKeyTypeCAST) }
44     }
45 
46     #[cfg(feature = "OSX_10_9")]
ec() -> Self47     pub fn ec() -> Self {
48         unsafe { Self(kSecAttrKeyTypeEC) }
49     }
50 
to_str(self) -> CFString51     pub(crate) fn to_str(self) -> CFString {
52         unsafe { CFString::wrap_under_get_rule(self.0) }
53     }
54 }
55 
56 /// An extension trait adding OSX specific functionality to `ItemSearchOptions`.
57 pub trait ItemSearchOptionsExt {
58     /// Search within the specified keychains.
59     ///
60     /// If this is not called, the default keychain will be searched.
keychains(&mut self, keychains: &[SecKeychain]) -> &mut Self61     fn keychains(&mut self, keychains: &[SecKeychain]) -> &mut Self;
62 }
63 
64 impl ItemSearchOptionsExt for ItemSearchOptions {
keychains(&mut self, keychains: &[SecKeychain]) -> &mut Self65     fn keychains(&mut self, keychains: &[SecKeychain]) -> &mut Self {
66         ItemSearchOptionsInternals::keychains(self, keychains)
67     }
68 }
69 
70 #[cfg(test)]
71 mod test {
72     use tempdir::TempDir;
73 
74     use crate::item::*;
75     use crate::os::macos::certificate::SecCertificateExt;
76     use crate::os::macos::test::keychain;
77 
78     #[test]
79     #[allow(deprecated)]
find_certificate()80     fn find_certificate() {
81         let dir = p!(TempDir::new("find_certificate"));
82         let keychain = keychain(dir.path());
83         let results = p!(ItemSearchOptions::new()
84             .keychains(&[keychain])
85             .class(ItemClass::certificate())
86             .search());
87         assert_eq!(1, results.len());
88         let certificate = match results[0] {
89             SearchResult::Ref(Reference::Certificate(ref cert)) => cert,
90             _ => panic!("expected certificate"),
91         };
92         assert_eq!("foobar.com", p!(certificate.common_name()));
93     }
94 }
95