#![deny(unexpected_cfgs)]
pub type Error = anyhow::Error;
#[macro_use]
extern crate log;
#[macro_use]
mod helpers;
pub(crate) use helpers::{concat_cstr, handleResult, log_target, named};
pub(crate) mod adapters;
pub(crate) mod forge;
mod init;
mod query;
pub(crate) mod random;
pub(crate) mod asn_definitions;
#[cfg(test)]
pub(crate) mod tests;
use std::ffi::{CStr, CString};
use bindings::dispatch_table_entry;
use bindings::OSSL_PARAM;
use bindings::{
OSSL_FUNC_provider_get_capabilities_fn, OSSL_FUNC_provider_get_params_fn,
OSSL_FUNC_provider_gettable_params_fn, OSSL_FUNC_provider_query_operation_fn,
OSSL_FUNC_provider_teardown_fn, OSSL_DISPATCH, OSSL_FUNC_PROVIDER_GETTABLE_PARAMS,
OSSL_FUNC_PROVIDER_GET_CAPABILITIES, OSSL_FUNC_PROVIDER_GET_PARAMS,
OSSL_FUNC_PROVIDER_QUERY_OPERATION, OSSL_FUNC_PROVIDER_TEARDOWN, OSSL_PROV_PARAM_BUILDINFO,
OSSL_PROV_PARAM_NAME, OSSL_PROV_PARAM_VERSION,
};
use forge::{bindings, osslparams, upcalls};
use osslparams::{OSSLParam, OSSLParamData, Utf8PtrData, OSSL_PARAM_END};
use upcalls::traits::{CoreUpcaller, CoreUpcallerWithCoreHandle};
use upcalls::OSSL_CORE_HANDLE;
pub use upcalls::{CoreDispatch, CoreDispatchWithCoreHandle};
#[derive(Debug)]
pub struct ProviderInstance<'a> {
core_handle: *const OSSL_CORE_HANDLE,
core_dispatch: CoreDispatch<'a>,
pub name: &'a str,
pub version: &'a str,
params: Vec<OSSLParam<'a>>,
param_array_ptr: Option<*mut [OSSL_PARAM]>,
pub(crate) adapters_ctx: adapters::FinalizedAdaptersHandle,
}
impl<'a> Drop for ProviderInstance<'a> {
#[named]
fn drop(&mut self) {
let tname = std::any::type_name_of_val(self);
let name = self.name;
trace!(
target: log_target!(),
"🗑️\tDropping {tname} named {name}",
)
}
}
pub static PROV_NAME: &str = env!("CARGO_PKG_NAME");
pub static PROV_VER: &str = env!("CARGO_PKG_VERSION");
pub static PROV_BUILDINFO: &str = env!("CARGO_GIT_DESCRIBE");
const PROPERTY_DEFINITION: &CStr = c"provider=aurora,x.author=QUBIP";
impl<'a> ProviderInstance<'a> {
#[named]
pub fn new(handle: *const OSSL_CORE_HANDLE, core_dispatch: CoreDispatch<'a>) -> Self {
trace!(target: log_target!(), "Called");
let upcaller: CoreDispatchWithCoreHandle<'a> = (core_dispatch, handle).into();
#[cfg(not(test))]
helpers::examine_core_parameters(&upcaller).expect("Error while examining core parameters");
let adapters_ctx = { adapters::FinalizedAdaptersHandle::new(&upcaller) };
let core_dispatch: CoreDispatch = upcaller.into();
Self {
core_handle: handle,
core_dispatch,
name: PROV_NAME,
version: PROV_VER,
param_array_ptr: None,
params: vec![
OSSLParam::Utf8Ptr(Utf8PtrData::new_null(OSSL_PROV_PARAM_NAME)),
OSSLParam::Utf8Ptr(Utf8PtrData::new_null(OSSL_PROV_PARAM_VERSION)),
OSSLParam::Utf8Ptr(Utf8PtrData::new_null(OSSL_PROV_PARAM_BUILDINFO)),
],
adapters_ctx,
}
}
pub fn get_provider_dispatch(&mut self) -> *const OSSL_DISPATCH {
let ret = Box::new([
dispatch_table_entry!(
OSSL_FUNC_PROVIDER_TEARDOWN,
OSSL_FUNC_provider_teardown_fn,
crate::init::provider_teardown
),
dispatch_table_entry!(
OSSL_FUNC_PROVIDER_GETTABLE_PARAMS,
OSSL_FUNC_provider_gettable_params_fn,
crate::init::gettable_params
),
dispatch_table_entry!(
OSSL_FUNC_PROVIDER_GET_PARAMS,
OSSL_FUNC_provider_get_params_fn,
crate::init::get_params
),
dispatch_table_entry!(
OSSL_FUNC_PROVIDER_QUERY_OPERATION,
OSSL_FUNC_provider_query_operation_fn,
crate::query::query_operation
),
dispatch_table_entry!(
OSSL_FUNC_PROVIDER_GET_CAPABILITIES,
OSSL_FUNC_provider_get_capabilities_fn,
crate::query::get_capabilities
),
OSSL_DISPATCH::END,
]);
Box::into_raw(ret).cast()
}
fn get_params_array(&mut self) -> *const OSSL_PARAM {
let raw_ptr = match self.param_array_ptr {
Some(raw_ptr) => raw_ptr,
None => {
let slice = self
.params
.iter_mut()
.map(|p| unsafe { *p.get_c_struct() })
.chain(std::iter::once(OSSL_PARAM_END))
.collect::<Vec<_>>()
.into_boxed_slice();
let raw_ptr = Box::into_raw(slice);
self.param_array_ptr = Some(raw_ptr);
raw_ptr
}
};
raw_ptr.cast()
}
pub fn c_prov_name(&self) -> &CStr {
use std::sync::OnceLock;
static CELL: OnceLock<CString> = OnceLock::new();
let l = CELL.get_or_init(|| CString::new(self.name).expect("Error parsing self.name"));
l.as_ref()
}
pub fn c_prov_version(&self) -> &CStr {
use std::sync::OnceLock;
static CELL: OnceLock<CString> = OnceLock::new();
let l =
CELL.get_or_init(|| CString::new(self.version).expect("Error parsing self.version"));
l.as_ref()
}
pub fn c_prov_buildinfo(&self) -> &CStr {
use std::sync::OnceLock;
static CELL: OnceLock<CString> = OnceLock::new();
let l = CELL.get_or_init(|| {
CString::new(crate::PROV_BUILDINFO).expect("Error parsing cPROV_BUILDINFO")
});
l.as_ref()
}
}
impl<'a> TryFrom<*mut core::ffi::c_void> for &mut ProviderInstance<'a> {
type Error = Error;
#[named]
fn try_from(vctx: *mut core::ffi::c_void) -> Result<Self, Self::Error> {
trace!(target: log_target!(), "Called for {}",
"impl<'a> TryFrom<*mut core::ffi::c_void> for &mut ProviderInstance<'a>"
);
let provp = vctx as *mut ProviderInstance;
if provp.is_null() {
return Err(anyhow::anyhow!("vctx was null"));
}
Ok(unsafe { &mut *provp })
}
}
impl<'a> TryFrom<*mut core::ffi::c_void> for &ProviderInstance<'a> {
type Error = Error;
#[named]
fn try_from(vctx: *mut core::ffi::c_void) -> Result<Self, Self::Error> {
trace!(target: log_target!(), "Called for {}", "impl<'a> TryFrom<*mut core::ffi::c_void> for &ProviderInstance<'a>");
let r: &mut ProviderInstance<'a> = vctx.try_into()?;
Ok(r)
}
}
impl CoreUpcaller for ProviderInstance<'_> {
fn fn_from_core_dispatch(&self, id: u32) -> Option<unsafe extern "C" fn()> {
self.core_dispatch.fn_from_core_dispatch(id)
}
}
impl CoreUpcallerWithCoreHandle for ProviderInstance<'_> {
fn get_core_handle(&self) -> *const OSSL_CORE_HANDLE {
self.core_handle
}
}
pub mod traits {
pub use super::upcalls::traits::{CoreUpcaller, CoreUpcallerWithCoreHandle};
}