Juan Lang : crypt32: Decode enhanced key usages using CRYPT_AsnDecodeArrayNoAlloc.
Alexandre Julliard
julliard at winehq.org
Thu Oct 15 08:54:37 CDT 2009
Module: wine
Branch: master
Commit: b1a1b32b59cb3aef6a9e79397a099441ac9d2fff
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b1a1b32b59cb3aef6a9e79397a099441ac9d2fff
Author: Juan Lang <juan.lang at gmail.com>
Date: Wed Oct 14 13:06:47 2009 -0700
crypt32: Decode enhanced key usages using CRYPT_AsnDecodeArrayNoAlloc.
---
dlls/crypt32/decode.c | 197 ++++++-------------------------------------------
1 files changed, 22 insertions(+), 175 deletions(-)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 54fc790..e1bd1a6 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -58,12 +58,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
WINE_DECLARE_DEBUG_CHANNEL(crypt);
-struct GenericArray
-{
- DWORD cItems;
- BYTE *rgItems;
-};
-
typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *,
DWORD, DWORD, void *, DWORD *);
typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *,
@@ -605,173 +599,6 @@ struct AsnArrayItemSize
DWORD size;
};
-/* Decodes an array of like types into a struct GenericArray.
- * The layout and decoding of the array are described by a struct
- * AsnArrayDescriptor.
- */
-static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
- const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
- PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
- DWORD *pcbDecoded, void *startingPointer)
-{
- BOOL ret = TRUE;
-
- TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
- cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
- startingPointer);
-
- if (!cbEncoded)
- {
- SetLastError(CRYPT_E_ASN1_EOD);
- ret = FALSE;
- }
- else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
- {
- DWORD dataLen;
-
- if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
- {
- DWORD bytesNeeded, cItems = 0, decoded;
- BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
- /* There can be arbitrarily many items, but there is often only one.
- */
- struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
-
- decoded = 1 + lenBytes;
- bytesNeeded = sizeof(struct GenericArray);
- if (dataLen)
- {
- const BYTE *ptr;
- BOOL doneDecoding = FALSE;
-
- for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
- {
- if (dataLen == CMSG_INDEFINITE_LENGTH)
- {
- if (ptr[0] == 0)
- {
- doneDecoding = TRUE;
- if (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 itemEncoded, itemDataLen, itemDecoded, size = 0;
-
- /* Each item decoded may not tolerate extraneous bytes,
- * so get the length of the next element if known.
- */
- if ((ret = CRYPT_GetLengthIndefinite(ptr,
- cbEncoded - (ptr - pbEncoded), &itemDataLen)))
- {
- if (itemDataLen == CMSG_INDEFINITE_LENGTH)
- itemEncoded = cbEncoded - (ptr - pbEncoded);
- else
- itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
- itemDataLen;
- }
- if (ret)
- ret = arrayDesc->decodeFunc(ptr, itemEncoded,
- dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
- &itemDecoded);
- if (ret)
- {
- 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 = itemEncoded;
- itemSizes[cItems - 1].size = size;
- bytesNeeded += size;
- ptr += itemEncoded;
- }
- else
- ret = FALSE;
- }
- }
- }
- }
- if (ret)
- {
- if (pcbDecoded)
- *pcbDecoded = decoded;
- if (!pvStructInfo)
- *pcbStructInfo = bytesNeeded;
- else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
- pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
- {
- DWORD i;
- BYTE *nextData;
- const BYTE *ptr;
- struct GenericArray *array;
-
- if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
- pvStructInfo = *(BYTE **)pvStructInfo;
- array = pvStructInfo;
- array->cItems = cItems;
- if (startingPointer)
- array->rgItems = startingPointer;
- else
- array->rgItems = (BYTE *)array +
- sizeof(struct GenericArray);
- nextData = array->rgItems +
- array->cItems * arrayDesc->itemSize;
- for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
- i < cItems && ptr - pbEncoded - 1 - lenBytes <
- dataLen; i++)
- {
- DWORD itemDecoded;
-
- if (arrayDesc->hasPointer)
- *(BYTE **)(array->rgItems + i * arrayDesc->itemSize
- + arrayDesc->pointerOffset) = nextData;
- ret = arrayDesc->decodeFunc(ptr,
- itemSizes[i].encodedLen,
- dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
- array->rgItems + i * arrayDesc->itemSize,
- &itemSizes[i].size, &itemDecoded);
- if (ret)
- {
- nextData += itemSizes[i].size - arrayDesc->itemSize;
- ptr += itemDecoded;
- }
- }
- if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
- CRYPT_FreeSpace(pDecodePara, pvStructInfo);
- }
- }
- if (itemSizes != &itemSize)
- CryptMemFree(itemSizes);
- }
- }
- else
- {
- SetLastError(CRYPT_E_ASN1_BADTAG);
- ret = FALSE;
- }
- return ret;
-}
-
/* Decodes an array of like types into a structure described by a struct
* AsnArrayDescriptor. Doesn't allocate memory for the decoded items,
* leaves that up to the caller.
@@ -5128,9 +4955,29 @@ static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier),
sizeof(CERT_ENHKEY_USAGE),
CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
+ DWORD bytesNeeded;
+
+ ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
+ dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
+ if (ret)
+ {
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
+ pvStructInfo, pcbStructInfo, bytesNeeded)))
+ {
+ CERT_ENHKEY_USAGE *usage;
- ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
- pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+ usage = pvStructInfo;
+ usage->rgpszUsageIdentifier = (LPSTR *)
+ ((BYTE *)pvStructInfo + sizeof(CERT_ENHKEY_USAGE));
+ ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc,
+ pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
+ &usage->cUsageIdentifier, pcbStructInfo, NULL);
+ }
+ }
}
__EXCEPT_PAGE_FAULT
{
More information about the wine-cvs
mailing list