1use serde_json::Value;
2
3use crate::bridge;
4use crate::certificate::Certificate;
5use crate::error::Result;
6use crate::key::PrivateKey;
7
8#[derive(Debug)]
9pub 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 pub fn type_id() -> usize {
25 unsafe { bridge::security_identity_get_type_id() }
26 }
27
28 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 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 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 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 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 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 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 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 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 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 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 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}