cprocsp-sys 0.0.2

CryptoPRO bindings
Documentation
//
// Copyright © 2023, Oleg Lelenkov <o.lelenkov@gmail.com>
// License: Distributed under terms of the BSD 3-Clause license.
//

pub fn main() {
    build_bundled::main()
}

#[cfg(not(feature = "buildtime_bindgen"))]
mod build_bundled {
    use std::path::{Path, PathBuf};

    pub fn main() {
        let out_path = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
        println!(
            "cargo:rustc-env=BINDGEN_OUT_PATH={}",
            out_path.join("bindgen").to_str().unwrap()
        );
    }
}

#[cfg(feature = "buildtime_bindgen")]
mod build_bundled {
    use bindgen::CodegenConfig;
    use std::path::{Path, PathBuf};

    pub fn main() {
        let out_path = PathBuf::from(std::env::var("OUT_DIR").unwrap());
        println!(
            "cargo:rustc-env=BINDGEN_OUT_PATH={}",
            out_path.to_str().unwrap()
        );

        let target = std::env::var("CARGO_CFG_TARGET_ARCH").expect("Failed cargo target");
        let void_p = match target.as_str() {
            "x86" => 4,
            "x86_64" => 8,
            _ => panic!(),
        };
        println!("cargo:warning=SIZEOF_VOID_P={}", void_p);

        types_bindgen(&out_path, void_p);
        ssp_bindgen(&out_path, void_p);
        cades_bindgen(&out_path, void_p);
    }

    fn builder(void_p: u8) -> bindgen::Builder {
        bindgen::Builder::default()
            .clang_arg("-I/opt/cprocsp/include/pki")
            .clang_arg("-I/opt/cprocsp/include/cpcsp")
            .clang_arg("-DUNIX")
            .derive_default(true)
            .clang_arg(format!("-DSIZEOF_VOID_P={}", void_p))
            .allowlist_recursively(true)
            .blocklist_item("ULONG_PTR.*")
            .blocklist_item("LONG_PTR.*")
            .blocklist_item("INT_PTR.*")
            .blocklist_item("UINT_PTR.*")
            .parse_callbacks(Box::new(bindgen::CargoCallbacks))
    }

    fn types_bindgen(out_path: &Path, void_p: u8) {
        let bindings = builder(void_p)
            .header("src/ssp_wrapper.h")
            .header("src/cades_wrapper.h")
            .raw_line(
                r#"#[cfg(target_arch = "x86_64")]
pub type ULONG_PTR = ::std::os::raw::c_ulonglong;
#[cfg(target_arch = "x86")]
pub type ULONG_PTR = ::std::os::raw::c_ulong;"#,
            )
            .allowlist_type("HCRYPTPROV")
            .allowlist_type("DWORD")
            .allowlist_type("BOOL")
            .allowlist_type("LPCWSTR")
            .allowlist_type("LPCSTR")
            .allowlist_type("LPCVOID")
            .allowlist_type("LPTSTR")
            .allowlist_type("va_list")
            .allowlist_type("PCRYPT_DATA_BLOB")
            .allowlist_type("PCADES_VERIFICATION_INFO")
            .allowlist_type("PCADES_ENHANCE_MESSAGE_PARA")
            .allowlist_type("PCADES_VERIFY_MESSAGE_PARA")
            .allowlist_type("PCADES_SIGN_MESSAGE_PARA")
            .allowlist_type("PCRYPT_ALGORITHM_IDENTIFIER")
            .allowlist_type("HCRYPTHASH")
            .allowlist_type("HCRYPTKEY")
            .allowlist_type("ALG_ID")
            .allowlist_var("CRYPT_.*")
            .with_codegen_config(CodegenConfig::TYPES | CodegenConfig::VARS)
            .generate()
            .expect("Unable to generate types bindings");

        bindings
            .write_to_file(out_path.join("types_bindings.rs"))
            .expect("Counldn't write types bindings!");
    }

    fn ssp_bindgen(out_path: &Path, void_p: u8) {
        println!("cargo:rerun-if-changed=src/ssp_wrapper.h");

        let bindings = builder(void_p)
            .header("src/ssp_wrapper.h")
            .dynamic_library_name("SSP")
            .dynamic_link_require_all(true)
            .with_codegen_config(CodegenConfig::FUNCTIONS)
            .allowlist_function("GetLastError")
            .allowlist_function("CryptAcquireContextW")
            .allowlist_function("CryptReleaseContext")
            .allowlist_function("CryptGenKey")
            .allowlist_function("CryptDeriveKey")
            .allowlist_function("CryptDestroyKey")
            .allowlist_function("CryptSetKeyParam")
            .allowlist_function("CryptGetKeyParam")
            .allowlist_function("CryptSetHashParam")
            .allowlist_function("CryptGetHashParam")
            .allowlist_function("CryptSetProvParam")
            .allowlist_function("CryptGetProvParam")
            .allowlist_function("CryptGenRandom")
            .allowlist_function("CryptGetUserKey")
            .allowlist_function("CryptExportKey")
            .allowlist_function("CryptImportKey")
            .allowlist_function("CryptEncrypt")
            .allowlist_function("CryptDecrypt")
            .allowlist_function("CryptCreateHash")
            .allowlist_function("CryptHashData")
            .allowlist_function("CryptHashSessionKey")
            .allowlist_function("CryptDestroyHash")
            .allowlist_function("CryptSignHashA")
            .allowlist_function("CryptVerifySignatureA")
            .allowlist_function("CryptDuplicateKey")
            .allowlist_function("CryptDuplicateHash")
            .allowlist_function("RNetConvertPublicKeyInfo")
            .allowlist_function("RNetEncodePublicKeyAndParameters")
            .allowlist_function("CryptEnumProvidersA")
            .allowlist_function("CertOpenStore")
            .allowlist_function("CertCloseStore")
            .allowlist_function("CertFreeCertificateContext")
            .allowlist_function("CertEnumCertificatesInStore")
            .allowlist_function("CertGetCertificateContextProperty")
            .allowlist_function("CertEnumCertificateContextProperties")
            .generate()
            .expect("Unable to generate ssp bindings");

        bindings
            .write_to_file(out_path.join("ssp_bindings.rs"))
            .expect("Counldn't write ssp bindings!");
    }

    fn cades_bindgen(out_path: &Path, void_p: u8) {
        println!("cargo:rerun-if-changed=src/ssp_wrapper.h");

        let bindings = builder(void_p)
            .header("src/cades_wrapper.h")
            .dynamic_library_name("Cades")
            .dynamic_link_require_all(true)
            .with_codegen_config(CodegenConfig::FUNCTIONS)
            .allowlist_function("GetLastError")
            .allowlist_function("CadesSignMessage")
            .allowlist_function("CadesSignHash")
            .allowlist_function("CadesVerifyHash")
            .allowlist_function("CadesFormatMessage")
            .allowlist_function("CadesFreeVerificationInfo")
            .allowlist_function("CadesVerifyDetachedMessage")
            .allowlist_function("CadesEnhanceMessage")
            .allowlist_function("CadesFreeBlob")
            .generate()
            .expect("Unable to generate cades bindings");

        bindings
            .write_to_file(out_path.join("cades_bindings.rs"))
            .expect("Counldn't write cades bindings!");
    }
}