Under Windows passing to CryptAcquireCertificatePrivateKey() a certificate retrieved from the key container using CryptGetKeyParam(KP_CERTIFICATE) + CertCreateCertificateContext() works although such a certificate doesn't have assigned properties at all. In order this to work Windows probably looks up an original certificate in the user's private store.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/crypt32/cert.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index e1c7c54340..02693b96d0 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -886,6 +886,7 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, PCRYPT_KEY_PROV_INFO info = NULL; CERT_KEY_CONTEXT keyContext; DWORD size; + PCCERT_CONTEXT cert_in_store = NULL;
TRACE("(%p, %08x, %p, %p, %p, %p)\n", pCert, dwFlags, pvReserved, phCryptProv, pdwKeySpec, pfCallerFreeProv); @@ -896,6 +897,34 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert,
ret = CertGetCertificateContextProperty(pCert, CERT_KEY_PROV_INFO_PROP_ID, 0, &size); + + if (!ret) + { + static const WCHAR myW[] = { 'M','y',0 }; + HCERTSTORE hstore; + + hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, + CERT_SYSTEM_STORE_CURRENT_USER, myW); + if (hstore) + { + cert_in_store = CertFindCertificateInStore(hstore, pCert->dwCertEncodingType, 0, + CERT_FIND_EXISTING, pCert, NULL); + if (cert_in_store) + { + ret = CertGetCertificateContextProperty(cert_in_store, CERT_KEY_PROV_INFO_PROP_ID, 0, &size); + if (ret) + pCert = cert_in_store; + else + { + CertFreeCertificateContext(cert_in_store); + cert_in_store = NULL; + } + } + + CertCloseStore(hstore, 0); + } + } + if (ret) { info = HeapAlloc(GetProcessHeap(), 0, size); @@ -949,6 +978,8 @@ BOOL WINAPI CryptAcquireCertificatePrivateKey(PCCERT_CONTEXT pCert, } } HeapFree(GetProcessHeap(), 0, info); + if (cert_in_store) + CertFreeCertificateContext(cert_in_store); return ret; }
On Wed, 2019-02-06 at 15:25 +0800, Dmitry Timoshkov wrote:
Under Windows passing to CryptAcquireCertificatePrivateKey() a certificate retrieved from the key container using (KP_CERTIFICATE) + CertCreateCertificateContext() works although such a certificate doesn't have assigned properties at all. In order this to work Windows probably looks up an original certificate in the user's private store.
Does the function fail if you remove the original certificate from the private store?
Hans Leidekker hans@codeweavers.com wrote:
On Wed, 2019-02-06 at 15:25 +0800, Dmitry Timoshkov wrote:
Under Windows passing to CryptAcquireCertificatePrivateKey() a certificate retrieved from the key container using (KP_CERTIFICATE) + CertCreateCertificateContext() works although such a certificate doesn't have assigned properties at all. In order this to work Windows probably looks up an original certificate in the user's private store.
Does the function fail if you remove the original certificate from the private store?
You mean under Windows? Yes, it starts to fail after that.