Juan Lang : crypt32: Support indefinite-length encoded arrays.
Alexandre Julliard
julliard at winehq.org
Tue Sep 18 05:31:22 CDT 2007
Module: wine
Branch: master
Commit: 5d168bd4c0fe9725114a652175ffcab01a25fb91
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5d168bd4c0fe9725114a652175ffcab01a25fb91
Author: Juan Lang <juan.lang at gmail.com>
Date: Mon Sep 17 16:58:25 2007 -0700
crypt32: Support indefinite-length encoded arrays.
---
dlls/crypt32/decode.c | 101 ++++++++++++++++++++++++++----------------
dlls/crypt32/tests/encode.c | 1 -
2 files changed, 62 insertions(+), 40 deletions(-)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 7161058..a5229b5 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -536,7 +536,7 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
{
DWORD dataLen;
- if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+ if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
{
DWORD bytesNeeded, cItems = 0, decoded;
BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
@@ -549,53 +549,76 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
if (dataLen)
{
const BYTE *ptr;
+ BOOL doneDecoding = FALSE;
- for (ptr = pbEncoded + 1 + lenBytes; ret &&
- ptr - pbEncoded - 1 - lenBytes < dataLen; )
+ for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
{
- DWORD itemLenBytes, itemDataLen, itemDecoded, size = 0;
+ DWORD itemLenBytes;
itemLenBytes = GET_LEN_BYTES(ptr[1]);
- /* 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),
- &itemDataLen);
- if (ret)
- ret = arrayDesc->decodeFunc(ptr,
- 1 + itemLenBytes + itemDataLen,
- dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
- &itemDecoded);
- if (ret)
+ if (dataLen == CMSG_INDEFINITE_LENGTH)
{
- DWORD nextLen;
-
- cItems++;
- if (itemSizes != &itemSize)
- itemSizes = CryptMemRealloc(itemSizes,
- cItems * sizeof(struct AsnArrayItemSize));
- else if (cItems > 1)
+ if (ptr[0] == 0)
{
- itemSizes =
- CryptMemAlloc(
- cItems * sizeof(struct AsnArrayItemSize));
- if (itemSizes)
- memcpy(itemSizes, &itemSize, sizeof(itemSize));
+ doneDecoding = TRUE;
+ if (itemLenBytes != 1 || ptr[1] != 0)
+ {
+ SetLastError(CRYPT_E_ASN1_CORRUPT);
+ ret = FALSE;
+ }
+ else
+ decoded += 2;
}
- if (itemSizes)
+ }
+ 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),
+ &itemDataLen);
+ if (ret)
+ ret = arrayDesc->decodeFunc(ptr,
+ 1 + itemLenBytes + itemDataLen,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
+ &itemDecoded);
+ if (ret)
{
- decoded += itemDecoded;
- itemSizes[cItems - 1].encodedLen = 1 + itemLenBytes
- + itemDataLen;
- itemSizes[cItems - 1].size = size;
- bytesNeeded += size;
- ret = CRYPT_GetLen(ptr,
- cbEncoded - (ptr - pbEncoded), &nextLen);
- if (ret)
- ptr += nextLen + 1 + GET_LEN_BYTES(ptr[1]);
+ DWORD nextLen;
+
+ cItems++;
+ if (itemSizes != &itemSize)
+ itemSizes = CryptMemRealloc(itemSizes,
+ cItems * sizeof(struct AsnArrayItemSize));
+ else if (cItems > 1)
+ {
+ itemSizes =
+ CryptMemAlloc(
+ cItems * sizeof(struct AsnArrayItemSize));
+ if (itemSizes)
+ memcpy(itemSizes, &itemSize,
+ sizeof(itemSize));
+ }
+ if (itemSizes)
+ {
+ decoded += itemDecoded;
+ itemSizes[cItems - 1].encodedLen =
+ 1 + itemLenBytes + itemDataLen;
+ itemSizes[cItems - 1].size = size;
+ bytesNeeded += size;
+ ret = CRYPT_GetLen(ptr,
+ cbEncoded - (ptr - pbEncoded), &nextLen);
+ if (ret)
+ ptr += nextLen + 1 + GET_LEN_BYTES(ptr[1]);
+ }
+ else
+ ret = FALSE;
}
- else
- ret = FALSE;
}
}
}
diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c
index 37046b0..13d288b 100644
--- a/dlls/crypt32/tests/encode.c
+++ b/dlls/crypt32/tests/encode.c
@@ -1015,7 +1015,6 @@ static void test_decodeName(DWORD dwEncoding)
ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
(BYTE *)&buf, &bufSize);
- todo_wine
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
More information about the wine-cvs
mailing list