1 //! Identity support.
2 
3 use core_foundation::base::TCFType;
4 use security_framework_sys::base::SecIdentityRef;
5 use security_framework_sys::identity::*;
6 use std::fmt;
7 use std::ptr;
8 
9 use crate::base::Result;
10 use crate::certificate::SecCertificate;
11 use crate::cvt;
12 use crate::key::SecKey;
13 
14 declare_TCFType! {
15     /// A type representing an identity.
16     ///
17     /// Identities are a certificate paired with the corresponding private key.
18     SecIdentity, SecIdentityRef
19 }
20 impl_TCFType!(SecIdentity, SecIdentityRef, SecIdentityGetTypeID);
21 
22 unsafe impl Sync for SecIdentity {}
23 unsafe impl Send for SecIdentity {}
24 
25 impl fmt::Debug for SecIdentity {
26     #[cold]
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result27     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
28         let mut builder = fmt.debug_struct("SecIdentity");
29         if let Ok(cert) = self.certificate() {
30             builder.field("certificate", &cert);
31         }
32         if let Ok(key) = self.private_key() {
33             builder.field("private_key", &key);
34         }
35         builder.finish()
36     }
37 }
38 
39 impl SecIdentity {
40     /// Returns the certificate corresponding to this identity.
certificate(&self) -> Result<SecCertificate>41     pub fn certificate(&self) -> Result<SecCertificate> {
42         unsafe {
43             let mut certificate = ptr::null_mut();
44             cvt(SecIdentityCopyCertificate(self.0, &mut certificate))?;
45             Ok(SecCertificate::wrap_under_create_rule(certificate))
46         }
47     }
48 
49     /// Returns the private key corresponding to this identity.
private_key(&self) -> Result<SecKey>50     pub fn private_key(&self) -> Result<SecKey> {
51         unsafe {
52             let mut key = ptr::null_mut();
53             cvt(SecIdentityCopyPrivateKey(self.0, &mut key))?;
54             Ok(SecKey::wrap_under_create_rule(key))
55         }
56     }
57 }
58 
59 #[cfg(test)]
60 mod test {
61     use super::SecIdentity;
62 
63     #[test]
identity_has_send_bound()64     fn identity_has_send_bound() {
65         fn assert_send<T: Send>() {}
66         assert_send::<SecIdentity>();
67     }
68 }
69