/*
 * Copyright 2005-2009 Juan Lang
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * This file implements ASN.1 DER decoding of a limited set of types.
 * It isn't a full ASN.1 implementation.  Microsoft implements BER
 * encoding of many of the basic types in msasn1.dll, but that interface isn't
 * implemented, so I implement them here.
 *
 * References:
 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
 * (available online, look for a PDF copy as the HTML versions tend to have
 * translation errors.)
 *
 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
 *
 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
 */

#include "config.h"
#include "wine/port.h"

#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "winnls.h"
#include "snmp.h"
#include "wine/debug.h"
#include "wine/exception.h"
#include "crypt32_private.h"

/* This is a bit arbitrary, but to set some limit: */
#define MAX_ENCODED_LEN 0x02000000

#define ASN_FLAGS_MASK 0xe0
#define ASN_TYPE_MASK  0x1f

WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
WINE_DECLARE_DEBUG_CHANNEL(crypt);

typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *,
 DWORD, DWORD, void *, DWORD *);
typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *,
 DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *);

/* Internal decoders don't do memory allocation or exception handling, and
 * they report how many bytes they decoded.
 */
typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);

static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded);
static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded);
/* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
 */
static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
/* Assumes algo->Parameters.pbData is set ahead of time. */
static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
/* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded);
/* Doesn't check the tag, assumes the caller does so */
static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
/* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
 * member has been initialized, doesn't do exception handling, and doesn't do
 * memory allocation.  Also doesn't check tag, assumes the caller has checked
 * it.
 */
static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded);
/* Like CRYPT_AsnDecodeInteger, but unsigned.  */
static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded);
static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded);

/* Gets the number of length bytes from the given (leading) length byte */
#define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))

/* Helper function to get the encoded length of the data starting at pbEncoded,
 * where pbEncoded[0] is the tag.  If the data are too short to contain a
 * length or if the length is too large for cbEncoded, sets an appropriate
 * error code and returns FALSE.  If the encoded length is unknown due to
 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
 */
static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD *len)
{
    BOOL ret;

    if (cbEncoded <= 1)
    {
        SetLastError(CRYPT_E_ASN1_CORRUPT);
        ret = FALSE;
    }
    else if (pbEncoded[1] <= 0x7f)
    {
        if (pbEncoded[1] + 1 > cbEncoded)
        {
            SetLastError(CRYPT_E_ASN1_EOD);
            ret = FALSE;
        }
        else
        {
            *len = pbEncoded[1];
            ret = TRUE;
        }
    }
    else if (pbEncoded[1] == 0x80)
    {
        *len = CMSG_INDEFINITE_LENGTH;
        ret = TRUE;
    }
    else
    {
        BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);

        if (lenLen > sizeof(DWORD) + 1)
        {
            SetLastError(CRYPT_E_ASN1_LARGE);
            ret = FALSE;
        }
        else if (lenLen + 2 > cbEncoded)
        {
            SetLastError(CRYPT_E_ASN1_CORRUPT);
            ret = FALSE;
        }
        else
        {
            DWORD out = 0;

            pbEncoded += 2;
            while (--lenLen)
            {
                out <<= 8;
                out |= *pbEncoded++;
            }
            if (out + lenLen + 1 > cbEncoded)
            {
                SetLastError(CRYPT_E_ASN1_EOD);
                ret = FALSE;
            }
            else
            {
                *len = out;
                ret = TRUE;
            }
        }
    }
    return ret;
}

/* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
{
    BOOL ret;

    if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
     *len == CMSG_INDEFINITE_LENGTH)
    {
        SetLastError(CRYPT_E_ASN1_CORRUPT);
        ret = FALSE;
    }
    return ret;
}

/* Helper function to check *pcbStructInfo, set it to the required size, and
 * optionally to allocate memory.  Assumes pvStructInfo is not NULL.
 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
 * pointer to the newly allocated memory.
 */
static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD bytesNeeded)
{
    BOOL ret = TRUE;

    if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
    {
        if (pDecodePara && pDecodePara->pfnAlloc)
            *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
        else
            *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
        if (!*(BYTE **)pvStructInfo)
            ret = FALSE;
        else
            *pcbStructInfo = bytesNeeded;
    }
    else if (*pcbStructInfo < bytesNeeded)
    {
        *pcbStructInfo = bytesNeeded;
        SetLastError(ERROR_MORE_DATA);
        ret = FALSE;
    }
    else
        *pcbStructInfo = bytesNeeded;
    return ret;
}

static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara, LPVOID pv)
{
    if (pDecodePara && pDecodePara->pfnFree)
        pDecodePara->pfnFree(pv);
    else
        LocalFree(pv);
}

/* Helper function to check *pcbStructInfo and set it to the required size.
 * Assumes pvStructInfo is not NULL.
 */
static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
{
    BOOL ret;

    if (*pcbStructInfo < bytesNeeded)
    {
        *pcbStructInfo = bytesNeeded;
        SetLastError(ERROR_MORE_DATA);
        ret = FALSE;
    }
    else
    {
        *pcbStructInfo = bytesNeeded;
        ret = TRUE;
    }
    return ret;
}

/* tag:
 *     The expected tag of the item.  If tag is 0, decodeFunc is called
 *     regardless of the tag value seen.
 * offset:
 *     A sequence is decoded into a struct.  The offset member is the
 *     offset of this item within that struct.
 * decodeFunc:
 *     The decoder function to use.  If this is NULL, then the member isn't
 *     decoded, but minSize space is reserved for it.
 * minSize:
 *     The minimum amount of space occupied after decoding.  You must set this.
 * optional:
 *     If true, and the tag doesn't match the expected tag for this item,
 *     or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
 *     filled with 0 for this member.
 * hasPointer, pointerOffset:
 *     If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
 *     the offset within the struct of the data pointer (or to the
 *     first data pointer, if more than one exist).
 * size:
 *     Used by CRYPT_AsnDecodeSequence, not for your use.
 */
struct AsnDecodeSequenceItem
{
    BYTE               tag;
    DWORD              offset;
    InternalDecodeFunc decodeFunc;
    DWORD              minSize;
    BOOL               optional;
    BOOL               hasPointer;
    DWORD              pointerOffset;
    DWORD              size;
};

#define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
#define MEMBERSIZE(s, member, nextmember) \
    (offsetof(s, nextmember) - offsetof(s, member))

/* Decodes the items in a sequence, where the items are described in items,
 * the encoded data are in pbEncoded with length cbEncoded.  Decodes into
 * pvStructInfo.  nextData is a pointer to the memory location at which the
 * first decoded item with a dynamic pointer should point.
 * Upon decoding, *cbDecoded is the total number of bytes decoded.
 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
 */
static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
{
    BOOL ret;
    DWORD i, decoded = 0;
    const BYTE *ptr = pbEncoded;

    TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
     cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);

    for (i = 0, ret = TRUE; ret && i < cItem; i++)
    {
        if (cbEncoded - (ptr - pbEncoded) != 0)
        {
            DWORD itemLen;

            if ((ret = CRYPT_GetLengthIndefinite(ptr,
             cbEncoded - (ptr - pbEncoded), &itemLen)))
            {
                BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);

                if (ptr[0] == items[i].tag || !items[i].tag)
                {
                    DWORD itemEncodedLen;

                    if (itemLen == CMSG_INDEFINITE_LENGTH)
                        itemEncodedLen = cbEncoded - (ptr - pbEncoded);
                    else
                        itemEncodedLen = 1 + itemLenBytes + itemLen;
                    if (nextData && pvStructInfo && items[i].hasPointer)
                    {
                        TRACE("Setting next pointer to %p\n",
                         nextData);
                        *(BYTE **)((BYTE *)pvStructInfo +
                         items[i].pointerOffset) = nextData;
                    }
                    if (items[i].decodeFunc)
                    {
                        DWORD itemDecoded;

                        if (pvStructInfo)
                            TRACE("decoding item %d\n", i);
                        else
                            TRACE("sizing item %d\n", i);
                        ret = items[i].decodeFunc(ptr, itemEncodedLen,
                         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
                         pvStructInfo ?  (BYTE *)pvStructInfo + items[i].offset
                         : NULL, &items[i].size, &itemDecoded);
                        if (ret)
                        {
                            /* Account for alignment padding */
                            items[i].size = ALIGN_DWORD_PTR(items[i].size);
                            TRACE("item %d size: %d\n", i, items[i].size);
                            if (nextData && items[i].hasPointer &&
                             items[i].size > items[i].minSize)
                                nextData += items[i].size - items[i].minSize;
                            if (itemDecoded > itemEncodedLen)
                            {
                                WARN("decoded length %d exceeds encoded %d\n",
                                 itemDecoded, itemEncodedLen);
                                SetLastError(CRYPT_E_ASN1_CORRUPT);
                                ret = FALSE;
                            }
                            else
                            {
                                ptr += itemDecoded;
                                decoded += itemDecoded;
                                TRACE("item %d: decoded %d bytes\n", i,
                                 itemDecoded);
                            }
                        }
                        else if (items[i].optional &&
                         GetLastError() == CRYPT_E_ASN1_BADTAG)
                        {
                            TRACE("skipping optional item %d\n", i);
                            items[i].size = items[i].minSize;
                            SetLastError(NOERROR);
                            ret = TRUE;
                        }
                        else
                            TRACE("item %d failed: %08x\n", i,
                             GetLastError());
                    }
                    else if (itemLen == CMSG_INDEFINITE_LENGTH)
                    {
                        ERR("can't use indefinite length encoding without a decoder\n");
                        SetLastError(CRYPT_E_ASN1_CORRUPT);
                        ret = FALSE;
                    }
                    else
                    {
                        TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
                        ptr += itemEncodedLen;
                        decoded += itemEncodedLen;
                        items[i].size = items[i].minSize;
                    }
                }
                else if (items[i].optional)
                {
                    TRACE("skipping optional item %d\n", i);
                    items[i].size = items[i].minSize;
                }
                else
                {
                    TRACE("item %d: tag %02x doesn't match expected %02x\n",
                     i, ptr[0], items[i].tag);
                    SetLastError(CRYPT_E_ASN1_BADTAG);
                    ret = FALSE;
                }
            }
        }
        else if (items[i].optional)
        {
            TRACE("missing optional item %d, skipping\n", i);
            items[i].size = items[i].minSize;
        }
        else
        {
            TRACE("not enough bytes for item %d, failing\n", i);
            SetLastError(CRYPT_E_ASN1_CORRUPT);
            ret = FALSE;
        }
    }
    if (cbDecoded)
        *cbDecoded = decoded;
    TRACE("returning %d\n", ret);
    return ret;
}

/* This decodes an arbitrary sequence into a contiguous block of memory
 * (basically, a struct.)  Each element being decoded is described by a struct
 * AsnDecodeSequenceItem, see above.
 * startingPointer is an optional pointer to the first place where dynamic
 * data will be stored.  If you know the starting offset, you may pass it
 * here.  Otherwise, pass NULL, and one will be inferred from the items.
 */
static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded, void *startingPointer)
{
    BOOL ret;

    TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
     cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
     startingPointer);

    if (!cbEncoded)
    {
        SetLastError(CRYPT_E_ASN1_EOD);
        return FALSE;
    }
    if (pbEncoded[0] == ASN_SEQUENCE)
    {
        DWORD dataLen;

        if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
        {
            DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
            const BYTE *ptr = pbEncoded + 1 + lenBytes;
            BOOL indefinite = FALSE;

            cbEncoded -= 1 + lenBytes;
            if (dataLen == CMSG_INDEFINITE_LENGTH)
            {
                dataLen = cbEncoded;
                indefinite = TRUE;
            }
            else if (cbEncoded < dataLen)
            {
                TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
                 cbEncoded);
                SetLastError(CRYPT_E_ASN1_CORRUPT);
                ret = FALSE;
            }
            if (ret)
            {
                ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
                 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
                if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
                {
                    if (cbDecoded > cbEncoded - 2)
                    {
                        /* Not enough space for 0 TLV */
                        SetLastError(CRYPT_E_ASN1_CORRUPT);
                        ret = FALSE;
                    }
                    else if (*(ptr + cbDecoded) != 0 ||
                     *(ptr + cbDecoded + 1) != 0)
                    {
                        TRACE("expected 0 TLV\n");
                        SetLastError(CRYPT_E_ASN1_CORRUPT);
                        ret = FALSE;
                    }
                    else
                        cbDecoded += 2;
                }
            }
            if (ret && !indefinite && cbDecoded != dataLen)
            {
                TRACE("expected %d decoded, got %d, failing\n", dataLen,
                 cbDecoded);
                SetLastError(CRYPT_E_ASN1_CORRUPT);
                ret = FALSE;
            }
            if (ret)
            {
                DWORD i, bytesNeeded = 0, structSize = 0;

                for (i = 0; i < cItem; i++)
                {
                    bytesNeeded += items[i].size;
                    structSize = max( structSize, items[i].offset + items[i].minSize );
                }
                if (pcbDecoded)
                    *pcbDecoded = 1 + lenBytes + cbDecoded;
                if (!pvStructInfo)
                    *pcbStructInfo = bytesNeeded;
                else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
                 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
                {
                    BYTE *nextData;

                    if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                        pvStructInfo = *(BYTE **)pvStructInfo;
                    if (startingPointer)
                        nextData = startingPointer;
                    else
                        nextData = (BYTE *)pvStructInfo + structSize;
                    memset(pvStructInfo, 0, structSize);
                    ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
                     ptr, dataLen, dwFlags, pvStructInfo, nextData,
                     &cbDecoded);
                    if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
                        CRYPT_FreeSpace(pDecodePara, pvStructInfo);
                }
            }
        }
    }
    else
    {
        SetLastError(CRYPT_E_ASN1_BADTAG);
        ret = FALSE;
    }
    TRACE("returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

/* tag:
 *     The expected tag of the entire encoded array (usually a variant
 *     of ASN_SETOF or ASN_SEQUENCEOF.)  If tag is 0, decodeFunc is called
 *     regardless of the tag seen.
 * countOffset:
 *     The offset within the outer structure at which the count exists.
 *     For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
 *     while CRYPT_ATTRIBUTE has countOffset ==
 *     offsetof(CRYPT_ATTRIBUTE, cValue).
 * arrayOffset:
 *     The offset within the outer structure at which the array pointer exists.
 *     For example, CRYPT_ATTRIBUTES has arrayOffset ==
 *     offsetof(CRYPT_ATTRIBUTES, rgAttr).
 * minArraySize:
 *     The minimum size of the decoded array.  On WIN32, this is always 8:
 *     sizeof(DWORD) + sizeof(void *).  On WIN64, it can be larger due to
 *     alignment.
 * decodeFunc:
 *     used to decode each item in the array
 * itemSize:
 *      is the minimum size of each decoded item
 * hasPointer:
 *      indicates whether each item has a dynamic pointer
 * pointerOffset:
 *     indicates the offset within itemSize at which the pointer exists
 */
struct AsnArrayDescriptor
{
    BYTE               tag;
    DWORD              countOffset;
    DWORD              arrayOffset;
    DWORD              minArraySize;
    InternalDecodeFunc decodeFunc;
    DWORD              itemSize;
    BOOL               hasPointer;
    DWORD              pointerOffset;
};

struct AsnArrayItemSize
{
    DWORD encodedLen;
    DWORD size;
};

/* Decodes an array of like types into a structure 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)
{
    BOOL ret = TRUE;

    TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded,
     cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);

    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 = arrayDesc->minArraySize, 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;
            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, *pcItems;
                    BYTE *nextData;
                    const BYTE *ptr;
                    void *rgItems;

                    if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                        pvStructInfo = *(void **)pvStructInfo;
                    pcItems = pvStructInfo;
                    *pcItems = cItems;
                    if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    {
                        rgItems = (BYTE *)pvStructInfo +
                         arrayDesc->minArraySize;
                        *(void **)((BYTE *)pcItems -
                         arrayDesc->countOffset + arrayDesc->arrayOffset) =
                         rgItems;
                    }
                    else
                        rgItems = *(void **)((BYTE *)pcItems -
                         arrayDesc->countOffset + arrayDesc->arrayOffset);
                    nextData = (BYTE *)rgItems + 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 **)((BYTE *)rgItems + i * arrayDesc->itemSize
                             + arrayDesc->pointerOffset) = nextData;
                        ret = arrayDesc->decodeFunc(ptr,
                         itemSizes[i].encodedLen,
                         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
                         (BYTE *)rgItems + i * arrayDesc->itemSize,
                         &itemSizes[i].size, &itemDecoded);
                        if (ret)
                        {
                            nextData += itemSizes[i].size - arrayDesc->itemSize;
                            ptr += itemDecoded;
                        }
                    }
                }
            }
            if (itemSizes != &itemSize)
                CryptMemFree(itemSizes);
        }
    }
    else
    {
        SetLastError(CRYPT_E_ASN1_BADTAG);
        ret = FALSE;
    }
    return ret;
}

/* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
 * pvStructInfo.  The BLOB must be non-empty, otherwise the last error is set
 * to CRYPT_E_ASN1_CORRUPT.
 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
 * set!
 */
static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    DWORD dataLen;

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
        DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
       
        if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
            bytesNeeded += 1 + lenBytes + dataLen;

        if (pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
        if (!pvStructInfo)
            *pcbStructInfo = bytesNeeded;
        else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
        {
            CRYPT_DER_BLOB *blob;

            if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                pvStructInfo = *(BYTE **)pvStructInfo;
            blob = pvStructInfo;
            blob->cbData = 1 + lenBytes + dataLen;
            if (blob->cbData)
            {
                if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
                    blob->pbData = (BYTE *)pbEncoded;
                else
                {
                    assert(blob->pbData);
                    memcpy(blob->pbData, pbEncoded, blob->cbData);
                }
            }
            else
            {
                SetLastError(CRYPT_E_ASN1_CORRUPT);
                ret = FALSE;
            }
        }
    }
    return ret;
}

/* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;

    TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
     * place.
     */
    ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
     dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
     pcbDecoded);
    if (ret && pvStructInfo)
    {
        CRYPT_BIT_BLOB *blob = pvStructInfo;

        if (blob->cbData)
        {
            DWORD i;
            BYTE temp;

            for (i = 0; i < blob->cbData / 2; i++)
            {
                temp = blob->pbData[i];
                blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
                blob->pbData[blob->cbData - i - 1] = temp;
            }
        }
    }
    TRACE("returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = TRUE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        struct AsnDecodeSequenceItem items[] = {
         { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
           CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
           offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
         { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
           SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
           sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
           offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
         { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
           CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
           offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
        };

        if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
            items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
        ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
         pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
         pcbStructInfo, NULL, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY

    TRACE("Returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    DWORD dataLen;

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);

        ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
         dwFlags, pvStructInfo, pcbStructInfo, NULL);
        if (pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
    }
    return ret;
}

static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;

    struct AsnDecodeSequenceItem items[] = {
     { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
       CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
     { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
       CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
    };

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, NULL);
    return ret;
}

static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
     offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
     FINALMEMBERSIZE(CERT_INFO, cExtension),
     CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
     offsetof(CERT_EXTENSION, pszObjId) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    DWORD dataLen;

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);

        ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes,
         dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
        if (ret && pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
    }
    return ret;
}

static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = TRUE;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
       CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
     { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
       CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
       TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
     { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
       CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
       FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
     { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
       sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
       Issuer.pbData) },
     { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
       CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
       FALSE, 0 },
     { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
       sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
       Subject.pbData) },
     { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
       CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
       FALSE, TRUE, offsetof(CERT_INFO,
       SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
     { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
       CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
       offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
     { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
       CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
       offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
     { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
       CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension),
       TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
    };

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
     NULL, NULL);
    if (ret && pvStructInfo)
    {
        CERT_INFO *info;

        if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
            info = *(CERT_INFO **)pvStructInfo;
        else
            info = pvStructInfo;
        if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
         !info->Subject.cbData)
        {
            SetLastError(CRYPT_E_ASN1_CORRUPT);
            /* Don't need to deallocate, because it should have failed on the
             * first pass (and no memory was allocated.)
             */
            ret = FALSE;
        }
    }

    TRACE("Returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        DWORD size = 0;

        /* Unless told not to, first try to decode it as a signed cert. */
        if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
        {
            PCERT_SIGNED_CONTENT_INFO signedCert = NULL;

            ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
             X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
             &signedCert, &size);
            if (ret)
            {
                size = 0;
                ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
                 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
                 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
                 pvStructInfo, pcbStructInfo);
                LocalFree(signedCert);
            }
        }
        /* Failing that, try it as an unsigned cert */
        if (!ret)
        {
            size = 0;
            ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
             X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
             pDecodePara, pvStructInfo, pcbStructInfo);
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY

    TRACE("Returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
     offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
     FINALMEMBERSIZE(CRL_ENTRY, cExtension),
     CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
     offsetof(CERT_EXTENSION, pszObjId) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
       CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
       offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
     { 0, offsetof(CRL_ENTRY, RevocationDate),
       CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
     { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
       CRYPT_AsnDecodeCRLEntryExtensions,
       FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
       offsetof(CRL_ENTRY, rgExtension), 0 },
    };
    PCRL_ENTRY entry = pvStructInfo;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
     *pcbStructInfo);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
     entry ? entry->SerialNumber.pbData : NULL);
    if (ret && entry && !entry->SerialNumber.cbData)
    {
        WARN("empty CRL entry serial number\n");
        SetLastError(CRYPT_E_ASN1_CORRUPT);
        ret = FALSE;
    }
    return ret;
}

/* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
 * whose rgCRLEntry member has been set prior to calling.
 */
static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
     offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
     MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
     CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
     offsetof(CRL_ENTRY, SerialNumber.pbData) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    TRACE("Returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
     offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
     FINALMEMBERSIZE(CRL_INFO, cExtension),
     CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
     offsetof(CERT_EXTENSION, pszObjId) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    DWORD dataLen;

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);

        ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes,
         dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
        if (ret && pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
    }
    return ret;
}

static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    struct AsnDecodeSequenceItem items[] = {
     { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
       CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
     { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
       CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
       FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
     { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
       sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
       Issuer.pbData) },
     { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
       sizeof(FILETIME), FALSE, FALSE, 0 },
     { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
       sizeof(FILETIME), TRUE, FALSE, 0 },
     { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
       CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
       TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
     { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
       CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension),
       TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
    };
    BOOL ret = TRUE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
     NULL, NULL);

    TRACE("Returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        DWORD size = 0;

        /* Unless told not to, first try to decode it as a signed crl. */
        if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
        {
            PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;

            ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
             X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
             &signedCrl, &size);
            if (ret)
            {
                size = 0;
                ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
                 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
                 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
                 pvStructInfo, pcbStructInfo);
                LocalFree(signedCrl);
            }
        }
        /* Failing that, try it as an unsigned crl */
        if (!ret)
        {
            size = 0;
            ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
             X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
             dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY

    TRACE("Returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    DWORD dataLen;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo);

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
        DWORD bytesNeeded = sizeof(LPSTR);

        if (dataLen)
        {
            /* The largest possible string for the first two components
             * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
             */
            char firstTwo[6];
            const BYTE *ptr;

            snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
             pbEncoded[1 + lenBytes] / 40,
             pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
             * 40);
            bytesNeeded += strlen(firstTwo) + 1;
            for (ptr = pbEncoded + 2 + lenBytes; ret &&
             ptr - pbEncoded - 1 - lenBytes < dataLen; )
            {
                /* large enough for ".4000000" */
                char str[9];
                int val = 0;

                while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
                 (*ptr & 0x80))
                {
                    val <<= 7;
                    val |= *ptr & 0x7f;
                    ptr++;
                }
                if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
                 (*ptr & 0x80))
                {
                    SetLastError(CRYPT_E_ASN1_CORRUPT);
                    ret = FALSE;
                }
                else
                {
                    val <<= 7;
                    val |= *ptr++;
                    snprintf(str, sizeof(str), ".%d", val);
                    bytesNeeded += strlen(str);
                }
            }
        }
        if (pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
        if (!pvStructInfo)
            *pcbStructInfo = bytesNeeded;
        else if (*pcbStructInfo < bytesNeeded)
        {
            *pcbStructInfo = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            if (dataLen)
            {
                const BYTE *ptr;
                LPSTR pszObjId = *(LPSTR *)pvStructInfo;

                *pszObjId = 0;
                sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
                 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
                 40) * 40);
                pszObjId += strlen(pszObjId);
                for (ptr = pbEncoded + 2 + lenBytes; ret &&
                 ptr - pbEncoded - 1 - lenBytes < dataLen; )
                {
                    int val = 0;

                    while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
                     (*ptr & 0x80))
                    {
                        val <<= 7;
                        val |= *ptr & 0x7f;
                        ptr++;
                    }
                    val <<= 7;
                    val |= *ptr++;
                    sprintf(pszObjId, ".%d", val);
                    pszObjId += strlen(pszObjId);
                }
            }
            else
                *(LPSTR *)pvStructInfo = NULL;
            *pcbStructInfo = bytesNeeded;
        }
    }
    return ret;
}

static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo);

    if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
        ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
         pvStructInfo, pcbStructInfo, pcbDecoded);
    else
    {
        SetLastError(CRYPT_E_ASN1_BADTAG);
        ret = FALSE;
    }
    return ret;
}

static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    struct AsnDecodeSequenceItem items[] = {
     { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
       CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
       offsetof(CERT_EXTENSION, pszObjId), 0 },
     { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
       sizeof(BOOL), TRUE, FALSE, 0, 0 },
     { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
       CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
       offsetof(CERT_EXTENSION, Value.pbData) },
    };
    BOOL ret = TRUE;
    PCERT_EXTENSION ext = pvStructInfo;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
     *pcbStructInfo);

    if (ext)
        TRACE("ext->pszObjId is %p\n", ext->pszObjId);
    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
     pcbDecoded, ext ? ext->pszObjId : NULL);
    if (ext)
        TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
         debugstr_a(ext->pszObjId));
    TRACE("returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = TRUE;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);

    __TRY
    {
        struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
         offsetof(CERT_EXTENSIONS, cExtension),
         offsetof(CERT_EXTENSIONS, rgExtension),
         sizeof(CERT_EXTENSIONS),
         CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
         offsetof(CERT_EXTENSION, pszObjId) };

        ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
         dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

/* Warning: this assumes the address of value->Value.pbData is already set, in
 * order to avoid overwriting memory.  (In some cases, it may change it, if it
 * doesn't copy anything to memory.)  Be sure to set it correctly!
 */
static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    DWORD dataLen;
    CERT_NAME_VALUE *value = pvStructInfo;

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
        DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;

        switch (pbEncoded[0])
        {
        case ASN_OCTETSTRING:
            valueType = CERT_RDN_OCTET_STRING;
            if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
                bytesNeeded += dataLen;
            break;
        case ASN_NUMERICSTRING:
            valueType = CERT_RDN_NUMERIC_STRING;
            if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
                bytesNeeded += dataLen;
            break;
        case ASN_PRINTABLESTRING:
            valueType = CERT_RDN_PRINTABLE_STRING;
            if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
                bytesNeeded += dataLen;
            break;
        case ASN_IA5STRING:
            valueType = CERT_RDN_IA5_STRING;
            if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
                bytesNeeded += dataLen;
            break;
        case ASN_T61STRING:
            valueType = CERT_RDN_T61_STRING;
            if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
                bytesNeeded += dataLen;
            break;
        case ASN_VIDEOTEXSTRING:
            valueType = CERT_RDN_VIDEOTEX_STRING;
            if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
                bytesNeeded += dataLen;
            break;
        case ASN_GRAPHICSTRING:
            valueType = CERT_RDN_GRAPHIC_STRING;
            if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
                bytesNeeded += dataLen;
            break;
        case ASN_VISIBLESTRING:
            valueType = CERT_RDN_VISIBLE_STRING;
            if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
                bytesNeeded += dataLen;
            break;
        case ASN_GENERALSTRING:
            valueType = CERT_RDN_GENERAL_STRING;
            if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
                bytesNeeded += dataLen;
            break;
        case ASN_UNIVERSALSTRING:
            FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
            SetLastError(CRYPT_E_ASN1_BADTAG);
            return FALSE;
        case ASN_BMPSTRING:
            valueType = CERT_RDN_BMP_STRING;
            bytesNeeded += dataLen;
            break;
        case ASN_UTF8STRING:
            valueType = CERT_RDN_UTF8_STRING;
            bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
             (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
            break;
        default:
            SetLastError(CRYPT_E_ASN1_BADTAG);
            return FALSE;
        }

        if (pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
        if (!value)
            *pcbStructInfo = bytesNeeded;
        else if (*pcbStructInfo < bytesNeeded)
        {
            *pcbStructInfo = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            *pcbStructInfo = bytesNeeded;
            value->dwValueType = valueType;
            if (dataLen)
            {
                DWORD i;

                assert(value->Value.pbData);
                switch (pbEncoded[0])
                {
                case ASN_OCTETSTRING:
                case ASN_NUMERICSTRING:
                case ASN_PRINTABLESTRING:
                case ASN_IA5STRING:
                case ASN_T61STRING:
                case ASN_VIDEOTEXSTRING:
                case ASN_GRAPHICSTRING:
                case ASN_VISIBLESTRING:
                case ASN_GENERALSTRING:
                    value->Value.cbData = dataLen;
                    if (dataLen)
                    {
                        if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
                            memcpy(value->Value.pbData,
                             pbEncoded + 1 + lenBytes, dataLen);
                        else
                            value->Value.pbData = (LPBYTE)pbEncoded + 1 +
                             lenBytes;
                    }
                    break;
                case ASN_BMPSTRING:
                {
                    LPWSTR str = (LPWSTR)value->Value.pbData;

                    value->Value.cbData = dataLen;
                    for (i = 0; i < dataLen / 2; i++)
                        str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
                         pbEncoded[1 + lenBytes + 2 * i + 1];
                    break;
                }
                case ASN_UTF8STRING:
                {
                    LPWSTR str = (LPWSTR)value->Value.pbData;

                    value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
                     (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, 
                     str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
                    break;
                }
                }
            }
            else
            {
                value->Value.cbData = 0;
                value->Value.pbData = NULL;
            }
        }
    }
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = TRUE;

    __TRY
    {
        ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
        if (ret && pvStructInfo)
        {
            ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
             pcbStructInfo, *pcbStructInfo);
            if (ret)
            {
                CERT_NAME_VALUE *value;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                value = pvStructInfo;
                value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
                ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
                 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 pcbStructInfo, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    DWORD dataLen;
    CERT_NAME_VALUE *value = pvStructInfo;

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
        DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;

        switch (pbEncoded[0])
        {
        case ASN_NUMERICSTRING:
            valueType = CERT_RDN_NUMERIC_STRING;
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_PRINTABLESTRING:
            valueType = CERT_RDN_PRINTABLE_STRING;
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_IA5STRING:
            valueType = CERT_RDN_IA5_STRING;
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_T61STRING:
            valueType = CERT_RDN_T61_STRING;
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_VIDEOTEXSTRING:
            valueType = CERT_RDN_VIDEOTEX_STRING;
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_GRAPHICSTRING:
            valueType = CERT_RDN_GRAPHIC_STRING;
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_VISIBLESTRING:
            valueType = CERT_RDN_VISIBLE_STRING;
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_GENERALSTRING:
            valueType = CERT_RDN_GENERAL_STRING;
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_UNIVERSALSTRING:
            valueType = CERT_RDN_UNIVERSAL_STRING;
            if (dataLen)
                bytesNeeded += dataLen / 2 + sizeof(WCHAR);
            break;
        case ASN_BMPSTRING:
            valueType = CERT_RDN_BMP_STRING;
            if (dataLen)
                bytesNeeded += dataLen + sizeof(WCHAR);
            break;
        case ASN_UTF8STRING:
            valueType = CERT_RDN_UTF8_STRING;
            if (dataLen)
                bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
                 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
            break;
        default:
            SetLastError(CRYPT_E_ASN1_BADTAG);
            return FALSE;
        }

        if (pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
        if (!value)
            *pcbStructInfo = bytesNeeded;
        else if (*pcbStructInfo < bytesNeeded)
        {
            *pcbStructInfo = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            *pcbStructInfo = bytesNeeded;
            value->dwValueType = valueType;
            if (dataLen)
            {
                DWORD i;
                LPWSTR str = (LPWSTR)value->Value.pbData;

                assert(value->Value.pbData);
                switch (pbEncoded[0])
                {
                case ASN_NUMERICSTRING:
                case ASN_PRINTABLESTRING:
                case ASN_IA5STRING:
                case ASN_T61STRING:
                case ASN_VIDEOTEXSTRING:
                case ASN_GRAPHICSTRING:
                case ASN_VISIBLESTRING:
                case ASN_GENERALSTRING:
                    value->Value.cbData = dataLen * 2;
                    for (i = 0; i < dataLen; i++)
                        str[i] = pbEncoded[1 + lenBytes + i];
                    str[i] = 0;
                    break;
                case ASN_UNIVERSALSTRING:
                    value->Value.cbData = dataLen / 2;
                    for (i = 0; i < dataLen / 4; i++)
                        str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
                         | pbEncoded[1 + lenBytes + 2 * i + 3];
                    str[i] = 0;
                    break;
                case ASN_BMPSTRING:
                    value->Value.cbData = dataLen;
                    for (i = 0; i < dataLen / 2; i++)
                        str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
                         pbEncoded[1 + lenBytes + 2 * i + 1];
                    str[i] = 0;
                    break;
                case ASN_UTF8STRING:
                    value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
                     (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
                     str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
                    *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
                    value->Value.cbData += sizeof(WCHAR);
                    break;
                }
            }
            else
            {
                value->Value.cbData = 0;
                value->Value.pbData = NULL;
            }
        }
    }
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = TRUE;

    __TRY
    {
        ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
        if (ret && pvStructInfo)
        {
            ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
             pcbStructInfo, *pcbStructInfo);
            if (ret)
            {
                CERT_NAME_VALUE *value;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                value = pvStructInfo;
                value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
                ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
                 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 pcbStructInfo, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
       CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
       offsetof(CERT_RDN_ATTR, pszObjId), 0 },
     { 0, offsetof(CERT_RDN_ATTR, dwValueType),
       CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
       FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
    };
    CERT_RDN_ATTR *attr = pvStructInfo;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo);

    if (attr)
        TRACE("attr->pszObjId is %p\n", attr->pszObjId);
    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
     attr ? attr->pszObjId : NULL);
    if (attr)
    {
        TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
         debugstr_a(attr->pszObjId));
        TRACE("attr->dwValueType is %d\n", attr->dwValueType);
    }
    TRACE("returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags,  void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
     offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
     sizeof(CERT_RDN),
     CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
     offsetof(CERT_RDN_ATTR, pszObjId) };

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
     NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = TRUE;

    __TRY
    {
        struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
         offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
         sizeof(CERT_NAME_INFO),
         CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
         offsetof(CERT_RDN, rgRDNAttr) };

        ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
         dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
       CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
       offsetof(CERT_RDN_ATTR, pszObjId), 0 },
     { 0, offsetof(CERT_RDN_ATTR, dwValueType),
       CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
       FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
    };
    CERT_RDN_ATTR *attr = pvStructInfo;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo);

    if (attr)
        TRACE("attr->pszObjId is %p\n", attr->pszObjId);
    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
     attr ? attr->pszObjId : NULL);
    if (attr)
    {
        TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
         debugstr_a(attr->pszObjId));
        TRACE("attr->dwValueType is %d\n", attr->dwValueType);
    }
    TRACE("returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
     offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
     sizeof(CERT_RDN),
     CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
     offsetof(CERT_RDN_ATTR, pszObjId) };

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
     NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = TRUE;

    __TRY
    {
        struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
         offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
         sizeof(CERT_NAME_INFO),
         CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
         offsetof(CERT_RDN, rgRDNAttr) };

        ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
         dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE, done = FALSE;
    DWORD indefiniteNestingLevels = 0, decoded = 0;

    TRACE("(%p, %d)\n", pbEncoded, cbEncoded);

    do {
        DWORD dataLen;

        if (!cbEncoded)
            done = TRUE;
        else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
         &dataLen)))
        {
            BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);

            if (dataLen == CMSG_INDEFINITE_LENGTH)
            {
                indefiniteNestingLevels++;
                pbEncoded += 1 + lenBytes;
                cbEncoded -= 1 + lenBytes;
                decoded += 1 + lenBytes;
                TRACE("indefiniteNestingLevels = %d\n",
                 indefiniteNestingLevels);
            }
            else
            {
                if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
                 indefiniteNestingLevels)
                {
                    indefiniteNestingLevels--;
                    TRACE("indefiniteNestingLevels = %d\n",
                     indefiniteNestingLevels);
                }
                pbEncoded += 1 + lenBytes + dataLen;
                cbEncoded -= 1 + lenBytes + dataLen;
                decoded += 1 + lenBytes + dataLen;
                if (!indefiniteNestingLevels)
                    done = TRUE;
            }
        }
    } while (ret && !done);
    /* If we haven't found all 0 TLVs, we haven't found the end */
    if (ret && indefiniteNestingLevels)
    {
        SetLastError(CRYPT_E_ASN1_EOD);
        ret = FALSE;
    }
    if (ret)
        *pcbDecoded = decoded;
    TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
    return ret;
}

static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo);

    if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
    {
        if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
            bytesNeeded += encodedLen;
        if (!pvStructInfo)
            *pcbStructInfo = bytesNeeded;
        else if (*pcbStructInfo < bytesNeeded)
        {
            SetLastError(ERROR_MORE_DATA);
            *pcbStructInfo = bytesNeeded;
            ret = FALSE;
        }
        else
        {
            PCRYPT_OBJID_BLOB blob = pvStructInfo;

            *pcbStructInfo = bytesNeeded;
            blob->cbData = encodedLen;
            if (encodedLen)
            {
                if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
                    blob->pbData = (LPBYTE)pbEncoded;
                else
                {
                    assert(blob->pbData);
                    memcpy(blob->pbData, pbEncoded, blob->cbData);
                }
            }
            else
                blob->pbData = NULL;
        }
        if (pcbDecoded)
            *pcbDecoded = encodedLen;
    }
    return ret;
}

static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
     offsetof(CTL_USAGE, cUsageIdentifier),
     offsetof(CTL_USAGE, rgpszUsageIdentifier),
     sizeof(CTL_USAGE),
     CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
     NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    struct AsnArrayDescriptor arrayDesc = { 0,
     offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
     FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
     CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
     offsetof(CRYPT_ATTRIBUTE, pszObjId) };
    BOOL ret;

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    struct AsnDecodeSequenceItem items[] = {
     { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
       CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
       offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
     { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
       CRYPT_AsnDecodeCTLEntryAttributes,
       FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
       offsetof(CTL_ENTRY, rgAttribute), 0 },
    };
    BOOL ret = TRUE;
    CTL_ENTRY *entry = pvStructInfo;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
     *pcbStructInfo);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
     pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
    return ret;
}

static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
     offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
     FINALMEMBERSIZE(CTL_INFO, cExtension),
     CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
     offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
     offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
     FINALMEMBERSIZE(CTL_INFO, cExtension),
     CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
     offsetof(CERT_EXTENSION, pszObjId) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    DWORD dataLen;

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);

        ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes,
         dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
        if (ret && pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
    }
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        struct AsnDecodeSequenceItem items[] = {
         { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
           CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
         { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
           CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
           offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
         { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
           CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
           TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
         { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
           CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
           TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
         { 0, offsetof(CTL_INFO, ThisUpdate),
           CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
           0 },
         { 0, offsetof(CTL_INFO, NextUpdate),
           CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
           0 },
         { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
           CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
           FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
         { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
           CRYPT_AsnDecodeCTLEntries,
           MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
           TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
         { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
           CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension),
           TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
        };

        ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
         pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
         pcbStructInfo, NULL, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
       CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
       offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
     { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
       CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
       offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
    };
    PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, capability ? capability->pszObjId : NULL);
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
         offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
         offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
         sizeof(CRYPT_SMIME_CAPABILITIES),
         CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
         offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };

        ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
         dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    DWORD dataLen;
    LPSTR *pStr = pvStructInfo;

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
        DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);

        if (pbEncoded[0] != ASN_IA5STRING)
        {
            SetLastError(CRYPT_E_ASN1_CORRUPT);
            ret = FALSE;
        }
        else
        {
            bytesNeeded += dataLen;
            if (pcbDecoded)
                *pcbDecoded = 1 + lenBytes + dataLen;
            if (!pvStructInfo)
                *pcbStructInfo = bytesNeeded;
            else if (*pcbStructInfo < bytesNeeded)
            {
                *pcbStructInfo = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                *pcbStructInfo = bytesNeeded;
                if (dataLen)
                {
                    LPSTR str = *pStr;

                    assert(str);
                    memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
                    str[dataLen] = 0;
                }
                else
                    *pStr = NULL;
            }
        }
    }
    return ret;
}

static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
     offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
     offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers),
     FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
     CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
    BOOL ret;

    TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, pvStructInfo ? *pcbDecoded : 0);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
       pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
       offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
     { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
       cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
       FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
       FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
       rgNoticeNumbers), 0 },
    };
    DWORD bytesNeeded;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
     NULL);
    if (ret)
    {
        /* The caller is expecting a pointer to a
         * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
         * CRYPT_AsnDecodeSequence is decoding a
         * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.  Increment the bytes
         * needed, and decode again if the requisite space is available.
         */
        bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
        if (!pvStructInfo)
            *pcbStructInfo = bytesNeeded;
        else if (*pcbStructInfo < bytesNeeded)
        {
            *pcbStructInfo = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;

            *pcbStructInfo = bytesNeeded;
            /* The pointer (pvStructInfo) passed in points to the first dynamic
             * pointer, so use it as the pointer to the
             * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
             * appropriate offset for the first dynamic pointer within the
             * notice reference by pointing to the first memory location past
             * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
             */
            noticeRef =
             *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
            noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
             sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
            ret = CRYPT_AsnDecodeSequence(items,
             sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
             NULL, noticeRef, &bytesNeeded, pcbDecoded,
             noticeRef->pszOrganization);
        }
    }
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    DWORD dataLen;

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
        DWORD bytesNeeded = sizeof(LPWSTR);

        switch (pbEncoded[0])
        {
        case ASN_NUMERICSTRING:
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_PRINTABLESTRING:
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_IA5STRING:
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_T61STRING:
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_VIDEOTEXSTRING:
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_GRAPHICSTRING:
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_VISIBLESTRING:
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_GENERALSTRING:
            if (dataLen)
                bytesNeeded += (dataLen + 1) * 2;
            break;
        case ASN_UNIVERSALSTRING:
            if (dataLen)
                bytesNeeded += dataLen / 2 + sizeof(WCHAR);
            break;
        case ASN_BMPSTRING:
            if (dataLen)
                bytesNeeded += dataLen + sizeof(WCHAR);
            break;
        case ASN_UTF8STRING:
            if (dataLen)
                bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
                 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
            break;
        default:
            SetLastError(CRYPT_E_ASN1_BADTAG);
            return FALSE;
        }

        if (pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
        if (!pvStructInfo)
            *pcbStructInfo = bytesNeeded;
        else if (*pcbStructInfo < bytesNeeded)
        {
            *pcbStructInfo = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            LPWSTR *pStr = pvStructInfo;

            *pcbStructInfo = bytesNeeded;
            if (dataLen)
            {
                DWORD i;
                LPWSTR str = *(LPWSTR *)pStr;

                assert(str);
                switch (pbEncoded[0])
                {
                case ASN_NUMERICSTRING:
                case ASN_PRINTABLESTRING:
                case ASN_IA5STRING:
                case ASN_T61STRING:
                case ASN_VIDEOTEXSTRING:
                case ASN_GRAPHICSTRING:
                case ASN_VISIBLESTRING:
                case ASN_GENERALSTRING:
                    for (i = 0; i < dataLen; i++)
                        str[i] = pbEncoded[1 + lenBytes + i];
                    str[i] = 0;
                    break;
                case ASN_UNIVERSALSTRING:
                    for (i = 0; i < dataLen / 4; i++)
                        str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
                         | pbEncoded[1 + lenBytes + 2 * i + 3];
                    str[i] = 0;
                    break;
                case ASN_BMPSTRING:
                    for (i = 0; i < dataLen / 2; i++)
                        str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
                         pbEncoded[1 + lenBytes + 2 * i + 1];
                    str[i] = 0;
                    break;
                case ASN_UTF8STRING:
                {
                    int len = MultiByteToWideChar(CP_UTF8, 0,
                     (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
                     str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
                    str[len] = 0;
                    break;
                }
                }
            }
            else
                *pStr = NULL;
        }
    }
    return ret;
}

static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
 DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
       pNoticeReference), CRYPT_AsnDecodeNoticeReference,
       sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
       offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
     { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
       CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
       offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
    };
    PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, notice ? notice->pNoticeReference : NULL);
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
 void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        DWORD bytesNeeded;

        ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(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)))
            {
                PCERT_POLICY_QUALIFIER_USER_NOTICE notice;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                notice = pvStructInfo;
                notice->pNoticeReference =
                 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
                 ((BYTE *)pvStructInfo +
                 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
                ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
                 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
                 pvStructInfo, &bytesNeeded, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnArrayDescriptor arrayDesc = { 0,
     offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
     FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue),
     CRYPT_AsnDecodeCopyBytes,
     sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
       CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
       offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
     { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
       CRYPT_AsnDecodePKCSAttributeValue,
       FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
       TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
    };
    PCRYPT_ATTRIBUTE attr = pvStructInfo;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, attr ? attr->pszObjId : NULL);
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        DWORD bytesNeeded;

        ret = CRYPT_AsnDecodePKCSAttributeInternal(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)))
            {
                PCRYPT_ATTRIBUTE attr;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                attr = pvStructInfo;
                attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
                 sizeof(CRYPT_ATTRIBUTE));
                ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
                 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
                 NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    struct AsnArrayDescriptor arrayDesc = { 0,
     offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
     sizeof(CRYPT_ATTRIBUTES),
     CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
     offsetof(CRYPT_ATTRIBUTE, pszObjId) };
    BOOL ret;

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
     NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
         offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
         sizeof(CRYPT_ATTRIBUTES),
         CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
         TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };

        ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
         dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
    BOOL ret = TRUE;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
       CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
       offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
     { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
       CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE, 
       offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
    };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, algo ? algo->pszObjId : NULL);
    if (ret && pvStructInfo)
    {
        TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
         debugstr_a(algo->pszObjId));
    }
    return ret;
}

static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
       CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
       FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
       Algorithm.pszObjId) },
     { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
       CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
       offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
    };
    PCERT_PUBLIC_KEY_INFO info = pvStructInfo;

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = TRUE;

    __TRY
    {
        DWORD bytesNeeded;

        if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
        {
            if (!pvStructInfo)
                *pcbStructInfo = bytesNeeded;
            else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
             pvStructInfo, pcbStructInfo, bytesNeeded)))
            {
                PCERT_PUBLIC_KEY_INFO info;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                info = pvStructInfo;
                info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
                 sizeof(CERT_PUBLIC_KEY_INFO);
                ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
                 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 &bytesNeeded, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;

    if (cbEncoded < 3)
    {
        SetLastError(CRYPT_E_ASN1_CORRUPT);
        return FALSE;
    }
    if (GET_LEN_BYTES(pbEncoded[1]) > 1)
    {
        SetLastError(CRYPT_E_ASN1_CORRUPT);
        return FALSE;
    }
    if (pbEncoded[1] > 1)
    {
        SetLastError(CRYPT_E_ASN1_CORRUPT);
        return FALSE;
    }
    if (pcbDecoded)
        *pcbDecoded = 3;
    if (!pvStructInfo)
    {
        *pcbStructInfo = sizeof(BOOL);
        ret = TRUE;
    }
    else if (*pcbStructInfo < sizeof(BOOL))
    {
        *pcbStructInfo = sizeof(BOOL);
        SetLastError(ERROR_MORE_DATA);
        ret = FALSE;
    }
    else
    {
        *pcbStructInfo = sizeof(BOOL);
        *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
        ret = TRUE;
    }
    TRACE("returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
    DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
    BOOL ret;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo);

    if (cbEncoded < 2)
    {
        SetLastError(CRYPT_E_ASN1_CORRUPT);
        return FALSE;
    }
    lenBytes = GET_LEN_BYTES(pbEncoded[1]);
    if (1 + lenBytes > cbEncoded)
    {
        SetLastError(CRYPT_E_ASN1_CORRUPT);
        return FALSE;
    }
    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        switch (pbEncoded[0] & ASN_TYPE_MASK)
        {
        case 1: /* rfc822Name */
        case 2: /* dNSName */
        case 6: /* uniformResourceIdentifier */
            bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
            break;
        case 4: /* directoryName */
        case 7: /* iPAddress */
            bytesNeeded += dataLen;
            break;
        case 8: /* registeredID */
            ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
             &dataLen, NULL);
            if (ret)
            {
                /* FIXME: ugly, shouldn't need to know internals of OID decode
                 * function to use it.
                 */
                bytesNeeded += dataLen - sizeof(LPSTR);
            }
            break;
        case 0: /* otherName */
            FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
            SetLastError(CRYPT_E_ASN1_BADTAG);
            ret = FALSE;
            break;
        case 3: /* x400Address, unimplemented */
        case 5: /* ediPartyName, unimplemented */
            TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
            SetLastError(CRYPT_E_ASN1_BADTAG);
            ret = FALSE;
            break;
        default:
            TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
            SetLastError(CRYPT_E_ASN1_CORRUPT);
            ret = FALSE;
        }
        if (ret)
        {
            if (pcbDecoded)
                *pcbDecoded = 1 + lenBytes + dataLen;
            if (!entry)
                *pcbStructInfo = bytesNeeded;
            else if (*pcbStructInfo < bytesNeeded)
            {
                *pcbStructInfo = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                *pcbStructInfo = bytesNeeded;
                /* MS used values one greater than the asn1 ones.. sigh */
                entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
                switch (pbEncoded[0] & ASN_TYPE_MASK)
                {
                case 1: /* rfc822Name */
                case 2: /* dNSName */
                case 6: /* uniformResourceIdentifier */
                {
                    DWORD i;

                    for (i = 0; i < dataLen; i++)
                        entry->u.pwszURL[i] =
                         (WCHAR)pbEncoded[1 + lenBytes + i];
                    entry->u.pwszURL[i] = 0;
                    TRACE("URL is %p (%s)\n", entry->u.pwszURL,
                     debugstr_w(entry->u.pwszURL));
                    break;
                }
                case 4: /* directoryName */
                    /* The data are memory-equivalent with the IPAddress case,
                     * fall-through
                     */
                case 7: /* iPAddress */
                    /* The next data pointer is in the pwszURL spot, that is,
                     * the first 4 bytes.  Need to move it to the next spot.
                     */
                    entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
                    entry->u.IPAddress.cbData = dataLen;
                    memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
                     dataLen);
                    break;
                case 8: /* registeredID */
                    ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
                     &entry->u.pszRegisteredID, &dataLen, NULL);
                    break;
                }
            }
        }
    }
    return ret;
}

static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnArrayDescriptor arrayDesc = { 0,
     offsetof(CERT_ALT_NAME_INFO, cAltEntry),
     offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
     sizeof(CERT_ALT_NAME_INFO),
     CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
     offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
     NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

/* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;

    TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
     * place.
     */
    ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
     dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
     pcbDecoded);
    if (ret && pvStructInfo)
    {
        CRYPT_DATA_BLOB *blob = pvStructInfo;

        if (blob->cbData)
        {
            DWORD i;
            BYTE temp;

            for (i = 0; i < blob->cbData / 2; i++)
            {
                temp = blob->pbData[i];
                blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
                blob->pbData[blob->cbData - i - 1] = temp;
            }
        }
    }
    TRACE("returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    __TRY
    {
        struct AsnDecodeSequenceItem items[] = {
         { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
           CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
           TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
         { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
           offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
           CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
           offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
         { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
           CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
           sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
           offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
        };

        ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
         pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
         pcbStructInfo, NULL, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    __TRY
    {
        struct AsnDecodeSequenceItem items[] = {
         { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
           CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
           TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
         { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
           offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
           CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
           TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
           AuthorityCertIssuer.rgAltEntry), 0 },
         { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
           AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
           sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
           offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
           AuthorityCertSerialNumber.pbData), 0 },
        };

        ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
         pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
         pcbStructInfo, NULL, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    struct AsnDecodeSequenceItem items[] = {
     { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
       CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
       offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
     { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
       CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
       TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
    };
    CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;

    return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, descr ? descr->pszAccessMethod : NULL);
}

static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
         offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr),
         offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr),
         sizeof(CERT_AUTHORITY_INFO_ACCESS),
         CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
         TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };

        ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
         dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    DWORD dataLen;

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    /* The caller has already checked the tag, no need to check it again.
     * Check the outer length is valid:
     */
    if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
        DWORD innerLen;

        pbEncoded += 1 + lenBytes;
        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)))
        {
            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;
}

static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    CRYPT_CONTENT_INFO *info = pvStructInfo;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
       CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
       offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
     { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
       offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
       sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
       offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
    };
    BOOL ret;

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, info ? info->pszObjId : NULL);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
        if (ret && pvStructInfo)
        {
            ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
             pcbStructInfo, *pcbStructInfo);
            if (ret)
            {
                CRYPT_CONTENT_INFO *info;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                info = pvStructInfo;
                info->pszObjId = (LPSTR)((BYTE *)info +
                 sizeof(CRYPT_CONTENT_INFO));
                ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
                 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 pcbStructInfo, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY
    return ret;
}

BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
{
    BOOL ret;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
       CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
     { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
       CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
       FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
       0 },
     { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
       CRYPT_AsnDecodePKCSContentInfoInternal,
       sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
       ContentInfo.pszObjId), 0 },
     { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
       CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
       offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
    };

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
     NULL, NULL);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = TRUE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        DWORD bytesNeeded;

        if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
        {
            if (!pvStructInfo)
                *pcbStructInfo = bytesNeeded;
            else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
             pvStructInfo, pcbStructInfo, bytesNeeded)))
            {
                CERT_ALT_NAME_INFO *name;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                name = pvStructInfo;
                name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
                 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
                ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
                 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 &bytesNeeded, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

struct PATH_LEN_CONSTRAINT
{
    BOOL  fPathLenConstraint;
    DWORD dwPathLenConstraint;
};

static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    if (!pvStructInfo)
    {
        ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
         &size, pcbDecoded);
        *pcbStructInfo = bytesNeeded;
    }
    else if (*pcbStructInfo < bytesNeeded)
    {
        SetLastError(ERROR_MORE_DATA);
        *pcbStructInfo = bytesNeeded;
        ret = FALSE;
    }
    else
    {
        struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;

        *pcbStructInfo = bytesNeeded;
        size = sizeof(constraint->dwPathLenConstraint);
        ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
         &constraint->dwPathLenConstraint, &size, pcbDecoded);
        if (ret)
            constraint->fPathLenConstraint = TRUE;
        TRACE("got an int, dwPathLenConstraint is %d\n",
         constraint->dwPathLenConstraint);
    }
    TRACE("returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
     offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
     offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
     FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
     CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
     offsetof(CERT_NAME_BLOB, pbData) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    TRACE("Returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    __TRY
    {
        struct AsnDecodeSequenceItem items[] = {
         { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
           CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE, 
           offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
         { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
           fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
           sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
         { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
           cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
           FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
           TRUE, TRUE,
           offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
        };

        ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
         pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
         pcbStructInfo, NULL, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    __TRY
    {
        struct AsnDecodeSequenceItem items[] = {
         { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
           CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
         { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
           fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
           sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
        };

        ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
         pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
         pcbStructInfo, NULL, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    struct AsnDecodeSequenceItem items[] = {
     { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
       pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
       FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
       0 },
     { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
       CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
       offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
    };
    BOOL ret;
    CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
    return ret;
}

static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
     offsetof(CERT_POLICY_INFO, cPolicyQualifier),
     offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
     FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
     CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
     offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    TRACE("Returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    struct AsnDecodeSequenceItem items[] = {
     { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
       CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
       offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
     { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
       CRYPT_AsnDecodePolicyQualifiers,
       FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE,
       TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
    };
    CERT_POLICY_INFO *info = pvStructInfo;
    BOOL ret;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);

    __TRY
    {
        struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
         offsetof(CERT_POLICIES_INFO, cPolicyInfo),
         offsetof(CERT_POLICIES_INFO, rgPolicyInfo),
         sizeof(CERT_POLICIES_INFO),
         CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
         offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };

        ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
         dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY
    return ret;
}

#define RSA1_MAGIC 0x31415352

struct DECODED_RSA_PUB_KEY
{
    DWORD              pubexp;
    CRYPT_INTEGER_BLOB modulus;
};

static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    __TRY
    {
        struct AsnDecodeSequenceItem items[] = {
         { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
           CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
           FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
           0 },
         { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
           CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
        };
        struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
        DWORD size = 0;

        ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
         pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
         &size, NULL, NULL);
        if (ret)
        {
            DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
             decodedKey->modulus.cbData;

            if (!pvStructInfo)
            {
                *pcbStructInfo = bytesNeeded;
                ret = TRUE;
            }
            else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
             pvStructInfo, pcbStructInfo, bytesNeeded)))
            {
                BLOBHEADER *hdr;
                RSAPUBKEY *rsaPubKey;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                hdr = pvStructInfo;
                hdr->bType = PUBLICKEYBLOB;
                hdr->bVersion = CUR_BLOB_VERSION;
                hdr->reserved = 0;
                hdr->aiKeyAlg = CALG_RSA_KEYX;
                rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
                 sizeof(BLOBHEADER));
                rsaPubKey->magic = RSA1_MAGIC;
                rsaPubKey->pubexp = decodedKey->pubexp;
                rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
                memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
                 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
                 decodedKey->modulus.cbData);
            }
            LocalFree(decodedKey);
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    DWORD bytesNeeded, dataLen;

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);

        if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
            bytesNeeded = sizeof(CRYPT_DATA_BLOB);
        else
            bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
        if (pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
        if (!pvStructInfo)
            *pcbStructInfo = bytesNeeded;
        else if (*pcbStructInfo < bytesNeeded)
        {
            SetLastError(ERROR_MORE_DATA);
            *pcbStructInfo = bytesNeeded;
            ret = FALSE;
        }
        else
        {
            CRYPT_DATA_BLOB *blob;

            *pcbStructInfo = bytesNeeded;
            blob = pvStructInfo;
            blob->cbData = dataLen;
            if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
                blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
            else
            {
                assert(blob->pbData);
                if (blob->cbData)
                    memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
                     blob->cbData);
            }
        }
    }
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        DWORD bytesNeeded;

        if (!cbEncoded)
        {
            SetLastError(CRYPT_E_ASN1_CORRUPT);
            ret = FALSE;
        }
        else if (pbEncoded[0] != ASN_OCTETSTRING)
        {
            SetLastError(CRYPT_E_ASN1_BADTAG);
            ret = FALSE;
        }
        else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
        {
            if (!pvStructInfo)
                *pcbStructInfo = bytesNeeded;
            else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
             pvStructInfo, pcbStructInfo, bytesNeeded)))
            {
                CRYPT_DATA_BLOB *blob;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                blob = pvStructInfo;
                blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
                ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
                 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 &bytesNeeded, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    DWORD bytesNeeded, dataLen;
    BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);

    TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
            bytesNeeded = sizeof(CRYPT_BIT_BLOB);
        else
            bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
        if (pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
        if (!pvStructInfo)
            *pcbStructInfo = bytesNeeded;
        else if (*pcbStructInfo < bytesNeeded)
        {
            *pcbStructInfo = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            CRYPT_BIT_BLOB *blob;

            *pcbStructInfo = bytesNeeded;
            blob = pvStructInfo;
            blob->cbData = dataLen - 1;
            blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
            if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
            {
                blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
            }
            else
            {
                assert(blob->pbData);
                if (blob->cbData)
                {
                    BYTE mask = 0xff << blob->cUnusedBits;

                    memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
                     blob->cbData);
                    blob->pbData[blob->cbData - 1] &= mask;
                }
            }
        }
    }
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, pcbStructInfo);

    __TRY
    {
        DWORD bytesNeeded;

        if (!cbEncoded)
        {
            SetLastError(CRYPT_E_ASN1_CORRUPT);
            ret = FALSE;
        }
        else if (pbEncoded[0] != ASN_BITSTRING)
        {
            SetLastError(CRYPT_E_ASN1_BADTAG);
            ret = FALSE;
        }
        else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
        {
            if (!pvStructInfo)
                *pcbStructInfo = bytesNeeded;
            else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
             pvStructInfo, pcbStructInfo, bytesNeeded)))
            {
                CRYPT_BIT_BLOB *blob;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                blob = pvStructInfo;
                blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
                ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
                 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 &bytesNeeded, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    TRACE("returning %d (%08x)\n", ret, GetLastError());
    return ret;
}

/* Ignores tag.  Only allows integers 4 bytes or smaller in size. */
static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    DWORD dataLen;

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);

        if (pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
        if (dataLen > sizeof(int))
        {
            SetLastError(CRYPT_E_ASN1_LARGE);
            ret = FALSE;
        }
        else if (!pvStructInfo)
            *pcbStructInfo = sizeof(int);
        else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
        {
            int val, i;

            if (dataLen && pbEncoded[1 + lenBytes] & 0x80)
            {
                /* initialize to a negative value to sign-extend */
                val = -1;
            }
            else
                val = 0;
            for (i = 0; i < dataLen; i++)
            {
                val <<= 8;
                val |= pbEncoded[1 + lenBytes + i];
            }
            memcpy(pvStructInfo, &val, sizeof(int));
        }
    }
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    __TRY
    {
        DWORD bytesNeeded;

        if (!cbEncoded)
        {
            SetLastError(CRYPT_E_ASN1_EOD);
            ret = FALSE;
        }
        else if (pbEncoded[0] != ASN_INTEGER)
        {
            SetLastError(CRYPT_E_ASN1_BADTAG);
            ret = FALSE;
        }
        else
            ret = CRYPT_AsnDecodeIntInternal(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)))
            {
                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
                 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 &bytesNeeded, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    DWORD bytesNeeded, dataLen;

    if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
    {
        BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);

        bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
        if (pcbDecoded)
            *pcbDecoded = 1 + lenBytes + dataLen;
        if (!pvStructInfo)
            *pcbStructInfo = bytesNeeded;
        else if (*pcbStructInfo < bytesNeeded)
        {
            *pcbStructInfo = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            CRYPT_INTEGER_BLOB *blob = pvStructInfo;

            *pcbStructInfo = bytesNeeded;
            blob->cbData = dataLen;
            assert(blob->pbData);
            if (blob->cbData)
            {
                DWORD i;

                for (i = 0; i < blob->cbData; i++)
                {
                    blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
                     dataLen - i - 1);
                }
            }
        }
    }
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    __TRY
    {
        DWORD bytesNeeded;

        if (pbEncoded[0] != ASN_INTEGER)
        {
            SetLastError(CRYPT_E_ASN1_BADTAG);
            ret = FALSE;
        }
        else
            ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
             dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
        if (ret)
        {
            if (!pvStructInfo)
                *pcbStructInfo = bytesNeeded;
            else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
             pvStructInfo, pcbStructInfo, bytesNeeded)))
            {
                CRYPT_INTEGER_BLOB *blob;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                blob = pvStructInfo;
                blob->pbData = (BYTE *)pvStructInfo +
                 sizeof(CRYPT_INTEGER_BLOB);
                ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
                 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
                 &bytesNeeded, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;

    if (pbEncoded[0] == ASN_INTEGER)
    {
        DWORD bytesNeeded, dataLen;

        if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
        {
            BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);

            if (pcbDecoded)
                *pcbDecoded = 1 + lenBytes + dataLen;
            bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
            if (!pvStructInfo)
                *pcbStructInfo = bytesNeeded;
            else if (*pcbStructInfo < bytesNeeded)
            {
                *pcbStructInfo = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                CRYPT_INTEGER_BLOB *blob = pvStructInfo;

                *pcbStructInfo = bytesNeeded;
                blob->cbData = dataLen;
                assert(blob->pbData);
                /* remove leading zero byte if it exists */
                if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
                {
                    blob->cbData--;
                    blob->pbData++;
                }
                if (blob->cbData)
                {
                    DWORD i;

                    for (i = 0; i < blob->cbData; i++)
                    {
                        blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
                         dataLen - i - 1);
                    }
                }
            }
        }
    }
    else
    {
        SetLastError(CRYPT_E_ASN1_BADTAG);
        ret = FALSE;
    }
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    __TRY
    {
        DWORD bytesNeeded;

        if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
         dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
        {
            if (!pvStructInfo)
                *pcbStructInfo = bytesNeeded;
            else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
             pvStructInfo, pcbStructInfo, bytesNeeded)))
            {
                CRYPT_INTEGER_BLOB *blob;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                blob = pvStructInfo;
                blob->pbData = (BYTE *)pvStructInfo +
                 sizeof(CRYPT_INTEGER_BLOB);
                ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
                 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
                 &bytesNeeded, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    if (!pvStructInfo)
    {
        *pcbStructInfo = sizeof(int);
        return TRUE;
    }
    __TRY
    {
        if (pbEncoded[0] == ASN_ENUMERATED)
        {
            unsigned int val = 0, i;

            if (cbEncoded <= 1)
            {
                SetLastError(CRYPT_E_ASN1_EOD);
                ret = FALSE;
            }
            else if (pbEncoded[1] == 0)
            {
                SetLastError(CRYPT_E_ASN1_CORRUPT);
                ret = FALSE;
            }
            else
            {
                /* A little strange looking, but we have to accept a sign byte:
                 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff.  Also,
                 * assuming a small length is okay here, it has to be in short
                 * form.
                 */
                if (pbEncoded[1] > sizeof(unsigned int) + 1)
                {
                    SetLastError(CRYPT_E_ASN1_LARGE);
                    return FALSE;
                }
                for (i = 0; i < pbEncoded[1]; i++)
                {
                    val <<= 8;
                    val |= pbEncoded[2 + i];
                }
                if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
                 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
                {
                    if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                        pvStructInfo = *(BYTE **)pvStructInfo;
                    memcpy(pvStructInfo, &val, sizeof(unsigned int));
                }
            }
        }
        else
        {
            SetLastError(CRYPT_E_ASN1_BADTAG);
            ret = FALSE;
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

/* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
 * if it fails.
 */
#define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
 do { \
    BYTE i; \
 \
    (word) = 0; \
    for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
    { \
        if (!isdigit(*(pbEncoded))) \
        { \
            SetLastError(CRYPT_E_ASN1_CORRUPT); \
            ret = FALSE; \
        } \
        else \
        { \
            (word) *= 10; \
            (word) += *(pbEncoded)++ - '0'; \
        } \
    } \
 } while (0)

static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
 SYSTEMTIME *sysTime)
{
    BOOL ret = TRUE;

    if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
    {
        WORD hours, minutes = 0;
        BYTE sign = *pbEncoded++;

        len--;
        CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
        if (ret && hours >= 24)
        {
            SetLastError(CRYPT_E_ASN1_CORRUPT);
            ret = FALSE;
        }
        else if (len >= 2)
        {
            CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
            if (ret && minutes >= 60)
            {
                SetLastError(CRYPT_E_ASN1_CORRUPT);
                ret = FALSE;
            }
        }
        if (ret)
        {
            if (sign == '+')
            {
                sysTime->wHour += hours;
                sysTime->wMinute += minutes;
            }
            else
            {
                if (hours > sysTime->wHour)
                {
                    sysTime->wDay--;
                    sysTime->wHour = 24 - (hours - sysTime->wHour);
                }
                else
                    sysTime->wHour -= hours;
                if (minutes > sysTime->wMinute)
                {
                    sysTime->wHour--;
                    sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
                }
                else
                    sysTime->wMinute -= minutes;
            }
        }
    }
    return ret;
}

#define MIN_ENCODED_TIME_LENGTH 10

static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = FALSE;

    if (pbEncoded[0] == ASN_UTCTIME)
    {
        if (cbEncoded <= 1)
            SetLastError(CRYPT_E_ASN1_EOD);
        else if (pbEncoded[1] > 0x7f)
        {
            /* long-form date strings really can't be valid */
            SetLastError(CRYPT_E_ASN1_CORRUPT);
        }
        else
        {
            SYSTEMTIME sysTime = { 0 };
            BYTE len = pbEncoded[1];

            if (len < MIN_ENCODED_TIME_LENGTH)
                SetLastError(CRYPT_E_ASN1_CORRUPT);
            else
            {
                ret = TRUE;
                if (pcbDecoded)
                    *pcbDecoded = 2 + len;
                pbEncoded += 2;
                CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
                if (sysTime.wYear >= 50)
                    sysTime.wYear += 1900;
                else
                    sysTime.wYear += 2000;
                CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
                CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
                CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
                CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
                if (ret && len > 0)
                {
                    if (len >= 2 && isdigit(*pbEncoded) &&
                     isdigit(*(pbEncoded + 1)))
                        CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
                         sysTime.wSecond);
                    else if (isdigit(*pbEncoded))
                        CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
                         sysTime.wSecond);
                    if (ret)
                        ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
                         &sysTime);
                }
                if (ret)
                {
                    if (!pvStructInfo)
                        *pcbStructInfo = sizeof(FILETIME);
                    else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
                     sizeof(FILETIME))))
                        ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
                }
            }
        }
    }
    else
        SetLastError(CRYPT_E_ASN1_BADTAG);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    __TRY
    {
        DWORD bytesNeeded;

        ret = CRYPT_AsnDecodeUtcTimeInternal(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)))
            {
                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
                 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 &bytesNeeded, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = FALSE;

    if (pbEncoded[0] == ASN_GENERALTIME)
    {
        if (cbEncoded <= 1)
            SetLastError(CRYPT_E_ASN1_EOD);
        else if (pbEncoded[1] > 0x7f)
        {
            /* long-form date strings really can't be valid */
            SetLastError(CRYPT_E_ASN1_CORRUPT);
        }
        else
        {
            BYTE len = pbEncoded[1];

            if (len < MIN_ENCODED_TIME_LENGTH)
                SetLastError(CRYPT_E_ASN1_CORRUPT);
            else
            {
                SYSTEMTIME sysTime = { 0 };

                ret = TRUE;
                if (pcbDecoded)
                    *pcbDecoded = 2 + len;
                pbEncoded += 2;
                CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
                CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
                CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
                CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
                if (ret && len > 0)
                {
                    CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
                     sysTime.wMinute);
                    if (ret && len > 0)
                        CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
                         sysTime.wSecond);
                    if (ret && len > 0 && (*pbEncoded == '.' ||
                     *pbEncoded == ','))
                    {
                        BYTE digits;

                        pbEncoded++;
                        len--;
                        /* workaround macro weirdness */
                        digits = min(len, 3);
                        CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
                         sysTime.wMilliseconds);
                    }
                    if (ret)
                        ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
                         &sysTime);
                }
                if (ret)
                {
                    if (!pvStructInfo)
                        *pcbStructInfo = sizeof(FILETIME);
                    else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
                     sizeof(FILETIME))))
                        ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
                }
            }
        }
    }
    else
        SetLastError(CRYPT_E_ASN1_BADTAG);
    return ret;
}

static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    InternalDecodeFunc decode = NULL;

    if (pbEncoded[0] == ASN_UTCTIME)
        decode = CRYPT_AsnDecodeUtcTimeInternal;
    else if (pbEncoded[0] == ASN_GENERALTIME)
        decode = CRYPT_AsnDecodeGeneralizedTime;
    if (decode)
        ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
         pcbStructInfo, pcbDecoded);
    else
    {
        SetLastError(CRYPT_E_ASN1_BADTAG);
        ret = FALSE;
    }
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    __TRY
    {
        DWORD bytesNeeded;

        ret = CRYPT_AsnDecodeChoiceOfTimeInternal(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)))
            {
                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
                 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 &bytesNeeded, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = TRUE;

    __TRY
    {
        if (pbEncoded[0] == ASN_SEQUENCEOF)
        {
            DWORD bytesNeeded, dataLen, remainingLen, cValue;

            if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
            {
                BYTE lenBytes;
                const BYTE *ptr;

                lenBytes = GET_LEN_BYTES(pbEncoded[1]);
                bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
                cValue = 0;
                ptr = pbEncoded + 1 + lenBytes;
                remainingLen = dataLen;
                while (ret && remainingLen)
                {
                    DWORD nextLen;

                    ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
                    if (ret)
                    {
                        DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);

                        remainingLen -= 1 + nextLenBytes + nextLen;
                        ptr += 1 + nextLenBytes + nextLen;
                        bytesNeeded += sizeof(CRYPT_DER_BLOB);
                        if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
                            bytesNeeded += 1 + nextLenBytes + nextLen;
                        cValue++;
                    }
                }
                if (ret)
                {
                    CRYPT_SEQUENCE_OF_ANY *seq;
                    BYTE *nextPtr;
                    DWORD i;

                    if (!pvStructInfo)
                        *pcbStructInfo = bytesNeeded;
                    else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
                     pvStructInfo, pcbStructInfo, bytesNeeded)))
                    {
                        if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                            pvStructInfo = *(BYTE **)pvStructInfo;
                        seq = pvStructInfo;
                        seq->cValue = cValue;
                        seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
                         sizeof(*seq));
                        nextPtr = (BYTE *)seq->rgValue +
                         cValue * sizeof(CRYPT_DER_BLOB);
                        ptr = pbEncoded + 1 + lenBytes;
                        remainingLen = dataLen;
                        i = 0;
                        while (ret && remainingLen)
                        {
                            DWORD nextLen;

                            ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
                            if (ret)
                            {
                                DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);

                                seq->rgValue[i].cbData = 1 + nextLenBytes +
                                 nextLen;
                                if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
                                    seq->rgValue[i].pbData = (BYTE *)ptr;
                                else
                                {
                                    seq->rgValue[i].pbData = nextPtr;
                                    memcpy(nextPtr, ptr, 1 + nextLenBytes +
                                     nextLen);
                                    nextPtr += 1 + nextLenBytes + nextLen;
                                }
                                remainingLen -= 1 + nextLenBytes + nextLen;
                                ptr += 1 + nextLenBytes + nextLen;
                                i++;
                            }
                        }
                    }
                }
            }
        }
        else
        {
            SetLastError(CRYPT_E_ASN1_BADTAG);
            ret = FALSE;
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;

    if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
    {
        DWORD bytesNeeded, dataLen;

        if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
        {
            struct AsnArrayDescriptor arrayDesc = {
             ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
             offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry),
             offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry),
             FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u),
             CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
             offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
            BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
            DWORD nameLen;

            if (dataLen)
            {
                ret = CRYPT_AsnDecodeArray(&arrayDesc,
                 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
                 dwFlags, NULL, NULL, &nameLen, NULL);
                bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
                 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u);
            }
            else
                bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
            if (pcbDecoded)
                *pcbDecoded = 1 + lenBytes + dataLen;
            if (!pvStructInfo)
                *pcbStructInfo = bytesNeeded;
            else if (*pcbStructInfo < bytesNeeded)
            {
                *pcbStructInfo = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                CRL_DIST_POINT_NAME *name = pvStructInfo;

                *pcbStructInfo = bytesNeeded;
                if (dataLen)
                {
                    name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
                    ret = CRYPT_AsnDecodeArray(&arrayDesc,
                     pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
                     dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen,
                     NULL);
                }
                else
                    name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
            }
        }
    }
    else
    {
        SetLastError(CRYPT_E_ASN1_BADTAG);
        ret = FALSE;
    }
    return ret;
}

static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    struct AsnDecodeSequenceItem items[] = {
     { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
       DistPointName), CRYPT_AsnDecodeDistPointName,
       sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
       DistPointName.u.FullName.rgAltEntry), 0 },
     { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
       CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
       offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
     { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
       CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
       offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
    };
    CRL_DIST_POINT *point = pvStructInfo;
    BOOL ret;

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
         offsetof(CRL_DIST_POINTS_INFO, cDistPoint),
         offsetof(CRL_DIST_POINTS_INFO, rgDistPoint),
         sizeof(CRL_DIST_POINTS_INFO),
         CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
         offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };

        ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
         dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
         offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier),
         offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier),
         sizeof(CERT_ENHKEY_USAGE),
         CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };

        ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
         dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        struct AsnDecodeSequenceItem items[] = {
         { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
           DistPointName), CRYPT_AsnDecodeDistPointName,
           sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
           offsetof(CRL_ISSUING_DIST_POINT,
           DistPointName.u.FullName.rgAltEntry), 0 },
         { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
           fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
           FALSE, 0 },
         { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
           fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
           FALSE, 0 },
         { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
           OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
           sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
           OnlySomeReasonFlags.pbData), 0 },
         { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
           fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
        };

        ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
         pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
         pcbStructInfo, NULL, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        ret = FALSE;
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    DWORD max, size = sizeof(max);

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    if (!cbEncoded)
    {
        SetLastError(CRYPT_E_ASN1_EOD);
        return FALSE;
    }
    if (pbEncoded[0] != (ASN_CONTEXT | 1))
    {
        SetLastError(CRYPT_E_ASN1_BADTAG);
        return FALSE;
    }
    if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
     &max, &size, pcbDecoded)))
    {
        DWORD bytesNeeded = FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum);

        if (!pvStructInfo)
            *pcbStructInfo = bytesNeeded;
        else if (*pcbStructInfo < bytesNeeded)
        {
            *pcbStructInfo = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            CERT_GENERAL_SUBTREE *subtree = (CERT_GENERAL_SUBTREE *)
             ((BYTE *)pvStructInfo - offsetof(CERT_GENERAL_SUBTREE, fMaximum));

            *pcbStructInfo = bytesNeeded;
            /* The BOOL is implicit:  if the integer is present, then it's
             * TRUE.
             */
            subtree->fMaximum = TRUE;
            subtree->dwMaximum = max;
        }
    }
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnDecodeSequenceItem items[] = {
     { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
       CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
       offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
     { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
       CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
     { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
       CRYPT_AsnDecodeMaximum, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum),
       TRUE, FALSE, 0, 0 },
    };
    CERT_GENERAL_SUBTREE *subtree = pvStructInfo;

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
    if (pcbDecoded)
    {
        TRACE("%d\n", *pcbDecoded);
        if (*pcbDecoded < cbEncoded)
            TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
             *(pbEncoded + *pcbDecoded + 1));
    }
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    struct AsnArrayDescriptor arrayDesc = { 0,
     offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
     offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree),
     MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
                cExcludedSubtree),
     CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
     offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret = TRUE;
    struct AsnArrayDescriptor arrayDesc = { 0,
     offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
     offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree),
     FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
     CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
     offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        struct AsnDecodeSequenceItem items[] = {
         { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
           offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
           CRYPT_AsnDecodePermittedSubtree,
           MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
           cExcludedSubtree), TRUE, TRUE,
           offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
         { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
           offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
           CRYPT_AsnDecodeExcludedSubtree,
           FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
           TRUE, TRUE,
           offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
        };

        ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
         pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
         pcbStructInfo, NULL, NULL);
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY
    return ret;
}

static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnDecodeSequenceItem items[] = {
     { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
       sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
       Issuer.pbData) },
     { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
       CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
       TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
    };
    CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
    if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
    {
        SetLastError(CRYPT_E_ASN1_CORRUPT);
        ret = FALSE;
    }
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    CMSG_SIGNER_INFO *info = pvStructInfo;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
       CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
     { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
       CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
       FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
     { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
       CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
       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),
       CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
       FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
       HashEncryptionAlgorithm.pszObjId), 0 },
     { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
       CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
       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 },
    };
    BOOL ret;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, info ? info->Issuer.pbData : NULL);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
        if (ret && pvStructInfo)
        {
            ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
             pcbStructInfo, *pcbStructInfo);
            if (ret)
            {
                CMSG_SIGNER_INFO *info;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                info = pvStructInfo;
                info->Issuer.pbData = ((BYTE *)info +
                 sizeof(CMSG_SIGNER_INFO));
                ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
                 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 pcbStructInfo, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnArrayDescriptor arrayDesc = { 0,
     offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
     offsetof(CRYPT_SIGNED_INFO, rgCertEncoded),
     MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded),
     CRYPT_AsnDecodeCopyBytes,
     sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnArrayDescriptor arrayDesc = { 0,
     offsetof(CRYPT_SIGNED_INFO, cCrlEncoded),
     offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded),
     MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content),
     CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB),
     TRUE, offsetof(CRYPT_DER_BLOB, pbData) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    CERT_ID *id = pvStructInfo;
    BOOL ret = FALSE;

    if (*pbEncoded == ASN_SEQUENCEOF)
    {
        ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
         id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
        if (ret)
        {
            if (id)
                id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
            if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
                *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
                 sizeof(CERT_ISSUER_SERIAL_NUMBER);
            else
                *pcbStructInfo = sizeof(CERT_ID);
        }
    }
    else if (*pbEncoded == (ASN_CONTEXT | 0))
    {
        ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
         id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
        if (ret)
        {
            if (id)
                id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
            if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
                *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
                 sizeof(CRYPT_DATA_BLOB);
            else
                *pcbStructInfo = sizeof(CERT_ID);
        }
    }
    else
        SetLastError(CRYPT_E_ASN1_BADTAG);
    return ret;
}

static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
 DWORD *pcbDecoded)
{
    CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
       CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
     { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
       CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
       offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
     { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
       CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
       FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
     { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
       offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
       CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
       TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
     { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
       CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
       FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
       HashEncryptionAlgorithm.pszObjId), 0 },
     { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
       CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
       FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
     { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
       offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
       CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
       TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
    };
    BOOL ret;

    TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
     pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
    return ret;
}

static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, pvStructInfo, *pcbStructInfo);

    __TRY
    {
        ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
        if (ret && pvStructInfo)
        {
            ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
             pcbStructInfo, *pcbStructInfo);
            if (ret)
            {
                CMSG_CMS_SIGNER_INFO *info;

                if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                    pvStructInfo = *(BYTE **)pvStructInfo;
                info = pvStructInfo;
                info->SignerId.u.KeyId.pbData = ((BYTE *)info +
                 sizeof(CMSG_CMS_SIGNER_INFO));
                ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
                 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
                 pcbStructInfo, NULL);
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
    }
    __ENDTRY
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
{
    BOOL ret;
    struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
     offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
     offsetof(CRYPT_SIGNED_INFO, rgSignerInfo),
     FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo),
     CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
     offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };

    TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, *pcbStructInfo, pcbDecoded);

    ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
     dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
    return ret;
}

BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
{
    BOOL ret = FALSE;
    struct AsnDecodeSequenceItem items[] = {
     { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
       CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
     /* Placeholder for the hash algorithms - redundant with those in the
      * signers, so just ignore them.
      */
     { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
     { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
       CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
       FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
     { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
       offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded,
       MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE,
       offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
     { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
       offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded,
       MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE,
       offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
     { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
       CRYPT_DecodeSignerArray,
       FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE,
       offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
    };

    TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
     pDecodePara, signedInfo, *pcbSignedInfo);

    ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
     pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
     NULL, NULL);
    TRACE("returning %d\n", ret);
    return ret;
}

static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
 LPCSTR lpszStructType)
{
    CryptDecodeObjectExFunc decodeFunc = NULL;

    if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
     && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
    {
        SetLastError(ERROR_FILE_NOT_FOUND);
        return NULL;
    }
    if (!HIWORD(lpszStructType))
    {
        switch (LOWORD(lpszStructType))
        {
        case LOWORD(X509_CERT):
            decodeFunc = CRYPT_AsnDecodeCertSignedContent;
            break;
        case LOWORD(X509_CERT_TO_BE_SIGNED):
            decodeFunc = CRYPT_AsnDecodeCert;
            break;
        case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
            decodeFunc = CRYPT_AsnDecodeCRL;
            break;
        case LOWORD(X509_EXTENSIONS):
            decodeFunc = CRYPT_AsnDecodeExtensions;
            break;
        case LOWORD(X509_NAME_VALUE):
            decodeFunc = CRYPT_AsnDecodeNameValue;
            break;
        case LOWORD(X509_NAME):
            decodeFunc = CRYPT_AsnDecodeName;
            break;
        case LOWORD(X509_PUBLIC_KEY_INFO):
            decodeFunc = CRYPT_AsnDecodePubKeyInfo;
            break;
        case LOWORD(X509_AUTHORITY_KEY_ID):
            decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
            break;
        case LOWORD(X509_ALTERNATE_NAME):
            decodeFunc = CRYPT_AsnDecodeAltName;
            break;
        case LOWORD(X509_BASIC_CONSTRAINTS):
            decodeFunc = CRYPT_AsnDecodeBasicConstraints;
            break;
        case LOWORD(X509_BASIC_CONSTRAINTS2):
            decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
            break;
        case LOWORD(X509_CERT_POLICIES):
            decodeFunc = CRYPT_AsnDecodeCertPolicies;
            break;
        case LOWORD(RSA_CSP_PUBLICKEYBLOB):
            decodeFunc = CRYPT_AsnDecodeRsaPubKey;
            break;
        case LOWORD(X509_UNICODE_NAME):
            decodeFunc = CRYPT_AsnDecodeUnicodeName;
            break;
        case LOWORD(PKCS_ATTRIBUTE):
            decodeFunc = CRYPT_AsnDecodePKCSAttribute;
            break;
        case LOWORD(X509_UNICODE_NAME_VALUE):
            decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
            break;
        case LOWORD(X509_OCTET_STRING):
            decodeFunc = CRYPT_AsnDecodeOctets;
            break;
        case LOWORD(X509_BITS):
        case LOWORD(X509_KEY_USAGE):
            decodeFunc = CRYPT_AsnDecodeBits;
            break;
        case LOWORD(X509_INTEGER):
            decodeFunc = CRYPT_AsnDecodeInt;
            break;
        case LOWORD(X509_MULTI_BYTE_INTEGER):
            decodeFunc = CRYPT_AsnDecodeInteger;
            break;
        case LOWORD(X509_MULTI_BYTE_UINT):
            decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
            break;
        case LOWORD(X509_ENUMERATED):
            decodeFunc = CRYPT_AsnDecodeEnumerated;
            break;
        case LOWORD(X509_CHOICE_OF_TIME):
            decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
            break;
        case LOWORD(X509_AUTHORITY_KEY_ID2):
            decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
            break;
        case LOWORD(X509_AUTHORITY_INFO_ACCESS):
            decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
            break;
        case LOWORD(PKCS_CONTENT_INFO):
            decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
            break;
        case LOWORD(X509_SEQUENCE_OF_ANY):
            decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
            break;
        case LOWORD(PKCS_UTC_TIME):
            decodeFunc = CRYPT_AsnDecodeUtcTime;
            break;
        case LOWORD(X509_CRL_DIST_POINTS):
            decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
            break;
        case LOWORD(X509_ENHANCED_KEY_USAGE):
            decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
            break;
        case LOWORD(PKCS_CTL):
            decodeFunc = CRYPT_AsnDecodeCTL;
            break;
        case LOWORD(PKCS_SMIME_CAPABILITIES):
            decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
            break;
        case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
            decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
            break;
        case LOWORD(PKCS_ATTRIBUTES):
            decodeFunc = CRYPT_AsnDecodePKCSAttributes;
            break;
        case LOWORD(X509_ISSUING_DIST_POINT):
            decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
            break;
        case LOWORD(X509_NAME_CONSTRAINTS):
            decodeFunc = CRYPT_AsnDecodeNameConstraints;
            break;
        case LOWORD(PKCS7_SIGNER_INFO):
            decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
            break;
        case LOWORD(CMS_SIGNER_INFO):
            decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
            break;
        }
    }
    else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
        decodeFunc = CRYPT_AsnDecodeExtensions;
    else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
        decodeFunc = CRYPT_AsnDecodeUtcTime;
    else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
        decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
    else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
        decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
    else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
        decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
    else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
        decodeFunc = CRYPT_AsnDecodeEnumerated;
    else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
        decodeFunc = CRYPT_AsnDecodeBits;
    else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
        decodeFunc = CRYPT_AsnDecodeOctets;
    else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
        decodeFunc = CRYPT_AsnDecodeBasicConstraints;
    else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
        decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
    else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
        decodeFunc = CRYPT_AsnDecodeAltName;
    else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
        decodeFunc = CRYPT_AsnDecodeAltName;
    else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
        decodeFunc = CRYPT_AsnDecodeAltName;
    else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
        decodeFunc = CRYPT_AsnDecodeAltName;
    else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
        decodeFunc = CRYPT_AsnDecodeAltName;
    else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
        decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
    else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
        decodeFunc = CRYPT_AsnDecodeCertPolicies;
    else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
        decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
    else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
        decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
    else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
        decodeFunc = CRYPT_AsnDecodeNameConstraints;
    else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
        decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
    else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
        decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
    else if (!strcmp(lpszStructType, szOID_CTL))
        decodeFunc = CRYPT_AsnDecodeCTL;
    return decodeFunc;
}

static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
{
    static HCRYPTOIDFUNCSET set = NULL;
    CryptDecodeObjectFunc decodeFunc = NULL;

    if (!set)
        set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
    CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
     (void **)&decodeFunc, hFunc);
    return decodeFunc;
}

static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
{
    static HCRYPTOIDFUNCSET set = NULL;
    CryptDecodeObjectExFunc decodeFunc = NULL;

    if (!set)
        set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
    CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
     (void **)&decodeFunc, hFunc);
    return decodeFunc;
}

BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
 DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;
    CryptDecodeObjectFunc pCryptDecodeObject = NULL;
    CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
    HCRYPTOIDFUNCADDR hFunc = NULL;

    TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
     debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
     pvStructInfo, pcbStructInfo);

    if (!pvStructInfo && !pcbStructInfo)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    if (cbEncoded > MAX_ENCODED_LEN)
    {
        SetLastError(CRYPT_E_ASN1_LARGE);
        return FALSE;
    }

    if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
     lpszStructType)))
    {
        TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
         debugstr_a(lpszStructType));
        pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
         lpszStructType, &hFunc);
        if (!pCryptDecodeObject)
            pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
             lpszStructType, &hFunc);
    }
    if (pCryptDecodeObject)
        ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
         pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
    else if (pCryptDecodeObjectEx)
        ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
         pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
         pvStructInfo, pcbStructInfo);
    if (hFunc)
        CryptFreeOIDFunctionAddress(hFunc, 0);
    TRACE_(crypt)("returning %d\n", ret);
    return ret;
}

BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
{
    BOOL ret = FALSE;
    CryptDecodeObjectExFunc decodeFunc;
    HCRYPTOIDFUNCADDR hFunc = NULL;

    TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
     dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
     cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);

    if (!pvStructInfo && !pcbStructInfo)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    if (cbEncoded > MAX_ENCODED_LEN)
    {
        SetLastError(CRYPT_E_ASN1_LARGE);
        return FALSE;
    }

    SetLastError(NOERROR);
    if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
        *(BYTE **)pvStructInfo = NULL;
    decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
    if (!decodeFunc)
    {
        TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
         debugstr_a(lpszStructType));
        decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
         &hFunc);
    }
    if (decodeFunc)
        ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
         cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
    else
    {
        CryptDecodeObjectFunc pCryptDecodeObject =
         CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);

        /* Try CryptDecodeObject function.  Don't call CryptDecodeObject
         * directly, as that could cause an infinite loop.
         */
        if (pCryptDecodeObject)
        {
            if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
            {
                ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
                 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
                if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
                 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
                    ret = pCryptDecodeObject(dwCertEncodingType,
                     lpszStructType, pbEncoded, cbEncoded, dwFlags,
                     *(BYTE **)pvStructInfo, pcbStructInfo);
            }
            else
                ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
                 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
        }
    }
    if (hFunc)
        CryptFreeOIDFunctionAddress(hFunc, 0);
    TRACE_(crypt)("returning %d\n", ret);
    return ret;
}

BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
{
    BOOL ret;

    TRACE_(crypt)("(%p)\n", pPFX);

    /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
     * version integer of length 1 (3 encoded byes) and at least one other
     * datum (two encoded bytes), plus at least two bytes for the outer
     * sequence.  Thus, even an empty PFX blob is at least 7 bytes in length.
     */
    if (pPFX->cbData < 7)
        ret = FALSE;
    else if (pPFX->pbData[0] == ASN_SEQUENCE)
    {
        DWORD len;

        if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
        {
            BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);

            /* Need at least three bytes for the integer version */
            if (pPFX->cbData < 1 + lenLen + 3)
                ret = FALSE;
            else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
             pPFX->pbData[1 + lenLen + 1] != 1 ||          /* Definite length */
             pPFX->pbData[1 + lenLen + 2] != 3)            /* PFX version */
                ret = FALSE;
        }
    }
    else
        ret = FALSE;
    return ret;
}

HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
 DWORD dwFlags)
{
    FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);
    return NULL;
}
