Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CertAddCertificateContextToStore CERT_STORE_ADD_REPLACE_EXISTING crashing CertGetCertificateContextProperty

313 views
Skip to first unread message

John S.

unread,
Sep 17, 2008, 4:03:41 PM9/17/08
to
I import a certificate and it's private key:

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.

John S.

unread,
Sep 17, 2008, 5:28:03 PM9/17/08
to
After trying to come up with a minimal sample, It looks like the
problem may not occur until the certificate is freed. The call to
CryptFindCertificateKeyProvInfo is returning TRUE that it found a
private key for the public-key-only certificate:

-----------------------------------------------------------------------------------------

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;
}

0 new messages