[PATCH 5/5] crypt32: Always release the default provider (Valgrind).

Sven Baars sbaars at codeweavers.com
Fri Feb 18 14:56:16 CST 2022


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 at 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);
-- 
2.30.0.335.ge6362826a0




More information about the wine-devel mailing list