1use crate::error::ErrorStack;
44use crate::ffi;
45use crate::stack::StackRef;
46use crate::x509::verify::{X509VerifyFlags, X509VerifyParamRef};
47use crate::x509::{X509Object, X509Ref};
48use crate::{cvt, cvt_p};
49use foreign_types::{ForeignType, ForeignTypeRef};
50use openssl_macros::corresponds;
51use std::mem::ManuallyDrop;
52
53foreign_type_and_impl_send_sync! {
54 type CType = ffi::X509_STORE;
55 fn drop = ffi::X509_STORE_free;
56
57 pub struct X509StoreBuilder;
59}
60
61impl X509StoreBuilder {
62 pub fn new() -> Result<X509StoreBuilder, ErrorStack> {
66 unsafe {
67 ffi::init();
68
69 cvt_p(ffi::X509_STORE_new()).map(|p| X509StoreBuilder::from_ptr(p))
70 }
71 }
72
73 #[must_use]
75 pub fn build(self) -> X509Store {
76 X509Store(ManuallyDrop::new(self).0)
77 }
78}
79
80impl X509StoreBuilderRef {
81 #[corresponds(X509_STORE_add_cert)]
83 pub fn add_cert(&mut self, cert: impl AsRef<X509Ref>) -> Result<(), ErrorStack> {
84 let cert = cert.as_ref();
85 unsafe { cvt(ffi::X509_STORE_add_cert(self.as_ptr(), cert.as_ptr())) }
86 }
87
88 #[corresponds(X509_STORE_set_default_paths)]
94 pub fn set_default_paths(&mut self) -> Result<(), ErrorStack> {
95 unsafe { cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())) }
96 }
97
98 #[corresponds(X509_STORE_set_flags)]
100 pub fn try_set_flags(&mut self, flags: X509VerifyFlags) -> Result<(), ErrorStack> {
101 unsafe { cvt(ffi::X509_STORE_set_flags(self.as_ptr(), flags.bits())) }
102 }
103
104 #[corresponds(X509_STORE_set_flags)]
106 pub fn set_flags(&mut self, flags: X509VerifyFlags) {
107 self.try_set_flags(flags).expect("use try_set_flags");
108 }
109
110 #[corresponds(X509_STORE_get0_param)]
112 pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef {
113 unsafe { X509VerifyParamRef::from_ptr_mut(ffi::X509_STORE_get0_param(self.as_ptr())) }
114 }
115
116 #[corresponds(X509_STORE_set1_param)]
118 pub fn set_param(&mut self, param: &X509VerifyParamRef) -> Result<(), ErrorStack> {
119 unsafe { cvt(ffi::X509_STORE_set1_param(self.as_ptr(), param.as_ptr())) }
120 }
121
122 #[cfg(test)]
124 pub fn objects_len(&self) -> usize {
125 unsafe {
126 StackRef::<X509Object>::from_ptr(ffi::X509_STORE_get0_objects(self.as_ptr())).len()
127 }
128 }
129}
130
131foreign_type_and_impl_send_sync! {
132 type CType = ffi::X509_STORE;
133 fn drop = ffi::X509_STORE_free;
134
135 pub struct X509Store;
137}
138
139impl ToOwned for X509StoreRef {
140 type Owned = X509Store;
141
142 fn to_owned(&self) -> X509Store {
143 unsafe {
144 ffi::X509_STORE_up_ref(self.as_ptr());
145 X509Store::from_ptr(self.as_ptr())
146 }
147 }
148}
149
150impl Clone for X509Store {
151 fn clone(&self) -> X509Store {
152 (**self).to_owned()
153 }
154}
155
156impl X509StoreRef {
157 #[deprecated(
164 note = "This method is unsound https://github.com/sfackler/rust-openssl/issues/2096"
165 )]
166 #[corresponds(X509_STORE_get0_objects)]
167 #[must_use]
168 pub fn objects(&self) -> &StackRef<X509Object> {
169 unsafe { StackRef::from_ptr(ffi::X509_STORE_get0_objects(self.as_ptr())) }
170 }
171
172 #[cfg(test)]
174 #[allow(deprecated)]
175 #[must_use]
176 pub fn objects_len(&self) -> usize {
177 self.objects().len()
178 }
179}
180
181#[test]
182#[allow(clippy::redundant_clone)]
183#[should_panic = "Shared X509Store can't be mutated"]
184fn set_cert_store_pevents_mutability() {
185 use crate::ssl::*;
186
187 let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
188 let store = X509StoreBuilder::new().unwrap().build();
189
190 ctx.set_cert_store(store.clone());
191
192 let _aliased_store = ctx.cert_store_mut();
194}