crypt32(14/20): Separate signer handles from signer info to avoid unnecessary memory allocation

Juan Lang juan.lang at gmail.com
Mon Jul 23 20:31:34 CDT 2007


--Juan
-------------- next part --------------
From befb3864fad1079a1424ac3be2b80c87a6228065 Mon Sep 17 00:00:00 2001
From: Juan Lang <juanlang at juan.corp.google.com>
Date: Mon, 23 Jul 2007 18:12:47 -0700
Subject: [PATCH] Separate signer handles from signer info to avoid unnecessary memory allocation
---
 dlls/crypt32/msg.c |  153 ++++++++++++++++++++++++++++------------------------
 1 files changed, 81 insertions(+), 72 deletions(-)

diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c
index 1fcf980..bcea3c2 100644
--- a/dlls/crypt32/msg.c
+++ b/dlls/crypt32/msg.c
@@ -601,13 +601,12 @@ static BOOL CRYPT_IsValidSigner(CMSG_SIG
     return TRUE;
 }
 
-typedef struct _CSignerInfo
+typedef struct _CSignerHandles
 {
     HCRYPTPROV       prov;
     HCRYPTHASH       hash;
     HCRYPTKEY        key;
-    CMSG_SIGNER_INFO info;
-} CSignerInfo;
+} CSignerHandles;
 
 static BOOL CRYPT_CopyBlob(CRYPT_DATA_BLOB *out, const CRYPT_DATA_BLOB *in)
 {
@@ -699,81 +698,82 @@ static BOOL CRYPT_CopyAttributes(CRYPT_A
     return ret;
 }
 
-static BOOL CSignerInfo_Construct(CSignerInfo *out,
- CMSG_SIGNER_ENCODE_INFO_WITH_CMS *in, DWORD open_flags)
+/* Constructs both a CSignerHandles and a CMSG_SIGNER_INFO from a
+ * CMSG_SIGNER_ENCODE_INFO_WITH_CMS.
+ */
+static BOOL CSignerInfo_Construct(CSignerHandles *handles,
+ CMSG_SIGNER_INFO *info, CMSG_SIGNER_ENCODE_INFO_WITH_CMS *in, DWORD open_flags)
 {
     ALG_ID algID;
     BOOL ret;
 
-    out->prov = in->hCryptProv;
+    handles->prov = in->hCryptProv;
     if (!(open_flags & CMSG_CRYPT_RELEASE_CONTEXT_FLAG))
-        CryptContextAddRef(out->prov, NULL, 0);
+        CryptContextAddRef(handles->prov, NULL, 0);
     algID = CertOIDToAlgId(in->HashAlgorithm.pszObjId);
-    ret = CryptCreateHash(out->prov, algID, 0, 0, &out->hash);
+    ret = CryptCreateHash(handles->prov, algID, 0, 0, &handles->hash);
     if (ret)
     {
         /* Note: needs to change if CMS fields are supported */
-        out->info.dwVersion = CMSG_SIGNER_INFO_V1;
-        ret = CRYPT_CopyBlob(&out->info.Issuer, &in->pCertInfo->Issuer);
+        info->dwVersion = CMSG_SIGNER_INFO_V1;
+        ret = CRYPT_CopyBlob(&info->Issuer, &in->pCertInfo->Issuer);
         if (ret)
-            ret = CRYPT_CopyBlob(&out->info.SerialNumber,
+            ret = CRYPT_CopyBlob(&info->SerialNumber,
              &in->pCertInfo->SerialNumber);
         /* Assumption:  algorithm IDs will point to static strings, not
          * stack-based ones, so copying the pointer values is safe.
          */
-        out->info.HashAlgorithm.pszObjId = in->HashAlgorithm.pszObjId;
+        info->HashAlgorithm.pszObjId = in->HashAlgorithm.pszObjId;
         if (ret)
-            ret = CRYPT_CopyBlob(&out->info.HashAlgorithm.Parameters,
+            ret = CRYPT_CopyBlob(&info->HashAlgorithm.Parameters,
              &in->HashAlgorithm.Parameters);
-        memset(&out->info.HashEncryptionAlgorithm, 0,
-         sizeof(out->info.HashEncryptionAlgorithm));
+        memset(&info->HashEncryptionAlgorithm, 0,
+         sizeof(info->HashEncryptionAlgorithm));
         if (ret)
-            ret = CRYPT_CopyAttributes(&out->info.AuthAttrs,
+            ret = CRYPT_CopyAttributes(&info->AuthAttrs,
              (CRYPT_ATTRIBUTES *)&in->cAuthAttr);
         if (ret)
-            ret = CRYPT_CopyAttributes(&out->info.UnauthAttrs,
+            ret = CRYPT_CopyAttributes(&info->UnauthAttrs,
              (CRYPT_ATTRIBUTES *)&in->cUnauthAttr);
     }
     return ret;
 }
 
-static void CSignerInfo_Free(CSignerInfo *signer)
+static void CSignerInfo_Free(CMSG_SIGNER_INFO *info)
 {
     DWORD i, j;
 
-    CryptDestroyKey(signer->key);
-    CryptDestroyHash(signer->hash);
-    CryptReleaseContext(signer->prov, 0);
-    CryptMemFree(signer->info.Issuer.pbData);
-    CryptMemFree(signer->info.SerialNumber.pbData);
-    CryptMemFree(signer->info.HashAlgorithm.Parameters.pbData);
-    CryptMemFree(signer->info.EncryptedHash.pbData);
-    for (i = 0; i < signer->info.AuthAttrs.cAttr; i++)
+    CryptMemFree(info->Issuer.pbData);
+    CryptMemFree(info->SerialNumber.pbData);
+    CryptMemFree(info->HashAlgorithm.Parameters.pbData);
+    CryptMemFree(info->EncryptedHash.pbData);
+    for (i = 0; i < info->AuthAttrs.cAttr; i++)
     {
-        for (j = 0; j < signer->info.AuthAttrs.rgAttr[i].cValue; j++)
-            CryptMemFree(signer->info.AuthAttrs.rgAttr[i].rgValue[j].pbData);
-        CryptMemFree(signer->info.AuthAttrs.rgAttr[i].rgValue);
+        for (j = 0; j < info->AuthAttrs.rgAttr[i].cValue; j++)
+            CryptMemFree(info->AuthAttrs.rgAttr[i].rgValue[j].pbData);
+        CryptMemFree(info->AuthAttrs.rgAttr[i].rgValue);
     }
-    CryptMemFree(signer->info.AuthAttrs.rgAttr);
-    for (i = 0; i < signer->info.UnauthAttrs.cAttr; i++)
+    CryptMemFree(info->AuthAttrs.rgAttr);
+    for (i = 0; i < info->UnauthAttrs.cAttr; i++)
     {
-        for (j = 0; j < signer->info.UnauthAttrs.rgAttr[i].cValue; j++)
-            CryptMemFree(signer->info.UnauthAttrs.rgAttr[i].rgValue[j].pbData);
-        CryptMemFree(signer->info.UnauthAttrs.rgAttr[i].rgValue);
+        for (j = 0; j < info->UnauthAttrs.rgAttr[i].cValue; j++)
+            CryptMemFree(info->UnauthAttrs.rgAttr[i].rgValue[j].pbData);
+        CryptMemFree(info->UnauthAttrs.rgAttr[i].rgValue);
     }
-    CryptMemFree(signer->info.UnauthAttrs.rgAttr);
+    CryptMemFree(info->UnauthAttrs.rgAttr);
 }
 
 typedef struct _CSignedEncodeMsg
 {
-    CryptMsgBase    base;
-    CRYPT_DATA_BLOB data;
-    DWORD           cSigners;
-    CSignerInfo    *signers;
-    DWORD           cCertEncoded;
-    PCERT_BLOB      rgCertEncoded;
-    DWORD           cCrlEncoded;
-    PCRL_BLOB       rgCrlEncoded;
+    CryptMsgBase      base;
+    CRYPT_DATA_BLOB   data;
+    DWORD             cSigners;
+    CSignerHandles   *signerHandles;
+    PCMSG_SIGNER_INFO rgSignerInfo;
+    DWORD             cCertEncoded;
+    PCERT_BLOB        rgCertEncoded;
+    DWORD             cCrlEncoded;
+    PCRL_BLOB         rgCrlEncoded;
 } CSignedEncodeMsg;
 
 static void CSignedEncodeMsg_Close(HCRYPTMSG hCryptMsg)
@@ -785,8 +785,14 @@ static void CSignedEncodeMsg_Close(HCRYP
     CRYPT_FreeBlobArray((BlobArray *)&msg->cCertEncoded);
     CRYPT_FreeBlobArray((BlobArray *)&msg->cCrlEncoded);
     for (i = 0; i < msg->cSigners; i++)
-        CSignerInfo_Free(&msg->signers[i]);
-    CryptMemFree(msg->signers);
+    {
+        CSignerInfo_Free(&msg->rgSignerInfo[i]);
+        CryptDestroyKey(msg->signerHandles[i].key);
+        CryptDestroyHash(msg->signerHandles[i].hash);
+        CryptReleaseContext(msg->signerHandles[i].prov, 0);
+    }
+    CryptMemFree(msg->signerHandles);
+    CryptMemFree(msg->rgSignerInfo);
 }
 
 static BOOL CSignedEncodeMsg_GetParam(HCRYPTMSG hCryptMsg, DWORD dwParamType,
@@ -859,17 +865,8 @@ static BOOL CSignedEncodeMsg_GetParam(HC
         }
         if (ret)
         {
-            info.rgSignerInfo =
-             CryptMemAlloc(msg->cSigners * sizeof(CMSG_SIGNER_INFO));
-            if (info.rgSignerInfo)
-            {
-                DWORD i;
-
-                for (i = 0; i < info.cSignerInfo; i++)
-                    info.rgSignerInfo[i] = msg->signers[i].info;
+            info.rgSignerInfo = msg->rgSignerInfo;
                 ret = CRYPT_AsnEncodePKCSSignedInfo(&info, pvData, pcbData);
-                CryptMemFree(info.rgSignerInfo);
-            }
             LocalFree(info.content.Content.pbData);
         }
         break;
@@ -878,8 +875,8 @@ static BOOL CSignedEncodeMsg_GetParam(HC
         if (dwIndex >= msg->cSigners)
             SetLastError(CRYPT_E_INVALID_INDEX);
         else
-            ret = CryptGetHashParam(msg->signers[dwIndex].hash, HP_HASHVAL,
-             pvData, pcbData, 0);
+            ret = CryptGetHashParam(msg->signerHandles[dwIndex].hash,
+             HP_HASHVAL, pvData, pcbData, 0);
         break;
     default:
         FIXME("unimplemented for %d\n", dwParamType);
@@ -897,7 +894,7 @@ static BOOL CSignedEncodeMsg_UpdateHash(
     TRACE("(%p, %p, %d)\n", msg, pbData, cbData);
 
     for (i = 0; ret && i < msg->cSigners; i++)
-        ret = CryptHashData(msg->signers[i].hash, pbData, cbData, 0);
+        ret = CryptHashData(msg->signerHandles[i].hash, pbData, cbData, 0);
     return ret;
 }
 
@@ -923,19 +920,19 @@ static BOOL CSignedEncodeMsg_Sign(CSigne
 
     for (i = 0; ret && i < msg->cSigners; i++)
     {
-        ret = CryptSignHashW(msg->signers[i].hash, AT_SIGNATURE, NULL, 0, NULL,
-         &msg->signers[i].info.EncryptedHash.cbData);
+        ret = CryptSignHashW(msg->signerHandles[i].hash, AT_SIGNATURE, NULL, 0,
+         NULL, &msg->rgSignerInfo[i].EncryptedHash.cbData);
         if (ret)
         {
-            msg->signers[i].info.EncryptedHash.pbData =
-             CryptMemAlloc(msg->signers[i].info.EncryptedHash.cbData);
-            if (msg->signers[i].info.EncryptedHash.pbData)
+            msg->rgSignerInfo[i].EncryptedHash.pbData =
+             CryptMemAlloc(msg->rgSignerInfo[i].EncryptedHash.cbData);
+            if (msg->rgSignerInfo[i].EncryptedHash.pbData)
             {
-                ret = CryptSignHashW(msg->signers[i].hash, AT_SIGNATURE, NULL,
-                 0, msg->signers[i].info.EncryptedHash.pbData,
-                 &msg->signers[i].info.EncryptedHash.cbData);
+                ret = CryptSignHashW(msg->signerHandles[i].hash, AT_SIGNATURE,
+                 NULL, 0, msg->rgSignerInfo[i].EncryptedHash.pbData,
+                 &msg->rgSignerInfo[i].EncryptedHash.cbData);
                 if (ret)
-                    CRYPT_ReverseBytes(&msg->signers[i].info.EncryptedHash);
+                    CRYPT_ReverseBytes(&msg->rgSignerInfo[i].EncryptedHash);
             }
             else
                 ret = FALSE;
@@ -1023,14 +1020,26 @@ static HCRYPTMSG CSignedEncodeMsg_Open(D
         msg->cSigners = 0;
         if (info->cSigners)
         {
-            msg->signers = CryptMemAlloc(info->cSigners * sizeof(CSignerInfo));
-            if (msg->signers)
+            msg->signerHandles =
+             CryptMemAlloc(info->cSigners * sizeof(CSignerHandles));
+            if (msg->signerHandles)
+                msg->rgSignerInfo =
+                 CryptMemAlloc(info->cSigners * sizeof(CMSG_SIGNER_INFO));
+            else
+            {
+                ret = FALSE;
+                msg->rgSignerInfo = NULL;
+            }
+            if (msg->rgSignerInfo)
             {
                 msg->cSigners = info->cSigners;
-                memset(msg->signers, 0, msg->cSigners * sizeof(CSignerInfo));
+                memset(msg->signerHandles, 0,
+                 msg->cSigners * sizeof(CSignerHandles));
+                memset(msg->rgSignerInfo, 0,
+                 msg->cSigners * sizeof(CMSG_SIGNER_INFO));
                 for (i = 0; ret && i < msg->cSigners; i++)
-                    ret = CSignerInfo_Construct(&msg->signers[i],
-                     &info->rgSigners[i], dwFlags);
+                    ret = CSignerInfo_Construct(&msg->signerHandles[i],
+                     &msg->rgSignerInfo[i], &info->rgSigners[i], dwFlags);
             }
             else
                 ret = FALSE;
-- 
1.4.1


More information about the wine-patches mailing list