[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(¶, 0, sizeof(para));
SetLastError(0xdeadbeef);
ret = CryptSignMessage(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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(¶, 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