1#![deny(unexpected_cfgs)]
2
3pub type Error = anyhow::Error;
4
5#[macro_use]
6extern crate log;
7
8#[macro_use]
9mod helpers;
10pub(crate) use helpers::{concat_cstr, handleResult, log_target, named, str_to_cstr};
11
12pub(crate) mod adapters;
13pub(crate) mod forge;
14pub(crate) mod traits;
15
16mod init;
17mod query;
18pub(crate) mod random;
19
20pub(crate) mod asn_definitions;
21
22#[cfg(feature = "built_info")]
23pub mod built_info;
24
25#[cfg(test)]
26pub(crate) mod tests;
27
28use std::ffi::{CStr, CString};
29
30use bindings::dispatch_table_entry;
31use bindings::OSSL_PARAM;
32use bindings::{
33 OSSL_FUNC_provider_get_capabilities_fn, OSSL_FUNC_provider_get_params_fn,
34 OSSL_FUNC_provider_gettable_params_fn, OSSL_FUNC_provider_query_operation_fn,
35 OSSL_FUNC_provider_teardown_fn, OSSL_DISPATCH, OSSL_FUNC_PROVIDER_GETTABLE_PARAMS,
36 OSSL_FUNC_PROVIDER_GET_CAPABILITIES, OSSL_FUNC_PROVIDER_GET_PARAMS,
37 OSSL_FUNC_PROVIDER_QUERY_OPERATION, OSSL_FUNC_PROVIDER_TEARDOWN, OSSL_PROV_PARAM_BUILDINFO,
38 OSSL_PROV_PARAM_NAME, OSSL_PROV_PARAM_VERSION,
39};
40use forge::{bindings, osslparams, upcalls};
41use osslparams::{OSSLParam, OSSLParamData, Utf8PtrData, OSSL_PARAM_END};
42use upcalls::traits::{CoreUpcaller, CoreUpcallerWithCoreHandle};
43use upcalls::OSSL_CORE_HANDLE;
44pub use upcalls::{CoreDispatch, CoreDispatchWithCoreHandle};
45
46#[derive(Debug)]
56pub struct ProviderInstance<'a> {
57 core_handle: *const OSSL_CORE_HANDLE,
58 core_dispatch: CoreDispatch<'a>,
59 pub name: &'a str,
60 pub version: &'a str,
61 params: Vec<OSSLParam<'a>>,
62 param_array_ptr: Option<*mut [OSSL_PARAM]>,
63 pub(crate) adapters_ctx: adapters::FinalizedAdaptersHandle,
64}
65
66impl<'a> Drop for ProviderInstance<'a> {
70 #[named]
71 fn drop(&mut self) {
72 let tname = std::any::type_name_of_val(self);
73 let name = self.name;
74 trace!(
75 target: log_target!(),
76 "🗑️\tDropping {tname} named {name}",
77 )
78 }
79}
80
81pub static PROV_NAME: &str = "aurora";
83pub static PROV_VER: &str = env!("CARGO_PKG_VERSION");
84pub static PROV_BUILDINFO: &str = env!("CARGO_GIT_DESCRIBE");
85
86const PROPERTY_DEFINITION: &CStr =
87 concat_cstr!(c"provider=", str_to_cstr!(PROV_NAME), c",x.author=QUBIP");
88
89impl<'a> ProviderInstance<'a> {
90 #[named]
91 pub fn new(handle: *const OSSL_CORE_HANDLE, core_dispatch: CoreDispatch<'a>) -> Self {
92 trace!(target: log_target!(), "Called");
93
94 let upcaller: CoreDispatchWithCoreHandle<'a> = (core_dispatch, handle).into();
95
96 #[cfg(not(test))]
97 helpers::examine_core_parameters(&upcaller).expect("Error while examining core parameters");
98
99 let adapters_ctx = { adapters::FinalizedAdaptersHandle::new(&upcaller) };
100
101 let core_dispatch: CoreDispatch = upcaller.into();
102
103 Self {
104 core_handle: handle,
105 core_dispatch,
106 name: PROV_NAME,
107 version: PROV_VER,
108 param_array_ptr: None,
109 params: vec![
110 OSSLParam::Utf8Ptr(Utf8PtrData::new_null(OSSL_PROV_PARAM_NAME)),
111 OSSLParam::Utf8Ptr(Utf8PtrData::new_null(OSSL_PROV_PARAM_VERSION)),
112 OSSLParam::Utf8Ptr(Utf8PtrData::new_null(OSSL_PROV_PARAM_BUILDINFO)),
113 ],
114 adapters_ctx,
115 }
116 }
117
118 pub fn get_provider_dispatch(&mut self) -> *const OSSL_DISPATCH {
120 let ret = Box::new([
121 dispatch_table_entry!(
122 OSSL_FUNC_PROVIDER_TEARDOWN,
123 OSSL_FUNC_provider_teardown_fn,
124 crate::init::provider_teardown
125 ),
126 dispatch_table_entry!(
127 OSSL_FUNC_PROVIDER_GETTABLE_PARAMS,
128 OSSL_FUNC_provider_gettable_params_fn,
129 crate::init::gettable_params
130 ),
131 dispatch_table_entry!(
132 OSSL_FUNC_PROVIDER_GET_PARAMS,
133 OSSL_FUNC_provider_get_params_fn,
134 crate::init::get_params
135 ),
136 dispatch_table_entry!(
137 OSSL_FUNC_PROVIDER_QUERY_OPERATION,
138 OSSL_FUNC_provider_query_operation_fn,
139 crate::query::query_operation
140 ),
141 dispatch_table_entry!(
142 OSSL_FUNC_PROVIDER_GET_CAPABILITIES,
143 OSSL_FUNC_provider_get_capabilities_fn,
144 crate::query::get_capabilities
145 ),
146 OSSL_DISPATCH::END,
147 ]);
148 Box::into_raw(ret).cast()
149 }
150
151 fn get_params_array(&mut self) -> *const OSSL_PARAM {
152 let raw_ptr = match self.param_array_ptr {
154 Some(raw_ptr) => raw_ptr,
155 None => {
156 let slice = self
157 .params
158 .iter_mut()
159 .map(|p| unsafe { *p.get_c_struct() })
160 .chain(std::iter::once(OSSL_PARAM_END))
161 .collect::<Vec<_>>()
162 .into_boxed_slice();
163 let raw_ptr = Box::into_raw(slice);
164 self.param_array_ptr = Some(raw_ptr);
165 raw_ptr
166 }
167 };
168 raw_ptr.cast()
169 }
170
171 pub fn c_prov_name(&self) -> &CStr {
172 use std::sync::OnceLock;
173
174 static CELL: OnceLock<CString> = OnceLock::new();
175
176 let l = CELL.get_or_init(|| CString::new(self.name).expect("Error parsing self.name"));
177 l.as_ref()
178 }
179
180 pub fn c_prov_version(&self) -> &CStr {
181 use std::sync::OnceLock;
182
183 static CELL: OnceLock<CString> = OnceLock::new();
184
185 let l =
186 CELL.get_or_init(|| CString::new(self.version).expect("Error parsing self.version"));
187 l.as_ref()
188 }
189
190 pub fn c_prov_buildinfo(&self) -> &CStr {
191 use std::sync::OnceLock;
192
193 static CELL: OnceLock<CString> = OnceLock::new();
194
195 let l = CELL.get_or_init(|| {
196 CString::new(crate::PROV_BUILDINFO).expect("Error parsing cPROV_BUILDINFO")
197 });
198 l.as_ref()
199 }
200}
201
202impl<'a> TryFrom<*mut core::ffi::c_void> for &mut ProviderInstance<'a> {
203 type Error = Error;
204
205 #[named]
206 fn try_from(vctx: *mut core::ffi::c_void) -> Result<Self, Self::Error> {
207 trace!(target: log_target!(), "Called for {}",
208 "impl<'a> TryFrom<*mut core::ffi::c_void> for &mut ProviderInstance<'a>"
209 );
210 let provp = vctx as *mut ProviderInstance;
211 if provp.is_null() {
212 return Err(anyhow::anyhow!("vctx was null"));
213 }
214 Ok(unsafe { &mut *provp })
215 }
216}
217
218impl<'a> TryFrom<*mut core::ffi::c_void> for &ProviderInstance<'a> {
219 type Error = Error;
220
221 #[named]
222 fn try_from(vctx: *mut core::ffi::c_void) -> Result<Self, Self::Error> {
223 trace!(target: log_target!(), "Called for {}", "impl<'a> TryFrom<*mut core::ffi::c_void> for &ProviderInstance<'a>");
224 let r: &mut ProviderInstance<'a> = vctx.try_into()?;
225 Ok(r)
226 }
227}
228
229impl CoreUpcaller for ProviderInstance<'_> {
230 fn fn_from_core_dispatch(&self, id: u32) -> Option<unsafe extern "C" fn()> {
231 self.core_dispatch.fn_from_core_dispatch(id)
232 }
233}
234
235impl CoreUpcallerWithCoreHandle for ProviderInstance<'_> {
236 fn get_core_handle(&self) -> *const OSSL_CORE_HANDLE {
237 self.core_handle
238 }
239}