1#![deny(unexpected_cfgs)]
2
3#[macro_use]
4extern crate log;
5
6pub(crate) use ::function_name::named;
7use std::ffi::{CStr, CString};
8use std::sync::LazyLock;
9
10pub type Error = anyhow::Error;
11
12macro_rules! function_path {
13 () => {
14 concat!(module_path!(), "::", function_name!(), "()")
15 };
16}
17
18macro_rules! log_target {
19 () => {
20 function_path!()
21 };
22}
23
24pub(crate) mod adapters;
25pub(crate) mod forge;
26mod init;
27mod query;
28pub(crate) mod random;
29
30pub(crate) mod asn_definitions;
31
32#[cfg(test)]
33pub(crate) mod tests;
34
35use bindings::dispatch_table_entry;
36use bindings::OSSL_PARAM;
37use bindings::{
38 OSSL_FUNC_provider_get_capabilities_fn, OSSL_FUNC_provider_get_params_fn,
39 OSSL_FUNC_provider_gettable_params_fn, OSSL_FUNC_provider_query_operation_fn,
40 OSSL_FUNC_provider_teardown_fn, OSSL_DISPATCH, OSSL_FUNC_PROVIDER_GETTABLE_PARAMS,
41 OSSL_FUNC_PROVIDER_GET_CAPABILITIES, OSSL_FUNC_PROVIDER_GET_PARAMS,
42 OSSL_FUNC_PROVIDER_QUERY_OPERATION, OSSL_FUNC_PROVIDER_TEARDOWN, OSSL_PROV_PARAM_BUILDINFO,
43 OSSL_PROV_PARAM_NAME, OSSL_PROV_PARAM_VERSION,
44};
45use forge::{bindings, osslparams, upcalls};
46use osslparams::{OSSLParam, OSSLParamData, Utf8PtrData, OSSL_PARAM_END};
47use upcalls::traits::{CoreUpcaller, CoreUpcallerWithCoreHandle};
48use upcalls::OSSL_CORE_HANDLE;
49pub use upcalls::{CoreDispatch, CoreDispatchWithCoreHandle};
50
51#[derive(Debug)]
61pub struct ProviderInstance<'a> {
62 pub data: [u8; 10],
63 core_handle: *const OSSL_CORE_HANDLE,
64 core_dispatch: CoreDispatch<'a>,
65 pub name: &'a str,
66 pub version: &'a str,
67 params: Vec<OSSLParam<'a>>,
68 param_array_ptr: Option<*mut [OSSL_PARAM]>,
69 pub(crate) adapters_ctx: adapters::FinalizedAdaptersHandle,
70}
71
72impl<'a> Drop for ProviderInstance<'a> {
76 #[named]
77 fn drop(&mut self) {
78 let tname = std::any::type_name_of_val(self);
79 let name = self.name;
80 trace!(
81 target: log_target!(),
82 "🗑️\tDropping {tname} named {name}",
83 )
84 }
85}
86
87pub static PROV_NAME: &str = env!("CARGO_PKG_NAME");
88pub static PROV_VER: &str = env!("CARGO_PKG_VERSION");
89pub static PROV_BUILDINFO: &str = env!("CARGO_GIT_DESCRIBE");
90
91impl<'a> ProviderInstance<'a> {
92 pub fn new(handle: *const OSSL_CORE_HANDLE, core_dispatch: CoreDispatch<'a>) -> Self {
93 let upcaller: CoreDispatchWithCoreHandle<'a> = (core_dispatch, handle).into();
94
95 let adapters_ctx = { adapters::FinalizedAdaptersHandle::new(&upcaller) };
96
97 let core_dispatch: CoreDispatch = upcaller.into();
98
99 Self {
100 data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0],
101 core_handle: handle,
102 core_dispatch,
103 name: PROV_NAME,
104 version: PROV_VER,
105 param_array_ptr: None,
106 params: vec![
107 OSSLParam::Utf8Ptr(Utf8PtrData::new_null(OSSL_PROV_PARAM_NAME)),
108 OSSLParam::Utf8Ptr(Utf8PtrData::new_null(OSSL_PROV_PARAM_VERSION)),
109 OSSLParam::Utf8Ptr(Utf8PtrData::new_null(OSSL_PROV_PARAM_BUILDINFO)),
110 ],
111 adapters_ctx,
112 }
113 }
114
115 pub fn get_provider_dispatch(&mut self) -> *const OSSL_DISPATCH {
117 let ret = Box::new([
118 dispatch_table_entry!(
119 OSSL_FUNC_PROVIDER_TEARDOWN,
120 OSSL_FUNC_provider_teardown_fn,
121 crate::init::provider_teardown
122 ),
123 dispatch_table_entry!(
124 OSSL_FUNC_PROVIDER_GETTABLE_PARAMS,
125 OSSL_FUNC_provider_gettable_params_fn,
126 crate::init::gettable_params
127 ),
128 dispatch_table_entry!(
129 OSSL_FUNC_PROVIDER_GET_PARAMS,
130 OSSL_FUNC_provider_get_params_fn,
131 crate::init::get_params
132 ),
133 dispatch_table_entry!(
134 OSSL_FUNC_PROVIDER_QUERY_OPERATION,
135 OSSL_FUNC_provider_query_operation_fn,
136 crate::query::query_operation
137 ),
138 dispatch_table_entry!(
139 OSSL_FUNC_PROVIDER_GET_CAPABILITIES,
140 OSSL_FUNC_provider_get_capabilities_fn,
141 crate::query::get_capabilities
142 ),
143 OSSL_DISPATCH::END,
144 ]);
145 Box::into_raw(ret).cast()
146 }
147
148 fn get_params_array(&mut self) -> *const OSSL_PARAM {
149 let raw_ptr = match self.param_array_ptr {
151 Some(raw_ptr) => raw_ptr,
152 None => {
153 let slice = self
154 .params
155 .iter_mut()
156 .map(|p| unsafe { *p.get_c_struct() })
157 .chain(std::iter::once(OSSL_PARAM_END))
158 .collect::<Vec<_>>()
159 .into_boxed_slice();
160 let raw_ptr = Box::into_raw(slice);
161 self.param_array_ptr = Some(raw_ptr);
162 raw_ptr
163 }
164 };
165 raw_ptr.cast()
166 }
167
168 pub fn c_prov_name(&self) -> &CStr {
169 #[expect(clippy::let_and_return)]
170 static L: LazyLock<CString> = LazyLock::new(|| {
171 let _s = CString::new(crate::PROV_NAME).expect("Error parsing cPROV_NAME");
172 _s
173 });
174 L.as_ref()
175 }
176
177 pub fn c_prov_version(&self) -> &CStr {
178 #[expect(clippy::let_and_return)]
179 static L: LazyLock<CString> = LazyLock::new(|| {
180 let _s = CString::new(crate::PROV_VER).expect("Error parsing cPROV_VER");
181 _s
182 });
183 L.as_ref()
184 }
185
186 pub fn c_prov_buildinfo(&self) -> &CStr {
187 #[expect(clippy::let_and_return)]
188 static L: LazyLock<CString> = LazyLock::new(|| {
189 let _s = CString::new(crate::PROV_BUILDINFO).expect("Error parsing cPROV_BUILDINFO");
190 _s
191 });
192 L.as_ref()
193 }
194}
195
196impl<'a> TryFrom<*mut core::ffi::c_void> for &mut ProviderInstance<'a> {
197 type Error = Error;
198
199 #[named]
200 fn try_from(vctx: *mut core::ffi::c_void) -> Result<Self, Self::Error> {
201 trace!(target: log_target!(), "Called for {}",
202 "impl<'a> TryFrom<*mut core::ffi::c_void> for &mut ProviderInstance<'a>"
203 );
204 let provp = vctx as *mut ProviderInstance;
205 if provp.is_null() {
206 return Err(anyhow::anyhow!("vctx was null"));
207 }
208 Ok(unsafe { &mut *provp })
209 }
210}
211
212impl<'a> TryFrom<*mut core::ffi::c_void> for &ProviderInstance<'a> {
213 type Error = Error;
214
215 #[named]
216 fn try_from(vctx: *mut core::ffi::c_void) -> Result<Self, Self::Error> {
217 trace!(target: log_target!(), "Called for {}", "impl<'a> TryFrom<*mut core::ffi::c_void> for &ProviderInstance<'a>");
218 let r: &mut ProviderInstance<'a> = vctx.try_into()?;
219 Ok(r)
220 }
221}
222
223#[macro_export]
237macro_rules! handleResult {
238 ($e:expr) => { match ($e)
239 {
240 Ok(r) => r,
241 Err(e) => {
242 error!(target: log_target!(), "{:#?}", e);
243 return ERROR_RET;
244 }
245 }
246 };
247 }
256
257impl CoreUpcaller for ProviderInstance<'_> {
258 fn fn_from_core_dispatch(&self, id: u32) -> Option<unsafe extern "C" fn()> {
259 self.core_dispatch.fn_from_core_dispatch(id)
260 }
261}
262
263impl CoreUpcallerWithCoreHandle for ProviderInstance<'_> {
264 fn get_core_handle(&self) -> *const OSSL_CORE_HANDLE {
265 self.core_handle
266 }
267}
268
269pub mod traits {
270 pub use super::upcalls::traits::{CoreUpcaller, CoreUpcallerWithCoreHandle};
271}