1use serde_json::Value;
2
3use crate::bridge;
4use crate::certificate::Certificate;
5use crate::error::{Result, SecurityError};
6pub use crate::policy::Policy;
7
8#[derive(Debug)]
9pub struct Trust {
10 handle: bridge::Handle,
11}
12
13impl Trust {
14 pub fn new(certificate: &Certificate, policies: &[Policy]) -> Result<Self> {
15 Self::from_certificates(std::slice::from_ref(certificate), policies)
16 }
17
18 pub fn from_certificates(certificates: &[Certificate], policies: &[Policy]) -> Result<Self> {
19 let certificate_handles = certificates.iter().map(Certificate::handle).collect::<Vec<_>>();
20 let policy_handles = policies.iter().map(Policy::handle).collect::<Vec<_>>();
21 let certificate_pointers = bridge::handle_pointer_array(&certificate_handles);
22 let policy_pointers = bridge::handle_pointer_array(&policy_handles);
23 let mut status = 0;
24 let mut error = std::ptr::null_mut();
25 let raw = unsafe {
26 bridge::security_trust_create(
27 certificate_pointers.as_ptr(),
28 bridge::len_to_isize(certificate_pointers.len())?,
29 policy_pointers.as_ptr(),
30 bridge::len_to_isize(policy_pointers.len())?,
31 &mut status,
32 &mut error,
33 )
34 };
35 bridge::required_handle("security_trust_create", raw, status, error).map(|handle| Self {
36 handle,
37 })
38 }
39
40 pub fn set_policies(&mut self, policies: &[Policy]) -> Result<()> {
41 let policy_handles = policies.iter().map(Policy::handle).collect::<Vec<_>>();
42 let pointers = bridge::handle_pointer_array(&policy_handles);
43 let mut error = std::ptr::null_mut();
44 let status = unsafe {
45 bridge::security_trust_set_policies(
46 self.handle.as_ptr(),
47 pointers.as_ptr(),
48 bridge::len_to_isize(pointers.len())?,
49 &mut error,
50 )
51 };
52 bridge::status_result("security_trust_set_policies", status, error)
53 }
54
55 pub fn set_anchor_certificates(&mut self, certificates: &[Certificate]) -> Result<()> {
56 let certificate_handles = certificates.iter().map(Certificate::handle).collect::<Vec<_>>();
57 let pointers = bridge::handle_pointer_array(&certificate_handles);
58 let mut error = std::ptr::null_mut();
59 let status = unsafe {
60 bridge::security_trust_set_anchor_certificates(
61 self.handle.as_ptr(),
62 pointers.as_ptr(),
63 bridge::len_to_isize(pointers.len())?,
64 &mut error,
65 )
66 };
67 bridge::status_result("security_trust_set_anchor_certificates", status, error)
68 }
69
70 pub fn set_anchor_certificates_only(&mut self, only_anchor_certificates: bool) -> Result<()> {
71 let mut error = std::ptr::null_mut();
72 let status = unsafe {
73 bridge::security_trust_set_anchor_certificates_only(
74 self.handle.as_ptr(),
75 only_anchor_certificates,
76 &mut error,
77 )
78 };
79 bridge::status_result("security_trust_set_anchor_certificates_only", status, error)
80 }
81
82 pub fn set_network_fetch_allowed(&mut self, allowed: bool) -> Result<()> {
83 let mut error = std::ptr::null_mut();
84 let status = unsafe {
85 bridge::security_trust_set_network_fetch_allowed(self.handle.as_ptr(), allowed, &mut error)
86 };
87 bridge::status_result("security_trust_set_network_fetch_allowed", status, error)
88 }
89
90 pub fn evaluate(&self) -> Result<()> {
91 let mut error = std::ptr::null_mut();
92 let trusted = unsafe { bridge::security_trust_evaluate(self.handle.as_ptr(), &mut error) };
93 if trusted {
94 Ok(())
95 } else {
96 let message = bridge::optional_string(error)?.unwrap_or_else(|| "trust evaluation failed".to_owned());
97 Err(SecurityError::TrustEvaluationFailed(message))
98 }
99 }
100
101 pub fn result(&self) -> Result<Value> {
102 let mut status = 0;
103 let mut error = std::ptr::null_mut();
104 let raw = unsafe { bridge::security_trust_copy_result(self.handle.as_ptr(), &mut status, &mut error) };
105 bridge::required_json("security_trust_copy_result", raw, status, error)
106 }
107
108 pub fn certificate_chain(&self) -> Result<Vec<Certificate>> {
109 let mut status = 0;
110 let mut error = std::ptr::null_mut();
111 let raw = unsafe {
112 bridge::security_trust_copy_certificate_chain(self.handle.as_ptr(), &mut status, &mut error)
113 };
114 let array_handle = bridge::required_handle(
115 "security_trust_copy_certificate_chain",
116 raw,
117 status,
118 error,
119 )?;
120 let count = usize::try_from(unsafe {
121 bridge::security_certificate_array_get_count(array_handle.as_ptr())
122 })
123 .unwrap_or_default();
124 let mut certificates = Vec::with_capacity(count);
125 for index in 0..count {
126 let mut status = 0;
127 let mut error = std::ptr::null_mut();
128 let raw = unsafe {
129 bridge::security_certificate_array_copy_item(
130 array_handle.as_ptr(),
131 bridge::len_to_isize(index)?,
132 &mut status,
133 &mut error,
134 )
135 };
136 let handle = bridge::required_handle(
137 "security_certificate_array_copy_item",
138 raw,
139 status,
140 error,
141 )?;
142 certificates.push(Certificate::from_handle(handle));
143 }
144 Ok(certificates)
145 }
146}