variant_ssl/x509/
store.rs1use cfg_if::cfg_if;
45use foreign_types::{ForeignType, ForeignTypeRef};
46use std::mem;
47
48use crate::error::ErrorStack;
49#[cfg(not(any(boringssl, awslc)))]
50use crate::ssl::SslFiletype;
51#[cfg(any(ossl300, boringssl))]
52use crate::stack::Stack;
53use crate::util::ForeignTypeRefExt;
54use crate::x509::verify::{X509VerifyFlags, X509VerifyParamRef};
55#[cfg(any(ossl330, boringssl))]
56use crate::x509::X509Object;
57use crate::x509::{X509PurposeId, X509};
58use crate::{cvt, cvt_p};
59use openssl_macros::corresponds;
60#[cfg(not(any(boringssl, awslc)))]
61use std::ffi::CString;
62#[cfg(not(any(boringssl, awslc)))]
63use std::path::Path;
64
65foreign_type_and_impl_send_sync! {
66 type CType = ffi::X509_STORE;
67 fn drop = ffi::X509_STORE_free;
68
69 pub struct X509StoreBuilder;
71 pub struct X509StoreBuilderRef;
73}
74
75impl X509StoreBuilder {
76 #[corresponds(X509_STORE_new)]
80 pub fn new() -> Result<X509StoreBuilder, ErrorStack> {
81 unsafe {
82 ffi::init();
83
84 cvt_p(ffi::X509_STORE_new()).map(X509StoreBuilder)
85 }
86 }
87
88 pub fn build(self) -> X509Store {
90 let store = X509Store(self.0);
91 mem::forget(self);
92 store
93 }
94}
95
96impl X509StoreBuilderRef {
97 #[corresponds(X509_STORE_add_cert)]
100 pub fn add_cert(&mut self, cert: X509) -> Result<(), ErrorStack> {
101 unsafe { cvt(ffi::X509_STORE_add_cert(self.as_ptr(), cert.as_ptr())).map(|_| ()) }
102 }
103
104 #[corresponds(X509_STORE_set_default_paths)]
110 pub fn set_default_paths(&mut self) -> Result<(), ErrorStack> {
111 unsafe { cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())).map(|_| ()) }
112 }
113
114 #[corresponds(X509_STORE_add_lookup)]
116 pub fn add_lookup<T>(
117 &mut self,
118 method: &'static X509LookupMethodRef<T>,
119 ) -> Result<&mut X509LookupRef<T>, ErrorStack> {
120 let lookup = unsafe { ffi::X509_STORE_add_lookup(self.as_ptr(), method.as_ptr()) };
121 cvt_p(lookup).map(|ptr| unsafe { X509LookupRef::from_ptr_mut(ptr) })
122 }
123
124 #[corresponds(X509_STORE_set_flags)]
126 pub fn set_flags(&mut self, flags: X509VerifyFlags) -> Result<(), ErrorStack> {
127 unsafe { cvt(ffi::X509_STORE_set_flags(self.as_ptr(), flags.bits())).map(|_| ()) }
128 }
129
130 #[corresponds(X509_STORE_set_purpose)]
133 pub fn set_purpose(&mut self, purpose: X509PurposeId) -> Result<(), ErrorStack> {
134 unsafe { cvt(ffi::X509_STORE_set_purpose(self.as_ptr(), purpose.as_raw())).map(|_| ()) }
135 }
136
137 #[corresponds[X509_STORE_set1_param]]
139 pub fn set_param(&mut self, param: &X509VerifyParamRef) -> Result<(), ErrorStack> {
140 unsafe { cvt(ffi::X509_STORE_set1_param(self.as_ptr(), param.as_ptr())).map(|_| ()) }
141 }
142}
143
144generic_foreign_type_and_impl_send_sync! {
145 type CType = ffi::X509_LOOKUP;
146 fn drop = ffi::X509_LOOKUP_free;
147
148 pub struct X509Lookup<T>;
150 pub struct X509LookupRef<T>;
152}
153
154pub struct HashDir;
159
160impl X509Lookup<HashDir> {
161 #[corresponds(X509_LOOKUP_hash_dir)]
166 pub fn hash_dir() -> &'static X509LookupMethodRef<HashDir> {
167 unsafe { X509LookupMethodRef::from_const_ptr(ffi::X509_LOOKUP_hash_dir()) }
168 }
169}
170
171#[cfg(not(any(boringssl, awslc)))]
172impl X509LookupRef<HashDir> {
173 #[corresponds(X509_LOOKUP_add_dir)]
176 pub fn add_dir(&mut self, name: &str, file_type: SslFiletype) -> Result<(), ErrorStack> {
177 let name = CString::new(name).unwrap();
178 unsafe {
179 cvt(ffi::X509_LOOKUP_add_dir(
180 self.as_ptr(),
181 name.as_ptr(),
182 file_type.as_raw(),
183 ))
184 .map(|_| ())
185 }
186 }
187}
188
189pub struct File;
193
194impl X509Lookup<File> {
195 #[corresponds(X509_LOOKUP_file)]
198 pub fn file() -> &'static X509LookupMethodRef<File> {
199 unsafe { X509LookupMethodRef::from_const_ptr(ffi::X509_LOOKUP_file()) }
200 }
201}
202
203#[cfg(not(any(boringssl, awslc)))]
204impl X509LookupRef<File> {
205 #[corresponds(X509_load_cert_file)]
207 pub fn load_cert_file<P: AsRef<Path>>(
209 &mut self,
210 file: P,
211 file_type: SslFiletype,
212 ) -> Result<(), ErrorStack> {
213 let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap();
214 unsafe {
215 cvt(ffi::X509_load_cert_file(
216 self.as_ptr(),
217 file.as_ptr(),
218 file_type.as_raw(),
219 ))
220 .map(|_| ())
221 }
222 }
223
224 #[corresponds(X509_load_crl_file)]
226 pub fn load_crl_file<P: AsRef<Path>>(
227 &mut self,
228 file: P,
229 file_type: SslFiletype,
230 ) -> Result<i32, ErrorStack> {
231 let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap();
232 unsafe {
233 cvt(ffi::X509_load_crl_file(
234 self.as_ptr(),
235 file.as_ptr(),
236 file_type.as_raw(),
237 ))
238 }
239 }
240}
241
242generic_foreign_type_and_impl_send_sync! {
243 type CType = ffi::X509_LOOKUP_METHOD;
244 fn drop = X509_LOOKUP_meth_free;
245
246 pub struct X509LookupMethod<T>;
248 pub struct X509LookupMethodRef<T>;
250}
251
252foreign_type_and_impl_send_sync! {
253 type CType = ffi::X509_STORE;
254 fn drop = ffi::X509_STORE_free;
255
256 pub struct X509Store;
258 pub struct X509StoreRef;
260}
261
262impl X509StoreRef {
263 #[corresponds(X509_STORE_get1_objects)]
267 #[cfg(any(ossl330, boringssl))]
268 pub fn objects(&self) -> Stack<X509Object> {
269 unsafe { Stack::from_ptr(ffi::X509_STORE_get1_objects(self.as_ptr())) }
270 }
271
272 #[corresponds(X509_STORE_get1_all_certs)]
274 #[cfg(ossl300)]
275 pub fn all_certificates(&self) -> Stack<X509> {
276 unsafe { Stack::from_ptr(ffi::X509_STORE_get1_all_certs(self.as_ptr())) }
277 }
278}
279
280cfg_if! {
281 if #[cfg(ossl110)] {
282 use ffi::X509_LOOKUP_meth_free;
283 } else {
284 #[allow(bad_style)]
285 unsafe fn X509_LOOKUP_meth_free(_x: *mut ffi::X509_LOOKUP_METHOD) {}
286 }
287}