Signed-off-by: Sven Baars sbaars@codeweavers.com --- v2: Remove changes that crashed the tests.
dlls/crypt32/tests/cert.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index b96f94cc662..27685da1512 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -4318,6 +4318,7 @@ static void test_VerifySignature(void) BCryptDestroyHash(bhash); done: BCryptCloseAlgorithmProvider(alg, 0); + BCryptDestroyKey(bkey);
LocalFree(info); CertFreeCertificateContext(cert);
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/crypt32/cert.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 33811dfadc1..5fc76c9556f 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -214,7 +214,8 @@ static BOOL add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *ce { TRACE("found matching certificate, not adding\n"); SetLastError(CRYPT_E_EXISTS); - return FALSE; + ret = FALSE; + goto done; } break; case CERT_STORE_ADD_REPLACE_EXISTING: @@ -231,8 +232,7 @@ static BOOL add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *ce if (existing) { Context_CopyProperties(existing, cert); - if (ret_context) - *ret_context = CertDuplicateCertificateContext(existing); + *ret_context = existing; return TRUE; } break; @@ -241,7 +241,8 @@ static BOOL add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *ce { TRACE("existing certificate is newer, not adding\n"); SetLastError(CRYPT_E_EXISTS); - return FALSE; + ret = FALSE; + goto done; } break; case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES: @@ -251,7 +252,8 @@ static BOOL add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *ce { TRACE("existing certificate is newer, not adding\n"); SetLastError(CRYPT_E_EXISTS); - return FALSE; + ret = FALSE; + goto done; } inherit_props = TRUE; } @@ -262,13 +264,14 @@ static BOOL add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *ce if(!store) { if(ret_context) *ret_context = CertDuplicateCertificateContext(cert); - return TRUE; + ret = TRUE; + goto done; }
ret = store->vtbl->certs.addContext(store, context_from_ptr(cert), existing ? context_from_ptr(existing) : NULL, (ret_context || inherit_props) ? &new_context : NULL, use_link); if(!ret) - return FALSE; + goto done;
if(inherit_props) Context_CopyProperties(context_ptr(new_context), existing); @@ -278,7 +281,12 @@ static BOOL add_cert_to_store(WINECRYPT_CERTSTORE *store, const CERT_CONTEXT *ce else if(new_context) Context_Release(new_context);
+done: TRACE("returning %d\n", ret); + + if (existing) + CertFreeCertificateContext(existing); + return ret; }
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/crypt32/cert.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 5fc76c9556f..c651dd18512 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -2255,10 +2255,12 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, TRACE("(%08Ix, %d, %08lx, %p, %ld, %p, %p)\n", hCryptProv, Algid, dwFlags, pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash);
- if (!hCryptProv) - hCryptProv = I_CryptGetDefaultCryptProv(Algid); if (!Algid) Algid = CALG_SHA1; + + if (!hCryptProv) + hCryptProv = I_CryptGetDefaultCryptProv(Algid); + if (ret) { ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); @@ -2337,10 +2339,12 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, TRACE("(%08Ix, %d, %08lx, %ld, %p, %p, %p)\n", hCryptProv, Algid, dwFlags, dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash);
- if (!hCryptProv) - hCryptProv = I_CryptGetDefaultCryptProv(0); if (!Algid) Algid = CALG_MD5; + + if (!hCryptProv) + hCryptProv = I_CryptGetDefaultCryptProv(Algid); + if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING) { SetLastError(ERROR_FILE_NOT_FOUND); @@ -2389,8 +2393,6 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, PCCRYPT_OID_INFO oidInfo; HCRYPTHASH hHash;
- if (!hCryptProv) - hCryptProv = I_CryptGetDefaultCryptProv(0); oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, info->SignatureAlgorithm.pszObjId, 0); if (!oidInfo) @@ -2400,6 +2402,9 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, } else { + if (!hCryptProv) + hCryptProv = I_CryptGetDefaultCryptProv(oidInfo->u.Algid); + ret = CryptCreateHash(hCryptProv, oidInfo->u.Algid, 0, 0, &hHash); if (ret) { @@ -2439,7 +2444,8 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, if (info->dwGroupId == CRYPT_HASH_ALG_OID_GROUP_ID) { if (!hCryptProv) - hCryptProv = I_CryptGetDefaultCryptProv(0); + hCryptProv = I_CryptGetDefaultCryptProv(info->u.Algid); + ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash); if (ret) {
Signed-off-by: Sven Baars sbaars@codeweavers.com --- dlls/crypt32/cert.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index c651dd18512..687b60bac54 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -2249,7 +2249,7 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash) { - BOOL ret = TRUE; + BOOL ret; HCRYPTHASH hHash = 0;
TRACE("(%08Ix, %d, %08lx, %p, %ld, %p, %p)\n", hCryptProv, Algid, dwFlags, @@ -2261,17 +2261,14 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, if (!hCryptProv) hCryptProv = I_CryptGetDefaultCryptProv(Algid);
+ ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); if (ret) { - ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); + ret = CryptHashData(hHash, pbEncoded, cbEncoded, 0); if (ret) - { - ret = CryptHashData(hHash, pbEncoded, cbEncoded, 0); - if (ret) - ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash, - pcbComputedHash, 0); - CryptDestroyHash(hHash); - } + ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash, + pcbComputedHash, 0); + CryptDestroyHash(hHash); } return ret; } @@ -2333,8 +2330,10 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, BYTE *pbComputedHash, DWORD *pcbComputedHash) { - BOOL ret = TRUE; HCRYPTHASH hHash = 0; + DWORD size = 0; + BYTE *buf; + BOOL ret;
TRACE("(%08Ix, %d, %08lx, %ld, %p, %p, %p)\n", hCryptProv, Algid, dwFlags, dwCertEncodingType, pInfo, pbComputedHash, pcbComputedHash); @@ -2350,27 +2349,22 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; } + + ret = CRYPT_AsnEncodePubKeyInfoNoNull(dwCertEncodingType, + X509_PUBLIC_KEY_INFO, pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL, + (LPBYTE)&buf, &size); if (ret) { - BYTE *buf; - DWORD size = 0; - - ret = CRYPT_AsnEncodePubKeyInfoNoNull(dwCertEncodingType, - X509_PUBLIC_KEY_INFO, pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL, - (LPBYTE)&buf, &size); + ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); if (ret) { - ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); + ret = CryptHashData(hHash, buf, size, 0); if (ret) - { - ret = CryptHashData(hHash, buf, size, 0); - if (ret) - ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash, - pcbComputedHash, 0); - CryptDestroyHash(hHash); - } - LocalFree(buf); + ret = CryptGetHashParam(hHash, HP_HASHVAL, pbComputedHash, + pcbComputedHash, 0); + CryptDestroyHash(hHash); } + LocalFree(buf); } return ret; }
In case the default provider does not support an algorithm, other providers are iterated and a different provider is returned that should be released.
The default provider itself is also destroyed in DllMain if we always properly release it.
Signed-off-by: Sven Baars sbaars@codeweavers.com --- I'm not sure if this is useful in practice and if it's worth the bookkeeping.
dlls/crypt32/cert.c | 58 +++++++++++++++++++++++++++++++++------------ dlls/crypt32/msg.c | 8 +++---- 2 files changed, 47 insertions(+), 19 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c index 687b60bac54..584a47e9163 100644 --- a/dlls/crypt32/cert.c +++ b/dlls/crypt32/cert.c @@ -1395,11 +1395,15 @@ DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType, info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, pPublicKey->Algorithm.pszObjId, 0); if (info) { + HCRYPTPROV prov; HCRYPTKEY key;
TRACE("public key algid %#x (%s)\n", info->u.Algid, debugstr_a(pPublicKey->Algorithm.pszObjId));
- ret = CryptImportPublicKeyInfo(I_CryptGetDefaultCryptProv(info->u.Algid), dwCertEncodingType, pPublicKey, &key); + prov = I_CryptGetDefaultCryptProv(info->u.Algid); + ret = CryptImportPublicKeyInfo(prov, dwCertEncodingType, pPublicKey, &key); + CryptReleaseContext(prov, 0); + if (ret) { size = sizeof(len); @@ -2249,8 +2253,9 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash) { - BOOL ret; + HCRYPTPROV prov = hCryptProv; HCRYPTHASH hHash = 0; + BOOL ret;
TRACE("(%08Ix, %d, %08lx, %p, %ld, %p, %p)\n", hCryptProv, Algid, dwFlags, pbEncoded, cbEncoded, pbComputedHash, pcbComputedHash); @@ -2259,9 +2264,9 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, Algid = CALG_SHA1;
if (!hCryptProv) - hCryptProv = I_CryptGetDefaultCryptProv(Algid); + prov = I_CryptGetDefaultCryptProv(Algid);
- ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); + ret = CryptCreateHash(prov, Algid, 0, 0, &hHash); if (ret) { ret = CryptHashData(hHash, pbEncoded, cbEncoded, 0); @@ -2270,6 +2275,10 @@ BOOL WINAPI CryptHashCertificate(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, pcbComputedHash, 0); CryptDestroyHash(hHash); } + + if (!hCryptProv) + CryptReleaseContext(prov, 0); + return ret; }
@@ -2330,6 +2339,7 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, DWORD dwFlags, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, BYTE *pbComputedHash, DWORD *pcbComputedHash) { + HCRYPTPROV prov = hCryptProv; HCRYPTHASH hHash = 0; DWORD size = 0; BYTE *buf; @@ -2341,9 +2351,6 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, if (!Algid) Algid = CALG_MD5;
- if (!hCryptProv) - hCryptProv = I_CryptGetDefaultCryptProv(Algid); - if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING) { SetLastError(ERROR_FILE_NOT_FOUND); @@ -2355,7 +2362,10 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, (LPBYTE)&buf, &size); if (ret) { - ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); + if (!hCryptProv) + prov = I_CryptGetDefaultCryptProv(Algid); + + ret = CryptCreateHash(prov, Algid, 0, 0, &hHash); if (ret) { ret = CryptHashData(hHash, buf, size, 0); @@ -2365,6 +2375,9 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, CryptDestroyHash(hHash); } LocalFree(buf); + + if (!hCryptProv) + CryptReleaseContext(prov, 0); } return ret; } @@ -2373,6 +2386,7 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, const BYTE *pbEncoded, DWORD cbEncoded, BYTE *pbComputedHash, DWORD *pcbComputedHash) { + HCRYPTPROV prov = hCryptProv; BOOL ret; CERT_SIGNED_CONTENT_INFO *info; DWORD size; @@ -2397,9 +2411,9 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, else { if (!hCryptProv) - hCryptProv = I_CryptGetDefaultCryptProv(oidInfo->u.Algid); + prov = I_CryptGetDefaultCryptProv(oidInfo->u.Algid);
- ret = CryptCreateHash(hCryptProv, oidInfo->u.Algid, 0, 0, &hHash); + ret = CryptCreateHash(prov, oidInfo->u.Algid, 0, 0, &hHash); if (ret) { ret = CryptHashData(hHash, info->ToBeSigned.pbData, @@ -2409,6 +2423,9 @@ BOOL WINAPI CryptHashToBeSigned(HCRYPTPROV_LEGACY hCryptProv, pcbComputedHash, 0); CryptDestroyHash(hHash); } + + if (!hCryptProv) + CryptReleaseContext(prov, 0); } LocalFree(info); } @@ -2420,6 +2437,7 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, DWORD cbEncodedToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, const void *pvHashAuxInfo, BYTE *pbSignature, DWORD *pcbSignature) { + HCRYPTPROV prov = hCryptProv; BOOL ret; PCCRYPT_OID_INFO info; HCRYPTHASH hHash; @@ -2438,9 +2456,9 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, if (info->dwGroupId == CRYPT_HASH_ALG_OID_GROUP_ID) { if (!hCryptProv) - hCryptProv = I_CryptGetDefaultCryptProv(info->u.Algid); + prov = I_CryptGetDefaultCryptProv(info->u.Algid);
- ret = CryptCreateHash(hCryptProv, info->u.Algid, 0, 0, &hHash); + ret = CryptCreateHash(prov, info->u.Algid, 0, 0, &hHash); if (ret) { ret = CryptHashData(hHash, pbEncodedToBeSigned, @@ -2450,6 +2468,9 @@ BOOL WINAPI CryptSignCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv, pcbSignature, 0); CryptDestroyHash(hHash); } + + if (!hCryptProv) + CryptReleaseContext(prov, 0); } else { @@ -2552,6 +2573,7 @@ BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV_LEGACY hCryptProv, static BOOL CRYPT_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType, CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, const CRYPT_OID_INFO *info) { + HCRYPTPROV prov = hCryptProv; BOOL ret; HCRYPTKEY key; ALG_ID pubKeyID, hashID; @@ -2561,16 +2583,18 @@ static BOOL CRYPT_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEnco pubKeyID = *(ALG_ID *)info->ExtraInfo.pbData; else pubKeyID = hashID; + /* Load the default provider if necessary */ if (!hCryptProv) - hCryptProv = I_CryptGetDefaultCryptProv(hashID); - ret = CryptImportPublicKeyInfoEx(hCryptProv, dwCertEncodingType, + prov = I_CryptGetDefaultCryptProv(hashID); + + ret = CryptImportPublicKeyInfoEx(prov, dwCertEncodingType, pubKeyInfo, pubKeyID, 0, NULL, &key); if (ret) { HCRYPTHASH hash;
- ret = CryptCreateHash(hCryptProv, hashID, 0, 0, &hash); + ret = CryptCreateHash(prov, hashID, 0, 0, &hash); if (ret) { ret = CryptHashData(hash, signedCert->ToBeSigned.pbData, @@ -2582,6 +2606,10 @@ static BOOL CRYPT_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEnco } CryptDestroyKey(key); } + + if (!hCryptProv) + CryptReleaseContext(prov, 0); + return ret; }
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c index 6087f423f8c..d148252e05c 100644 --- a/dlls/crypt32/msg.c +++ b/dlls/crypt32/msg.c @@ -570,7 +570,7 @@ static HCRYPTMSG CHashEncodeMsg_Open(DWORD dwFlags, const void *pvMsgEncodeInfo, SetLastError(E_INVALIDARG); return NULL; } - dwFlags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG; + dwFlags |= CMSG_CRYPT_RELEASE_CONTEXT_FLAG; } msg = CryptMemAlloc(sizeof(CHashEncodeMsg)); if (msg) @@ -935,7 +935,7 @@ static BOOL CSignedMsgData_ConstructSignerHandles(CSignedMsgData *msg_data, { *crypt_prov = I_CryptGetDefaultCryptProv(algID); if (!*crypt_prov) return FALSE; - *flags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG; + *flags |= CMSG_CRYPT_RELEASE_CONTEXT_FLAG; }
ret = CryptCreateHash(*crypt_prov, algID, 0, 0, @@ -1975,7 +1975,7 @@ static HCRYPTMSG CEnvelopedEncodeMsg_Open(DWORD dwFlags, else { prov = I_CryptGetDefaultCryptProv(0); - dwFlags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG; + dwFlags |= CMSG_CRYPT_RELEASE_CONTEXT_FLAG; } msg = CryptMemAlloc(sizeof(CEnvelopedEncodeMsg)); if (msg) @@ -2352,7 +2352,7 @@ static BOOL CDecodeMsg_FinalizeHashedContent(CDecodeMsg *msg, { msg->crypt_prov = I_CryptGetDefaultCryptProv(algID); if (msg->crypt_prov) - msg->base.open_flags &= ~CMSG_CRYPT_RELEASE_CONTEXT_FLAG; + msg->base.open_flags |= CMSG_CRYPT_RELEASE_CONTEXT_FLAG; }
ret = CryptCreateHash(msg->crypt_prov, algID, 0, 0, &msg->u.hash);