#![allow(
dead_code,
unused_imports,
unused_qualifications,
unreachable_patterns,
unsafe_code,
let_underscore_drop
)]
use windows::core::PCWSTR;
use windows::Win32::Security::Cryptography::*;
pub const PLATFORM_PROVIDER: &str = "Microsoft Platform Crypto Provider";
#[derive(Debug)]
pub struct NcryptHandle(pub NCRYPT_HANDLE);
unsafe impl Send for NcryptHandle {}
unsafe impl Sync for NcryptHandle {}
impl NcryptHandle {
pub fn as_prov(&self) -> NCRYPT_PROV_HANDLE {
NCRYPT_PROV_HANDLE(self.0 .0)
}
pub fn as_key(&self) -> NCRYPT_KEY_HANDLE {
NCRYPT_KEY_HANDLE(self.0 .0)
}
}
impl Drop for NcryptHandle {
fn drop(&mut self) {
if self.0 .0 != 0 {
unsafe {
let _ = NCryptFreeObject(self.0);
}
}
}
}
pub fn open_provider() -> crate::internal::core::Result<NcryptHandle> {
let provider_name: Vec<u16> = PLATFORM_PROVIDER
.encode_utf16()
.chain(std::iter::once(0))
.collect();
let mut handle = NCRYPT_PROV_HANDLE::default();
unsafe {
NCryptOpenStorageProvider(&mut handle, PCWSTR(provider_name.as_ptr()), 0).map_err(|e| {
crate::internal::core::Error::KeyOperation {
operation: "open_provider".into(),
detail: e.to_string(),
}
})?;
}
Ok(NcryptHandle(NCRYPT_HANDLE(handle.0)))
}
pub fn is_available() -> bool {
open_provider().is_ok()
}