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 {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result26     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
27         let mut builder = fmt.debug_struct("SecIdentity");
28         if let Ok(cert) = self.certificate() {
29             builder.field("certificate", &cert);
30         }
31         if let Ok(key) = self.private_key() {
32             builder.field("private_key", &key);
33         }
34         builder.finish()
35     }
36 }
37 
38 impl SecIdentity {
39     /// Returns the certificate corresponding to this identity.
certificate(&self) -> Result<SecCertificate>40     pub fn certificate(&self) -> Result<SecCertificate> {
41         unsafe {
42             let mut certificate = ptr::null_mut();
43             cvt(SecIdentityCopyCertificate(self.0, &mut certificate))?;
44             Ok(SecCertificate::wrap_under_create_rule(certificate))
45         }
46     }
47 
48     /// Returns the private key corresponding to this identity.
private_key(&self) -> Result<SecKey>49     pub fn private_key(&self) -> Result<SecKey> {
50         unsafe {
51             let mut key = ptr::null_mut();
52             cvt(SecIdentityCopyPrivateKey(self.0, &mut key))?;
53             Ok(SecKey::wrap_under_create_rule(key))
54         }
55     }
56 }
57 
58 #[cfg(test)]
59 mod test {
60     use super::SecIdentity;
61 
62     #[test]
identity_has_send_bound()63     fn identity_has_send_bound() {
64         fn assert_send<T: Send>() {}
65         assert_send::<SecIdentity>();
66     }
67 }
68