fn main() {
#[cfg(feature = "generate-bindings")]
{
generate::generate_bindings();
}
#[cfg(not(feature = "generate-bindings"))]
{
use std::str::FromStr;
use target_lexicon::{Architecture, OperatingSystem, Triple};
let target = Triple::from_str(&std::env::var("TARGET").unwrap())
.expect("Failed to parse target triple");
match (target.architecture, target.operating_system) {
(Architecture::Arm(_), OperatingSystem::Linux) => {}
(Architecture::Aarch64(_), OperatingSystem::Linux) => {}
(Architecture::X86_64, OperatingSystem::Linux) => {}
(Architecture::X86_32(_), OperatingSystem::Linux) => {}
(Architecture::Powerpc64, OperatingSystem::Linux) => {}
(Architecture::Powerpc64le, OperatingSystem::Linux) => {}
(Architecture::X86_64, OperatingSystem::Darwin) => {}
(Architecture::Aarch64(_), OperatingSystem::Darwin) => {}
(Architecture::X86_64, OperatingSystem::Windows) => {}
(Architecture::X86_64, OperatingSystem::Freebsd) => {}
(arch, os) => {
panic!("Compilation target (architecture, OS) tuple ({}, {}) is not part of the supported tuples. Please compile with the \"generate-bindings\" feature or add support for your platform :)", arch, os);
}
}
}
}
#[cfg(feature = "generate-bindings")]
mod generate {
use bindgen::callbacks;
#[derive(Debug)]
pub struct CargoCallbacks;
impl callbacks::ParseCallbacks for CargoCallbacks {
fn int_macro(&self, name: &str, _: i64) -> Option<callbacks::IntKind> {
let prefixes = [
("CK_", "CK_ULONG"),
("CKA_", "CK_ATTRIBUTE_TYPE"),
("CKC_", "CK_CERTIFICATE_TYPE"),
("CKD_", "CK_EC_KDF_TYPE"),
("CKF_", "CK_FLAGS"),
("CKG_MGF1_", "CK_RSA_PKCS_MGF_TYPE"),
("CKH_", "CK_HW_FEATURE_TYPE"),
("CKK_", "CK_KEY_TYPE"),
("CKM_", "CK_MECHANISM_TYPE"),
("CKN_", "CK_NOTIFICATION"),
("CKO_", "CK_OBJECT_CLASS"),
("CKP_", "CK_PROFILE_ID"),
("CKR_", "CK_RV"),
("CKS_", "CK_STATE"),
("CKU_", "CK_USER_TYPE"),
("CKZ_", "CK_RSA_PKCS_OAEP_SOURCE_TYPE"),
("CRYPTOKI_VERSION_", "CK_BYTE"),
];
if ["CK_TRUE", "CK_FALSE"].contains(&name) {
Some(callbacks::IntKind::Custom {
name: "CK_BBOOL",
is_signed: false,
})
} else {
let mut result = None;
for (prefix, variable) in &prefixes {
if name.starts_with(prefix) {
result = Some(callbacks::IntKind::Custom {
name: variable,
is_signed: false,
})
}
}
result
}
}
}
pub fn generate_bindings() {
let bindings = bindgen::Builder::default()
.header("pkcs11.h")
.dynamic_library_name("Pkcs11")
.allowlist_function("C_GetFunctionList")
.allowlist_type("*")
.allowlist_file("pkcs11.h")
.blocklist_type("max_align_t")
.derive_debug(true)
.derive_default(true)
.parse_callbacks(Box::new(CargoCallbacks))
.generate()
.expect("Unable to generate bindings");
let out_path = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("pkcs11_bindings.rs"))
.expect("Couldn't write bindings!");
}
}