security_framework/os/macos/
identity.rs1use core_foundation::array::CFArray;
3use core_foundation::base::TCFType;
4use security_framework_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.is_empty() { 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::os::macos::certificate::SecCertificateExt;
48 use crate::os::macos::import_export::ImportOptions;
49 use crate::os::macos::keychain::CreateOptions;
50 use crate::os::macos::test::identity;
51 use crate::test;
52
53 #[test]
54 fn certificate() {
55 let dir = p!(tempdir());
56 let identity = identity(dir.path());
57 let certificate = p!(identity.certificate());
58 assert_eq!("foobar.com", p!(certificate.common_name()));
59 }
60
61 #[test]
62 fn private_key() {
63 let dir = p!(tempdir());
64 let identity = identity(dir.path());
65 p!(identity.private_key());
66 }
67
68 #[test]
69 fn with_certificate() {
70 let dir = p!(tempdir());
71
72 let keychain = p!(CreateOptions::new()
73 .password("foobar")
74 .create(dir.path().join("test.keychain")));
75
76 let key = include_bytes!("../../../test/server.key");
77 p!(ImportOptions::new()
78 .filename("server.key")
79 .keychain(&keychain)
80 .import(key));
81
82 let cert = test::certificate();
83 p!(SecIdentity::with_certificate(&[keychain], &cert));
84 }
85}