apple_security/os/macos/
identity.rs1use core_foundation::array::CFArray;
3use core_foundation::base::TCFType;
4use apple_security_sys::identity::SecIdentityCreateWithCertificate;
5use std::ptr;
6
7use crate::base::Result;
8use crate::certificate::SecCertificate;
9use crate::cvt;
10use crate::identity::SecIdentity;
11use crate::os::macos::keychain::SecKeychain;
12
13pub trait SecIdentityExt {
15 fn with_certificate(
22 keychains: &[SecKeychain],
23 certificate: &SecCertificate,
24 ) -> Result<SecIdentity>;
25}
26
27impl SecIdentityExt for SecIdentity {
28 fn with_certificate(keychains: &[SecKeychain], certificate: &SecCertificate) -> Result<Self> {
29 let keychains = CFArray::from_CFTypes(keychains);
30 unsafe {
31 let mut identity = ptr::null_mut();
32 cvt(SecIdentityCreateWithCertificate(
33 if keychains.len() > 0 {keychains.as_CFTypeRef()} else {ptr::null()},
34 certificate.as_concrete_TypeRef(),
35 &mut identity,
36 ))?;
37 Ok(Self::wrap_under_create_rule(identity))
38 }
39 }
40}
41
42#[cfg(test)]
43mod test {
44 use tempfile::tempdir;
45
46 use super::*;
47 use crate::identity::SecIdentity;
48 use crate::os::macos::certificate::SecCertificateExt;
49 use crate::os::macos::import_export::ImportOptions;
50 use crate::os::macos::keychain::CreateOptions;
51 use crate::os::macos::test::identity;
52 use crate::test;
53
54 #[test]
55 fn certificate() {
56 let dir = p!(tempdir());
57 let identity = identity(dir.path());
58 let certificate = p!(identity.certificate());
59 assert_eq!("foobar.com", p!(certificate.common_name()));
60 }
61
62 #[test]
63 fn private_key() {
64 let dir = p!(tempdir());
65 let identity = identity(dir.path());
66 p!(identity.private_key());
67 }
68
69 #[test]
70 fn with_certificate() {
71 let dir = p!(tempdir());
72
73 let mut keychain = p!(CreateOptions::new()
74 .password("foobar")
75 .create(dir.path().join("test.keychain")));
76
77 let key = include_bytes!("../../../test/server.key");
78 p!(ImportOptions::new()
79 .filename("server.key")
80 .keychain(&mut keychain)
81 .import(key));
82
83 let cert = test::certificate();
84 p!(SecIdentity::with_certificate(&[keychain], &cert));
85 }
86}