[PATCH 1/2] crypt32: Implement CryptSignMessage.

Alexander Morozov amorozov at etersoft.ru
Thu Sep 16 09:59:20 CDT 2010


This patch adds some todo_wine. This is not a regression. It is only because 
signedBlobSize was equal 0 before. These todo_wine are fixed by [2/2] patch.
-------------- next part --------------
From 930c3fc74f020527ccdfe2a4932d4ab446f6bd6a Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov at etersoft.ru>
Date: Thu, 16 Sep 2010 18:44:53 +0400
Subject: [PATCH 1/2] crypt32: Implement CryptSignMessage.

---
 dlls/crypt32/message.c       |  111 +++++++++++++++++++++++++++++++++++++++++-
 dlls/crypt32/tests/message.c |   22 ++------
 2 files changed, 115 insertions(+), 18 deletions(-)

diff --git a/dlls/crypt32/message.c b/dlls/crypt32/message.c
index 81eb913..40a22e9 100644
--- a/dlls/crypt32/message.c
+++ b/dlls/crypt32/message.c
@@ -420,7 +420,114 @@ BOOL WINAPI CryptSignMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara,
  BOOL fDetachedSignature, DWORD cToBeSigned, const BYTE *rgpbToBeSigned[],
  DWORD rgcbToBeSigned[], BYTE *pbSignedBlob, DWORD *pcbSignedBlob)
 {
-    FIXME("(%p, %d, %d, %p, %p, %p, %p): stub\n", pSignPara, fDetachedSignature,
+    HCRYPTPROV hCryptProv;
+    BOOL ret, freeProv = FALSE;
+    DWORD i, keySpec;
+    PCERT_BLOB certBlob = NULL;
+    PCRL_BLOB crlBlob = NULL;
+    CMSG_SIGNED_ENCODE_INFO signInfo;
+    CMSG_SIGNER_ENCODE_INFO signer;
+    HCRYPTMSG msg;
+
+    TRACE("(%p, %d, %d, %p, %p, %p, %p)\n", pSignPara, fDetachedSignature,
      cToBeSigned, rgpbToBeSigned, rgcbToBeSigned, pbSignedBlob, pcbSignedBlob);
-    return FALSE;
+
+    if (pSignPara->cbSize != sizeof(CRYPT_SIGN_MESSAGE_PARA) ||
+     GET_CMSG_ENCODING_TYPE(pSignPara->dwMsgEncodingType) !=
+     PKCS_7_ASN_ENCODING)
+    {
+        *pcbSignedBlob = 0;
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if (!pSignPara->pSigningCert)
+        return TRUE;
+
+    ret = CryptAcquireCertificatePrivateKey(pSignPara->pSigningCert,
+     CRYPT_ACQUIRE_CACHE_FLAG, NULL, &hCryptProv, &keySpec, &freeProv);
+    if (!ret)
+        return FALSE;
+
+    memset(&signer, 0, sizeof(signer));
+    signer.cbSize = sizeof(signer);
+    signer.pCertInfo = pSignPara->pSigningCert->pCertInfo;
+    signer.hCryptProv = hCryptProv;
+    signer.dwKeySpec = keySpec;
+    signer.HashAlgorithm = pSignPara->HashAlgorithm;
+    signer.pvHashAuxInfo = pSignPara->pvHashAuxInfo;
+    signer.cAuthAttr = pSignPara->cAuthAttr;
+    signer.rgAuthAttr = pSignPara->rgAuthAttr;
+    signer.cUnauthAttr = pSignPara->cUnauthAttr;
+    signer.rgUnauthAttr = pSignPara->rgUnauthAttr;
+
+    memset(&signInfo, 0, sizeof(signInfo));
+    signInfo.cbSize = sizeof(signInfo);
+    signInfo.cSigners = 1;
+    signInfo.rgSigners = &signer;
+
+    if (pSignPara->cMsgCert)
+    {
+        certBlob = CryptMemAlloc(sizeof(CERT_BLOB) * pSignPara->cMsgCert);
+        if (certBlob)
+        {
+            for (i = 0; i < pSignPara->cMsgCert; ++i)
+            {
+                certBlob[i].cbData = pSignPara->rgpMsgCert[i]->cbCertEncoded;
+                certBlob[i].pbData = pSignPara->rgpMsgCert[i]->pbCertEncoded;
+            }
+            signInfo.cCertEncoded = pSignPara->cMsgCert;
+            signInfo.rgCertEncoded = certBlob;
+        }
+        else
+            ret = FALSE;
+    }
+    if (pSignPara->cMsgCrl)
+    {
+        crlBlob = CryptMemAlloc(sizeof(CRL_BLOB) * pSignPara->cMsgCrl);
+        if (crlBlob)
+        {
+            for (i = 0; i < pSignPara->cMsgCrl; ++i)
+            {
+                crlBlob[i].cbData = pSignPara->rgpMsgCrl[i]->cbCrlEncoded;
+                crlBlob[i].pbData = pSignPara->rgpMsgCrl[i]->pbCrlEncoded;
+            }
+            signInfo.cCrlEncoded = pSignPara->cMsgCrl;
+            signInfo.rgCrlEncoded = crlBlob;
+        }
+        else
+            ret = FALSE;
+    }
+    if (pSignPara->dwFlags || pSignPara->dwInnerContentType)
+        FIXME("unimplemented feature\n");
+
+    if (ret)
+        msg = CryptMsgOpenToEncode(pSignPara->dwMsgEncodingType,
+         fDetachedSignature ? CMSG_DETACHED_FLAG : 0, CMSG_SIGNED, &signInfo,
+         NULL, NULL);
+    if (msg)
+    {
+        if (cToBeSigned)
+        {
+            for (i = 0; ret && i < cToBeSigned; ++i)
+            {
+                ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i],
+                 i == cToBeSigned - 1 ? TRUE : FALSE);
+            }
+        }
+        else
+            ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
+        if (ret)
+            ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbSignedBlob,
+             pcbSignedBlob);
+        CryptMsgClose(msg);
+    }
+    else
+        ret = FALSE;
+    if (crlBlob)
+        CryptMemFree(crlBlob);
+    if (certBlob)
+        CryptMemFree(certBlob);
+    if (freeProv)
+        CryptReleaseContext(hCryptProv, 0);
+    return ret;
 }
diff --git a/dlls/crypt32/tests/message.c b/dlls/crypt32/tests/message.c
index a2706fe..8e214e7 100644
--- a/dlls/crypt32/tests/message.c
+++ b/dlls/crypt32/tests/message.c
@@ -959,7 +959,6 @@ static void test_sign_message(void)
     memset(&para, 0, sizeof(para));
     SetLastError(0xdeadbeef);
     ret = CryptSignMessage(&para, FALSE, 0, NULL, NULL, NULL, &signedBlobSize);
-    todo_wine
     ok(!ret &&
      (GetLastError() == E_INVALIDARG ||
       GetLastError() == ERROR_ARITHMETIC_OVERFLOW), /* Win7 */
@@ -970,16 +969,13 @@ static void test_sign_message(void)
     SetLastError(0xdeadbeef);
     signedBlobSize = 255;
     ret = CryptSignMessage(&para, FALSE, 0, NULL, NULL, NULL, &signedBlobSize);
-    todo_wine
     ok(!ret && GetLastError() == E_INVALIDARG,
      "expected E_INVALIDARG, got %08x\n", GetLastError());
-    todo_wine
     ok(!signedBlobSize, "unexpected size %d\n", signedBlobSize);
     para.dwMsgEncodingType = PKCS_7_ASN_ENCODING;
     SetLastError(0xdeadbeef);
     signedBlobSize = 0;
     ret = CryptSignMessage(&para, FALSE, 0, NULL, NULL, NULL, &signedBlobSize);
-    todo_wine
     ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
     todo_wine
     ok(signedBlobSize, "bad size\n");
@@ -1020,7 +1016,6 @@ static void test_sign_message(void)
     SetLastError(0xdeadbeef);
     signedBlobSize = 0;
     ret = CryptSignMessage(&para, TRUE, 0, NULL, NULL, NULL, &signedBlobSize);
-    todo_wine
     ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
     signedBlob = CryptMemAlloc(signedBlobSize);
     if (signedBlob)
@@ -1028,11 +1023,11 @@ static void test_sign_message(void)
         SetLastError(0xdeadbeef);
         ret = CryptSignMessage(&para, TRUE, 0, NULL, NULL, signedBlob,
          &signedBlobSize);
-        todo_wine
         ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
         todo_wine
         ok(signedBlobSize == sizeof(signedHashForEmptyMessage),
          "unexpected size %d\n", signedBlobSize);
+        todo_wine
         ok(!memcmp(signedBlob, signedHashForEmptyMessage, signedBlobSize),
          "unexpected value\n");
         CryptMemFree(signedBlob);
@@ -1041,7 +1036,6 @@ static void test_sign_message(void)
     SetLastError(0xdeadbeef);
     signedBlobSize = 0;
     ret = CryptSignMessage(&para, FALSE, 0, NULL, NULL, NULL, &signedBlobSize);
-    todo_wine
     ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
     signedBlob = CryptMemAlloc(signedBlobSize);
     if (signedBlob)
@@ -1049,11 +1043,11 @@ static void test_sign_message(void)
         SetLastError(0xdeadbeef);
         ret = CryptSignMessage(&para, FALSE, 0, NULL, NULL, signedBlob,
          &signedBlobSize);
-        todo_wine
         ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
         todo_wine
         ok(signedBlobSize == sizeof(signedEmptyMessage), "unexpected size %d\n",
          signedBlobSize);
+        todo_wine
         ok(!memcmp(signedBlob, signedEmptyMessage, signedBlobSize),
          "unexpected value\n");
         CryptMemFree(signedBlob);
@@ -1063,7 +1057,6 @@ static void test_sign_message(void)
     signedBlobSize = 0;
     ret = CryptSignMessage(&para, TRUE, 2, toSign, signSize, NULL,
      &signedBlobSize);
-    todo_wine
     ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
     signedBlob = CryptMemAlloc(signedBlobSize);
     if (signedBlob)
@@ -1071,11 +1064,11 @@ static void test_sign_message(void)
         SetLastError(0xdeadbeef);
         ret = CryptSignMessage(&para, TRUE, 2, toSign, signSize, signedBlob,
          &signedBlobSize);
-        todo_wine
         ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
         todo_wine
         ok(signedBlobSize == sizeof(signedHash),
          "unexpected size of signed blob %d\n", signedBlobSize);
+        todo_wine
         ok(!memcmp(signedBlob, signedHash, signedBlobSize),
          "unexpected value\n");
         CryptMemFree(signedBlob);
@@ -1088,7 +1081,6 @@ static void test_sign_message(void)
     signedBlobSize = 0;
     ret = CryptSignMessage(&para, TRUE, 2, toSign, signSize, NULL,
      &signedBlobSize);
-    todo_wine
     ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
     signedBlob = CryptMemAlloc(signedBlobSize);
     if (signedBlob)
@@ -1096,11 +1088,11 @@ static void test_sign_message(void)
         SetLastError(0xdeadbeef);
         ret = CryptSignMessage(&para, TRUE, 2, toSign, signSize, signedBlob,
          &signedBlobSize);
-        todo_wine
         ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
         todo_wine
         ok(signedBlobSize == sizeof(signedHashWithCert),
          "unexpected size of signed blob %d\n", signedBlobSize);
+        todo_wine
         ok(!memcmp(signedBlob, signedHashWithCert, signedBlobSize),
          "unexpected value\n");
         CryptMemFree(signedBlob);
@@ -1120,7 +1112,6 @@ static void test_sign_message(void)
     signedBlobSize = 0;
     ret = CryptSignMessage(&para, TRUE, 2, toSign, signSize, NULL,
      &signedBlobSize);
-    todo_wine
     ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
     signedBlob = CryptMemAlloc(signedBlobSize);
     if (signedBlob)
@@ -1128,11 +1119,11 @@ static void test_sign_message(void)
         SetLastError(0xdeadbeef);
         ret = CryptSignMessage(&para, TRUE, 2, toSign, signSize, signedBlob,
          &signedBlobSize);
-        todo_wine
         ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
         todo_wine
         ok(signedBlobSize == sizeof(signedHashWithCRL),
          "unexpected size of signed blob %d\n", signedBlobSize);
+        todo_wine
         ok(!memcmp(signedBlob, signedHashWithCRL, signedBlobSize),
          "unexpected value\n");
         CryptMemFree(signedBlob);
@@ -1146,7 +1137,6 @@ static void test_sign_message(void)
     signedBlobSize = 0;
     ret = CryptSignMessage(&para, FALSE, 1, toSign, signSize, NULL,
      &signedBlobSize);
-    todo_wine
     ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
     signedBlob = CryptMemAlloc(signedBlobSize);
     if (signedBlob)
@@ -1154,11 +1144,11 @@ static void test_sign_message(void)
         SetLastError(0xdeadbeef);
         ret = CryptSignMessage(&para, FALSE, 1, toSign, signSize, signedBlob,
          &signedBlobSize);
-        todo_wine
         ok(ret, "CryptSignMessage failed: %08x\n", GetLastError());
         todo_wine
         ok(signedBlobSize == sizeof(signedData),
          "unexpected size of signed blob %d\n", signedBlobSize);
+        todo_wine
         ok(!memcmp(signedBlob, signedData, signedBlobSize),
          "unexpected value\n");
         CryptMemFree(signedBlob);
-- 
1.7.2.3



More information about the wine-patches mailing list