Commit 8cdf1463 authored by Alexander Morozov's avatar Alexander Morozov Committed by Alexandre Julliard

crypt32: Implement CryptSignMessage.

parent 76730382
......@@ -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 = 0;
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;
}
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment