crypt32: Support indefinite-length encoded arrays.
This commit is contained in:
parent
159a369318
commit
5d168bd4c0
|
@ -536,7 +536,7 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
|
||||||
{
|
{
|
||||||
DWORD dataLen;
|
DWORD dataLen;
|
||||||
|
|
||||||
if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
|
if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
|
||||||
{
|
{
|
||||||
DWORD bytesNeeded, cItems = 0, decoded;
|
DWORD bytesNeeded, cItems = 0, decoded;
|
||||||
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
|
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
|
||||||
|
@ -549,15 +549,36 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
|
||||||
if (dataLen)
|
if (dataLen)
|
||||||
{
|
{
|
||||||
const BYTE *ptr;
|
const BYTE *ptr;
|
||||||
|
BOOL doneDecoding = FALSE;
|
||||||
|
|
||||||
for (ptr = pbEncoded + 1 + lenBytes; ret &&
|
for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
|
||||||
ptr - pbEncoded - 1 - lenBytes < dataLen; )
|
|
||||||
{
|
{
|
||||||
DWORD itemLenBytes, itemDataLen, itemDecoded, size = 0;
|
DWORD itemLenBytes;
|
||||||
|
|
||||||
itemLenBytes = GET_LEN_BYTES(ptr[1]);
|
itemLenBytes = GET_LEN_BYTES(ptr[1]);
|
||||||
/* Each item decoded may not tolerate extraneous bytes, so
|
if (dataLen == CMSG_INDEFINITE_LENGTH)
|
||||||
* get the length of the next element and pass it directly.
|
{
|
||||||
|
if (ptr[0] == 0)
|
||||||
|
{
|
||||||
|
doneDecoding = TRUE;
|
||||||
|
if (itemLenBytes != 1 || ptr[1] != 0)
|
||||||
|
{
|
||||||
|
SetLastError(CRYPT_E_ASN1_CORRUPT);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
decoded += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
|
||||||
|
doneDecoding = TRUE;
|
||||||
|
if (!doneDecoding)
|
||||||
|
{
|
||||||
|
DWORD itemDataLen, itemDecoded, size = 0;
|
||||||
|
|
||||||
|
/* Each item decoded may not tolerate extraneous bytes,
|
||||||
|
* so get the length of the next element and pass it
|
||||||
|
* directly.
|
||||||
*/
|
*/
|
||||||
ret = CRYPT_GetLen(ptr, cbEncoded - (ptr - pbEncoded),
|
ret = CRYPT_GetLen(ptr, cbEncoded - (ptr - pbEncoded),
|
||||||
&itemDataLen);
|
&itemDataLen);
|
||||||
|
@ -580,13 +601,14 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
|
||||||
CryptMemAlloc(
|
CryptMemAlloc(
|
||||||
cItems * sizeof(struct AsnArrayItemSize));
|
cItems * sizeof(struct AsnArrayItemSize));
|
||||||
if (itemSizes)
|
if (itemSizes)
|
||||||
memcpy(itemSizes, &itemSize, sizeof(itemSize));
|
memcpy(itemSizes, &itemSize,
|
||||||
|
sizeof(itemSize));
|
||||||
}
|
}
|
||||||
if (itemSizes)
|
if (itemSizes)
|
||||||
{
|
{
|
||||||
decoded += itemDecoded;
|
decoded += itemDecoded;
|
||||||
itemSizes[cItems - 1].encodedLen = 1 + itemLenBytes
|
itemSizes[cItems - 1].encodedLen =
|
||||||
+ itemDataLen;
|
1 + itemLenBytes + itemDataLen;
|
||||||
itemSizes[cItems - 1].size = size;
|
itemSizes[cItems - 1].size = size;
|
||||||
bytesNeeded += size;
|
bytesNeeded += size;
|
||||||
ret = CRYPT_GetLen(ptr,
|
ret = CRYPT_GetLen(ptr,
|
||||||
|
@ -599,6 +621,7 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
if (pcbDecoded)
|
if (pcbDecoded)
|
||||||
|
|
|
@ -1015,7 +1015,6 @@ static void test_decodeName(DWORD dwEncoding)
|
||||||
ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
|
ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
|
||||||
sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
|
sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
|
||||||
(BYTE *)&buf, &bufSize);
|
(BYTE *)&buf, &bufSize);
|
||||||
todo_wine
|
|
||||||
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
|
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue