apple_security_framework/
identity.rs1use std::{fmt, ptr};
4
5use core_foundation::{
6 base::{TCFType, ToVoid},
7 dictionary::CFMutableDictionary,
8};
9use security_framework_sys::{
10 base::SecIdentityRef,
11 identity::{SecIdentityCopyCertificate, SecIdentityCopyPrivateKey, SecIdentityGetTypeID},
12 item::kSecValueRef,
13 keychain_item::SecItemDelete,
14};
15
16use crate::{
17 base::{Error, Result},
18 certificate::SecCertificate,
19 cvt,
20 key::SecKey,
21};
22
23declare_TCFType! {
24 SecIdentity, SecIdentityRef
28}
29impl_TCFType!(SecIdentity, SecIdentityRef, SecIdentityGetTypeID);
30
31unsafe impl Sync for SecIdentity {}
32unsafe impl Send for SecIdentity {}
33
34impl fmt::Debug for SecIdentity {
35 #[cold]
36 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
37 let mut builder = fmt.debug_struct("SecIdentity");
38 if let Ok(cert) = self.certificate() {
39 builder.field("certificate", &cert);
40 }
41 if let Ok(key) = self.private_key() {
42 builder.field("private_key", &key);
43 }
44 builder.finish()
45 }
46}
47
48impl SecIdentity {
49 pub fn certificate(&self) -> Result<SecCertificate> {
51 unsafe {
52 let mut certificate = ptr::null_mut();
53 cvt(SecIdentityCopyCertificate(self.0, &mut certificate))?;
54 Ok(SecCertificate::wrap_under_create_rule(certificate))
55 }
56 }
57
58 pub fn private_key(&self) -> Result<SecKey> {
60 unsafe {
61 let mut key = ptr::null_mut();
62 cvt(SecIdentityCopyPrivateKey(self.0, &mut key))?;
63 Ok(SecKey::wrap_under_create_rule(key))
64 }
65 }
66
67 pub fn delete(&self) -> Result<(), Error> {
69 let query = CFMutableDictionary::from_CFType_pairs(&[(
70 unsafe { kSecValueRef }.to_void(),
71 self.to_void(),
72 )]);
73
74 cvt(unsafe { SecItemDelete(query.as_concrete_TypeRef()) })
75 }
76}
77
78#[cfg(test)]
79mod test {
80 use super::SecIdentity;
81
82 #[test]
83 fn identity_has_send_bound() {
84 fn assert_send<T: Send>() {}
85 assert_send::<SecIdentity>();
86 }
87}