use puffin::put_registry::PutRegistry;
use crate::protocol::TLSProtocolBehavior;
pub mod bindings {
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
use security_claims::Claim;
include!(env!("RUST_BINDINGS_FILE"));
}
pub mod registration {
use std::sync::Mutex;
use once_cell::sync::Lazy;
use puffin::put_registry::Factory;
use crate::protocol::TLSProtocolBehavior;
pub fn all() -> Vec<Box<dyn Factory<TLSProtocolBehavior>>> {
PUTS.lock()
.unwrap()
.iter()
.map(|p| match p {
#[cfg(feature = "rust-put")]
GlobalFactory::RustFactory(f) => (*f).clone_factory(),
GlobalFactory::CFactory(f) => (*f).clone_factory(),
})
.collect()
}
#[allow(unused)]
macro_rules! registration_rust {
(
$id:ident, $name:expr, $harness_version:expr, $library_version:expr, $capabilities:expr
) => {
mod $id {
use super::GlobalFactory;
use crate::rust_put::RustFactory;
pub fn register() -> Option<GlobalFactory> {
crate::rust_put::rand::rng_init();
crate::rust_put::rand::rng_reseed();
Some(GlobalFactory::RustFactory(RustFactory::new(
$name,
$harness_version,
$library_version,
)))
}
}
};
}
#[allow(unused)]
macro_rules! registration_c {
(
$id:ident, $name:expr, $harness_version:expr, $library_version:expr, $capabilities:expr
) => {
mod $id {
use super::GlobalFactory;
use crate::put_registry::bindings::TLS_PUT_INTERFACE;
pub fn register() -> Option<GlobalFactory> {
let interface_ptr = unsafe { $id() };
if interface_ptr.is_null() {
log::error!("PUT registration failed: {} interface is NULL", &$name);
return None;
}
let interface = unsafe { *interface_ptr.clone() };
Some(GlobalFactory::CFactory(crate::put::CPut::new(
$name,
$harness_version,
$library_version,
$capabilities,
interface,
)))
}
extern "C" {
fn $id() -> *const TLS_PUT_INTERFACE;
}
}
};
}
enum GlobalFactory {
#[cfg(feature = "rust-put")]
RustFactory(crate::rust_put::RustFactory),
#[allow(dead_code)]
CFactory(crate::put::CPut),
}
static PUTS: Lazy<Mutex<Vec<GlobalFactory>>> = Lazy::new(|| Mutex::new(register()));
include!(env!("RUST_PUTS_BUNDLE_FILE"));
}
pub use registration::for_puts;
pub fn tls_registry() -> PutRegistry<TLSProtocolBehavior> {
let puts: Vec<_> = registration::all()
.into_iter()
.chain(std::iter::once(crate::tcp::new_tcp_factory()))
.map(|f| (f.name(), f))
.collect();
let default = puts.first().unwrap().0.clone();
PutRegistry::new(puts, default)
}
#[cfg(not(feature = "cputs"))]
#[cfg(test)]
mod tests {
use super::*;
#[test_log::test]
fn version_test() {
let registry = tls_registry();
let versions = registry.default().versions();
println!("Default tls PUT components:");
for (component, version) in versions.iter() {
println!(" {}: {}", component, version);
}
#[allow(unused_variables)]
let version = versions
.iter()
.find(|(c, _)| c == "library")
.map(|(_, v)| v);
#[cfg(feature = "openssl101f")]
assert!(version.expect("missing version string").contains("1.0.1f"));
#[cfg(feature = "openssl102u")]
assert!(version.expect("missing version string").contains("1.0.2u"));
#[cfg(feature = "openssl111k")]
assert!(version.expect("missing version string").contains("1.1.1k"));
#[cfg(feature = "openssl111j")]
assert!(version.expect("missing version string").contains("1.1.1j"));
#[cfg(feature = "openssl111u")]
assert!(version.expect("missing version string").contains("1.1.1u"));
#[cfg(feature = "openssl312")]
assert!(version.expect("missing version string").contains("3.1.2"));
#[cfg(feature = "wolfssl510")]
assert!(version.expect("missing version string").contains("5.1.0"));
#[cfg(feature = "wolfssl520")]
assert!(version.expect("missing version string").contains("5.2.0"));
#[cfg(feature = "wolfssl530")]
assert!(version.expect("missing version string").contains("5.3.0"));
#[cfg(feature = "wolfssl540")]
assert!(version.expect("missing version string").contains("5.4.0"));
#[cfg(feature = "wolfssl430")]
assert!(version.expect("missing version string").contains("4.3.0"));
}
}