Juan Lang : crypt32: Implement CryptVerifyDetachedMessageSignature.

Alexandre Julliard julliard at winehq.org
Tue Sep 9 05:50:38 CDT 2008


Module: wine
Branch: master
Commit: cb5385e326fda459892eff0ee3e1bd30d2a0889c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cb5385e326fda459892eff0ee3e1bd30d2a0889c

Author: Juan Lang <juan.lang at gmail.com>
Date:   Mon Sep  8 12:47:37 2008 -0700

crypt32: Implement CryptVerifyDetachedMessageSignature.

---

 dlls/crypt32/message.c       |  130 +++++++++++++++++++++++++++++++-----------
 dlls/crypt32/tests/message.c |   10 ---
 2 files changed, 97 insertions(+), 43 deletions(-)

diff --git a/dlls/crypt32/message.c b/dlls/crypt32/message.c
index ee7c5ba..2eb210c 100644
--- a/dlls/crypt32/message.c
+++ b/dlls/crypt32/message.c
@@ -60,39 +60,6 @@ LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType,
     return count;
 }
 
-BOOL WINAPI CryptVerifyDetachedMessageSignature(
- PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex,
- const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned,
- const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[],
- PCCERT_CONTEXT *ppSignerCert)
-{
-    FIXME("(%p, %d, %p, %d, %d, %p, %p, %p): stub\n", pVerifyPara, dwSignerIndex,
-     pbDetachedSignBlob, cbDetachedSignBlob, cToBeSigned, rgpbToBeSigned,
-     rgcbToBeSigned, ppSignerCert);
-    return FALSE;
-}
-
-static BOOL CRYPT_CopyParam(void *pvData, DWORD *pcbData, const void *src,
- DWORD len)
-{
-    BOOL ret = TRUE;
-
-    if (!pvData)
-        *pcbData = len;
-    else if (*pcbData < len)
-    {
-        *pcbData = len;
-        SetLastError(ERROR_MORE_DATA);
-        ret = FALSE;
-    }
-    else
-    {
-        *pcbData = len;
-        memcpy(pvData, src, len);
-    }
-    return ret;
-}
-
 static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg,
  DWORD dwSignerIndex)
 {
@@ -136,6 +103,103 @@ static inline PCCERT_CONTEXT CRYPT_GetSignerCertificate(HCRYPTMSG msg,
      pVerifyPara->dwMsgAndCertEncodingType, certInfo, store);
 }
 
+BOOL WINAPI CryptVerifyDetachedMessageSignature(
+ PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex,
+ const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned,
+ const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[],
+ PCCERT_CONTEXT *ppSignerCert)
+{
+    BOOL ret = FALSE;
+    HCRYPTMSG msg;
+
+    TRACE("(%p, %d, %p, %d, %d, %p, %p, %p)\n", pVerifyPara, dwSignerIndex,
+     pbDetachedSignBlob, cbDetachedSignBlob, cToBeSigned, rgpbToBeSigned,
+     rgcbToBeSigned, ppSignerCert);
+
+    if (ppSignerCert)
+        *ppSignerCert = NULL;
+    if (!pVerifyPara ||
+     pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) ||
+     GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) !=
+     PKCS_7_ASN_ENCODING)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+
+    msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType,
+     CMSG_DETACHED_FLAG, 0, pVerifyPara->hCryptProv, NULL, NULL);
+    if (msg)
+    {
+        ret = CryptMsgUpdate(msg, pbDetachedSignBlob, cbDetachedSignBlob, TRUE);
+        if (ret)
+        {
+            DWORD i;
+
+            for (i = 0; ret && i < cToBeSigned; i++)
+                ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i],
+                 i == cToBeSigned - 1 ? TRUE : FALSE);
+        }
+        if (ret)
+        {
+            CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg,
+             dwSignerIndex);
+
+            ret = FALSE;
+            if (certInfo)
+            {
+                HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG,
+                 pVerifyPara->dwMsgAndCertEncodingType,
+                 pVerifyPara->hCryptProv, 0, msg);
+
+                if (store)
+                {
+                    PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate(
+                     msg, pVerifyPara, certInfo, store);
+
+                    if (cert)
+                    {
+                        ret = CryptMsgControl(msg, 0,
+                         CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo);
+                        if (ret && ppSignerCert)
+                            *ppSignerCert = cert;
+                        else
+                            CertFreeCertificateContext(cert);
+                    }
+                    else
+                        SetLastError(CRYPT_E_NOT_FOUND);
+                    CertCloseStore(store, 0);
+                }
+                CryptMemFree(certInfo);
+            }
+        }
+        CryptMsgClose(msg);
+    }
+    TRACE("returning %d\n", ret);
+    return ret;
+}
+
+static BOOL CRYPT_CopyParam(void *pvData, DWORD *pcbData, const void *src,
+ DWORD len)
+{
+    BOOL ret = TRUE;
+
+    if (!pvData)
+        *pcbData = len;
+    else if (*pcbData < len)
+    {
+        *pcbData = len;
+        SetLastError(ERROR_MORE_DATA);
+        ret = FALSE;
+    }
+    else
+    {
+        *pcbData = len;
+        memcpy(pvData, src, len);
+    }
+    return ret;
+}
+
 BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
  DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
  BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert)
diff --git a/dlls/crypt32/tests/message.c b/dlls/crypt32/tests/message.c
index a6dde76..28f9a4e 100644
--- a/dlls/crypt32/tests/message.c
+++ b/dlls/crypt32/tests/message.c
@@ -335,34 +335,29 @@ static void test_verify_detached_message_signature(void)
     SetLastError(0xdeadbeef);
     ret = CryptVerifyDetachedMessageSignature(NULL, 0, NULL, 0, 0, NULL,
      NULL, NULL);
-    todo_wine
     ok(!ret && GetLastError() == E_INVALIDARG,
      "Expected E_INVALIDARG, got %08x\n", GetLastError());
     SetLastError(0xdeadbeef);
     ret = CryptVerifyDetachedMessageSignature(&para, 0, NULL, 0, 0, NULL,
      NULL, NULL);
-    todo_wine
     ok(!ret && GetLastError() == E_INVALIDARG,
      "Expected E_INVALIDARG, got %08x\n", GetLastError());
     para.cbSize = sizeof(para);
     SetLastError(0xdeadbeef);
     ret = CryptVerifyDetachedMessageSignature(&para, 0, NULL, 0, 0, NULL,
      NULL, NULL);
-    todo_wine
     ok(!ret && GetLastError() == E_INVALIDARG,
      "Expected E_INVALIDARG, got %08x\n", GetLastError());
     para.dwMsgAndCertEncodingType = X509_ASN_ENCODING;
     SetLastError(0xdeadbeef);
     ret = CryptVerifyDetachedMessageSignature(&para, 0, NULL, 0, 0, NULL,
      NULL, NULL);
-    todo_wine
     ok(!ret && GetLastError() == E_INVALIDARG,
      "Expected E_INVALIDARG, got %08x\n", GetLastError());
     para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
     SetLastError(0xdeadbeef);
     ret = CryptVerifyDetachedMessageSignature(&para, 0, NULL, 0, 0, NULL,
      NULL, NULL);
-    todo_wine
     ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
      "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
     /* None of these messages contains a cert in the message itself, so the
@@ -377,13 +372,11 @@ static void test_verify_detached_message_signature(void)
     SetLastError(0xdeadbeef);
     ret = CryptVerifyDetachedMessageSignature(&para, 0, signedContent,
      sizeof(signedContent), 0, NULL, NULL, NULL);
-    todo_wine
     ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
      "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
     SetLastError(0xdeadbeef);
     ret = CryptVerifyDetachedMessageSignature(&para, 0, detachedSignedContent,
      sizeof(detachedSignedContent), 0, NULL, NULL, NULL);
-    todo_wine
     ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
      "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
     SetLastError(0xdeadbeef);
@@ -391,14 +384,12 @@ static void test_verify_detached_message_signature(void)
     cbContent = sizeof(msgData);
     ret = CryptVerifyDetachedMessageSignature(&para, 0, detachedSignedContent,
      sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL);
-    todo_wine
     ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
      "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
     /* Passing the correct callback results in success */
     para.pfnGetSignerCertificate = msg_get_signer_callback;
     ret = CryptVerifyDetachedMessageSignature(&para, 0, detachedSignedContent,
      sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL);
-    todo_wine
     ok(ret, "CryptVerifyDetachedMessageSignature failed: %08x\n",
      GetLastError());
     /* Not passing the correct data to be signed results in the signature not
@@ -407,7 +398,6 @@ static void test_verify_detached_message_signature(void)
     SetLastError(0xdeadbeef);
     ret = CryptVerifyDetachedMessageSignature(&para, 0, detachedSignedContent,
      sizeof(detachedSignedContent), 0, NULL, NULL, NULL);
-    todo_wine
     ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
      "expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
 }




More information about the wine-cvs mailing list