crypt32: Test and fix encoding and decoding of attributes in PKCS signers.
This commit is contained in:
parent
3a85fa6b15
commit
c58cb379eb
@ -1896,9 +1896,8 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSAttributesInternal(
|
|||||||
DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
|
DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
|
||||||
void *pvStructInfo, DWORD *pcbStructInfo)
|
void *pvStructInfo, DWORD *pcbStructInfo)
|
||||||
{
|
{
|
||||||
struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
|
struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodePKCSAttribute,
|
||||||
CRYPT_AsnDecodePKCSAttribute, sizeof(CRYPT_ATTRIBUTE), TRUE,
|
sizeof(CRYPT_ATTRIBUTE), TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
|
||||||
offsetof(CRYPT_ATTRIBUTE, pszObjId) };
|
|
||||||
PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
|
PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
@ -1921,8 +1920,12 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
|
|||||||
{
|
{
|
||||||
DWORD bytesNeeded;
|
DWORD bytesNeeded;
|
||||||
|
|
||||||
if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType,
|
if (!cbEncoded)
|
||||||
lpszStructType, pbEncoded, cbEncoded,
|
SetLastError(CRYPT_E_ASN1_EOD);
|
||||||
|
else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
|
||||||
|
SetLastError(CRYPT_E_ASN1_CORRUPT);
|
||||||
|
else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(
|
||||||
|
dwCertEncodingType, lpszStructType, pbEncoded, cbEncoded,
|
||||||
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded)))
|
dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded)))
|
||||||
{
|
{
|
||||||
if (!pvStructInfo)
|
if (!pvStructInfo)
|
||||||
@ -3813,19 +3816,21 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
|
|||||||
{ ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
|
{ ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
|
||||||
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
|
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
|
||||||
FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
|
FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
|
||||||
|
{ ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
|
||||||
|
offsetof(CMSG_SIGNER_INFO, AuthAttrs),
|
||||||
|
CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
|
||||||
|
TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
|
||||||
{ ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
|
{ ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
|
||||||
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
|
CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
|
||||||
FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
|
FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
|
||||||
HashEncryptionAlgorithm.pszObjId), 0 },
|
HashEncryptionAlgorithm.pszObjId), 0 },
|
||||||
{ ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CMSG_SIGNER_INFO, AuthAttrs),
|
|
||||||
CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
|
|
||||||
TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
|
|
||||||
{ ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
|
|
||||||
CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
|
|
||||||
TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
|
|
||||||
{ ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
|
{ ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
|
||||||
CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
|
CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
|
||||||
FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
|
FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
|
||||||
|
{ ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
|
||||||
|
offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
|
||||||
|
CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
|
||||||
|
TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
|
ret = CRYPT_AsnDecodeSequence(dwCertEncodingType, items,
|
||||||
|
@ -3201,26 +3201,36 @@ static BOOL WINAPI CRYPT_AsnEncodePKCSSignerInfo(DWORD dwCertEncodingType,
|
|||||||
{ &info->Issuer, CRYPT_AsnEncodeIssuerSerialNumber, 0 },
|
{ &info->Issuer, CRYPT_AsnEncodeIssuerSerialNumber, 0 },
|
||||||
{ &info->HashAlgorithm, CRYPT_AsnEncodeAlgorithmIdWithNullParams,
|
{ &info->HashAlgorithm, CRYPT_AsnEncodeAlgorithmIdWithNullParams,
|
||||||
0 },
|
0 },
|
||||||
{ &info->HashEncryptionAlgorithm,
|
|
||||||
CRYPT_AsnEncodeAlgorithmIdWithNullParams, 0 },
|
|
||||||
};
|
};
|
||||||
DWORD cItem = 4;
|
struct AsnEncodeTagSwappedItem swapped[2] = { { 0 } };
|
||||||
|
DWORD cItem = 3, cSwapped = 0;
|
||||||
|
|
||||||
if (info->AuthAttrs.cAttr)
|
if (info->AuthAttrs.cAttr)
|
||||||
{
|
{
|
||||||
items[cItem].pvStructInfo = &info->AuthAttrs;
|
swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 0;
|
||||||
items[cItem].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
|
swapped[cSwapped].pvStructInfo = &info->AuthAttrs;
|
||||||
|
swapped[cSwapped].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
|
||||||
|
items[cItem].pvStructInfo = &swapped[cSwapped];
|
||||||
|
items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
|
||||||
|
cSwapped++;
|
||||||
cItem++;
|
cItem++;
|
||||||
}
|
}
|
||||||
if (info->UnauthAttrs.cAttr)
|
items[cItem].pvStructInfo = &info->HashEncryptionAlgorithm;
|
||||||
{
|
items[cItem].encodeFunc = CRYPT_AsnEncodeAlgorithmIdWithNullParams;
|
||||||
items[cItem].pvStructInfo = &info->UnauthAttrs;
|
|
||||||
items[cItem].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
|
|
||||||
cItem++;
|
cItem++;
|
||||||
}
|
|
||||||
items[cItem].pvStructInfo = &info->EncryptedHash;
|
items[cItem].pvStructInfo = &info->EncryptedHash;
|
||||||
items[cItem].encodeFunc = CRYPT_AsnEncodeOctets;
|
items[cItem].encodeFunc = CRYPT_AsnEncodeOctets;
|
||||||
cItem++;
|
cItem++;
|
||||||
|
if (info->UnauthAttrs.cAttr)
|
||||||
|
{
|
||||||
|
swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 1;
|
||||||
|
swapped[cSwapped].pvStructInfo = &info->UnauthAttrs;
|
||||||
|
swapped[cSwapped].encodeFunc = CRYPT_AsnEncodePKCSAttributes;
|
||||||
|
items[cItem].pvStructInfo = &swapped[cSwapped];
|
||||||
|
items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
|
||||||
|
cSwapped++;
|
||||||
|
cItem++;
|
||||||
|
}
|
||||||
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
|
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
|
||||||
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
|
dwFlags, pEncodePara, pbEncoded, pcbEncoded);
|
||||||
}
|
}
|
||||||
|
@ -4924,6 +4924,14 @@ static const BYTE PKCSSignerWithHash[] = {
|
|||||||
0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
|
0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
|
||||||
0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
|
0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
|
||||||
0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
|
0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
|
||||||
|
static const BYTE PKCSSignerWithAuthAttr[] = {
|
||||||
|
0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
|
||||||
|
0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
|
||||||
|
0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
|
||||||
|
0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
|
||||||
|
0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
|
||||||
|
0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
|
||||||
|
0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
|
||||||
|
|
||||||
static void test_encodePKCSSignerInfo(DWORD dwEncoding)
|
static void test_encodePKCSSignerInfo(DWORD dwEncoding)
|
||||||
{
|
{
|
||||||
@ -4932,6 +4940,10 @@ static void test_encodePKCSSignerInfo(DWORD dwEncoding)
|
|||||||
LPBYTE buf = NULL;
|
LPBYTE buf = NULL;
|
||||||
DWORD size = 0;
|
DWORD size = 0;
|
||||||
CMSG_SIGNER_INFO info = { 0 };
|
CMSG_SIGNER_INFO info = { 0 };
|
||||||
|
char oid_common_name[] = szOID_COMMON_NAME;
|
||||||
|
CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
|
||||||
|
(LPBYTE)encodedCommonName };
|
||||||
|
CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
|
||||||
|
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
|
ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
|
||||||
@ -5053,6 +5065,29 @@ static void test_encodePKCSSignerInfo(DWORD dwEncoding)
|
|||||||
LocalFree(buf);
|
LocalFree(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
info.AuthAttrs.cAttr = 1;
|
||||||
|
info.AuthAttrs.rgAttr = &attr;
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
|
||||||
|
CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
|
||||||
|
if (!(dwEncoding & PKCS_7_ASN_ENCODING))
|
||||||
|
ok(!ret && GetLastError() == E_INVALIDARG,
|
||||||
|
"Expected E_INVALIDARG, got %08x\n", GetLastError());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
|
||||||
|
if (buf)
|
||||||
|
{
|
||||||
|
ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
|
||||||
|
size);
|
||||||
|
if (size == sizeof(PKCSSignerWithAuthAttr))
|
||||||
|
ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
|
||||||
|
"Unexpected value\n");
|
||||||
|
else
|
||||||
|
ok(0, "Unexpected value\n");
|
||||||
|
LocalFree(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_decodePKCSSignerInfo(DWORD dwEncoding)
|
static void test_decodePKCSSignerInfo(DWORD dwEncoding)
|
||||||
@ -5157,6 +5192,26 @@ static void test_decodePKCSSignerInfo(DWORD dwEncoding)
|
|||||||
"Unexpected value\n");
|
"Unexpected value\n");
|
||||||
LocalFree(buf);
|
LocalFree(buf);
|
||||||
}
|
}
|
||||||
|
ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
|
||||||
|
PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
|
||||||
|
CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
|
||||||
|
if (buf)
|
||||||
|
{
|
||||||
|
info = (CMSG_SIGNER_INFO *)buf;
|
||||||
|
ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
|
||||||
|
info->AuthAttrs.cAttr);
|
||||||
|
ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
|
||||||
|
"Expected %s, got %s\n", szOID_COMMON_NAME,
|
||||||
|
info->AuthAttrs.rgAttr[0].pszObjId);
|
||||||
|
ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
|
||||||
|
info->AuthAttrs.rgAttr[0].cValue);
|
||||||
|
ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
|
||||||
|
sizeof(encodedCommonName), "Unexpected size %d\n",
|
||||||
|
info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
|
||||||
|
ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
|
||||||
|
encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
|
||||||
|
LocalFree(buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free *pInfo with HeapFree */
|
/* Free *pInfo with HeapFree */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user