Skip to main content

security/
identity.rs

1use serde_json::Value;
2
3use crate::bridge;
4use crate::certificate::Certificate;
5use crate::error::Result;
6use crate::key::PrivateKey;
7
8#[derive(Debug)]
9/// Wraps `SecIdentityRef`.
10pub struct Identity {
11    handle: bridge::Handle,
12}
13
14impl Identity {
15    pub(crate) fn from_handle(handle: bridge::Handle) -> Self {
16        Self { handle }
17    }
18
19    pub(crate) fn handle(&self) -> &bridge::Handle {
20        &self.handle
21    }
22
23    /// Wraps the corresponding `SecIdentityRef` operation.
24    pub fn type_id() -> usize {
25        unsafe { bridge::security_identity_get_type_id() }
26    }
27
28    /// Wraps the corresponding `SecIdentityRef` operation.
29    pub fn import_pkcs12_first(data: &[u8], password: &str) -> Result<Self> {
30        let password = bridge::cstring(password)?;
31        let mut status = 0;
32        let mut error = std::ptr::null_mut();
33        let raw = unsafe {
34            bridge::security_identity_import_pkcs12_first(
35                data.as_ptr().cast(),
36                bridge::len_to_isize(data.len())?,
37                password.as_ptr(),
38                &mut status,
39                &mut error,
40            )
41        };
42        bridge::required_handle("security_identity_import_pkcs12_first", raw, status, error)
43            .map(Self::from_handle)
44    }
45
46    /// Wraps the corresponding `SecIdentityRef` operation.
47    pub fn from_certificate_and_private_key(
48        certificate: &Certificate,
49        private_key: &PrivateKey,
50    ) -> Result<Self> {
51        let mut status = 0;
52        let mut error = std::ptr::null_mut();
53        let raw = unsafe {
54            bridge::security_identity_create(
55                certificate.handle().as_ptr(),
56                private_key.handle().as_ptr(),
57                &mut status,
58                &mut error,
59            )
60        };
61        bridge::required_handle("security_identity_create", raw, status, error)
62            .map(Self::from_handle)
63    }
64
65    /// Wraps the corresponding `SecIdentityRef` operation.
66    pub fn with_certificate(certificate: &Certificate) -> Result<Self> {
67        let mut status = 0;
68        let mut error = std::ptr::null_mut();
69        let raw = unsafe {
70            bridge::security_identity_create_with_certificate(
71                certificate.handle().as_ptr(),
72                &mut status,
73                &mut error,
74            )
75        };
76        bridge::required_handle(
77            "security_identity_create_with_certificate",
78            raw,
79            status,
80            error,
81        )
82        .map(Self::from_handle)
83    }
84
85    /// Wraps the corresponding `SecIdentityRef` operation.
86    pub fn preferred(
87        name: &str,
88        key_usage: &[&str],
89        valid_issuers: &[Vec<u8>],
90    ) -> Result<Option<Self>> {
91        let name = bridge::cstring(name)?;
92        let key_usage = (!key_usage.is_empty())
93            .then(|| bridge::json_cstring(&key_usage))
94            .transpose()?;
95        let valid_issuers = (!valid_issuers.is_empty())
96            .then(|| bridge::json_cstring(&valid_issuers))
97            .transpose()?;
98        let mut status = 0;
99        let mut error = std::ptr::null_mut();
100        let raw = unsafe {
101            bridge::security_identity_copy_preferred(
102                name.as_ptr(),
103                key_usage
104                    .as_ref()
105                    .map_or(std::ptr::null(), |value| value.as_ptr()),
106                valid_issuers
107                    .as_ref()
108                    .map_or(std::ptr::null(), |value| value.as_ptr()),
109                &mut status,
110                &mut error,
111            )
112        };
113        if raw.is_null() && status == 0 {
114            Ok(None)
115        } else {
116            bridge::required_handle("security_identity_copy_preferred", raw, status, error)
117                .map(Self::from_handle)
118                .map(Some)
119        }
120    }
121
122    /// Wraps the corresponding `SecIdentityRef` operation.
123    pub fn set_preferred(identity: Option<&Self>, name: &str, key_usage: &[&str]) -> Result<()> {
124        let name = bridge::cstring(name)?;
125        let key_usage = (!key_usage.is_empty())
126            .then(|| bridge::json_cstring(&key_usage))
127            .transpose()?;
128        let mut error = std::ptr::null_mut();
129        let status = unsafe {
130            bridge::security_identity_set_preferred(
131                identity.map_or(std::ptr::null_mut(), |value| value.handle.as_ptr()),
132                name.as_ptr(),
133                key_usage
134                    .as_ref()
135                    .map_or(std::ptr::null(), |value| value.as_ptr()),
136                &mut error,
137            )
138        };
139        bridge::status_result("security_identity_set_preferred", status, error)
140    }
141
142    /// Wraps the corresponding `SecIdentityRef` operation.
143    pub fn copy_system_identity(domain: &str) -> Result<Self> {
144        let domain = bridge::cstring(domain)?;
145        let mut status = 0;
146        let mut error = std::ptr::null_mut();
147        let raw = unsafe {
148            bridge::security_identity_copy_system_identity(domain.as_ptr(), &mut status, &mut error)
149        };
150        bridge::required_handle("security_identity_copy_system_identity", raw, status, error)
151            .map(Self::from_handle)
152    }
153
154    /// Wraps the corresponding `SecIdentityRef` operation.
155    pub fn set_system_identity(domain: &str, identity: Option<&Self>) -> Result<()> {
156        let domain = bridge::cstring(domain)?;
157        let mut error = std::ptr::null_mut();
158        let status = unsafe {
159            bridge::security_identity_set_system_identity(
160                domain.as_ptr(),
161                identity.map_or(std::ptr::null_mut(), |value| value.handle.as_ptr()),
162                &mut error,
163            )
164        };
165        bridge::status_result("security_identity_set_system_identity", status, error)
166    }
167
168    /// Wraps the corresponding `SecIdentityRef` operation.
169    pub fn actual_domain(&self) -> Result<Option<String>> {
170        let raw = unsafe { bridge::security_identity_copy_actual_domain(self.handle.as_ptr()) };
171        bridge::optional_string(raw)
172    }
173
174    /// Wraps the corresponding `SecIdentityRef` operation.
175    pub fn label(&self) -> Result<Option<String>> {
176        let raw = unsafe { bridge::security_identity_copy_label(self.handle.as_ptr()) };
177        bridge::optional_string(raw)
178    }
179
180    /// Wraps the corresponding `SecIdentityRef` operation.
181    pub fn chain_count(&self) -> usize {
182        usize::try_from(unsafe { bridge::security_identity_get_chain_count(self.handle.as_ptr()) })
183            .unwrap_or_default()
184    }
185
186    /// Wraps the corresponding `SecIdentityRef` operation.
187    pub fn certificate(&self) -> Result<Certificate> {
188        let mut status = 0;
189        let mut error = std::ptr::null_mut();
190        let raw = unsafe {
191            bridge::security_identity_copy_certificate(
192                self.handle.as_ptr(),
193                &mut status,
194                &mut error,
195            )
196        };
197        bridge::required_handle("security_identity_copy_certificate", raw, status, error)
198            .map(Certificate::from_handle)
199    }
200
201    /// Wraps the corresponding `SecIdentityRef` operation.
202    pub fn private_key_attributes(&self) -> Result<Value> {
203        let mut status = 0;
204        let mut error = std::ptr::null_mut();
205        let raw = unsafe {
206            bridge::security_identity_copy_private_key_attributes(
207                self.handle.as_ptr(),
208                &mut status,
209                &mut error,
210            )
211        };
212        bridge::required_json(
213            "security_identity_copy_private_key_attributes",
214            raw,
215            status,
216            error,
217        )
218    }
219}