PFXImportCertStore( ... )
CertAddCertificateContextToStore( ... )
then I import the same certificate without it's private key on top of
it (same store, etc.):
PFXImportCertStore( ... )
CertAddCertificateContextToStore( CERT_STORE_ADD_REPLACE_EXISTING )
I need to know how to figure out later if a certificate has an
associated private key. The following doesn't work because the private
key can be sitting around, though not associated with the certificate
anymore:
CryptFindCertificateKeyProvInfo( ... )
And this doesn't work because it crashes on the second certificate
(where the public key only replaced the public & private key):
CertGetCertificateContextProperty( CERT_KEY_PROV_INFO_PROP_ID )
This is a problem for me because of the use of wildcard certificates,
which may need to be used for the device web server in some cases, and
also added as trusted roots for web services. Using
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES is a poor solution
because it means private keys will not go away when a certificate is
changed to only to be trusted, no longer used to encrypt
communications.
Right now I am moving towards deleting any existing certificate
manually prior to importing it into the store.
Thanks for your time.
-----------------------------------------------------------------------------------------
void import(_TCHAR* filename, PCCERT_CONTEXT* result)
{
HANDLE cf = CreateFile(filename, GENERIC_READ,
0, NULL, OPEN_EXISTING, 0, NULL);
if (cf != INVALID_HANDLE_VALUE)
{
DWORD len = GetFileSize(cf, NULL);
BYTE* cfData = new BYTE[len];
if (cfData)
{
ReadFile(cf, cfData, len, &len, NULL);
CRYPT_DATA_BLOB cdb = { len, cfData };
HCERTSTORE store = PFXImportCertStore(&cdb,
_T("SSLCertificateDemo"), CRYPT_USER_KEYSET | CRYPT_EXPORTABLE);
PCCERT_CONTEXT cert = CertEnumCertificatesInStore(store, NULL);
HCERTSTORE dest = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL,
CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_CURRENT_USER,
L"My");
CertAddCertificateContextToStore(dest, cert,
CERT_STORE_ADD_REPLACE_EXISTING, result);
CertFreeCertificateContext(cert);
CertCloseStore(store, 0);
CertCloseStore(dest, 0);
delete[] cfData;
}
CloseHandle(cf);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
CRYPT_KEY_PROV_INFO provInfo;
BYTE overflow[1024]; // don't do this
PCCERT_CONTEXT cert;
import(_T("\\output.pfx"), &cert);
CertFreeCertificateContext(cert);
//same cert; no private key
import(_T("\\outputPublic.pfx"), &cert);
BOOL keyResult = CryptFindCertificateKeyProvInfo(cert, 0, NULL);
DWORD pcbData = sizeof(overflow) / 2;
memset(&provInfo, NULL, sizeof(provInfo));
memset(overflow, NULL, sizeof(overflow));
SetLastError(0);
BOOL propResult = CertGetCertificateContextProperty(cert,
CERT_KEY_PROV_INFO_PROP_ID, &provInfo, &pcbData);
DWORD err = GetLastError();
CertFreeCertificateContext(cert);
return 0;
}