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