crypt32: Test and correct decoding indefinite-length-encoded PKCS content.
This commit is contained in:
parent
43e6b48b33
commit
7e475b4a77
|
@ -2456,21 +2456,43 @@ static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
|
|||
pvStructInfo, *pcbStructInfo, pcbDecoded);
|
||||
|
||||
/* The caller has already checked the tag, no need to check it again.
|
||||
* Check the outer length is valid by calling CRYPT_GetLen:
|
||||
* Check the outer length is valid:
|
||||
*/
|
||||
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
|
||||
if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
|
||||
{
|
||||
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
|
||||
DWORD innerLen;
|
||||
|
||||
pbEncoded += 1 + lenBytes;
|
||||
/* Check the inner length is valid by calling CRYPT_GetLen again: */
|
||||
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &innerLen)))
|
||||
cbEncoded -= 1 + lenBytes;
|
||||
if (dataLen == CMSG_INDEFINITE_LENGTH)
|
||||
cbEncoded -= 2; /* space for 0 TLV */
|
||||
/* Check the inner length is valid: */
|
||||
if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
|
||||
{
|
||||
ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, dataLen, dwFlags,
|
||||
pvStructInfo, pcbStructInfo, NULL);
|
||||
if (pcbDecoded)
|
||||
*pcbDecoded = 1 + lenBytes + dataLen;
|
||||
DWORD decodedLen;
|
||||
|
||||
ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
|
||||
pvStructInfo, pcbStructInfo, &decodedLen);
|
||||
if (dataLen == CMSG_INDEFINITE_LENGTH)
|
||||
{
|
||||
if (*(pbEncoded + decodedLen) != 0 ||
|
||||
*(pbEncoded + decodedLen + 1) != 0)
|
||||
{
|
||||
TRACE("expected 0 TLV, got {%02x,%02x}\n",
|
||||
*(pbEncoded + decodedLen),
|
||||
*(pbEncoded + decodedLen + 1));
|
||||
SetLastError(CRYPT_E_ASN1_CORRUPT);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
decodedLen += 2;
|
||||
}
|
||||
if (ret && pcbDecoded)
|
||||
{
|
||||
*pcbDecoded = 1 + lenBytes + decodedLen;
|
||||
TRACE("decoded %d bytes\n", *pcbDecoded);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -4799,6 +4799,36 @@ static void test_encodePKCSContentInfo(DWORD dwEncoding)
|
|||
}
|
||||
}
|
||||
|
||||
static const BYTE indefiniteSignedPKCSContent[] = {
|
||||
0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
|
||||
0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
|
||||
0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
|
||||
0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
|
||||
0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
|
||||
0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
|
||||
0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
|
||||
0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
|
||||
0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
|
||||
0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
|
||||
0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
|
||||
0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
|
||||
0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
|
||||
0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
|
||||
0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
|
||||
0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
|
||||
0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
|
||||
0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
|
||||
0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
|
||||
0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
|
||||
0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
|
||||
0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
|
||||
0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
|
||||
0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
|
||||
0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
|
||||
0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
|
||||
static void test_decodePKCSContentInfo(DWORD dwEncoding)
|
||||
{
|
||||
BOOL ret;
|
||||
|
@ -4849,6 +4879,22 @@ static void test_decodePKCSContentInfo(DWORD dwEncoding)
|
|||
"Unexpected size %d\n", info->Content.cbData);
|
||||
ok(!memcmp(info->Content.pbData, ints[0].encoded,
|
||||
info->Content.cbData), "Unexpected value\n");
|
||||
LocalFree(buf);
|
||||
}
|
||||
ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
|
||||
indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
|
||||
CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
|
||||
ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
|
||||
if (buf)
|
||||
{
|
||||
info = (CRYPT_CONTENT_INFO *)buf;
|
||||
|
||||
ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
|
||||
"Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
|
||||
todo_wine
|
||||
ok(info->Content.cbData == 392, "Expected 392, got %d\n",
|
||||
info->Content.cbData);
|
||||
LocalFree(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue