Commit 75488b30 authored by Torge Matthies's avatar Torge Matthies Committed by Alexandre Julliard

crypt32: Fix CMS SignedData encoding.

Several items here were encoded conditionally even though they aren't marked as optional in the spec. Signed-off-by: 's avatarTorge Matthies <openglfreak@googlemail.com>
parent 62510642
...@@ -4345,30 +4345,19 @@ static BOOL WINAPI CRYPT_AsnEncodeCMSSignerInfo(DWORD dwCertEncodingType, ...@@ -4345,30 +4345,19 @@ static BOOL WINAPI CRYPT_AsnEncodeCMSSignerInfo(DWORD dwCertEncodingType,
BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData, BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
DWORD *pcbData) DWORD *pcbData)
{ {
struct DERSetDescriptor digestAlgorithmsSet = { signedInfo->cSignerInfo,
signedInfo->rgSignerInfo, sizeof(CMSG_CMS_SIGNER_INFO),
offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
CRYPT_AsnEncodeAlgorithmIdWithNullParams };
struct AsnEncodeSequenceItem items[7] = { struct AsnEncodeSequenceItem items[7] = {
{ &signedInfo->version, CRYPT_AsnEncodeInt, 0 }, { &signedInfo->version, CRYPT_AsnEncodeInt, 0 },
{ &digestAlgorithmsSet, CRYPT_DEREncodeItemsAsSet, 0 },
{ &signedInfo->content, CRYPT_AsnEncodePKCSContentInfoInternal, 0 }
}; };
struct DERSetDescriptor digestAlgorithmsSet = { 0 }, certSet = { 0 }; struct DERSetDescriptor certSet = { 0 }, crlSet = { 0 }, signerSet = { 0 };
struct DERSetDescriptor crlSet = { 0 }, signerSet = { 0 };
struct AsnEncodeTagSwappedItem swapped[2] = { { 0 } }; struct AsnEncodeTagSwappedItem swapped[2] = { { 0 } };
DWORD cItem = 1, cSwapped = 0; DWORD cItem = 3, cSwapped = 0;
BOOL ret = TRUE;
if (signedInfo->cSignerInfo)
{
digestAlgorithmsSet.cItems = signedInfo->cSignerInfo;
digestAlgorithmsSet.items = signedInfo->rgSignerInfo;
digestAlgorithmsSet.itemSize = sizeof(CMSG_CMS_SIGNER_INFO);
digestAlgorithmsSet.itemOffset =
offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm);
digestAlgorithmsSet.encode = CRYPT_AsnEncodeAlgorithmIdWithNullParams;
items[cItem].pvStructInfo = &digestAlgorithmsSet;
items[cItem].encodeFunc = CRYPT_DEREncodeItemsAsSet;
cItem++;
}
items[cItem].pvStructInfo = &signedInfo->content;
items[cItem].encodeFunc = CRYPT_AsnEncodePKCSContentInfoInternal;
cItem++;
if (signedInfo->cCertEncoded) if (signedInfo->cCertEncoded)
{ {
certSet.cItems = signedInfo->cCertEncoded; certSet.cItems = signedInfo->cCertEncoded;
...@@ -4399,22 +4388,17 @@ BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData, ...@@ -4399,22 +4388,17 @@ BOOL CRYPT_AsnEncodeCMSSignedInfo(CRYPT_SIGNED_INFO *signedInfo, void *pvData,
cSwapped++; cSwapped++;
cItem++; cItem++;
} }
if (ret && signedInfo->cSignerInfo) signerSet.cItems = signedInfo->cSignerInfo;
{ signerSet.items = signedInfo->rgSignerInfo;
signerSet.cItems = signedInfo->cSignerInfo; signerSet.itemSize = sizeof(CMSG_CMS_SIGNER_INFO);
signerSet.items = signedInfo->rgSignerInfo; signerSet.itemOffset = 0;
signerSet.itemSize = sizeof(CMSG_CMS_SIGNER_INFO); signerSet.encode = CRYPT_AsnEncodeCMSSignerInfo;
signerSet.itemOffset = 0; items[cItem].pvStructInfo = &signerSet;
signerSet.encode = CRYPT_AsnEncodeCMSSignerInfo; items[cItem].encodeFunc = CRYPT_DEREncodeItemsAsSet;
items[cItem].pvStructInfo = &signerSet; cItem++;
items[cItem].encodeFunc = CRYPT_DEREncodeItemsAsSet;
cItem++;
}
if (ret)
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
items, cItem, 0, NULL, pvData, pcbData);
return ret; return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
items, cItem, 0, NULL, pvData, pcbData);
} }
static BOOL WINAPI CRYPT_AsnEncodeRecipientInfo(DWORD dwCertEncodingType, static BOOL WINAPI CRYPT_AsnEncodeRecipientInfo(DWORD dwCertEncodingType,
......
...@@ -1256,6 +1256,18 @@ static void test_signed_msg_update(void) ...@@ -1256,6 +1256,18 @@ static void test_signed_msg_update(void)
CRYPT_DELETEKEYSET); CRYPT_DELETEKEYSET);
} }
static const BYTE unsignedEmptyBareContent[] = {
0x30,0x0b,0x02,0x01,0x01,0x31,0x00,0x30,0x02,0x06,0x00,0x31,0x00 };
static const BYTE unsignedEmptyContent[] = {
0x30,0x1a,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x0d,
0x30,0x0b,0x02,0x01,0x01,0x31,0x00,0x30,0x02,0x06,0x00,0x31,0x00 };
static const BYTE detachedUnsignedBareContent[] = {
0x30,0x14,0x02,0x01,0x01,0x31,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
0xf7,0x0d,0x01,0x07,0x01,0x31,0x00 };
static const BYTE detachedUnsignedContent[] = {
0x30,0x23,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x16,
0x30,0x14,0x02,0x01,0x01,0x31,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,
0xf7,0x0d,0x01,0x07,0x01,0x31,0x00 };
static const BYTE signedEmptyBareContent[] = { static const BYTE signedEmptyBareContent[] = {
0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86, 0x30,0x50,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02, 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x02,0x06,0x00,0x31,0x37,0x30,0x35,0x02,
...@@ -1590,6 +1602,32 @@ static void test_signed_msg_encoding(void) ...@@ -1590,6 +1602,32 @@ static void test_signed_msg_encoding(void)
HCRYPTKEY key; HCRYPTKEY key;
DWORD size; DWORD size;
msg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING,
CMSG_DETACHED_FLAG, CMSG_SIGNED, &signInfo, NULL, NULL);
ok(msg != NULL, "CryptMsgOpenToEncode failed: %lx\n", GetLastError());
check_param("detached unsigned empty bare content", msg,
CMSG_BARE_CONTENT_PARAM, unsignedEmptyBareContent,
sizeof(unsignedEmptyBareContent));
check_param("detached unsigned empty content", msg, CMSG_CONTENT_PARAM,
unsignedEmptyContent, sizeof(unsignedEmptyContent));
ret = CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
ok(ret, "CryptMsgUpdate failed: %lx\n", GetLastError());
check_param("detached unsigned bare content", msg, CMSG_BARE_CONTENT_PARAM,
detachedUnsignedBareContent, sizeof(detachedUnsignedBareContent));
check_param("detached unsigned content", msg, CMSG_CONTENT_PARAM,
detachedUnsignedContent, sizeof(detachedUnsignedContent));
SetLastError(0xdeadbeef);
ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, NULL, &size);
ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
"Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
SetLastError(0xdeadbeef);
ret = CryptMsgGetParam(msg, CMSG_ENCODED_SIGNER, 0, NULL, &size);
ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
"Expected CRYPT_E_INVALID_INDEX, got %lx\n", GetLastError());
CryptMsgClose(msg);
certInfo.SerialNumber.cbData = sizeof(serialNum); certInfo.SerialNumber.cbData = sizeof(serialNum);
certInfo.SerialNumber.pbData = serialNum; certInfo.SerialNumber.pbData = serialNum;
certInfo.Issuer.cbData = sizeof(encodedCommonName); certInfo.Issuer.cbData = sizeof(encodedCommonName);
......
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