I create a PKCS#10 CSR with certreq
and have set the option Exportable=TRUE
. This successfully creates a key under the location REQUEST
. I also have a valid certificate with key in MY
. If I try to access any one of them the CryptoAPI reports error code 0x80090016
.
Running under different access rights could not solve this problem so far.
My goal is to get both the keys in MY
and REQUEST
. If I call CryptAcquireContextA()
on any of those, it fails.
Windows 7 x64
My complete code looks like this:
hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE, "REQUEST");
pCert = CertFindCertificateInStore(hStore, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_A, "CERTIFICATE_SUBJECT", NULL);
CertGetCertificateContextProperty(pCert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len);
pinfo = (CRYPT_KEY_PROV_INFO *) malloc(len);
CertGetCertificateContextProperty(pCert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len);
provname = wide_to_asc(pinfo->pwszProvName);
contname = wide_to_asc(pinfo->pwszContainerName);
if(!CryptAcquireContextA(&hCryptProv, contname, provname, pinfo->dwProvType, 0)) {
err = GetLastError();
fprintf(stderr, "Error: 0x%x\n", err);
}
CryptGetUserKey(hCryptProv, pinfo->dwKeySpec, &hUserkey);
This code is mostly copied from the OpenSSL capi engine. Since the engine failed, I created the smallest possible code to search the error.
If I run this, it fails with the output Error: 0x80090016
. This means one of three things according to Microsoft:
Local Computer
After some googling, I tried to change permissions on the file system. I found the files by looking at the contname
variable of my code and searching for the file. I changed permissions on them (more accurate, I changed permissions on the parent folder). While this fixed the issue for MY
, it seems I cannot change it for REQUEST
.
One note here is that my container for MY
seems to be here:
%APPDATA%\Microsoft\Crypto\RSA\S-1-5-21-1650336054-1974872081-316617838-545102
For REQUEST
I found it under a different address:
%ALLUSERSPROFILE%\Microsoft\Crypto\RSA\MachineKeys
I am not sure on the workings here so I cannot explain why it would put them in different locations (one being user centric, the other one a system folder). The MY
store was created with a regular administrator prompt and the command certreq -new inf_file.inf cert-csr.csr
and after I received my certificate, I issued certreq -accept cert.pem
. Then I created a new csr with the same command.
I tried to execute my program with the following privileges:
whoami
output)To recieve a service prompt, I executed psexec.exe –ids cmd.exe
according to a tip from MaaSters Center
Any help or guidance on how to further narrow this problem down will be greatly appreciated.
I was finally able to solve this problem and it is a lot simpler than I thought. I was sure that I would receive an unambiguous container name and don't need to be more specific but CryptAcquireContext
actually requires me to pass a flag CRYPT_MACHINE_KEYSET
.
So my function call has to look like this:
CryptAcquireContextA(&hCryptProv, contname, provname, pinfo->dwProvType, CRYPT_MACHINE_KEYSET)
Unfortunately this is not supported by the OpenSSL engine, so you would have to alter it yourself in the engine.
See MSDN: "A key container created without this flag by a user that is not an administrator can be accessed only by the user creating the key container and the local system account."
Complete details here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379886(v=vs.85).aspx
User contributions licensed under CC BY-SA 3.0