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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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