Using the windows-rs
crate, I'm trying to import an RSA key pair as a BCRYPT_RSAFULLPRIVATE_BLOB
following these instructions:
https://learn.microsoft.com/en-us/windows/win32/seccng/key-import-and-export
To import a persisted key:
- Create a persisted key by using the NCryptCreatePersistedKey function.
- Set any desired properties on the key object by using the NCryptSetProperty function.
- Set the import key BLOB as a property on the key, with the BLOB type as the property name.
- Finalize the persisted key import by using the NCryptFinalizeKey function.
I'm doing:
unsafe {
let mut h = NCRYPT_KEY_HANDLE(0);
NCryptCreatePersistedKey(
self.handle,
&mut h,
to_pcwstr(BCRYPT_RSA_ALGORITHM),
to_pcwstr(key_name),
CERT_KEY_SPEC(0),
if overwrite {
NCRYPT_OVERWRITE_KEY_FLAG
} else {
NCRYPT_FLAGS(0)
},
)?;
let prop_handle = NCRYPT_HANDLE(h.0);
println!("set export policy");
let value =
(NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG).to_be_bytes();
let value: *const u8 = addr_of!(value[0]);
NCryptSetProperty(
prop_handle,
to_pcwstr(NCRYPT_EXPORT_POLICY_PROPERTY),
value,
std::mem::size_of::<u32>() as u32,
NCRYPT_PERSIST_FLAG | NCRYPT_SILENT_FLAG,
)?;
println!("set blob prop");
NCryptSetProperty(
prop_handle,
to_pcwstr(BCRYPT_RSAFULLPRIVATE_BLOB),
to_import.as_ptr(), // to_import is a Vec<u8>, structured as https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_rsakey_blob
to_import.len() as u32,
NCRYPT_PERSIST_FLAG | NCRYPT_SILENT_FLAG,
)?;
println!("finalize key");
NCryptFinalizeKey(h, NCRYPT_SILENT_FLAG)?;
h
}
but I encounter a failure on the first call to NCryptSetProperty
with NTE_NOT_SUPPORTED
error code.
The storage used is StorageProviderType::Tpm
as StorageProviderType::Soft
doesn't work on my system for some reason (can't open it)
What am I missing? Can't we set NCRYPT_EXPORT_POLICY_PROPERTY
for a RSA key?