1use crate::ffi;
4use crate::la_error::{LAError, Result};
5use crate::la_public_key::{LAPublicKey, SecKeyAlgorithm, SecKeyExchangeParameters};
6use crate::la_right::LARightState;
7use crate::private::{
8 bridge_bool, bridge_bytes, bridge_i32, bridge_i64, bridge_ptr, bridge_unit, cstring,
9 OwnedHandle,
10};
11
12#[derive(Debug)]
14pub struct LAPersistedRight {
15 handle: OwnedHandle,
16}
17
18impl LAPersistedRight {
19 pub(crate) fn from_raw(raw: std::ptr::NonNull<core::ffi::c_void>) -> Self {
20 Self {
21 handle: OwnedHandle::new(raw, ffi::la_persisted_right::la_persisted_right_release),
22 }
23 }
24
25 pub(crate) const fn as_ptr(&self) -> *mut core::ffi::c_void {
26 self.handle.as_ptr()
27 }
28
29 pub fn state(&self) -> Result<LARightState> {
35 let raw = bridge_i32(|out, error_out| unsafe {
36 ffi::la_persisted_right::la_persisted_right_get_state(
37 self.handle.as_ptr(),
38 out,
39 error_out,
40 )
41 })?;
42 Ok(LARightState::from_ffi(raw))
43 }
44
45 pub fn tag(&self) -> Result<i64> {
51 bridge_i64(|out, error_out| unsafe {
52 ffi::la_persisted_right::la_persisted_right_get_tag(
53 self.handle.as_ptr(),
54 out,
55 error_out,
56 )
57 })
58 }
59
60 pub fn set_tag(&self, tag: i64) -> Result<()> {
66 bridge_unit(|error_out| unsafe {
67 ffi::la_persisted_right::la_persisted_right_set_tag(
68 self.handle.as_ptr(),
69 tag,
70 error_out,
71 )
72 })
73 }
74
75 pub fn authorize(&self, localized_reason: &str) -> Result<()> {
81 if localized_reason.is_empty() {
82 return Err(LAError::InvalidArgument(
83 "localized reason must not be empty".to_owned(),
84 ));
85 }
86 let localized_reason = cstring(localized_reason)?;
87 bridge_unit(|error_out| unsafe {
88 ffi::la_persisted_right::la_persisted_right_authorize(
89 self.handle.as_ptr(),
90 localized_reason.as_ptr(),
91 error_out,
92 )
93 })
94 }
95
96 pub fn check_can_authorize(&self) -> Result<()> {
102 bridge_unit(|error_out| unsafe {
103 ffi::la_persisted_right::la_persisted_right_check_can_authorize(
104 self.handle.as_ptr(),
105 error_out,
106 )
107 })
108 }
109
110 pub fn deauthorize(&self) -> Result<()> {
116 bridge_unit(|error_out| unsafe {
117 ffi::la_persisted_right::la_persisted_right_deauthorize(self.handle.as_ptr(), error_out)
118 })
119 }
120
121 pub fn key(&self) -> Result<LAPrivateKey> {
127 Ok(LAPrivateKey::from_raw(bridge_ptr(
128 |out, error_out| unsafe {
129 ffi::la_persisted_right::la_persisted_right_get_key(
130 self.handle.as_ptr(),
131 out,
132 error_out,
133 )
134 },
135 )?))
136 }
137
138 pub fn secret(&self) -> Result<LASecret> {
144 Ok(LASecret::from_raw(bridge_ptr(|out, error_out| unsafe {
145 ffi::la_persisted_right::la_persisted_right_get_secret(
146 self.handle.as_ptr(),
147 out,
148 error_out,
149 )
150 })?))
151 }
152
153 pub fn public_key(&self) -> Result<LAPublicKey> {
159 self.key()?.public_key()
160 }
161}
162
163#[derive(Debug)]
165pub struct LASecret {
166 handle: OwnedHandle,
167}
168
169impl LASecret {
170 pub(crate) fn from_raw(raw: std::ptr::NonNull<core::ffi::c_void>) -> Self {
171 Self {
172 handle: OwnedHandle::new(raw, ffi::la_persisted_right::la_secret_release),
173 }
174 }
175
176 pub fn load_data(&self) -> Result<Vec<u8>> {
182 bridge_bytes(|out, out_len, error_out| unsafe {
183 ffi::la_persisted_right::la_secret_load_data(
184 self.handle.as_ptr(),
185 out,
186 out_len,
187 error_out,
188 )
189 })
190 }
191}
192
193#[derive(Debug)]
195pub struct LAPrivateKey {
196 handle: OwnedHandle,
197}
198
199impl LAPrivateKey {
200 pub(crate) fn from_raw(raw: std::ptr::NonNull<core::ffi::c_void>) -> Self {
201 Self {
202 handle: OwnedHandle::new(raw, ffi::la_persisted_right::la_private_key_release),
203 }
204 }
205
206 pub fn public_key(&self) -> Result<LAPublicKey> {
212 Ok(LAPublicKey::from_raw(bridge_ptr(
213 |out, error_out| unsafe {
214 ffi::la_persisted_right::la_private_key_get_public_key(
215 self.handle.as_ptr(),
216 out,
217 error_out,
218 )
219 },
220 )?))
221 }
222
223 pub fn can_sign_using(&self, algorithm: &SecKeyAlgorithm) -> Result<bool> {
229 let algorithm = cstring(algorithm.raw_name())?;
230 bridge_bool(|out, error_out| unsafe {
231 ffi::la_persisted_right::la_private_key_can_sign_using_algorithm(
232 self.handle.as_ptr(),
233 algorithm.as_ptr(),
234 out,
235 error_out,
236 )
237 })
238 }
239
240 pub fn sign(&self, data: &[u8], algorithm: &SecKeyAlgorithm) -> Result<Vec<u8>> {
246 let algorithm = cstring(algorithm.raw_name())?;
247 bridge_bytes(|out, out_len, error_out| unsafe {
248 ffi::la_persisted_right::la_private_key_sign_data(
249 self.handle.as_ptr(),
250 data.as_ptr(),
251 data.len(),
252 algorithm.as_ptr(),
253 out,
254 out_len,
255 error_out,
256 )
257 })
258 }
259
260 pub fn can_decrypt_using(&self, algorithm: &SecKeyAlgorithm) -> Result<bool> {
266 let algorithm = cstring(algorithm.raw_name())?;
267 bridge_bool(|out, error_out| unsafe {
268 ffi::la_persisted_right::la_private_key_can_decrypt_using_algorithm(
269 self.handle.as_ptr(),
270 algorithm.as_ptr(),
271 out,
272 error_out,
273 )
274 })
275 }
276
277 pub fn decrypt(&self, data: &[u8], algorithm: &SecKeyAlgorithm) -> Result<Vec<u8>> {
283 let algorithm = cstring(algorithm.raw_name())?;
284 bridge_bytes(|out, out_len, error_out| unsafe {
285 ffi::la_persisted_right::la_private_key_decrypt_data(
286 self.handle.as_ptr(),
287 data.as_ptr(),
288 data.len(),
289 algorithm.as_ptr(),
290 out,
291 out_len,
292 error_out,
293 )
294 })
295 }
296
297 pub fn can_exchange_keys_using(&self, algorithm: &SecKeyAlgorithm) -> Result<bool> {
303 let algorithm = cstring(algorithm.raw_name())?;
304 bridge_bool(|out, error_out| unsafe {
305 ffi::la_persisted_right::la_private_key_can_exchange_keys_using_algorithm(
306 self.handle.as_ptr(),
307 algorithm.as_ptr(),
308 out,
309 error_out,
310 )
311 })
312 }
313
314 pub fn exchange_keys_with_public_key(
320 &self,
321 public_key: &[u8],
322 algorithm: &SecKeyAlgorithm,
323 parameters: &SecKeyExchangeParameters,
324 ) -> Result<Vec<u8>> {
325 let algorithm = cstring(algorithm.raw_name())?;
326 let requested_size = parameters
327 .requested_size_value()
328 .map(i64::try_from)
329 .transpose()
330 .map_err(|_| {
331 LAError::InvalidArgument(
332 "requested key-exchange size must fit in a signed 64-bit integer".to_owned(),
333 )
334 })?
335 .unwrap_or(-1);
336 let shared_info = parameters.shared_info_value();
337 let shared_info_ptr = shared_info.map_or(std::ptr::null(), <[u8]>::as_ptr);
338 let shared_info_len = shared_info.map_or(0, <[u8]>::len);
339 let has_shared_info = u8::from(shared_info.is_some());
340
341 bridge_bytes(|out, out_len, error_out| unsafe {
342 ffi::la_persisted_right::la_private_key_exchange_keys_with_public_key(
343 self.handle.as_ptr(),
344 public_key.as_ptr(),
345 public_key.len(),
346 algorithm.as_ptr(),
347 requested_size,
348 shared_info_ptr,
349 shared_info_len,
350 has_shared_info,
351 out,
352 out_len,
353 error_out,
354 )
355 })
356 }
357}