imm32: Retrieve the graphics driver module from gdi32.
[wine] / dlls / crypt32 / decode.c
1 /*
2  * Copyright 2005-2009 Juan Lang
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  * This file implements ASN.1 DER decoding of a limited set of types.
19  * It isn't a full ASN.1 implementation.  Microsoft implements BER
20  * encoding of many of the basic types in msasn1.dll, but that interface isn't
21  * implemented, so I implement them here.
22  *
23  * References:
24  * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25  * (available online, look for a PDF copy as the HTML versions tend to have
26  * translation errors.)
27  *
28  * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
29  *
30  * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
31  */
32
33 #include "config.h"
34 #include "wine/port.h"
35
36 #include <assert.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40
41 #define NONAMELESSUNION
42
43 #include "windef.h"
44 #include "winbase.h"
45 #include "wincrypt.h"
46 #include "winnls.h"
47 #include "snmp.h"
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
51
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
54
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK  0x1f
57
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt);
60
61 typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *,
62  DWORD, DWORD, void *, DWORD *);
63 typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *,
64  DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *);
65
66 /* Internal decoders don't do memory allocation or exception handling, and
67  * they report how many bytes they decoded.
68  */
69 typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded,
70  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
71
72 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
73  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
74  DWORD *pcbDecoded);
75 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
76  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
77  DWORD *pcbDecoded);
78 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
79  */
80 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
81  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
82 /* Assumes algo->Parameters.pbData is set ahead of time. */
83 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
84  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
85 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
86  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
87 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
88 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
89  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
90  DWORD *pcbDecoded);
91 /* Doesn't check the tag, assumes the caller does so */
92 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
93  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
94 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
95  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
96 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
97  * member has been initialized, doesn't do exception handling, and doesn't do
98  * memory allocation.  Also doesn't check tag, assumes the caller has checked
99  * it.
100  */
101 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
102  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
103  DWORD *pcbDecoded);
104 /* Like CRYPT_AsnDecodeInteger, but unsigned.  */
105 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
106  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
107  DWORD *pcbDecoded);
108 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
109  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
110  DWORD *pcbDecoded);
111
112 /* Gets the number of length bytes from the given (leading) length byte */
113 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
114
115 /* Helper function to get the encoded length of the data starting at pbEncoded,
116  * where pbEncoded[0] is the tag.  If the data are too short to contain a
117  * length or if the length is too large for cbEncoded, sets an appropriate
118  * error code and returns FALSE.  If the encoded length is unknown due to
119  * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
120  */
121 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
122  DWORD *len)
123 {
124     BOOL ret;
125
126     if (cbEncoded <= 1)
127     {
128         SetLastError(CRYPT_E_ASN1_CORRUPT);
129         ret = FALSE;
130     }
131     else if (pbEncoded[1] <= 0x7f)
132     {
133         if (pbEncoded[1] + 1 > cbEncoded)
134         {
135             SetLastError(CRYPT_E_ASN1_EOD);
136             ret = FALSE;
137         }
138         else
139         {
140             *len = pbEncoded[1];
141             ret = TRUE;
142         }
143     }
144     else if (pbEncoded[1] == 0x80)
145     {
146         *len = CMSG_INDEFINITE_LENGTH;
147         ret = TRUE;
148     }
149     else
150     {
151         BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
152
153         if (lenLen > sizeof(DWORD) + 1)
154         {
155             SetLastError(CRYPT_E_ASN1_LARGE);
156             ret = FALSE;
157         }
158         else if (lenLen + 2 > cbEncoded)
159         {
160             SetLastError(CRYPT_E_ASN1_CORRUPT);
161             ret = FALSE;
162         }
163         else
164         {
165             DWORD out = 0;
166
167             pbEncoded += 2;
168             while (--lenLen)
169             {
170                 out <<= 8;
171                 out |= *pbEncoded++;
172             }
173             if (out + lenLen + 1 > cbEncoded)
174             {
175                 SetLastError(CRYPT_E_ASN1_EOD);
176                 ret = FALSE;
177             }
178             else
179             {
180                 *len = out;
181                 ret = TRUE;
182             }
183         }
184     }
185     return ret;
186 }
187
188 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
189 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
190 {
191     BOOL ret;
192
193     if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
194      *len == CMSG_INDEFINITE_LENGTH)
195     {
196         SetLastError(CRYPT_E_ASN1_CORRUPT);
197         ret = FALSE;
198     }
199     return ret;
200 }
201
202 /* Helper function to check *pcbStructInfo, set it to the required size, and
203  * optionally to allocate memory.  Assumes pvStructInfo is not NULL.
204  * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
205  * pointer to the newly allocated memory.
206  */
207 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
208  const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
209  DWORD bytesNeeded)
210 {
211     BOOL ret = TRUE;
212
213     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
214     {
215         if (pDecodePara && pDecodePara->pfnAlloc)
216             *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
217         else
218             *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
219         if (!*(BYTE **)pvStructInfo)
220             ret = FALSE;
221         else
222             *pcbStructInfo = bytesNeeded;
223     }
224     else if (*pcbStructInfo < bytesNeeded)
225     {
226         *pcbStructInfo = bytesNeeded;
227         SetLastError(ERROR_MORE_DATA);
228         ret = FALSE;
229     }
230     else
231         *pcbStructInfo = bytesNeeded;
232     return ret;
233 }
234
235 static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA *pDecodePara, LPVOID pv)
236 {
237     if (pDecodePara && pDecodePara->pfnFree)
238         pDecodePara->pfnFree(pv);
239     else
240         LocalFree(pv);
241 }
242
243 /* Helper function to check *pcbStructInfo and set it to the required size.
244  * Assumes pvStructInfo is not NULL.
245  */
246 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
247 {
248     BOOL ret;
249
250     if (*pcbStructInfo < bytesNeeded)
251     {
252         *pcbStructInfo = bytesNeeded;
253         SetLastError(ERROR_MORE_DATA);
254         ret = FALSE;
255     }
256     else
257     {
258         *pcbStructInfo = bytesNeeded;
259         ret = TRUE;
260     }
261     return ret;
262 }
263
264 /* tag:
265  *     The expected tag of the item.  If tag is 0, decodeFunc is called
266  *     regardless of the tag value seen.
267  * offset:
268  *     A sequence is decoded into a struct.  The offset member is the
269  *     offset of this item within that struct.
270  * decodeFunc:
271  *     The decoder function to use.  If this is NULL, then the member isn't
272  *     decoded, but minSize space is reserved for it.
273  * minSize:
274  *     The minimum amount of space occupied after decoding.  You must set this.
275  * optional:
276  *     If true, and the tag doesn't match the expected tag for this item,
277  *     or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
278  *     filled with 0 for this member.
279  * hasPointer, pointerOffset:
280  *     If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
281  *     the offset within the struct of the data pointer (or to the
282  *     first data pointer, if more than one exist).
283  * size:
284  *     Used by CRYPT_AsnDecodeSequence, not for your use.
285  */
286 struct AsnDecodeSequenceItem
287 {
288     BYTE               tag;
289     DWORD              offset;
290     InternalDecodeFunc decodeFunc;
291     DWORD              minSize;
292     BOOL               optional;
293     BOOL               hasPointer;
294     DWORD              pointerOffset;
295     DWORD              size;
296 };
297
298 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
299 #define MEMBERSIZE(s, member, nextmember) \
300     (offsetof(s, nextmember) - offsetof(s, member))
301
302 /* Decodes the items in a sequence, where the items are described in items,
303  * the encoded data are in pbEncoded with length cbEncoded.  Decodes into
304  * pvStructInfo.  nextData is a pointer to the memory location at which the
305  * first decoded item with a dynamic pointer should point.
306  * Upon decoding, *cbDecoded is the total number of bytes decoded.
307  * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
308  */
309 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
310  DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
311  void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
312 {
313     BOOL ret;
314     DWORD i, decoded = 0;
315     const BYTE *ptr = pbEncoded;
316
317     TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
318      cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
319
320     for (i = 0, ret = TRUE; ret && i < cItem; i++)
321     {
322         if (cbEncoded - (ptr - pbEncoded) != 0)
323         {
324             DWORD itemLen;
325
326             if ((ret = CRYPT_GetLengthIndefinite(ptr,
327              cbEncoded - (ptr - pbEncoded), &itemLen)))
328             {
329                 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
330
331                 if (ptr[0] == items[i].tag || !items[i].tag)
332                 {
333                     DWORD itemEncodedLen;
334
335                     if (itemLen == CMSG_INDEFINITE_LENGTH)
336                         itemEncodedLen = cbEncoded - (ptr - pbEncoded);
337                     else
338                         itemEncodedLen = 1 + itemLenBytes + itemLen;
339                     if (nextData && pvStructInfo && items[i].hasPointer)
340                     {
341                         TRACE("Setting next pointer to %p\n",
342                          nextData);
343                         *(BYTE **)((BYTE *)pvStructInfo +
344                          items[i].pointerOffset) = nextData;
345                     }
346                     if (items[i].decodeFunc)
347                     {
348                         DWORD itemDecoded;
349
350                         if (pvStructInfo)
351                             TRACE("decoding item %d\n", i);
352                         else
353                             TRACE("sizing item %d\n", i);
354                         ret = items[i].decodeFunc(ptr, itemEncodedLen,
355                          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
356                          pvStructInfo ?  (BYTE *)pvStructInfo + items[i].offset
357                          : NULL, &items[i].size, &itemDecoded);
358                         if (ret)
359                         {
360                             if (items[i].size < items[i].minSize)
361                                 items[i].size = items[i].minSize;
362                             else if (items[i].size > items[i].minSize)
363                             {
364                                 /* Account for alignment padding */
365                                 items[i].size = ALIGN_DWORD_PTR(items[i].size);
366                             }
367                             TRACE("item %d size: %d\n", i, items[i].size);
368                             if (nextData && items[i].hasPointer &&
369                              items[i].size > items[i].minSize)
370                                 nextData += items[i].size - items[i].minSize;
371                             if (itemDecoded > itemEncodedLen)
372                             {
373                                 WARN("decoded length %d exceeds encoded %d\n",
374                                  itemDecoded, itemEncodedLen);
375                                 SetLastError(CRYPT_E_ASN1_CORRUPT);
376                                 ret = FALSE;
377                             }
378                             else
379                             {
380                                 ptr += itemDecoded;
381                                 decoded += itemDecoded;
382                                 TRACE("item %d: decoded %d bytes\n", i,
383                                  itemDecoded);
384                             }
385                         }
386                         else if (items[i].optional &&
387                          GetLastError() == CRYPT_E_ASN1_BADTAG)
388                         {
389                             TRACE("skipping optional item %d\n", i);
390                             items[i].size = items[i].minSize;
391                             SetLastError(NOERROR);
392                             ret = TRUE;
393                         }
394                         else
395                             TRACE("item %d failed: %08x\n", i,
396                              GetLastError());
397                     }
398                     else if (itemLen == CMSG_INDEFINITE_LENGTH)
399                     {
400                         ERR("can't use indefinite length encoding without a decoder\n");
401                         SetLastError(CRYPT_E_ASN1_CORRUPT);
402                         ret = FALSE;
403                     }
404                     else
405                     {
406                         TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
407                         ptr += itemEncodedLen;
408                         decoded += itemEncodedLen;
409                         items[i].size = items[i].minSize;
410                     }
411                 }
412                 else if (items[i].optional)
413                 {
414                     TRACE("skipping optional item %d\n", i);
415                     items[i].size = items[i].minSize;
416                 }
417                 else
418                 {
419                     TRACE("item %d: tag %02x doesn't match expected %02x\n",
420                      i, ptr[0], items[i].tag);
421                     SetLastError(CRYPT_E_ASN1_BADTAG);
422                     ret = FALSE;
423                 }
424             }
425         }
426         else if (items[i].optional)
427         {
428             TRACE("missing optional item %d, skipping\n", i);
429             items[i].size = items[i].minSize;
430         }
431         else
432         {
433             TRACE("not enough bytes for item %d, failing\n", i);
434             SetLastError(CRYPT_E_ASN1_CORRUPT);
435             ret = FALSE;
436         }
437     }
438     if (cbDecoded)
439         *cbDecoded = decoded;
440     TRACE("returning %d\n", ret);
441     return ret;
442 }
443
444 /* This decodes an arbitrary sequence into a contiguous block of memory
445  * (basically, a struct.)  Each element being decoded is described by a struct
446  * AsnDecodeSequenceItem, see above.
447  * startingPointer is an optional pointer to the first place where dynamic
448  * data will be stored.  If you know the starting offset, you may pass it
449  * here.  Otherwise, pass NULL, and one will be inferred from the items.
450  */
451 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
452  DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
453  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
454  DWORD *pcbDecoded, void *startingPointer)
455 {
456     BOOL ret;
457
458     TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
459      cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
460      startingPointer);
461
462     if (!cbEncoded)
463     {
464         SetLastError(CRYPT_E_ASN1_EOD);
465         return FALSE;
466     }
467     if (pbEncoded[0] == ASN_SEQUENCE)
468     {
469         DWORD dataLen;
470
471         if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
472         {
473             DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
474             const BYTE *ptr = pbEncoded + 1 + lenBytes;
475             BOOL indefinite = FALSE;
476
477             cbEncoded -= 1 + lenBytes;
478             if (dataLen == CMSG_INDEFINITE_LENGTH)
479             {
480                 dataLen = cbEncoded;
481                 indefinite = TRUE;
482             }
483             else if (cbEncoded < dataLen)
484             {
485                 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
486                  cbEncoded);
487                 SetLastError(CRYPT_E_ASN1_CORRUPT);
488                 ret = FALSE;
489             }
490             if (ret)
491             {
492                 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
493                  ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
494                 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
495                 {
496                     if (cbDecoded > cbEncoded - 2)
497                     {
498                         /* Not enough space for 0 TLV */
499                         SetLastError(CRYPT_E_ASN1_CORRUPT);
500                         ret = FALSE;
501                     }
502                     else if (*(ptr + cbDecoded) != 0 ||
503                      *(ptr + cbDecoded + 1) != 0)
504                     {
505                         TRACE("expected 0 TLV\n");
506                         SetLastError(CRYPT_E_ASN1_CORRUPT);
507                         ret = FALSE;
508                     }
509                     else
510                         cbDecoded += 2;
511                 }
512             }
513             if (ret && !indefinite && cbDecoded != dataLen)
514             {
515                 TRACE("expected %d decoded, got %d, failing\n", dataLen,
516                  cbDecoded);
517                 SetLastError(CRYPT_E_ASN1_CORRUPT);
518                 ret = FALSE;
519             }
520             if (ret)
521             {
522                 DWORD i, bytesNeeded = 0, structSize = 0;
523
524                 for (i = 0; i < cItem; i++)
525                 {
526                     if (items[i].size > items[i].minSize)
527                         bytesNeeded += items[i].size - items[i].minSize;
528                     structSize = max( structSize, items[i].offset + items[i].minSize );
529                 }
530                 bytesNeeded += structSize;
531                 if (pcbDecoded)
532                     *pcbDecoded = 1 + lenBytes + cbDecoded;
533                 if (!pvStructInfo)
534                     *pcbStructInfo = bytesNeeded;
535                 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
536                  pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
537                 {
538                     BYTE *nextData;
539
540                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
541                         pvStructInfo = *(BYTE **)pvStructInfo;
542                     if (startingPointer)
543                         nextData = startingPointer;
544                     else
545                         nextData = (BYTE *)pvStructInfo + structSize;
546                     memset(pvStructInfo, 0, structSize);
547                     ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
548                      ptr, dataLen, dwFlags, pvStructInfo, nextData,
549                      &cbDecoded);
550                     if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
551                         CRYPT_FreeSpace(pDecodePara, pvStructInfo);
552                 }
553             }
554         }
555     }
556     else
557     {
558         SetLastError(CRYPT_E_ASN1_BADTAG);
559         ret = FALSE;
560     }
561     TRACE("returning %d (%08x)\n", ret, GetLastError());
562     return ret;
563 }
564
565 /* tag:
566  *     The expected tag of the entire encoded array (usually a variant
567  *     of ASN_SETOF or ASN_SEQUENCEOF.)  If tag is 0, decodeFunc is called
568  *     regardless of the tag seen.
569  * countOffset:
570  *     The offset within the outer structure at which the count exists.
571  *     For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
572  *     while CRYPT_ATTRIBUTE has countOffset ==
573  *     offsetof(CRYPT_ATTRIBUTE, cValue).
574  * arrayOffset:
575  *     The offset within the outer structure at which the array pointer exists.
576  *     For example, CRYPT_ATTRIBUTES has arrayOffset ==
577  *     offsetof(CRYPT_ATTRIBUTES, rgAttr).
578  * minArraySize:
579  *     The minimum size of the decoded array.  On WIN32, this is always 8:
580  *     sizeof(DWORD) + sizeof(void *).  On WIN64, it can be larger due to
581  *     alignment.
582  * decodeFunc:
583  *     used to decode each item in the array
584  * itemSize:
585  *      is the minimum size of each decoded item
586  * hasPointer:
587  *      indicates whether each item has a dynamic pointer
588  * pointerOffset:
589  *     indicates the offset within itemSize at which the pointer exists
590  */
591 struct AsnArrayDescriptor
592 {
593     BYTE               tag;
594     DWORD              countOffset;
595     DWORD              arrayOffset;
596     DWORD              minArraySize;
597     InternalDecodeFunc decodeFunc;
598     DWORD              itemSize;
599     BOOL               hasPointer;
600     DWORD              pointerOffset;
601 };
602
603 struct AsnArrayItemSize
604 {
605     DWORD encodedLen;
606     DWORD size;
607 };
608
609 /* Decodes an array of like types into a structure described by a struct
610  * AsnArrayDescriptor.
611  */
612 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
613  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
614  const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
615  DWORD *pcbDecoded)
616 {
617     BOOL ret = TRUE;
618
619     TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded,
620      cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
621
622     if (!cbEncoded)
623     {
624         SetLastError(CRYPT_E_ASN1_EOD);
625         ret = FALSE;
626     }
627     else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
628     {
629         DWORD dataLen;
630
631         if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
632         {
633             DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded;
634             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
635             /* There can be arbitrarily many items, but there is often only one.
636              */
637             struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
638
639             decoded = 1 + lenBytes;
640             if (dataLen)
641             {
642                 const BYTE *ptr;
643                 BOOL doneDecoding = FALSE;
644
645                 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
646                 {
647                     if (dataLen == CMSG_INDEFINITE_LENGTH)
648                     {
649                         if (ptr[0] == 0)
650                         {
651                             doneDecoding = TRUE;
652                             if (ptr[1] != 0)
653                             {
654                                 SetLastError(CRYPT_E_ASN1_CORRUPT);
655                                 ret = FALSE;
656                             }
657                             else
658                                 decoded += 2;
659                         }
660                     }
661                     else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
662                         doneDecoding = TRUE;
663                     if (!doneDecoding)
664                     {
665                         DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
666
667                         /* Each item decoded may not tolerate extraneous bytes,
668                          * so get the length of the next element if known.
669                          */
670                         if ((ret = CRYPT_GetLengthIndefinite(ptr,
671                          cbEncoded - (ptr - pbEncoded), &itemDataLen)))
672                         {
673                             if (itemDataLen == CMSG_INDEFINITE_LENGTH)
674                                 itemEncoded = cbEncoded - (ptr - pbEncoded);
675                             else
676                                 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
677                                  itemDataLen;
678                         }
679                         if (ret)
680                             ret = arrayDesc->decodeFunc(ptr, itemEncoded,
681                              dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
682                              &itemDecoded);
683                         if (ret)
684                         {
685                             cItems++;
686                             if (itemSizes != &itemSize)
687                                 itemSizes = CryptMemRealloc(itemSizes,
688                                  cItems * sizeof(struct AsnArrayItemSize));
689                             else if (cItems > 1)
690                             {
691                                 itemSizes =
692                                  CryptMemAlloc(
693                                  cItems * sizeof(struct AsnArrayItemSize));
694                                 if (itemSizes)
695                                     *itemSizes = itemSize;
696                             }
697                             if (itemSizes)
698                             {
699                                 decoded += itemDecoded;
700                                 itemSizes[cItems - 1].encodedLen = itemEncoded;
701                                 itemSizes[cItems - 1].size = size;
702                                 bytesNeeded += size;
703                                 ptr += itemEncoded;
704                             }
705                             else
706                                 ret = FALSE;
707                         }
708                     }
709                 }
710             }
711             if (ret)
712             {
713                 if (pcbDecoded)
714                     *pcbDecoded = decoded;
715                 if (!pvStructInfo)
716                     *pcbStructInfo = bytesNeeded;
717                 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
718                  pvStructInfo, pcbStructInfo, bytesNeeded)))
719                 {
720                     DWORD i, *pcItems;
721                     BYTE *nextData;
722                     const BYTE *ptr;
723                     void *rgItems;
724
725                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
726                         pvStructInfo = *(void **)pvStructInfo;
727                     pcItems = pvStructInfo;
728                     *pcItems = cItems;
729                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
730                     {
731                         rgItems = (BYTE *)pvStructInfo +
732                          arrayDesc->minArraySize;
733                         *(void **)((BYTE *)pcItems -
734                          arrayDesc->countOffset + arrayDesc->arrayOffset) =
735                          rgItems;
736                     }
737                     else
738                         rgItems = *(void **)((BYTE *)pcItems -
739                          arrayDesc->countOffset + arrayDesc->arrayOffset);
740                     nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize;
741                     for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
742                      i < cItems && ptr - pbEncoded - 1 - lenBytes <
743                      dataLen; i++)
744                     {
745                         DWORD itemDecoded;
746
747                         if (arrayDesc->hasPointer)
748                             *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize
749                              + arrayDesc->pointerOffset) = nextData;
750                         ret = arrayDesc->decodeFunc(ptr,
751                          itemSizes[i].encodedLen,
752                          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
753                          (BYTE *)rgItems + i * arrayDesc->itemSize,
754                          &itemSizes[i].size, &itemDecoded);
755                         if (ret)
756                         {
757                             nextData += itemSizes[i].size - arrayDesc->itemSize;
758                             ptr += itemDecoded;
759                         }
760                     }
761                     if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
762                         CRYPT_FreeSpace(pDecodePara, pvStructInfo);
763                 }
764             }
765             if (itemSizes != &itemSize)
766                 CryptMemFree(itemSizes);
767         }
768     }
769     else
770     {
771         SetLastError(CRYPT_E_ASN1_BADTAG);
772         ret = FALSE;
773     }
774     return ret;
775 }
776
777 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
778  * pvStructInfo.  The BLOB must be non-empty, otherwise the last error is set
779  * to CRYPT_E_ASN1_CORRUPT.
780  * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
781  * set!
782  */
783 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
784  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
785 {
786     BOOL ret;
787     DWORD dataLen;
788
789     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
790     {
791         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
792         DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
793        
794         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
795             bytesNeeded += 1 + lenBytes + dataLen;
796
797         if (pcbDecoded)
798             *pcbDecoded = 1 + lenBytes + dataLen;
799         if (!pvStructInfo)
800             *pcbStructInfo = bytesNeeded;
801         else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
802         {
803             CRYPT_DER_BLOB *blob;
804
805             if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
806                 pvStructInfo = *(BYTE **)pvStructInfo;
807             blob = pvStructInfo;
808             blob->cbData = 1 + lenBytes + dataLen;
809             if (blob->cbData)
810             {
811                 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
812                     blob->pbData = (BYTE *)pbEncoded;
813                 else
814                 {
815                     assert(blob->pbData);
816                     memcpy(blob->pbData, pbEncoded, blob->cbData);
817                 }
818             }
819             else
820             {
821                 SetLastError(CRYPT_E_ASN1_CORRUPT);
822                 ret = FALSE;
823             }
824         }
825     }
826     return ret;
827 }
828
829 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
830 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
831  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
832  DWORD *pcbDecoded)
833 {
834     BOOL ret;
835
836     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
837      pvStructInfo, *pcbStructInfo, pcbDecoded);
838
839     /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
840      * place.
841      */
842     ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
843      dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
844      pcbDecoded);
845     if (ret && pvStructInfo)
846     {
847         CRYPT_BIT_BLOB *blob = pvStructInfo;
848
849         if (blob->cbData)
850         {
851             DWORD i;
852             BYTE temp;
853
854             for (i = 0; i < blob->cbData / 2; i++)
855             {
856                 temp = blob->pbData[i];
857                 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
858                 blob->pbData[blob->cbData - i - 1] = temp;
859             }
860         }
861     }
862     TRACE("returning %d (%08x)\n", ret, GetLastError());
863     return ret;
864 }
865
866 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
867  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
868  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
869 {
870     BOOL ret = TRUE;
871
872     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
873      pDecodePara, pvStructInfo, *pcbStructInfo);
874
875     __TRY
876     {
877         struct AsnDecodeSequenceItem items[] = {
878          { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
879            CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
880            offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
881          { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
882            SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
883            sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
884            offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
885          { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
886            CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
887            offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
888         };
889
890         if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
891             items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
892         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
893          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
894          pcbStructInfo, NULL, NULL);
895     }
896     __EXCEPT_PAGE_FAULT
897     {
898         SetLastError(STATUS_ACCESS_VIOLATION);
899         ret = FALSE;
900     }
901     __ENDTRY
902
903     TRACE("Returning %d (%08x)\n", ret, GetLastError());
904     return ret;
905 }
906
907 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
908  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
909 {
910     BOOL ret;
911     DWORD dataLen;
912
913     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
914     {
915         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
916
917         ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
918          dwFlags, pvStructInfo, pcbStructInfo, NULL);
919         if (pcbDecoded)
920             *pcbDecoded = 1 + lenBytes + dataLen;
921     }
922     return ret;
923 }
924
925 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
926  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
927 {
928     BOOL ret;
929
930     struct AsnDecodeSequenceItem items[] = {
931      { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
932        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
933      { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
934        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
935     };
936
937     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
938      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
939      pcbDecoded, NULL);
940     return ret;
941 }
942
943 static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded,
944  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
945  DWORD *pcbDecoded)
946 {
947     BOOL ret = TRUE;
948     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
949      offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
950      FINALMEMBERSIZE(CERT_INFO, cExtension),
951      CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
952      offsetof(CERT_EXTENSION, pszObjId) };
953
954     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
955      pvStructInfo, *pcbStructInfo, pcbDecoded);
956
957     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
958      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
959     return ret;
960 }
961
962 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
963  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
964  DWORD *pcbDecoded)
965 {
966     BOOL ret;
967     DWORD dataLen;
968
969     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
970     {
971         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
972
973         ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes,
974          dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
975         if (ret && pcbDecoded)
976             *pcbDecoded = 1 + lenBytes + dataLen;
977     }
978     return ret;
979 }
980
981 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
982  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
983  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
984 {
985     BOOL ret = TRUE;
986     struct AsnDecodeSequenceItem items[] = {
987      { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
988        CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
989      { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
990        CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
991        TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
992      { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
993        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
994        FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
995      { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
996        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
997        Issuer.pbData) },
998      { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
999        CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
1000        FALSE, 0 },
1001      { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
1002        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
1003        Subject.pbData) },
1004      { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
1005        CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
1006        FALSE, TRUE, offsetof(CERT_INFO,
1007        SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
1008      { ASN_CONTEXT | 1, offsetof(CERT_INFO, IssuerUniqueId),
1009        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1010        offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
1011      { ASN_CONTEXT | 2, offsetof(CERT_INFO, SubjectUniqueId),
1012        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1013        offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
1014      { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
1015        CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension),
1016        TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
1017     };
1018
1019     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1020      pDecodePara, pvStructInfo, *pcbStructInfo);
1021
1022     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1023      pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1024      NULL, NULL);
1025     if (ret && pvStructInfo)
1026     {
1027         CERT_INFO *info;
1028
1029         if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1030             info = *(CERT_INFO **)pvStructInfo;
1031         else
1032             info = pvStructInfo;
1033         if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1034          !info->Subject.cbData)
1035         {
1036             SetLastError(CRYPT_E_ASN1_CORRUPT);
1037             /* Don't need to deallocate, because it should have failed on the
1038              * first pass (and no memory was allocated.)
1039              */
1040             ret = FALSE;
1041         }
1042     }
1043
1044     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1045     return ret;
1046 }
1047
1048 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1049  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1050  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1051 {
1052     BOOL ret = FALSE;
1053
1054     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1055      pDecodePara, pvStructInfo, *pcbStructInfo);
1056
1057     __TRY
1058     {
1059         DWORD size = 0;
1060
1061         /* Unless told not to, first try to decode it as a signed cert. */
1062         if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1063         {
1064             PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1065
1066             ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1067              X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1068              &signedCert, &size);
1069             if (ret)
1070             {
1071                 size = 0;
1072                 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1073                  X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1074                  signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1075                  pvStructInfo, pcbStructInfo);
1076                 LocalFree(signedCert);
1077             }
1078         }
1079         /* Failing that, try it as an unsigned cert */
1080         if (!ret)
1081         {
1082             size = 0;
1083             ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1084              X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1085              pDecodePara, pvStructInfo, pcbStructInfo);
1086         }
1087     }
1088     __EXCEPT_PAGE_FAULT
1089     {
1090         SetLastError(STATUS_ACCESS_VIOLATION);
1091     }
1092     __ENDTRY
1093
1094     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1095     return ret;
1096 }
1097
1098 static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded,
1099  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1100  DWORD *pcbDecoded)
1101 {
1102     BOOL ret = TRUE;
1103     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1104      offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
1105      FINALMEMBERSIZE(CRL_ENTRY, cExtension),
1106      CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1107      offsetof(CERT_EXTENSION, pszObjId) };
1108
1109     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1110      pvStructInfo, *pcbStructInfo, pcbDecoded);
1111
1112     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1113      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1114     return ret;
1115 }
1116
1117 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1118  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1119 {
1120     BOOL ret;
1121     struct AsnDecodeSequenceItem items[] = {
1122      { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1123        CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1124        offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1125      { 0, offsetof(CRL_ENTRY, RevocationDate),
1126        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1127      { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1128        CRYPT_AsnDecodeCRLEntryExtensions,
1129        FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
1130        offsetof(CRL_ENTRY, rgExtension), 0 },
1131     };
1132     PCRL_ENTRY entry = pvStructInfo;
1133
1134     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1135      *pcbStructInfo);
1136
1137     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1138      pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1139      entry ? entry->SerialNumber.pbData : NULL);
1140     if (ret && entry && !entry->SerialNumber.cbData)
1141     {
1142         WARN("empty CRL entry serial number\n");
1143         SetLastError(CRYPT_E_ASN1_CORRUPT);
1144         ret = FALSE;
1145     }
1146     return ret;
1147 }
1148
1149 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1150  * whose rgCRLEntry member has been set prior to calling.
1151  */
1152 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1153  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1154 {
1155     BOOL ret;
1156     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1157      offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
1158      MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1159      CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1160      offsetof(CRL_ENTRY, SerialNumber.pbData) };
1161
1162     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1163      pvStructInfo, *pcbStructInfo, pcbDecoded);
1164
1165     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1166      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1167     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1168     return ret;
1169 }
1170
1171 static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded,
1172  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1173  DWORD *pcbDecoded)
1174 {
1175     BOOL ret = TRUE;
1176     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1177      offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
1178      FINALMEMBERSIZE(CRL_INFO, cExtension),
1179      CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1180      offsetof(CERT_EXTENSION, pszObjId) };
1181
1182     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1183      pvStructInfo, *pcbStructInfo, pcbDecoded);
1184
1185     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1186      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1187     return ret;
1188 }
1189
1190 static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded,
1191  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1192  DWORD *pcbDecoded)
1193 {
1194     BOOL ret;
1195     DWORD dataLen;
1196
1197     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1198     {
1199         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1200
1201         ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes,
1202          dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1203         if (ret && pcbDecoded)
1204             *pcbDecoded = 1 + lenBytes + dataLen;
1205     }
1206     return ret;
1207 }
1208
1209 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1210  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1211  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1212 {
1213     struct AsnDecodeSequenceItem items[] = {
1214      { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1215        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1216      { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1217        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1218        FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1219      { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1220        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1221        Issuer.pbData) },
1222      { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1223        sizeof(FILETIME), FALSE, FALSE, 0 },
1224      { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1225        sizeof(FILETIME), TRUE, FALSE, 0 },
1226      { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1227        CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1228        TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
1229      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1230        CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension),
1231        TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
1232     };
1233     BOOL ret = TRUE;
1234
1235     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1236      pDecodePara, pvStructInfo, *pcbStructInfo);
1237
1238     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1239      pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1240      NULL, NULL);
1241
1242     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1243     return ret;
1244 }
1245
1246 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1247  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1248  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1249 {
1250     BOOL ret = FALSE;
1251
1252     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1253      pDecodePara, pvStructInfo, *pcbStructInfo);
1254
1255     __TRY
1256     {
1257         DWORD size = 0;
1258
1259         /* Unless told not to, first try to decode it as a signed crl. */
1260         if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1261         {
1262             PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1263
1264             ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1265              X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1266              &signedCrl, &size);
1267             if (ret)
1268             {
1269                 size = 0;
1270                 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1271                  X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1272                  signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1273                  pvStructInfo, pcbStructInfo);
1274                 LocalFree(signedCrl);
1275             }
1276         }
1277         /* Failing that, try it as an unsigned crl */
1278         if (!ret)
1279         {
1280             size = 0;
1281             ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1282              X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1283              dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1284         }
1285     }
1286     __EXCEPT_PAGE_FAULT
1287     {
1288         SetLastError(STATUS_ACCESS_VIOLATION);
1289     }
1290     __ENDTRY
1291
1292     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1293     return ret;
1294 }
1295
1296 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1297  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1298 {
1299     BOOL ret = TRUE;
1300     DWORD dataLen;
1301
1302     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1303      pvStructInfo, *pcbStructInfo);
1304
1305     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1306     {
1307         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1308         DWORD bytesNeeded = sizeof(LPSTR);
1309
1310         if (dataLen)
1311         {
1312             const BYTE *ptr;
1313             char str[32];
1314
1315             snprintf(str, sizeof(str), "%d.%d",
1316              pbEncoded[1 + lenBytes] / 40,
1317              pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1318              * 40);
1319             bytesNeeded += strlen(str) + 1;
1320             for (ptr = pbEncoded + 2 + lenBytes; ret &&
1321              ptr - pbEncoded - 1 - lenBytes < dataLen; )
1322             {
1323                 int val = 0;
1324
1325                 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1326                  (*ptr & 0x80))
1327                 {
1328                     val <<= 7;
1329                     val |= *ptr & 0x7f;
1330                     ptr++;
1331                 }
1332                 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1333                  (*ptr & 0x80))
1334                 {
1335                     SetLastError(CRYPT_E_ASN1_CORRUPT);
1336                     ret = FALSE;
1337                 }
1338                 else
1339                 {
1340                     val <<= 7;
1341                     val |= *ptr++;
1342                     snprintf(str, sizeof(str), ".%d", val);
1343                     bytesNeeded += strlen(str);
1344                 }
1345             }
1346         }
1347         if (pcbDecoded)
1348             *pcbDecoded = 1 + lenBytes + dataLen;
1349         if (!pvStructInfo)
1350             *pcbStructInfo = bytesNeeded;
1351         else if (*pcbStructInfo < bytesNeeded)
1352         {
1353             *pcbStructInfo = bytesNeeded;
1354             SetLastError(ERROR_MORE_DATA);
1355             ret = FALSE;
1356         }
1357         else
1358         {
1359             if (dataLen)
1360             {
1361                 const BYTE *ptr;
1362                 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1363
1364                 *pszObjId = 0;
1365                 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1366                  pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1367                  40) * 40);
1368                 pszObjId += strlen(pszObjId);
1369                 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1370                  ptr - pbEncoded - 1 - lenBytes < dataLen; )
1371                 {
1372                     int val = 0;
1373
1374                     while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1375                      (*ptr & 0x80))
1376                     {
1377                         val <<= 7;
1378                         val |= *ptr & 0x7f;
1379                         ptr++;
1380                     }
1381                     val <<= 7;
1382                     val |= *ptr++;
1383                     sprintf(pszObjId, ".%d", val);
1384                     pszObjId += strlen(pszObjId);
1385                 }
1386             }
1387             else
1388                 *(LPSTR *)pvStructInfo = NULL;
1389             *pcbStructInfo = bytesNeeded;
1390         }
1391     }
1392     return ret;
1393 }
1394
1395 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1396  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1397 {
1398     BOOL ret;
1399
1400     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1401      pvStructInfo, *pcbStructInfo);
1402
1403     if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1404         ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1405          pvStructInfo, pcbStructInfo, pcbDecoded);
1406     else
1407     {
1408         SetLastError(CRYPT_E_ASN1_BADTAG);
1409         ret = FALSE;
1410     }
1411     return ret;
1412 }
1413
1414 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1415  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1416 {
1417     struct AsnDecodeSequenceItem items[] = {
1418      { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1419        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1420        offsetof(CERT_EXTENSION, pszObjId), 0 },
1421      { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1422        sizeof(BOOL), TRUE, FALSE, 0, 0 },
1423      { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1424        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1425        offsetof(CERT_EXTENSION, Value.pbData) },
1426     };
1427     BOOL ret = TRUE;
1428     PCERT_EXTENSION ext = pvStructInfo;
1429
1430     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1431      *pcbStructInfo);
1432
1433     if (ext)
1434         TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1435     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1436      pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1437      pcbDecoded, ext ? ext->pszObjId : NULL);
1438     if (ext)
1439         TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1440          debugstr_a(ext->pszObjId));
1441     TRACE("returning %d (%08x)\n", ret, GetLastError());
1442     return ret;
1443 }
1444
1445 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1446  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1447  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1448 {
1449     BOOL ret = TRUE;
1450
1451     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1452      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1453
1454     __TRY
1455     {
1456         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1457          offsetof(CERT_EXTENSIONS, cExtension),
1458          offsetof(CERT_EXTENSIONS, rgExtension),
1459          sizeof(CERT_EXTENSIONS),
1460          CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1461          offsetof(CERT_EXTENSION, pszObjId) };
1462         CERT_EXTENSIONS *exts = pvStructInfo;
1463
1464         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1465             exts->rgExtension = (CERT_EXTENSION *)(exts + 1);
1466         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1467          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1468     }
1469     __EXCEPT_PAGE_FAULT
1470     {
1471         SetLastError(STATUS_ACCESS_VIOLATION);
1472         ret = FALSE;
1473     }
1474     __ENDTRY
1475     return ret;
1476 }
1477
1478 /* Warning: this assumes the address of value->Value.pbData is already set, in
1479  * order to avoid overwriting memory.  (In some cases, it may change it, if it
1480  * doesn't copy anything to memory.)  Be sure to set it correctly!
1481  */
1482 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1483  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1484  DWORD *pcbDecoded)
1485 {
1486     BOOL ret = TRUE;
1487     DWORD dataLen;
1488     CERT_NAME_VALUE *value = pvStructInfo;
1489
1490     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1491     {
1492         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1493         DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1494
1495         switch (pbEncoded[0])
1496         {
1497         case ASN_OCTETSTRING:
1498             valueType = CERT_RDN_OCTET_STRING;
1499             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1500                 bytesNeeded += dataLen;
1501             break;
1502         case ASN_NUMERICSTRING:
1503             valueType = CERT_RDN_NUMERIC_STRING;
1504             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1505                 bytesNeeded += dataLen;
1506             break;
1507         case ASN_PRINTABLESTRING:
1508             valueType = CERT_RDN_PRINTABLE_STRING;
1509             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1510                 bytesNeeded += dataLen;
1511             break;
1512         case ASN_IA5STRING:
1513             valueType = CERT_RDN_IA5_STRING;
1514             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1515                 bytesNeeded += dataLen;
1516             break;
1517         case ASN_T61STRING:
1518             valueType = CERT_RDN_T61_STRING;
1519             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1520                 bytesNeeded += dataLen;
1521             break;
1522         case ASN_VIDEOTEXSTRING:
1523             valueType = CERT_RDN_VIDEOTEX_STRING;
1524             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1525                 bytesNeeded += dataLen;
1526             break;
1527         case ASN_GRAPHICSTRING:
1528             valueType = CERT_RDN_GRAPHIC_STRING;
1529             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1530                 bytesNeeded += dataLen;
1531             break;
1532         case ASN_VISIBLESTRING:
1533             valueType = CERT_RDN_VISIBLE_STRING;
1534             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1535                 bytesNeeded += dataLen;
1536             break;
1537         case ASN_GENERALSTRING:
1538             valueType = CERT_RDN_GENERAL_STRING;
1539             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1540                 bytesNeeded += dataLen;
1541             break;
1542         case ASN_UNIVERSALSTRING:
1543             FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1544             SetLastError(CRYPT_E_ASN1_BADTAG);
1545             return FALSE;
1546         case ASN_BMPSTRING:
1547             valueType = CERT_RDN_BMP_STRING;
1548             bytesNeeded += dataLen;
1549             break;
1550         case ASN_UTF8STRING:
1551             valueType = CERT_RDN_UTF8_STRING;
1552             bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1553              (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1554             break;
1555         default:
1556             SetLastError(CRYPT_E_ASN1_BADTAG);
1557             return FALSE;
1558         }
1559
1560         if (pcbDecoded)
1561             *pcbDecoded = 1 + lenBytes + dataLen;
1562         if (!value)
1563             *pcbStructInfo = bytesNeeded;
1564         else if (*pcbStructInfo < bytesNeeded)
1565         {
1566             *pcbStructInfo = bytesNeeded;
1567             SetLastError(ERROR_MORE_DATA);
1568             ret = FALSE;
1569         }
1570         else
1571         {
1572             *pcbStructInfo = bytesNeeded;
1573             value->dwValueType = valueType;
1574             if (dataLen)
1575             {
1576                 DWORD i;
1577
1578                 assert(value->Value.pbData);
1579                 switch (pbEncoded[0])
1580                 {
1581                 case ASN_OCTETSTRING:
1582                 case ASN_NUMERICSTRING:
1583                 case ASN_PRINTABLESTRING:
1584                 case ASN_IA5STRING:
1585                 case ASN_T61STRING:
1586                 case ASN_VIDEOTEXSTRING:
1587                 case ASN_GRAPHICSTRING:
1588                 case ASN_VISIBLESTRING:
1589                 case ASN_GENERALSTRING:
1590                     value->Value.cbData = dataLen;
1591                     if (dataLen)
1592                     {
1593                         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1594                             memcpy(value->Value.pbData,
1595                              pbEncoded + 1 + lenBytes, dataLen);
1596                         else
1597                             value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1598                              lenBytes;
1599                     }
1600                     break;
1601                 case ASN_BMPSTRING:
1602                 {
1603                     LPWSTR str = (LPWSTR)value->Value.pbData;
1604
1605                     value->Value.cbData = dataLen;
1606                     for (i = 0; i < dataLen / 2; i++)
1607                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1608                          pbEncoded[1 + lenBytes + 2 * i + 1];
1609                     break;
1610                 }
1611                 case ASN_UTF8STRING:
1612                 {
1613                     LPWSTR str = (LPWSTR)value->Value.pbData;
1614
1615                     value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1616                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, 
1617                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1618                     break;
1619                 }
1620                 }
1621             }
1622             else
1623             {
1624                 value->Value.cbData = 0;
1625                 value->Value.pbData = NULL;
1626             }
1627         }
1628     }
1629     return ret;
1630 }
1631
1632 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1633  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1634  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1635 {
1636     BOOL ret = TRUE;
1637
1638     __TRY
1639     {
1640         ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1641          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1642         if (ret && pvStructInfo)
1643         {
1644             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1645              pcbStructInfo, *pcbStructInfo);
1646             if (ret)
1647             {
1648                 CERT_NAME_VALUE *value;
1649
1650                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1651                     pvStructInfo = *(BYTE **)pvStructInfo;
1652                 value = pvStructInfo;
1653                 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1654                 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1655                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1656                  pcbStructInfo, NULL);
1657                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1658                     CRYPT_FreeSpace(pDecodePara, value);
1659             }
1660         }
1661     }
1662     __EXCEPT_PAGE_FAULT
1663     {
1664         SetLastError(STATUS_ACCESS_VIOLATION);
1665         ret = FALSE;
1666     }
1667     __ENDTRY
1668     return ret;
1669 }
1670
1671 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1672  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1673  DWORD *pcbDecoded)
1674 {
1675     BOOL ret = TRUE;
1676     DWORD dataLen;
1677     CERT_NAME_VALUE *value = pvStructInfo;
1678
1679     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1680     {
1681         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1682         DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1683
1684         switch (pbEncoded[0])
1685         {
1686         case ASN_NUMERICSTRING:
1687             valueType = CERT_RDN_NUMERIC_STRING;
1688             if (dataLen)
1689                 bytesNeeded += (dataLen + 1) * 2;
1690             break;
1691         case ASN_PRINTABLESTRING:
1692             valueType = CERT_RDN_PRINTABLE_STRING;
1693             if (dataLen)
1694                 bytesNeeded += (dataLen + 1) * 2;
1695             break;
1696         case ASN_IA5STRING:
1697             valueType = CERT_RDN_IA5_STRING;
1698             if (dataLen)
1699                 bytesNeeded += (dataLen + 1) * 2;
1700             break;
1701         case ASN_T61STRING:
1702             valueType = CERT_RDN_T61_STRING;
1703             if (dataLen)
1704                 bytesNeeded += (dataLen + 1) * 2;
1705             break;
1706         case ASN_VIDEOTEXSTRING:
1707             valueType = CERT_RDN_VIDEOTEX_STRING;
1708             if (dataLen)
1709                 bytesNeeded += (dataLen + 1) * 2;
1710             break;
1711         case ASN_GRAPHICSTRING:
1712             valueType = CERT_RDN_GRAPHIC_STRING;
1713             if (dataLen)
1714                 bytesNeeded += (dataLen + 1) * 2;
1715             break;
1716         case ASN_VISIBLESTRING:
1717             valueType = CERT_RDN_VISIBLE_STRING;
1718             if (dataLen)
1719                 bytesNeeded += (dataLen + 1) * 2;
1720             break;
1721         case ASN_GENERALSTRING:
1722             valueType = CERT_RDN_GENERAL_STRING;
1723             if (dataLen)
1724                 bytesNeeded += (dataLen + 1) * 2;
1725             break;
1726         case ASN_UNIVERSALSTRING:
1727             valueType = CERT_RDN_UNIVERSAL_STRING;
1728             if (dataLen)
1729                 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1730             break;
1731         case ASN_BMPSTRING:
1732             valueType = CERT_RDN_BMP_STRING;
1733             if (dataLen)
1734                 bytesNeeded += dataLen + sizeof(WCHAR);
1735             break;
1736         case ASN_UTF8STRING:
1737             valueType = CERT_RDN_UTF8_STRING;
1738             if (dataLen)
1739                 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1740                  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1741             break;
1742         default:
1743             SetLastError(CRYPT_E_ASN1_BADTAG);
1744             return FALSE;
1745         }
1746
1747         if (pcbDecoded)
1748             *pcbDecoded = 1 + lenBytes + dataLen;
1749         if (!value)
1750             *pcbStructInfo = bytesNeeded;
1751         else if (*pcbStructInfo < bytesNeeded)
1752         {
1753             *pcbStructInfo = bytesNeeded;
1754             SetLastError(ERROR_MORE_DATA);
1755             ret = FALSE;
1756         }
1757         else
1758         {
1759             *pcbStructInfo = bytesNeeded;
1760             value->dwValueType = valueType;
1761             if (dataLen)
1762             {
1763                 DWORD i;
1764                 LPWSTR str = (LPWSTR)value->Value.pbData;
1765
1766                 assert(value->Value.pbData);
1767                 switch (pbEncoded[0])
1768                 {
1769                 case ASN_NUMERICSTRING:
1770                 case ASN_PRINTABLESTRING:
1771                 case ASN_IA5STRING:
1772                 case ASN_T61STRING:
1773                 case ASN_VIDEOTEXSTRING:
1774                 case ASN_GRAPHICSTRING:
1775                 case ASN_VISIBLESTRING:
1776                 case ASN_GENERALSTRING:
1777                     value->Value.cbData = dataLen * 2;
1778                     for (i = 0; i < dataLen; i++)
1779                         str[i] = pbEncoded[1 + lenBytes + i];
1780                     str[i] = 0;
1781                     break;
1782                 case ASN_UNIVERSALSTRING:
1783                     value->Value.cbData = dataLen / 2;
1784                     for (i = 0; i < dataLen / 4; i++)
1785                         str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1786                          | pbEncoded[1 + lenBytes + 2 * i + 3];
1787                     str[i] = 0;
1788                     break;
1789                 case ASN_BMPSTRING:
1790                     value->Value.cbData = dataLen;
1791                     for (i = 0; i < dataLen / 2; i++)
1792                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1793                          pbEncoded[1 + lenBytes + 2 * i + 1];
1794                     str[i] = 0;
1795                     break;
1796                 case ASN_UTF8STRING:
1797                     value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1798                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1799                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
1800                     *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
1801                     value->Value.cbData += sizeof(WCHAR);
1802                     break;
1803                 }
1804             }
1805             else
1806             {
1807                 value->Value.cbData = 0;
1808                 value->Value.pbData = NULL;
1809             }
1810         }
1811     }
1812     return ret;
1813 }
1814
1815 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1816  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1817  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1818 {
1819     BOOL ret = TRUE;
1820
1821     __TRY
1822     {
1823         ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1824          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1825         if (ret && pvStructInfo)
1826         {
1827             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1828              pcbStructInfo, *pcbStructInfo);
1829             if (ret)
1830             {
1831                 CERT_NAME_VALUE *value;
1832
1833                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1834                     pvStructInfo = *(BYTE **)pvStructInfo;
1835                 value = pvStructInfo;
1836                 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1837                 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1838                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1839                  pcbStructInfo, NULL);
1840                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1841                     CRYPT_FreeSpace(pDecodePara, value);
1842             }
1843         }
1844     }
1845     __EXCEPT_PAGE_FAULT
1846     {
1847         SetLastError(STATUS_ACCESS_VIOLATION);
1848         ret = FALSE;
1849     }
1850     __ENDTRY
1851     return ret;
1852 }
1853
1854 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1855  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1856 {
1857     BOOL ret;
1858     struct AsnDecodeSequenceItem items[] = {
1859      { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1860        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1861        offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1862      { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1863        CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1864        FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1865     };
1866     CERT_RDN_ATTR *attr = pvStructInfo;
1867
1868     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1869      pvStructInfo, *pcbStructInfo);
1870
1871     if (attr)
1872         TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1873     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1874      pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1875      attr ? attr->pszObjId : NULL);
1876     if (attr)
1877     {
1878         TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1879          debugstr_a(attr->pszObjId));
1880         TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1881     }
1882     TRACE("returning %d (%08x)\n", ret, GetLastError());
1883     return ret;
1884 }
1885
1886 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1887  DWORD dwFlags,  void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1888 {
1889     BOOL ret = TRUE;
1890     struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1891      offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1892      sizeof(CERT_RDN),
1893      CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1894      offsetof(CERT_RDN_ATTR, pszObjId) };
1895
1896     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1897      NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1898     return ret;
1899 }
1900
1901 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1902  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1903  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1904 {
1905     BOOL ret = TRUE;
1906
1907     __TRY
1908     {
1909         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1910          offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
1911          sizeof(CERT_NAME_INFO),
1912          CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1913          offsetof(CERT_RDN, rgRDNAttr) };
1914         DWORD bytesNeeded = 0;
1915
1916         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1917          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
1918          NULL);
1919         if (ret)
1920         {
1921             if (!pvStructInfo)
1922                 *pcbStructInfo = bytesNeeded;
1923             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
1924              pvStructInfo, pcbStructInfo, bytesNeeded)))
1925             {
1926                 CERT_NAME_INFO *info;
1927
1928                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1929                     pvStructInfo = *(BYTE **)pvStructInfo;
1930                 info = pvStructInfo;
1931                 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
1932                  sizeof(CERT_NAME_INFO));
1933                 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1934                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
1935                  &bytesNeeded, NULL);
1936                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1937                     CRYPT_FreeSpace(pDecodePara, info);
1938             }
1939         }
1940     }
1941     __EXCEPT_PAGE_FAULT
1942     {
1943         SetLastError(STATUS_ACCESS_VIOLATION);
1944         ret = FALSE;
1945     }
1946     __ENDTRY
1947     return ret;
1948 }
1949
1950 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1951  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1952  DWORD *pcbDecoded)
1953 {
1954     BOOL ret;
1955     struct AsnDecodeSequenceItem items[] = {
1956      { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1957        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1958        offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1959      { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1960        CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1961        FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1962     };
1963     CERT_RDN_ATTR *attr = pvStructInfo;
1964
1965     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1966      pvStructInfo, *pcbStructInfo);
1967
1968     if (attr)
1969         TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1970     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1971      pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1972      attr ? attr->pszObjId : NULL);
1973     if (attr)
1974     {
1975         TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1976          debugstr_a(attr->pszObjId));
1977         TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1978     }
1979     TRACE("returning %d (%08x)\n", ret, GetLastError());
1980     return ret;
1981 }
1982
1983 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1984  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1985 {
1986     BOOL ret = TRUE;
1987     struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1988      offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1989      sizeof(CERT_RDN),
1990      CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1991      offsetof(CERT_RDN_ATTR, pszObjId) };
1992
1993     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1994      NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1995     return ret;
1996 }
1997
1998 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1999  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2000  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2001 {
2002     BOOL ret = TRUE;
2003
2004     __TRY
2005     {
2006         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2007          offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
2008          sizeof(CERT_NAME_INFO),
2009          CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
2010          offsetof(CERT_RDN, rgRDNAttr) };
2011         DWORD bytesNeeded = 0;
2012
2013         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2014          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
2015          NULL);
2016         if (ret)
2017         {
2018             if (!pvStructInfo)
2019                 *pcbStructInfo = bytesNeeded;
2020             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2021              pvStructInfo, pcbStructInfo, bytesNeeded)))
2022             {
2023                 CERT_NAME_INFO *info;
2024
2025                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2026                     pvStructInfo = *(BYTE **)pvStructInfo;
2027                 info = pvStructInfo;
2028                 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
2029                  sizeof(CERT_NAME_INFO));
2030                 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2031                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
2032                  &bytesNeeded, NULL);
2033                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2034                     CRYPT_FreeSpace(pDecodePara, info);
2035             }
2036         }
2037     }
2038     __EXCEPT_PAGE_FAULT
2039     {
2040         SetLastError(STATUS_ACCESS_VIOLATION);
2041         ret = FALSE;
2042     }
2043     __ENDTRY
2044     return ret;
2045 }
2046
2047 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
2048  DWORD *pcbDecoded)
2049 {
2050     BOOL ret = TRUE, done = FALSE;
2051     DWORD indefiniteNestingLevels = 0, decoded = 0;
2052
2053     TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2054
2055     do {
2056         DWORD dataLen;
2057
2058         if (!cbEncoded)
2059             done = TRUE;
2060         else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2061          &dataLen)))
2062         {
2063             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2064
2065             if (dataLen == CMSG_INDEFINITE_LENGTH)
2066             {
2067                 indefiniteNestingLevels++;
2068                 pbEncoded += 1 + lenBytes;
2069                 cbEncoded -= 1 + lenBytes;
2070                 decoded += 1 + lenBytes;
2071                 TRACE("indefiniteNestingLevels = %d\n",
2072                  indefiniteNestingLevels);
2073             }
2074             else
2075             {
2076                 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2077                  indefiniteNestingLevels)
2078                 {
2079                     indefiniteNestingLevels--;
2080                     TRACE("indefiniteNestingLevels = %d\n",
2081                      indefiniteNestingLevels);
2082                 }
2083                 pbEncoded += 1 + lenBytes + dataLen;
2084                 cbEncoded -= 1 + lenBytes + dataLen;
2085                 decoded += 1 + lenBytes + dataLen;
2086                 if (!indefiniteNestingLevels)
2087                     done = TRUE;
2088             }
2089         }
2090     } while (ret && !done);
2091     /* If we haven't found all 0 TLVs, we haven't found the end */
2092     if (ret && indefiniteNestingLevels)
2093     {
2094         SetLastError(CRYPT_E_ASN1_EOD);
2095         ret = FALSE;
2096     }
2097     if (ret)
2098         *pcbDecoded = decoded;
2099     TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2100     return ret;
2101 }
2102
2103 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
2104  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2105  DWORD *pcbDecoded)
2106 {
2107     BOOL ret = TRUE;
2108     DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2109
2110     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2111      pvStructInfo, *pcbStructInfo);
2112
2113     if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2114     {
2115         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
2116             bytesNeeded += encodedLen;
2117         if (!pvStructInfo)
2118             *pcbStructInfo = bytesNeeded;
2119         else if (*pcbStructInfo < bytesNeeded)
2120         {
2121             SetLastError(ERROR_MORE_DATA);
2122             *pcbStructInfo = bytesNeeded;
2123             ret = FALSE;
2124         }
2125         else
2126         {
2127             PCRYPT_OBJID_BLOB blob = pvStructInfo;
2128
2129             *pcbStructInfo = bytesNeeded;
2130             blob->cbData = encodedLen;
2131             if (encodedLen)
2132             {
2133                 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2134                     blob->pbData = (LPBYTE)pbEncoded;
2135                 else
2136                 {
2137                     assert(blob->pbData);
2138                     memcpy(blob->pbData, pbEncoded, blob->cbData);
2139                 }
2140             }
2141             else
2142                 blob->pbData = NULL;
2143         }
2144         if (pcbDecoded)
2145             *pcbDecoded = encodedLen;
2146     }
2147     return ret;
2148 }
2149
2150 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2151  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2152 {
2153     BOOL ret;
2154     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2155      offsetof(CTL_USAGE, cUsageIdentifier),
2156      offsetof(CTL_USAGE, rgpszUsageIdentifier),
2157      sizeof(CTL_USAGE),
2158      CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2159
2160     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2161      NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2162     return ret;
2163 }
2164
2165 static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded,
2166  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2167  DWORD *pcbDecoded)
2168 {
2169     struct AsnArrayDescriptor arrayDesc = { 0,
2170      offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
2171      FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
2172      CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2173      offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2174     BOOL ret;
2175
2176     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2177      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2178     return ret;
2179 }
2180
2181 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2182  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2183 {
2184     struct AsnDecodeSequenceItem items[] = {
2185      { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2186        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2187        offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2188      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2189        CRYPT_AsnDecodeCTLEntryAttributes,
2190        FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
2191        offsetof(CTL_ENTRY, rgAttribute), 0 },
2192     };
2193     BOOL ret = TRUE;
2194     CTL_ENTRY *entry = pvStructInfo;
2195
2196     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2197      *pcbStructInfo);
2198
2199     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2200      pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2201      pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2202     return ret;
2203 }
2204
2205 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2206  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2207 {
2208     BOOL ret;
2209     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2210      offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
2211      FINALMEMBERSIZE(CTL_INFO, cExtension),
2212      CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2213      offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2214
2215     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2216      pvStructInfo, *pcbStructInfo, pcbDecoded);
2217
2218     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2219      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2220     return ret;
2221 }
2222
2223 static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded,
2224  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2225  DWORD *pcbDecoded)
2226 {
2227     BOOL ret = TRUE;
2228     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2229      offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
2230      FINALMEMBERSIZE(CTL_INFO, cExtension),
2231      CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
2232      offsetof(CERT_EXTENSION, pszObjId) };
2233
2234     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2235      pvStructInfo, *pcbStructInfo, pcbDecoded);
2236
2237     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2238      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2239     return ret;
2240 }
2241
2242 static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded,
2243  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2244  DWORD *pcbDecoded)
2245 {
2246     BOOL ret;
2247     DWORD dataLen;
2248
2249     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2250     {
2251         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2252
2253         ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes,
2254          dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
2255         if (ret && pcbDecoded)
2256             *pcbDecoded = 1 + lenBytes + dataLen;
2257     }
2258     return ret;
2259 }
2260
2261 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2262  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2263  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2264 {
2265     BOOL ret = FALSE;
2266
2267     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2268      pDecodePara, pvStructInfo, *pcbStructInfo);
2269
2270     __TRY
2271     {
2272         struct AsnDecodeSequenceItem items[] = {
2273          { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2274            CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2275          { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2276            CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2277            offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2278          { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2279            CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2280            TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2281          { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2282            CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2283            TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2284          { 0, offsetof(CTL_INFO, ThisUpdate),
2285            CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2286            0 },
2287          { 0, offsetof(CTL_INFO, NextUpdate),
2288            CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2289            0 },
2290          { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2291            CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2292            FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2293          { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2294            CRYPT_AsnDecodeCTLEntries,
2295            MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2296            TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2297          { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2298            CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension),
2299            TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
2300         };
2301
2302         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2303          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2304          pcbStructInfo, NULL, NULL);
2305     }
2306     __EXCEPT_PAGE_FAULT
2307     {
2308         SetLastError(STATUS_ACCESS_VIOLATION);
2309     }
2310     __ENDTRY
2311     return ret;
2312 }
2313
2314 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2315  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2316  DWORD *pcbDecoded)
2317 {
2318     BOOL ret;
2319     struct AsnDecodeSequenceItem items[] = {
2320      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2321        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2322        offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2323      { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2324        CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2325        offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2326     };
2327     PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2328
2329     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2330      pvStructInfo, *pcbStructInfo);
2331
2332     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2333      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2334      pcbDecoded, capability ? capability->pszObjId : NULL);
2335     TRACE("returning %d\n", ret);
2336     return ret;
2337 }
2338
2339 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2340  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2341  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2342 {
2343     BOOL ret = FALSE;
2344
2345     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2346      pDecodePara, pvStructInfo, *pcbStructInfo);
2347
2348     __TRY
2349     {
2350         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2351          offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
2352          offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
2353          sizeof(CRYPT_SMIME_CAPABILITIES),
2354          CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2355          offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2356         CRYPT_SMIME_CAPABILITIES *capabilities = pvStructInfo;
2357
2358         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2359             capabilities->rgCapability = (CRYPT_SMIME_CAPABILITY *)(capabilities + 1);
2360         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2361          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2362     }
2363     __EXCEPT_PAGE_FAULT
2364     {
2365         SetLastError(STATUS_ACCESS_VIOLATION);
2366     }
2367     __ENDTRY
2368     TRACE("returning %d\n", ret);
2369     return ret;
2370 }
2371
2372 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2373  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2374  DWORD *pcbDecoded)
2375 {
2376     BOOL ret = TRUE;
2377     DWORD dataLen;
2378     LPSTR *pStr = pvStructInfo;
2379
2380     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2381     {
2382         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2383         DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2384
2385         if (pbEncoded[0] != ASN_IA5STRING)
2386         {
2387             SetLastError(CRYPT_E_ASN1_CORRUPT);
2388             ret = FALSE;
2389         }
2390         else
2391         {
2392             bytesNeeded += dataLen;
2393             if (pcbDecoded)
2394                 *pcbDecoded = 1 + lenBytes + dataLen;
2395             if (!pvStructInfo)
2396                 *pcbStructInfo = bytesNeeded;
2397             else if (*pcbStructInfo < bytesNeeded)
2398             {
2399                 *pcbStructInfo = bytesNeeded;
2400                 SetLastError(ERROR_MORE_DATA);
2401                 ret = FALSE;
2402             }
2403             else
2404             {
2405                 *pcbStructInfo = bytesNeeded;
2406                 if (dataLen)
2407                 {
2408                     LPSTR str = *pStr;
2409
2410                     assert(str);
2411                     memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2412                     str[dataLen] = 0;
2413                 }
2414                 else
2415                     *pStr = NULL;
2416             }
2417         }
2418     }
2419     return ret;
2420 }
2421
2422 static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded,
2423  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2424  DWORD *pcbDecoded)
2425 {
2426     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2427      offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2428      offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers),
2429      FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2430      CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2431     BOOL ret;
2432
2433     TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2434      pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2435
2436     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2437      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2438     TRACE("returning %d\n", ret);
2439     return ret;
2440 }
2441
2442 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2443  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2444  DWORD *pcbDecoded)
2445 {
2446     BOOL ret;
2447     struct AsnDecodeSequenceItem items[] = {
2448      { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2449        pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2450        offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2451      { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2452        cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
2453        FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2454        FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2455        rgNoticeNumbers), 0 },
2456     };
2457     DWORD bytesNeeded = 0;
2458
2459     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2460      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2461
2462     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2463      pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2464      NULL);
2465     if (ret)
2466     {
2467         /* The caller is expecting a pointer to a
2468          * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2469          * CRYPT_AsnDecodeSequence is decoding a
2470          * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.  Increment the bytes
2471          * needed, and decode again if the requisite space is available.
2472          */
2473         bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2474         if (!pvStructInfo)
2475             *pcbStructInfo = bytesNeeded;
2476         else if (*pcbStructInfo < bytesNeeded)
2477         {
2478             *pcbStructInfo = bytesNeeded;
2479             SetLastError(ERROR_MORE_DATA);
2480             ret = FALSE;
2481         }
2482         else
2483         {
2484             PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2485
2486             *pcbStructInfo = bytesNeeded;
2487             /* The pointer (pvStructInfo) passed in points to the first dynamic
2488              * pointer, so use it as the pointer to the
2489              * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2490              * appropriate offset for the first dynamic pointer within the
2491              * notice reference by pointing to the first memory location past
2492              * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2493              */
2494             noticeRef =
2495              *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2496             noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2497              sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2498             ret = CRYPT_AsnDecodeSequence(items,
2499              sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2500              NULL, noticeRef, &bytesNeeded, pcbDecoded,
2501              noticeRef->pszOrganization);
2502         }
2503     }
2504     TRACE("returning %d\n", ret);
2505     return ret;
2506 }
2507
2508 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2509  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2510  DWORD *pcbDecoded)
2511 {
2512     BOOL ret = TRUE;
2513     DWORD dataLen;
2514
2515     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2516     {
2517         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2518         DWORD bytesNeeded = sizeof(LPWSTR);
2519
2520         switch (pbEncoded[0])
2521         {
2522         case ASN_NUMERICSTRING:
2523             if (dataLen)
2524                 bytesNeeded += (dataLen + 1) * 2;
2525             break;
2526         case ASN_PRINTABLESTRING:
2527             if (dataLen)
2528                 bytesNeeded += (dataLen + 1) * 2;
2529             break;
2530         case ASN_IA5STRING:
2531             if (dataLen)
2532                 bytesNeeded += (dataLen + 1) * 2;
2533             break;
2534         case ASN_T61STRING:
2535             if (dataLen)
2536                 bytesNeeded += (dataLen + 1) * 2;
2537             break;
2538         case ASN_VIDEOTEXSTRING:
2539             if (dataLen)
2540                 bytesNeeded += (dataLen + 1) * 2;
2541             break;
2542         case ASN_GRAPHICSTRING:
2543             if (dataLen)
2544                 bytesNeeded += (dataLen + 1) * 2;
2545             break;
2546         case ASN_VISIBLESTRING:
2547             if (dataLen)
2548                 bytesNeeded += (dataLen + 1) * 2;
2549             break;
2550         case ASN_GENERALSTRING:
2551             if (dataLen)
2552                 bytesNeeded += (dataLen + 1) * 2;
2553             break;
2554         case ASN_UNIVERSALSTRING:
2555             if (dataLen)
2556                 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2557             break;
2558         case ASN_BMPSTRING:
2559             if (dataLen)
2560                 bytesNeeded += dataLen + sizeof(WCHAR);
2561             break;
2562         case ASN_UTF8STRING:
2563             if (dataLen)
2564                 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2565                  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2566             break;
2567         default:
2568             SetLastError(CRYPT_E_ASN1_BADTAG);
2569             return FALSE;
2570         }
2571
2572         if (pcbDecoded)
2573             *pcbDecoded = 1 + lenBytes + dataLen;
2574         if (!pvStructInfo)
2575             *pcbStructInfo = bytesNeeded;
2576         else if (*pcbStructInfo < bytesNeeded)
2577         {
2578             *pcbStructInfo = bytesNeeded;
2579             SetLastError(ERROR_MORE_DATA);
2580             ret = FALSE;
2581         }
2582         else
2583         {
2584             LPWSTR *pStr = pvStructInfo;
2585
2586             *pcbStructInfo = bytesNeeded;
2587             if (dataLen)
2588             {
2589                 DWORD i;
2590                 LPWSTR str = *(LPWSTR *)pStr;
2591
2592                 assert(str);
2593                 switch (pbEncoded[0])
2594                 {
2595                 case ASN_NUMERICSTRING:
2596                 case ASN_PRINTABLESTRING:
2597                 case ASN_IA5STRING:
2598                 case ASN_T61STRING:
2599                 case ASN_VIDEOTEXSTRING:
2600                 case ASN_GRAPHICSTRING:
2601                 case ASN_VISIBLESTRING:
2602                 case ASN_GENERALSTRING:
2603                     for (i = 0; i < dataLen; i++)
2604                         str[i] = pbEncoded[1 + lenBytes + i];
2605                     str[i] = 0;
2606                     break;
2607                 case ASN_UNIVERSALSTRING:
2608                     for (i = 0; i < dataLen / 4; i++)
2609                         str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2610                          | pbEncoded[1 + lenBytes + 2 * i + 3];
2611                     str[i] = 0;
2612                     break;
2613                 case ASN_BMPSTRING:
2614                     for (i = 0; i < dataLen / 2; i++)
2615                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2616                          pbEncoded[1 + lenBytes + 2 * i + 1];
2617                     str[i] = 0;
2618                     break;
2619                 case ASN_UTF8STRING:
2620                 {
2621                     int len = MultiByteToWideChar(CP_UTF8, 0,
2622                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2623                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2624                     str[len] = 0;
2625                     break;
2626                 }
2627                 }
2628             }
2629             else
2630                 *pStr = NULL;
2631         }
2632     }
2633     return ret;
2634 }
2635
2636 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2637  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2638  DWORD *pcbStructInfo, DWORD *pcbDecoded)
2639 {
2640     BOOL ret;
2641     struct AsnDecodeSequenceItem items[] = {
2642      { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2643        pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2644        sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2645        offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2646      { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2647        CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2648        offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2649     };
2650     PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2651
2652     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2653      pvStructInfo, *pcbStructInfo);
2654
2655     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2656      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2657      pcbDecoded, notice ? notice->pNoticeReference : NULL);
2658     TRACE("returning %d\n", ret);
2659     return ret;
2660 }
2661
2662 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2663  DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2664  DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2665  void *pvStructInfo, DWORD *pcbStructInfo)
2666 {
2667     BOOL ret = FALSE;
2668
2669     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2670      pDecodePara, pvStructInfo, *pcbStructInfo);
2671
2672     __TRY
2673     {
2674         DWORD bytesNeeded = 0;
2675
2676         ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2677          cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2678          NULL);
2679         if (ret)
2680         {
2681             if (!pvStructInfo)
2682                 *pcbStructInfo = bytesNeeded;
2683             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2684              pvStructInfo, pcbStructInfo, bytesNeeded)))
2685             {
2686                 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2687
2688                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2689                     pvStructInfo = *(BYTE **)pvStructInfo;
2690                 notice = pvStructInfo;
2691                 notice->pNoticeReference =
2692                  (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2693                  ((BYTE *)pvStructInfo +
2694                  sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2695                 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2696                  pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2697                  pvStructInfo, &bytesNeeded, NULL);
2698                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2699                     CRYPT_FreeSpace(pDecodePara, notice);
2700             }
2701         }
2702     }
2703     __EXCEPT_PAGE_FAULT
2704     {
2705         SetLastError(STATUS_ACCESS_VIOLATION);
2706     }
2707     __ENDTRY
2708     TRACE("returning %d\n", ret);
2709     return ret;
2710 }
2711
2712 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
2713  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2714  DWORD *pcbDecoded)
2715 {
2716     BOOL ret;
2717     struct AsnArrayDescriptor arrayDesc = { 0,
2718      offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
2719      FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue),
2720      CRYPT_AsnDecodeCopyBytes,
2721      sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2722
2723     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2724      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
2725
2726     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2727      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2728     return ret;
2729 }
2730
2731 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2732  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2733  DWORD *pcbDecoded)
2734 {
2735     BOOL ret;
2736     struct AsnDecodeSequenceItem items[] = {
2737      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2738        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2739        offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2740      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2741        CRYPT_AsnDecodePKCSAttributeValue,
2742        FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
2743        TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2744     };
2745     PCRYPT_ATTRIBUTE attr = pvStructInfo;
2746
2747     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2748      pvStructInfo, *pcbStructInfo);
2749
2750     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2751      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2752      pcbDecoded, attr ? attr->pszObjId : NULL);
2753     TRACE("returning %d\n", ret);
2754     return ret;
2755 }
2756
2757 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2758  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2759  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2760 {
2761     BOOL ret = FALSE;
2762
2763     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2764      pDecodePara, pvStructInfo, *pcbStructInfo);
2765
2766     __TRY
2767     {
2768         DWORD bytesNeeded = 0;
2769
2770         ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2771          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2772         if (ret)
2773         {
2774             if (!pvStructInfo)
2775                 *pcbStructInfo = bytesNeeded;
2776             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2777              pvStructInfo, pcbStructInfo, bytesNeeded)))
2778             {
2779                 PCRYPT_ATTRIBUTE attr;
2780
2781                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2782                     pvStructInfo = *(BYTE **)pvStructInfo;
2783                 attr = pvStructInfo;
2784                 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2785                  sizeof(CRYPT_ATTRIBUTE));
2786                 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2787                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2788                  NULL);
2789                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2790                     CRYPT_FreeSpace(pDecodePara, attr);
2791             }
2792         }
2793     }
2794     __EXCEPT_PAGE_FAULT
2795     {
2796         SetLastError(STATUS_ACCESS_VIOLATION);
2797     }
2798     __ENDTRY
2799     TRACE("returning %d\n", ret);
2800     return ret;
2801 }
2802
2803 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2804  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2805  DWORD *pcbDecoded)
2806 {
2807     struct AsnArrayDescriptor arrayDesc = { 0,
2808      offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2809      sizeof(CRYPT_ATTRIBUTES),
2810      CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2811      offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2812     BOOL ret;
2813
2814     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2815      NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2816     return ret;
2817 }
2818
2819 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2820  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2821  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2822 {
2823     BOOL ret = FALSE;
2824
2825     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2826      pDecodePara, pvStructInfo, *pcbStructInfo);
2827
2828     __TRY
2829     {
2830         struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2831          offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2832          sizeof(CRYPT_ATTRIBUTES),
2833          CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
2834          TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2835         CRYPT_ATTRIBUTES *attrs = pvStructInfo;
2836
2837         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2838             attrs->rgAttr = (CRYPT_ATTRIBUTE *)(attrs + 1);
2839         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2840          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2841     }
2842     __EXCEPT_PAGE_FAULT
2843     {
2844         SetLastError(STATUS_ACCESS_VIOLATION);
2845     }
2846     __ENDTRY
2847     TRACE("returning %d\n", ret);
2848     return ret;
2849 }
2850
2851 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2852  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2853 {
2854     CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2855     BOOL ret = TRUE;
2856     struct AsnDecodeSequenceItem items[] = {
2857      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2858        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2859        offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2860      { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2861        CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE, 
2862        offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2863     };
2864
2865     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2866      pvStructInfo, *pcbStructInfo, pcbDecoded);
2867
2868     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2869      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2870      pcbDecoded, algo ? algo->pszObjId : NULL);
2871     if (ret && pvStructInfo)
2872     {
2873         TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2874          debugstr_a(algo->pszObjId));
2875     }
2876     return ret;
2877 }
2878
2879 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2880  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2881  DWORD *pcbDecoded)
2882 {
2883     BOOL ret = TRUE;
2884     struct AsnDecodeSequenceItem items[] = {
2885      { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2886        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2887        FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2888        Algorithm.pszObjId) },
2889      { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2890        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2891        offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2892     };
2893     PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2894
2895     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2896      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2897      pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2898     return ret;
2899 }
2900
2901 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2902  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2903  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2904 {
2905     BOOL ret = TRUE;
2906
2907     __TRY
2908     {
2909         DWORD bytesNeeded = 0;
2910
2911         if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2912          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2913         {
2914             if (!pvStructInfo)
2915                 *pcbStructInfo = bytesNeeded;
2916             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2917              pvStructInfo, pcbStructInfo, bytesNeeded)))
2918             {
2919                 PCERT_PUBLIC_KEY_INFO info;
2920
2921                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2922                     pvStructInfo = *(BYTE **)pvStructInfo;
2923                 info = pvStructInfo;
2924                 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2925                  sizeof(CERT_PUBLIC_KEY_INFO);
2926                 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2927                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2928                  &bytesNeeded, NULL);
2929                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2930                     CRYPT_FreeSpace(pDecodePara, info);
2931             }
2932         }
2933     }
2934     __EXCEPT_PAGE_FAULT
2935     {
2936         SetLastError(STATUS_ACCESS_VIOLATION);
2937         ret = FALSE;
2938     }
2939     __ENDTRY
2940     return ret;
2941 }
2942
2943 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2944  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2945 {
2946     BOOL ret;
2947
2948     if (cbEncoded < 3)
2949     {
2950         SetLastError(CRYPT_E_ASN1_CORRUPT);
2951         return FALSE;
2952     }
2953     if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2954     {
2955         SetLastError(CRYPT_E_ASN1_CORRUPT);
2956         return FALSE;
2957     }
2958     if (pbEncoded[1] > 1)
2959     {
2960         SetLastError(CRYPT_E_ASN1_CORRUPT);
2961         return FALSE;
2962     }
2963     if (pcbDecoded)
2964         *pcbDecoded = 3;
2965     if (!pvStructInfo)
2966     {
2967         *pcbStructInfo = sizeof(BOOL);
2968         ret = TRUE;
2969     }
2970     else if (*pcbStructInfo < sizeof(BOOL))
2971     {
2972         *pcbStructInfo = sizeof(BOOL);
2973         SetLastError(ERROR_MORE_DATA);
2974         ret = FALSE;
2975     }
2976     else
2977     {
2978         *pcbStructInfo = sizeof(BOOL);
2979         *(BOOL *)pvStructInfo = pbEncoded[2] != 0;
2980         ret = TRUE;
2981     }
2982     TRACE("returning %d (%08x)\n", ret, GetLastError());
2983     return ret;
2984 }
2985
2986 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2987  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2988 {
2989     PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2990     DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2991     BOOL ret;
2992
2993     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2994      pvStructInfo, *pcbStructInfo);
2995
2996     if (cbEncoded < 2)
2997     {
2998         SetLastError(CRYPT_E_ASN1_CORRUPT);
2999         return FALSE;
3000     }
3001     lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3002     if (1 + lenBytes > cbEncoded)
3003     {
3004         SetLastError(CRYPT_E_ASN1_CORRUPT);
3005         return FALSE;
3006     }
3007     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3008     {
3009         switch (pbEncoded[0] & ASN_TYPE_MASK)
3010         {
3011         case 1: /* rfc822Name */
3012         case 2: /* dNSName */
3013         case 6: /* uniformResourceIdentifier */
3014             if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen))
3015             {
3016                 SetLastError(CRYPT_E_ASN1_RULE);
3017                 ret = FALSE;
3018             }
3019             else
3020                 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
3021             break;
3022         case 4: /* directoryName */
3023         case 7: /* iPAddress */
3024             bytesNeeded += dataLen;
3025             break;
3026         case 8: /* registeredID */
3027             ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
3028              &dataLen, NULL);
3029             if (ret)
3030             {
3031                 /* FIXME: ugly, shouldn't need to know internals of OID decode
3032                  * function to use it.
3033                  */
3034                 bytesNeeded += dataLen - sizeof(LPSTR);
3035             }
3036             break;
3037         case 0: /* otherName */
3038             FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
3039             SetLastError(CRYPT_E_ASN1_BADTAG);
3040             ret = FALSE;
3041             break;
3042         case 3: /* x400Address, unimplemented */
3043         case 5: /* ediPartyName, unimplemented */
3044             TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
3045             SetLastError(CRYPT_E_ASN1_BADTAG);
3046             ret = FALSE;
3047             break;
3048         default:
3049             TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
3050             SetLastError(CRYPT_E_ASN1_CORRUPT);
3051             ret = FALSE;
3052         }
3053         if (ret)
3054         {
3055             if (pcbDecoded)
3056                 *pcbDecoded = 1 + lenBytes + dataLen;
3057             if (!entry)
3058                 *pcbStructInfo = bytesNeeded;
3059             else if (*pcbStructInfo < bytesNeeded)
3060             {
3061                 *pcbStructInfo = bytesNeeded;
3062                 SetLastError(ERROR_MORE_DATA);
3063                 ret = FALSE;
3064             }
3065             else
3066             {
3067                 *pcbStructInfo = bytesNeeded;
3068                 /* MS used values one greater than the asn1 ones.. sigh */
3069                 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
3070                 switch (pbEncoded[0] & ASN_TYPE_MASK)
3071                 {
3072                 case 1: /* rfc822Name */
3073                 case 2: /* dNSName */
3074                 case 6: /* uniformResourceIdentifier */
3075                 {
3076                     DWORD i;
3077
3078                     for (i = 0; i < dataLen; i++)
3079                         entry->u.pwszURL[i] =
3080                          (WCHAR)pbEncoded[1 + lenBytes + i];
3081                     entry->u.pwszURL[i] = 0;
3082                     TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3083                      debugstr_w(entry->u.pwszURL));
3084                     break;
3085                 }
3086                 case 4: /* directoryName */
3087                     /* The data are memory-equivalent with the IPAddress case,
3088                      * fall-through
3089                      */
3090                 case 7: /* iPAddress */
3091                     /* The next data pointer is in the pwszURL spot, that is,
3092                      * the first 4 bytes.  Need to move it to the next spot.
3093                      */
3094                     entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3095                     entry->u.IPAddress.cbData = dataLen;
3096                     memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3097                      dataLen);
3098                     break;
3099                 case 8: /* registeredID */
3100                     ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
3101                      &entry->u.pszRegisteredID, &dataLen, NULL);
3102                     break;
3103                 }
3104             }
3105         }
3106     }
3107     return ret;
3108 }
3109
3110 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
3111  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3112  DWORD *pcbDecoded)
3113 {
3114     BOOL ret;
3115     struct AsnArrayDescriptor arrayDesc = { 0,
3116      offsetof(CERT_ALT_NAME_INFO, cAltEntry),
3117      offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
3118      sizeof(CERT_ALT_NAME_INFO),
3119      CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3120      offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3121
3122     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3123      pvStructInfo, *pcbStructInfo, pcbDecoded);
3124
3125     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3126      NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3127     return ret;
3128 }
3129
3130 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3131  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3132  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3133 {
3134     BOOL ret;
3135
3136     __TRY
3137     {
3138         struct AsnDecodeSequenceItem items[] = {
3139          { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3140            CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB),
3141            TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3142          { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3143            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3144            CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3145            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3146          { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3147            CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3148            sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3149            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3150         };
3151
3152         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3153          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3154          pcbStructInfo, NULL, NULL);
3155     }
3156     __EXCEPT_PAGE_FAULT
3157     {
3158         SetLastError(STATUS_ACCESS_VIOLATION);
3159         ret = FALSE;
3160     }
3161     __ENDTRY
3162     return ret;
3163 }
3164
3165 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3166  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3167  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3168 {
3169     BOOL ret;
3170
3171     __TRY
3172     {
3173         struct AsnDecodeSequenceItem items[] = {
3174          { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3175            CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB),
3176            TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3177          { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3178            offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3179            CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3180            TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3181            AuthorityCertIssuer.rgAltEntry), 0 },
3182          { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3183            AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3184            sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3185            offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3186            AuthorityCertSerialNumber.pbData), 0 },
3187         };
3188
3189         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3190          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3191          pcbStructInfo, NULL, NULL);
3192     }
3193     __EXCEPT_PAGE_FAULT
3194     {
3195         SetLastError(STATUS_ACCESS_VIOLATION);
3196         ret = FALSE;
3197     }
3198     __ENDTRY
3199     return ret;
3200 }
3201
3202 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3203  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3204  DWORD *pcbDecoded)
3205 {
3206     struct AsnDecodeSequenceItem items[] = {
3207      { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3208        CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3209        offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3210      { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3211        CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3212        TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3213     };
3214     CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3215
3216     return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3217      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3218      pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3219 }
3220
3221 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3222  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3223  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3224 {
3225     BOOL ret;
3226
3227     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3228      pDecodePara, pvStructInfo, *pcbStructInfo);
3229
3230     __TRY
3231     {
3232         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3233          offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr),
3234          offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr),
3235          sizeof(CERT_AUTHORITY_INFO_ACCESS),
3236          CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3237          TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3238         CERT_AUTHORITY_INFO_ACCESS *info = pvStructInfo;
3239
3240         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3241             info->rgAccDescr = (CERT_ACCESS_DESCRIPTION *)(info + 1);
3242         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3243          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3244     }
3245     __EXCEPT_PAGE_FAULT
3246     {
3247         SetLastError(STATUS_ACCESS_VIOLATION);
3248         ret = FALSE;
3249     }
3250     __ENDTRY
3251     return ret;
3252 }
3253
3254 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3255  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3256 {
3257     BOOL ret;
3258     DWORD dataLen;
3259
3260     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3261      pvStructInfo, *pcbStructInfo, pcbDecoded);
3262
3263     /* The caller has already checked the tag, no need to check it again.
3264      * Check the outer length is valid:
3265      */
3266     if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3267     {
3268         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3269         DWORD innerLen;
3270
3271         pbEncoded += 1 + lenBytes;
3272         cbEncoded -= 1 + lenBytes;
3273         if (dataLen == CMSG_INDEFINITE_LENGTH)
3274             cbEncoded -= 2; /* space for 0 TLV */
3275         /* Check the inner length is valid: */
3276         if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3277         {
3278             DWORD decodedLen;
3279
3280             ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3281              pvStructInfo, pcbStructInfo, &decodedLen);
3282             if (dataLen == CMSG_INDEFINITE_LENGTH)
3283             {
3284                 if (*(pbEncoded + decodedLen) != 0 ||
3285                  *(pbEncoded + decodedLen + 1) != 0)
3286                 {
3287                     TRACE("expected 0 TLV, got {%02x,%02x}\n",
3288                      *(pbEncoded + decodedLen),
3289                      *(pbEncoded + decodedLen + 1));
3290                     SetLastError(CRYPT_E_ASN1_CORRUPT);
3291                     ret = FALSE;
3292                 }
3293                 else
3294                     decodedLen += 2;
3295             }
3296             if (ret && pcbDecoded)
3297             {
3298                 *pcbDecoded = 1 + lenBytes + decodedLen;
3299                 TRACE("decoded %d bytes\n", *pcbDecoded);
3300             }
3301         }
3302     }
3303     return ret;
3304 }
3305
3306 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3307  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3308  DWORD *pcbDecoded)
3309 {
3310     CRYPT_CONTENT_INFO *info = pvStructInfo;
3311     struct AsnDecodeSequenceItem items[] = {
3312      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3313        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3314        offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3315      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3316        offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3317        sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3318        offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3319     };
3320     BOOL ret;
3321
3322     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3323      pvStructInfo, *pcbStructInfo, pcbDecoded);
3324
3325     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3326      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3327      pcbDecoded, info ? info->pszObjId : NULL);
3328     return ret;
3329 }
3330
3331 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3332  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3333  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3334 {
3335     BOOL ret = FALSE;
3336
3337     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3338      pDecodePara, pvStructInfo, *pcbStructInfo);
3339
3340     __TRY
3341     {
3342         ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3343          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3344         if (ret && pvStructInfo)
3345         {
3346             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3347              pcbStructInfo, *pcbStructInfo);
3348             if (ret)
3349             {
3350                 CRYPT_CONTENT_INFO *info;
3351
3352                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3353                     pvStructInfo = *(BYTE **)pvStructInfo;
3354                 info = pvStructInfo;
3355                 info->pszObjId = (LPSTR)((BYTE *)info +
3356                  sizeof(CRYPT_CONTENT_INFO));
3357                 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3358                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3359                  pcbStructInfo, NULL);
3360                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3361                     CRYPT_FreeSpace(pDecodePara, info);
3362             }
3363         }
3364     }
3365     __EXCEPT_PAGE_FAULT
3366     {
3367         SetLastError(STATUS_ACCESS_VIOLATION);
3368     }
3369     __ENDTRY
3370     return ret;
3371 }
3372
3373 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3374  DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3375  CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3376 {
3377     BOOL ret;
3378     struct AsnDecodeSequenceItem items[] = {
3379      { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3380        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3381      { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3382        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3383        FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3384        0 },
3385      { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3386        CRYPT_AsnDecodePKCSContentInfoInternal,
3387        sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3388        ContentInfo.pszObjId), 0 },
3389      { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3390        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3391        offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3392     };
3393
3394     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3395      pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3396      NULL, NULL);
3397     return ret;
3398 }
3399
3400 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3401  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3402  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3403 {
3404     BOOL ret = TRUE;
3405
3406     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3407      pDecodePara, pvStructInfo, *pcbStructInfo);
3408
3409     __TRY
3410     {
3411         DWORD bytesNeeded = 0;
3412
3413         if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3414          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3415         {
3416             if (!pvStructInfo)
3417                 *pcbStructInfo = bytesNeeded;
3418             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3419              pvStructInfo, pcbStructInfo, bytesNeeded)))
3420             {
3421                 CERT_ALT_NAME_INFO *name;
3422
3423                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3424                     pvStructInfo = *(BYTE **)pvStructInfo;
3425                 name = pvStructInfo;
3426                 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3427                  ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3428                 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3429                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3430                  &bytesNeeded, NULL);
3431                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3432                     CRYPT_FreeSpace(pDecodePara, name);
3433             }
3434         }
3435     }
3436     __EXCEPT_PAGE_FAULT
3437     {
3438         SetLastError(STATUS_ACCESS_VIOLATION);
3439         ret = FALSE;
3440     }
3441     __ENDTRY
3442     return ret;
3443 }
3444
3445 struct PATH_LEN_CONSTRAINT
3446 {
3447     BOOL  fPathLenConstraint;
3448     DWORD dwPathLenConstraint;
3449 };
3450
3451 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3452  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3453  DWORD *pcbDecoded)
3454 {
3455     BOOL ret = TRUE;
3456     DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3457
3458     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3459      pvStructInfo, *pcbStructInfo, pcbDecoded);
3460
3461     if (!pvStructInfo)
3462     {
3463         ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3464          &size, pcbDecoded);
3465         *pcbStructInfo = bytesNeeded;
3466     }
3467     else if (*pcbStructInfo < bytesNeeded)
3468     {
3469         SetLastError(ERROR_MORE_DATA);
3470         *pcbStructInfo = bytesNeeded;
3471         ret = FALSE;
3472     }
3473     else
3474     {
3475         struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3476
3477         *pcbStructInfo = bytesNeeded;
3478         size = sizeof(constraint->dwPathLenConstraint);
3479         ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3480          &constraint->dwPathLenConstraint, &size, pcbDecoded);
3481         if (ret)
3482             constraint->fPathLenConstraint = TRUE;
3483         TRACE("got an int, dwPathLenConstraint is %d\n",
3484          constraint->dwPathLenConstraint);
3485     }
3486     TRACE("returning %d (%08x)\n", ret, GetLastError());
3487     return ret;
3488 }
3489
3490 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3491  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3492  DWORD *pcbDecoded)
3493 {
3494     BOOL ret;
3495     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3496      offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3497      offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
3498      FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3499      CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3500      offsetof(CERT_NAME_BLOB, pbData) };
3501
3502     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3503      pvStructInfo, *pcbStructInfo, pcbDecoded);
3504
3505     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3506      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3507     TRACE("Returning %d (%08x)\n", ret, GetLastError());
3508     return ret;
3509 }
3510
3511 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3512  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3513  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3514 {
3515     BOOL ret;
3516
3517     __TRY
3518     {
3519         struct AsnDecodeSequenceItem items[] = {
3520          { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3521            CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE, 
3522            offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3523          { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3524            fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3525            sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3526          { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3527            cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3528            FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3529            TRUE, TRUE,
3530            offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3531         };
3532
3533         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3534          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3535          pcbStructInfo, NULL, NULL);
3536     }
3537     __EXCEPT_PAGE_FAULT
3538     {
3539         SetLastError(STATUS_ACCESS_VIOLATION);
3540         ret = FALSE;
3541     }
3542     __ENDTRY
3543     return ret;
3544 }
3545
3546 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3547  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3548  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3549 {
3550     BOOL ret;
3551
3552     __TRY
3553     {
3554         struct AsnDecodeSequenceItem items[] = {
3555          { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3556            CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3557          { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3558            fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3559            sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3560         };
3561
3562         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3563          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3564          pcbStructInfo, NULL, NULL);
3565     }
3566     __EXCEPT_PAGE_FAULT
3567     {
3568         SetLastError(STATUS_ACCESS_VIOLATION);
3569         ret = FALSE;
3570     }
3571     __ENDTRY
3572     return ret;
3573 }
3574
3575 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
3576  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3577  DWORD *pcbDecoded)
3578 {
3579     struct AsnDecodeSequenceItem items[] = {
3580      { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
3581        pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3582        FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3583        0 },
3584      { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3585        CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3586        offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3587     };
3588     BOOL ret;
3589     CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3590
3591     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3592      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3593
3594     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3595      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3596      pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3597     return ret;
3598 }
3599
3600 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
3601  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3602  DWORD *pcbDecoded)
3603 {
3604     BOOL ret;
3605     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3606      offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3607      offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
3608      FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
3609      CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
3610      offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3611
3612     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3613      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3614
3615     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3616      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3617     TRACE("Returning %d (%08x)\n", ret, GetLastError());
3618     return ret;
3619 }
3620
3621 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
3622  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3623 {
3624     struct AsnDecodeSequenceItem items[] = {
3625      { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3626        CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3627        offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3628      { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3629        CRYPT_AsnDecodePolicyQualifiers,
3630        FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE,
3631        TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3632     };
3633     CERT_POLICY_INFO *info = pvStructInfo;
3634     BOOL ret;
3635
3636     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3637      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3638
3639     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3640      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3641      pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
3642     return ret;
3643 }
3644
3645 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
3646  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3647  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3648 {
3649     BOOL ret = FALSE;
3650
3651     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3652      pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3653
3654     __TRY
3655     {
3656         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3657          offsetof(CERT_POLICIES_INFO, cPolicyInfo),
3658          offsetof(CERT_POLICIES_INFO, rgPolicyInfo),
3659          sizeof(CERT_POLICIES_INFO),
3660          CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
3661          offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
3662         CERT_POLICIES_INFO *info = pvStructInfo;
3663
3664         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3665             info->rgPolicyInfo = (CERT_POLICY_INFO *)(info + 1);
3666
3667         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3668          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3669     }
3670     __EXCEPT_PAGE_FAULT
3671     {
3672         SetLastError(STATUS_ACCESS_VIOLATION);
3673     }
3674     __ENDTRY
3675     return ret;
3676 }
3677
3678 static BOOL CRYPT_AsnDecodeCertPolicyMapping(const BYTE *pbEncoded,
3679  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3680  DWORD *pcbDecoded)
3681 {
3682     struct AsnDecodeSequenceItem items[] = {
3683      { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
3684        pszIssuerDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3685        FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy), 0 },
3686      { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
3687        pszSubjectDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3688        FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszSubjectDomainPolicy), 0 },
3689     };
3690     CERT_POLICY_MAPPING *mapping = pvStructInfo;
3691     BOOL ret;
3692
3693     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3694      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3695
3696     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3697      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3698      pcbDecoded, mapping ? mapping->pszIssuerDomainPolicy : NULL);
3699     return ret;
3700 }
3701
3702 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType,
3703  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3704  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3705 {
3706     BOOL ret = FALSE;
3707
3708     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3709      pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3710
3711     __TRY
3712     {
3713         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3714          offsetof(CERT_POLICY_MAPPINGS_INFO, cPolicyMapping),
3715          offsetof(CERT_POLICY_MAPPINGS_INFO, rgPolicyMapping),
3716          sizeof(CERT_POLICY_MAPPING),
3717          CRYPT_AsnDecodeCertPolicyMapping, sizeof(CERT_POLICY_MAPPING), TRUE,
3718          offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy) };
3719         CERT_POLICY_MAPPINGS_INFO *info = pvStructInfo;
3720
3721         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3722             info->rgPolicyMapping = (CERT_POLICY_MAPPING *)(info + 1);
3723         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3724          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3725     }
3726     __EXCEPT_PAGE_FAULT
3727     {
3728         SetLastError(STATUS_ACCESS_VIOLATION);
3729     }
3730     __ENDTRY
3731     return ret;
3732 }
3733
3734 static BOOL CRYPT_AsnDecodeRequireExplicit(const BYTE *pbEncoded,
3735  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3736  DWORD *pcbDecoded)
3737 {
3738     BOOL ret;
3739     DWORD skip, size = sizeof(skip);
3740
3741     if (!cbEncoded)
3742     {
3743         SetLastError(CRYPT_E_ASN1_EOD);
3744         return FALSE;
3745     }
3746     if (pbEncoded[0] != (ASN_CONTEXT | 0))
3747     {
3748         SetLastError(CRYPT_E_ASN1_BADTAG);
3749         return FALSE;
3750     }
3751     if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3752      &skip, &size, pcbDecoded)))
3753     {
3754         DWORD bytesNeeded = MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
3755          fRequireExplicitPolicy, fInhibitPolicyMapping);
3756
3757         if (!pvStructInfo)
3758             *pcbStructInfo = bytesNeeded;
3759         else if (*pcbStructInfo < bytesNeeded)
3760         {
3761             *pcbStructInfo = bytesNeeded;
3762             SetLastError(ERROR_MORE_DATA);
3763             ret = FALSE;
3764         }
3765         else
3766         {
3767             CERT_POLICY_CONSTRAINTS_INFO *info = CONTAINING_RECORD(pvStructInfo,
3768               CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy);
3769
3770             *pcbStructInfo = bytesNeeded;
3771             /* The BOOL is implicit:  if the integer is present, then it's
3772              * TRUE.
3773              */
3774             info->fRequireExplicitPolicy = TRUE;
3775             info->dwRequireExplicitPolicySkipCerts = skip;
3776         }
3777     }
3778     return ret;
3779 }
3780
3781 static BOOL CRYPT_AsnDecodeInhibitMapping(const BYTE *pbEncoded,
3782  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3783  DWORD *pcbDecoded)
3784 {
3785     BOOL ret;
3786     DWORD skip, size = sizeof(skip);
3787
3788     if (!cbEncoded)
3789     {
3790         SetLastError(CRYPT_E_ASN1_EOD);
3791         return FALSE;
3792     }
3793     if (pbEncoded[0] != (ASN_CONTEXT | 1))
3794     {
3795         SetLastError(CRYPT_E_ASN1_BADTAG);
3796         return FALSE;
3797     }
3798     if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3799      &skip, &size, pcbDecoded)))
3800     {
3801         DWORD bytesNeeded = FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
3802          fInhibitPolicyMapping);
3803
3804         if (!pvStructInfo)
3805             *pcbStructInfo = bytesNeeded;
3806         else if (*pcbStructInfo < bytesNeeded)
3807         {
3808             *pcbStructInfo = bytesNeeded;
3809             SetLastError(ERROR_MORE_DATA);
3810             ret = FALSE;
3811         }
3812         else
3813         {
3814             CERT_POLICY_CONSTRAINTS_INFO *info = CONTAINING_RECORD(pvStructInfo,
3815               CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping);
3816
3817             *pcbStructInfo = bytesNeeded;
3818             /* The BOOL is implicit:  if the integer is present, then it's
3819              * TRUE.
3820              */
3821             info->fInhibitPolicyMapping = TRUE;
3822             info->dwInhibitPolicyMappingSkipCerts = skip;
3823         }
3824     }
3825     return ret;
3826 }
3827
3828 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints(
3829  DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
3830  DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3831  void *pvStructInfo, DWORD *pcbStructInfo)
3832 {
3833     BOOL ret = FALSE;
3834
3835     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3836      pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3837
3838     __TRY
3839     {
3840         struct AsnDecodeSequenceItem items[] = {
3841          { ASN_CONTEXT | 0,
3842            offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy),
3843            CRYPT_AsnDecodeRequireExplicit,
3844            MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy,
3845            fInhibitPolicyMapping), TRUE, FALSE, 0, 0 },
3846          { ASN_CONTEXT | 1,
3847            offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3848            CRYPT_AsnDecodeInhibitMapping,
3849            FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3850            TRUE, FALSE, 0, 0 },
3851         };
3852
3853         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3854          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3855          pcbStructInfo, NULL, NULL);
3856     }
3857     __EXCEPT_PAGE_FAULT
3858     {
3859         SetLastError(STATUS_ACCESS_VIOLATION);
3860     }
3861     __ENDTRY
3862     return ret;
3863 }
3864
3865 #define RSA1_MAGIC 0x31415352
3866
3867 struct DECODED_RSA_PUB_KEY
3868 {
3869     DWORD              pubexp;
3870     CRYPT_INTEGER_BLOB modulus;
3871 };
3872
3873 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3874  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3875  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3876 {
3877     BOOL ret;
3878
3879     __TRY
3880     {
3881         struct AsnDecodeSequenceItem items[] = {
3882          { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3883            CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3884            FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3885            0 },
3886          { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3887            CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3888         };
3889         struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3890         DWORD size = 0;
3891
3892         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3893          pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3894          &size, NULL, NULL);
3895         if (ret)
3896         {
3897             DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3898              decodedKey->modulus.cbData;
3899
3900             if (!pvStructInfo)
3901             {
3902                 *pcbStructInfo = bytesNeeded;
3903                 ret = TRUE;
3904             }
3905             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3906              pvStructInfo, pcbStructInfo, bytesNeeded)))
3907             {
3908                 BLOBHEADER *hdr;
3909                 RSAPUBKEY *rsaPubKey;
3910
3911                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3912                     pvStructInfo = *(BYTE **)pvStructInfo;
3913                 hdr = pvStructInfo;
3914                 hdr->bType = PUBLICKEYBLOB;
3915                 hdr->bVersion = CUR_BLOB_VERSION;
3916                 hdr->reserved = 0;
3917                 hdr->aiKeyAlg = CALG_RSA_KEYX;
3918                 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3919                  sizeof(BLOBHEADER));
3920                 rsaPubKey->magic = RSA1_MAGIC;
3921                 rsaPubKey->pubexp = decodedKey->pubexp;
3922                 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3923                 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3924                  sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3925                  decodedKey->modulus.cbData);
3926             }
3927             LocalFree(decodedKey);
3928         }
3929     }
3930     __EXCEPT_PAGE_FAULT
3931     {
3932         SetLastError(STATUS_ACCESS_VIOLATION);
3933         ret = FALSE;
3934     }
3935     __ENDTRY
3936     return ret;
3937 }
3938
3939 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3940  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3941  DWORD *pcbDecoded)
3942 {
3943     BOOL ret;
3944     DWORD bytesNeeded, dataLen;
3945
3946     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3947      pvStructInfo, *pcbStructInfo, pcbDecoded);
3948
3949     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3950     {
3951         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3952
3953         if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3954             bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3955         else
3956             bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3957         if (pcbDecoded)
3958             *pcbDecoded = 1 + lenBytes + dataLen;
3959         if (!pvStructInfo)
3960             *pcbStructInfo = bytesNeeded;
3961         else if (*pcbStructInfo < bytesNeeded)
3962         {
3963             SetLastError(ERROR_MORE_DATA);
3964             *pcbStructInfo = bytesNeeded;
3965             ret = FALSE;
3966         }
3967         else
3968         {
3969             CRYPT_DATA_BLOB *blob;
3970
3971             *pcbStructInfo = bytesNeeded;
3972             blob = pvStructInfo;
3973             blob->cbData = dataLen;
3974             if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3975                 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
3976             else
3977             {
3978                 assert(blob->pbData);
3979                 if (blob->cbData)
3980                     memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
3981                      blob->cbData);
3982             }
3983         }
3984     }
3985     return ret;
3986 }
3987
3988 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
3989  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3990  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3991 {
3992     BOOL ret;
3993
3994     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3995      pDecodePara, pvStructInfo, *pcbStructInfo);
3996
3997     __TRY
3998     {
3999         DWORD bytesNeeded = 0;
4000
4001         if (!cbEncoded)
4002         {
4003             SetLastError(CRYPT_E_ASN1_CORRUPT);
4004             ret = FALSE;
4005         }
4006         else if (pbEncoded[0] != ASN_OCTETSTRING)
4007         {
4008             SetLastError(CRYPT_E_ASN1_BADTAG);
4009             ret = FALSE;
4010         }
4011         else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
4012          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4013         {
4014             if (!pvStructInfo)
4015                 *pcbStructInfo = bytesNeeded;
4016             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4017              pvStructInfo, pcbStructInfo, bytesNeeded)))
4018             {
4019                 CRYPT_DATA_BLOB *blob;
4020
4021                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4022                     pvStructInfo = *(BYTE **)pvStructInfo;
4023                 blob = pvStructInfo;
4024                 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
4025                 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
4026                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4027                  &bytesNeeded, NULL);
4028                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4029                     CRYPT_FreeSpace(pDecodePara, blob);
4030             }
4031         }
4032     }
4033     __EXCEPT_PAGE_FAULT
4034     {
4035         SetLastError(STATUS_ACCESS_VIOLATION);
4036         ret = FALSE;
4037     }
4038     __ENDTRY
4039     return ret;
4040 }
4041
4042 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4043  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4044 {
4045     BOOL ret;
4046     DWORD bytesNeeded, dataLen;
4047     BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4048
4049     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
4050      pvStructInfo, *pcbStructInfo, pcbDecoded);
4051
4052     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4053     {
4054         if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4055             bytesNeeded = sizeof(CRYPT_BIT_BLOB);
4056         else
4057             bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
4058         if (pcbDecoded)
4059             *pcbDecoded = 1 + lenBytes + dataLen;
4060         if (!pvStructInfo)
4061             *pcbStructInfo = bytesNeeded;
4062         else if (*pcbStructInfo < bytesNeeded)
4063         {
4064             *pcbStructInfo = bytesNeeded;
4065             SetLastError(ERROR_MORE_DATA);
4066             ret = FALSE;
4067         }
4068         else
4069         {
4070             CRYPT_BIT_BLOB *blob;
4071
4072             *pcbStructInfo = bytesNeeded;
4073             blob = pvStructInfo;
4074             blob->cbData = dataLen - 1;
4075             blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
4076             if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4077             {
4078                 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
4079             }
4080             else
4081             {
4082                 assert(blob->pbData);
4083                 if (blob->cbData)
4084                 {
4085                     BYTE mask = 0xff << blob->cUnusedBits;
4086
4087                     memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
4088                      blob->cbData);
4089                     blob->pbData[blob->cbData - 1] &= mask;
4090                 }
4091             }
4092         }
4093     }
4094     return ret;
4095 }
4096
4097 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
4098  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4099  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4100 {
4101     BOOL ret;
4102
4103     TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
4104      pDecodePara, pvStructInfo, pcbStructInfo);
4105
4106     __TRY
4107     {
4108         DWORD bytesNeeded = 0;
4109
4110         if (!cbEncoded)
4111         {
4112             SetLastError(CRYPT_E_ASN1_CORRUPT);
4113             ret = FALSE;
4114         }
4115         else if (pbEncoded[0] != ASN_BITSTRING)
4116         {
4117             SetLastError(CRYPT_E_ASN1_BADTAG);
4118             ret = FALSE;
4119         }
4120         else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4121          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4122         {
4123             if (!pvStructInfo)
4124                 *pcbStructInfo = bytesNeeded;
4125             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4126              pvStructInfo, pcbStructInfo, bytesNeeded)))
4127             {
4128                 CRYPT_BIT_BLOB *blob;
4129
4130                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4131                     pvStructInfo = *(BYTE **)pvStructInfo;
4132                 blob = pvStructInfo;
4133                 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
4134                 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4135                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4136                  &bytesNeeded, NULL);
4137                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4138                     CRYPT_FreeSpace(pDecodePara, blob);
4139             }
4140         }
4141     }
4142     __EXCEPT_PAGE_FAULT
4143     {
4144         SetLastError(STATUS_ACCESS_VIOLATION);
4145         ret = FALSE;
4146     }
4147     __ENDTRY
4148     TRACE("returning %d (%08x)\n", ret, GetLastError());
4149     return ret;
4150 }
4151
4152 /* Ignores tag.  Only allows integers 4 bytes or smaller in size. */
4153 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4154  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4155 {
4156     BOOL ret;
4157     DWORD dataLen;
4158
4159     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4160     {
4161         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4162
4163         if (pcbDecoded)
4164             *pcbDecoded = 1 + lenBytes + dataLen;
4165         if (dataLen > sizeof(int))
4166         {
4167             SetLastError(CRYPT_E_ASN1_LARGE);
4168             ret = FALSE;
4169         }
4170         else if (!pvStructInfo)
4171             *pcbStructInfo = sizeof(int);
4172         else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
4173         {
4174             int val, i;
4175
4176             if (dataLen && pbEncoded[1 + lenBytes] & 0x80)
4177             {
4178                 /* initialize to a negative value to sign-extend */
4179                 val = -1;
4180             }
4181             else
4182                 val = 0;
4183             for (i = 0; i < dataLen; i++)
4184             {
4185                 val <<= 8;
4186                 val |= pbEncoded[1 + lenBytes + i];
4187             }
4188             memcpy(pvStructInfo, &val, sizeof(int));
4189         }
4190     }
4191     return ret;
4192 }
4193
4194 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
4195  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4196  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4197 {
4198     BOOL ret;
4199
4200     __TRY
4201     {
4202         DWORD bytesNeeded = 0;
4203
4204         if (!cbEncoded)
4205         {
4206             SetLastError(CRYPT_E_ASN1_EOD);
4207             ret = FALSE;
4208         }
4209         else if (pbEncoded[0] != ASN_INTEGER)
4210         {
4211             SetLastError(CRYPT_E_ASN1_BADTAG);
4212             ret = FALSE;
4213         }
4214         else
4215             ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4216              dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4217         if (ret)
4218         {
4219             if (!pvStructInfo)
4220                 *pcbStructInfo = bytesNeeded;
4221             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4222              pvStructInfo, pcbStructInfo, bytesNeeded)))
4223             {
4224                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4225                     pvStructInfo = *(BYTE **)pvStructInfo;
4226                 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4227                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4228                  &bytesNeeded, NULL);
4229                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4230                     CRYPT_FreeSpace(pDecodePara, pvStructInfo);
4231             }
4232         }
4233     }
4234     __EXCEPT_PAGE_FAULT
4235     {
4236         SetLastError(STATUS_ACCESS_VIOLATION);
4237         ret = FALSE;
4238     }
4239     __ENDTRY
4240     return ret;
4241 }
4242
4243 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
4244  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4245  DWORD *pcbDecoded)
4246 {
4247     BOOL ret;
4248     DWORD bytesNeeded, dataLen;
4249
4250     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4251     {
4252         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4253
4254         bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4255         if (pcbDecoded)
4256             *pcbDecoded = 1 + lenBytes + dataLen;
4257         if (!pvStructInfo)
4258             *pcbStructInfo = bytesNeeded;
4259         else if (*pcbStructInfo < bytesNeeded)
4260         {
4261             *pcbStructInfo = bytesNeeded;
4262             SetLastError(ERROR_MORE_DATA);
4263             ret = FALSE;
4264         }
4265         else
4266         {
4267             CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4268
4269             *pcbStructInfo = bytesNeeded;
4270             blob->cbData = dataLen;
4271             assert(blob->pbData);
4272             if (blob->cbData)
4273             {
4274                 DWORD i;
4275
4276                 for (i = 0; i < blob->cbData; i++)
4277                 {
4278                     blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4279                      dataLen - i - 1);
4280                 }
4281             }
4282         }
4283     }
4284     return ret;
4285 }
4286
4287 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
4288  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4289  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4290 {
4291     BOOL ret;
4292
4293     __TRY
4294     {
4295         DWORD bytesNeeded = 0;
4296
4297         if (pbEncoded[0] != ASN_INTEGER)
4298         {
4299             SetLastError(CRYPT_E_ASN1_BADTAG);
4300             ret = FALSE;
4301         }
4302         else
4303             ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4304              dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4305         if (ret)
4306         {
4307             if (!pvStructInfo)
4308                 *pcbStructInfo = bytesNeeded;
4309             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4310              pvStructInfo, pcbStructInfo, bytesNeeded)))
4311             {
4312                 CRYPT_INTEGER_BLOB *blob;
4313
4314                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4315                     pvStructInfo = *(BYTE **)pvStructInfo;
4316                 blob = pvStructInfo;
4317                 blob->pbData = (BYTE *)pvStructInfo +
4318                  sizeof(CRYPT_INTEGER_BLOB);
4319                 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4320                  dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4321                  &bytesNeeded, NULL);
4322                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4323                     CRYPT_FreeSpace(pDecodePara, blob);
4324             }
4325         }
4326     }
4327     __EXCEPT_PAGE_FAULT
4328     {
4329         SetLastError(STATUS_ACCESS_VIOLATION);
4330         ret = FALSE;
4331     }
4332     __ENDTRY
4333     return ret;
4334 }
4335
4336 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
4337  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4338  DWORD *pcbDecoded)
4339 {
4340     BOOL ret;
4341
4342     if (pbEncoded[0] == ASN_INTEGER)
4343     {
4344         DWORD bytesNeeded, dataLen;
4345
4346         if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4347         {
4348             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4349
4350             if (pcbDecoded)
4351                 *pcbDecoded = 1 + lenBytes + dataLen;
4352             bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4353             if (!pvStructInfo)
4354                 *pcbStructInfo = bytesNeeded;
4355             else if (*pcbStructInfo < bytesNeeded)
4356             {
4357                 *pcbStructInfo = bytesNeeded;
4358                 SetLastError(ERROR_MORE_DATA);
4359                 ret = FALSE;
4360             }
4361             else
4362             {
4363                 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4364
4365                 *pcbStructInfo = bytesNeeded;
4366                 blob->cbData = dataLen;
4367                 assert(blob->pbData);
4368                 /* remove leading zero byte if it exists */
4369                 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
4370                 {
4371                     blob->cbData--;
4372                     blob->pbData++;
4373                 }
4374                 if (blob->cbData)
4375                 {
4376                     DWORD i;
4377
4378                     for (i = 0; i < blob->cbData; i++)
4379                     {
4380                         blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4381                          dataLen - i - 1);
4382                     }
4383                 }
4384             }
4385         }
4386     }
4387     else
4388     {
4389         SetLastError(CRYPT_E_ASN1_BADTAG);
4390         ret = FALSE;
4391     }
4392     return ret;
4393 }
4394
4395 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
4396  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4397  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4398 {
4399     BOOL ret;
4400
4401     __TRY
4402     {
4403         DWORD bytesNeeded = 0;
4404
4405         if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
4406          dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4407         {
4408             if (!pvStructInfo)
4409                 *pcbStructInfo = bytesNeeded;
4410             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4411              pvStructInfo, pcbStructInfo, bytesNeeded)))
4412             {
4413                 CRYPT_INTEGER_BLOB *blob;
4414
4415                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4416                     pvStructInfo = *(BYTE **)pvStructInfo;
4417                 blob = pvStructInfo;
4418                 blob->pbData = (BYTE *)pvStructInfo +
4419                  sizeof(CRYPT_INTEGER_BLOB);
4420                 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
4421                  cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4422                  &bytesNeeded, NULL);
4423                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4424                     CRYPT_FreeSpace(pDecodePara, blob);
4425             }
4426         }
4427     }
4428     __EXCEPT_PAGE_FAULT
4429     {
4430         SetLastError(STATUS_ACCESS_VIOLATION);
4431         ret = FALSE;
4432     }
4433     __ENDTRY
4434     return ret;
4435 }
4436
4437 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
4438  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4439  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4440 {
4441     BOOL ret;
4442
4443     if (!pvStructInfo)
4444     {
4445         *pcbStructInfo = sizeof(int);
4446         return TRUE;
4447     }
4448     __TRY
4449     {
4450         if (pbEncoded[0] == ASN_ENUMERATED)
4451         {
4452             unsigned int val = 0, i;
4453
4454             if (cbEncoded <= 1)
4455             {
4456                 SetLastError(CRYPT_E_ASN1_EOD);
4457                 ret = FALSE;
4458             }
4459             else if (pbEncoded[1] == 0)
4460             {
4461                 SetLastError(CRYPT_E_ASN1_CORRUPT);
4462                 ret = FALSE;
4463             }
4464             else
4465             {
4466                 /* A little strange looking, but we have to accept a sign byte:
4467                  * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff.  Also,
4468                  * assuming a small length is okay here, it has to be in short
4469                  * form.
4470                  */
4471                 if (pbEncoded[1] > sizeof(unsigned int) + 1)
4472                 {
4473                     SetLastError(CRYPT_E_ASN1_LARGE);
4474                     return FALSE;
4475                 }
4476                 for (i = 0; i < pbEncoded[1]; i++)
4477                 {
4478                     val <<= 8;
4479                     val |= pbEncoded[2 + i];
4480                 }
4481                 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4482                  pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
4483                 {
4484                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4485                         pvStructInfo = *(BYTE **)pvStructInfo;
4486                     memcpy(pvStructInfo, &val, sizeof(unsigned int));
4487                 }
4488             }
4489         }
4490         else
4491         {
4492             SetLastError(CRYPT_E_ASN1_BADTAG);
4493             ret = FALSE;
4494         }
4495     }
4496     __EXCEPT_PAGE_FAULT
4497     {
4498         SetLastError(STATUS_ACCESS_VIOLATION);
4499         ret = FALSE;
4500     }
4501     __ENDTRY
4502     return ret;
4503 }
4504
4505 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4506  * if it fails.
4507  */
4508 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4509  do { \
4510     BYTE i; \
4511  \
4512     (word) = 0; \
4513     for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4514     { \
4515         if (!isdigit(*(pbEncoded))) \
4516         { \
4517             SetLastError(CRYPT_E_ASN1_CORRUPT); \
4518             ret = FALSE; \
4519         } \
4520         else \
4521         { \
4522             (word) *= 10; \
4523             (word) += *(pbEncoded)++ - '0'; \
4524         } \
4525     } \
4526  } while (0)
4527
4528 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
4529  SYSTEMTIME *sysTime)
4530 {
4531     BOOL ret = TRUE;
4532
4533     if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
4534     {
4535         WORD hours, minutes = 0;
4536         BYTE sign = *pbEncoded++;
4537
4538         len--;
4539         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
4540         if (ret && hours >= 24)
4541         {
4542             SetLastError(CRYPT_E_ASN1_CORRUPT);
4543             ret = FALSE;
4544         }
4545         else if (len >= 2)
4546         {
4547             CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
4548             if (ret && minutes >= 60)
4549             {
4550                 SetLastError(CRYPT_E_ASN1_CORRUPT);
4551                 ret = FALSE;
4552             }
4553         }
4554         if (ret)
4555         {
4556             if (sign == '+')
4557             {
4558                 sysTime->wHour += hours;
4559                 sysTime->wMinute += minutes;
4560             }
4561             else
4562             {
4563                 if (hours > sysTime->wHour)
4564                 {
4565                     sysTime->wDay--;
4566                     sysTime->wHour = 24 - (hours - sysTime->wHour);
4567                 }
4568                 else
4569                     sysTime->wHour -= hours;
4570                 if (minutes > sysTime->wMinute)
4571                 {
4572                     sysTime->wHour--;
4573                     sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
4574                 }
4575                 else
4576                     sysTime->wMinute -= minutes;
4577             }
4578         }
4579     }
4580     return ret;
4581 }
4582
4583 #define MIN_ENCODED_TIME_LENGTH 10
4584
4585 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
4586  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4587  DWORD *pcbDecoded)
4588 {
4589     BOOL ret = FALSE;
4590
4591     if (pbEncoded[0] == ASN_UTCTIME)
4592     {
4593         if (cbEncoded <= 1)
4594             SetLastError(CRYPT_E_ASN1_EOD);
4595         else if (pbEncoded[1] > 0x7f)
4596         {
4597             /* long-form date strings really can't be valid */
4598             SetLastError(CRYPT_E_ASN1_CORRUPT);
4599         }
4600         else
4601         {
4602             SYSTEMTIME sysTime = { 0 };
4603             BYTE len = pbEncoded[1];
4604
4605             if (len < MIN_ENCODED_TIME_LENGTH)
4606                 SetLastError(CRYPT_E_ASN1_CORRUPT);
4607             else
4608             {
4609                 ret = TRUE;
4610                 if (pcbDecoded)
4611                     *pcbDecoded = 2 + len;
4612                 pbEncoded += 2;
4613                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
4614                 if (sysTime.wYear >= 50)
4615                     sysTime.wYear += 1900;
4616                 else
4617                     sysTime.wYear += 2000;
4618                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4619                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4620                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4621                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
4622                 if (ret && len > 0)
4623                 {
4624                     if (len >= 2 && isdigit(*pbEncoded) &&
4625                      isdigit(*(pbEncoded + 1)))
4626                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4627                          sysTime.wSecond);
4628                     else if (isdigit(*pbEncoded))
4629                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
4630                          sysTime.wSecond);
4631                     if (ret)
4632                         ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4633                          &sysTime);
4634                 }
4635                 if (ret)
4636                 {
4637                     if (!pvStructInfo)
4638                         *pcbStructInfo = sizeof(FILETIME);
4639                     else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4640                      sizeof(FILETIME))))
4641                         ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4642                 }
4643             }
4644         }
4645     }
4646     else
4647         SetLastError(CRYPT_E_ASN1_BADTAG);
4648     return ret;
4649 }
4650
4651 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
4652  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4653  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4654 {
4655     BOOL ret = FALSE;
4656
4657     __TRY
4658     {
4659         DWORD bytesNeeded = 0;
4660
4661         ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4662          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4663         if (ret)
4664         {
4665             if (!pvStructInfo)
4666                 *pcbStructInfo = bytesNeeded;
4667             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
4668              pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
4669             {
4670                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4671                     pvStructInfo = *(BYTE **)pvStructInfo;
4672                 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4673                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4674                  &bytesNeeded, NULL);
4675                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4676                     CRYPT_FreeSpace(pDecodePara, pvStructInfo);
4677             }
4678         }
4679     }
4680     __EXCEPT_PAGE_FAULT
4681     {
4682         SetLastError(STATUS_ACCESS_VIOLATION);
4683     }
4684     __ENDTRY
4685     return ret;
4686 }
4687
4688 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
4689  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4690  DWORD *pcbDecoded)
4691 {
4692     BOOL ret = FALSE;
4693
4694     if (pbEncoded[0] == ASN_GENERALTIME)
4695     {
4696         if (cbEncoded <= 1)
4697             SetLastError(CRYPT_E_ASN1_EOD);
4698         else if (pbEncoded[1] > 0x7f)
4699         {
4700             /* long-form date strings really can't be valid */
4701             SetLastError(CRYPT_E_ASN1_CORRUPT);
4702         }
4703         else
4704         {
4705             BYTE len = pbEncoded[1];
4706
4707             if (len < MIN_ENCODED_TIME_LENGTH)
4708                 SetLastError(CRYPT_E_ASN1_CORRUPT);
4709             else
4710             {
4711                 SYSTEMTIME sysTime = { 0 };
4712
4713                 ret = TRUE;
4714                 if (pcbDecoded)
4715                     *pcbDecoded = 2 + len;
4716                 pbEncoded += 2;
4717                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
4718                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4719                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4720                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4721                 if (ret && len > 0)
4722                 {
4723                     CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4724                      sysTime.wMinute);
4725                     if (ret && len > 0)
4726                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4727                          sysTime.wSecond);
4728                     if (ret && len > 0 && (*pbEncoded == '.' ||
4729                      *pbEncoded == ','))
4730                     {
4731                         BYTE digits;
4732
4733                         pbEncoded++;
4734                         len--;
4735                         /* workaround macro weirdness */
4736                         digits = min(len, 3);
4737                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
4738                          sysTime.wMilliseconds);
4739                     }
4740                     if (ret)
4741                         ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4742                          &sysTime);
4743                 }
4744                 if (ret)
4745                 {
4746                     if (!pvStructInfo)
4747                         *pcbStructInfo = sizeof(FILETIME);
4748                     else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4749                      sizeof(FILETIME))))
4750                         ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4751                 }
4752             }
4753         }
4754     }
4755     else
4756         SetLastError(CRYPT_E_ASN1_BADTAG);
4757     return ret;
4758 }
4759
4760 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
4761  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4762  DWORD *pcbDecoded)
4763 {
4764     BOOL ret;
4765     InternalDecodeFunc decode = NULL;
4766
4767     if (pbEncoded[0] == ASN_UTCTIME)
4768         decode = CRYPT_AsnDecodeUtcTimeInternal;
4769     else if (pbEncoded[0] == ASN_GENERALTIME)
4770         decode = CRYPT_AsnDecodeGeneralizedTime;
4771     if (decode)
4772         ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
4773          pcbStructInfo, pcbDecoded);
4774     else
4775     {
4776         SetLastError(CRYPT_E_ASN1_BADTAG);
4777         ret = FALSE;
4778     }
4779     return ret;
4780 }
4781
4782 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
4783  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4784  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4785 {
4786     BOOL ret;
4787
4788     __TRY
4789     {
4790         DWORD bytesNeeded = 0;
4791
4792         ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4793          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4794         if (ret)
4795         {
4796             if (!pvStructInfo)
4797                 *pcbStructInfo = bytesNeeded;
4798             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4799              pvStructInfo, pcbStructInfo, bytesNeeded)))
4800             {
4801                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4802                     pvStructInfo = *(BYTE **)pvStructInfo;
4803                 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4804                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4805                  &bytesNeeded, NULL);
4806                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4807                     CRYPT_FreeSpace(pDecodePara, pvStructInfo);
4808             }
4809         }
4810     }
4811     __EXCEPT_PAGE_FAULT
4812     {
4813         SetLastError(STATUS_ACCESS_VIOLATION);
4814         ret = FALSE;
4815     }
4816     __ENDTRY
4817     return ret;
4818 }
4819
4820 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
4821  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4822  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4823 {
4824     BOOL ret = TRUE;
4825
4826     __TRY
4827     {
4828         if (pbEncoded[0] == ASN_SEQUENCEOF)
4829         {
4830             DWORD bytesNeeded, dataLen, remainingLen, cValue;
4831
4832             if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4833             {
4834                 BYTE lenBytes;
4835                 const BYTE *ptr;
4836
4837                 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4838                 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
4839                 cValue = 0;
4840                 ptr = pbEncoded + 1 + lenBytes;
4841                 remainingLen = dataLen;
4842                 while (ret && remainingLen)
4843                 {
4844                     DWORD nextLen;
4845
4846                     ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4847                     if (ret)
4848                     {
4849                         DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4850
4851                         remainingLen -= 1 + nextLenBytes + nextLen;
4852                         ptr += 1 + nextLenBytes + nextLen;
4853                         bytesNeeded += sizeof(CRYPT_DER_BLOB);
4854                         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
4855                             bytesNeeded += 1 + nextLenBytes + nextLen;
4856                         cValue++;
4857                     }
4858                 }
4859                 if (ret)
4860                 {
4861                     CRYPT_SEQUENCE_OF_ANY *seq;
4862                     BYTE *nextPtr;
4863                     DWORD i;
4864
4865                     if (!pvStructInfo)
4866                         *pcbStructInfo = bytesNeeded;
4867                     else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4868                      pvStructInfo, pcbStructInfo, bytesNeeded)))
4869                     {
4870                         if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4871                             pvStructInfo = *(BYTE **)pvStructInfo;
4872                         seq = pvStructInfo;
4873                         seq->cValue = cValue;
4874                         seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
4875                          sizeof(*seq));
4876                         nextPtr = (BYTE *)seq->rgValue +
4877                          cValue * sizeof(CRYPT_DER_BLOB);
4878                         ptr = pbEncoded + 1 + lenBytes;
4879                         remainingLen = dataLen;
4880                         i = 0;
4881                         while (ret && remainingLen)
4882                         {
4883                             DWORD nextLen;
4884
4885                             ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4886                             if (ret)
4887                             {
4888                                 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4889
4890                                 seq->rgValue[i].cbData = 1 + nextLenBytes +
4891                                  nextLen;
4892                                 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4893                                     seq->rgValue[i].pbData = (BYTE *)ptr;
4894                                 else
4895                                 {
4896                                     seq->rgValue[i].pbData = nextPtr;
4897                                     memcpy(nextPtr, ptr, 1 + nextLenBytes +
4898                                      nextLen);
4899                                     nextPtr += 1 + nextLenBytes + nextLen;
4900                                 }
4901                                 remainingLen -= 1 + nextLenBytes + nextLen;
4902                                 ptr += 1 + nextLenBytes + nextLen;
4903                                 i++;
4904                             }
4905                         }
4906                         if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4907                             CRYPT_FreeSpace(pDecodePara, seq);
4908                     }
4909                 }
4910             }
4911         }
4912         else
4913         {
4914             SetLastError(CRYPT_E_ASN1_BADTAG);
4915             ret = FALSE;
4916         }
4917     }
4918     __EXCEPT_PAGE_FAULT
4919     {
4920         SetLastError(STATUS_ACCESS_VIOLATION);
4921         ret = FALSE;
4922     }
4923     __ENDTRY
4924     return ret;
4925 }
4926
4927 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
4928  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4929  DWORD *pcbDecoded)
4930 {
4931     BOOL ret;
4932
4933     if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
4934     {
4935         DWORD bytesNeeded = 0, dataLen;
4936
4937         if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4938         {
4939             struct AsnArrayDescriptor arrayDesc = {
4940              ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4941              offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry),
4942              offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry),
4943              FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u),
4944              CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
4945              offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
4946             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4947             DWORD nameLen;
4948
4949             if (dataLen)
4950             {
4951                 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4952                  pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4953                  dwFlags, NULL, NULL, &nameLen, NULL);
4954                 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
4955                  FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u);
4956             }
4957             else
4958                 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
4959             if (pcbDecoded)
4960                 *pcbDecoded = 1 + lenBytes + dataLen;
4961             if (!pvStructInfo)
4962                 *pcbStructInfo = bytesNeeded;
4963             else if (*pcbStructInfo < bytesNeeded)
4964             {
4965                 *pcbStructInfo = bytesNeeded;
4966                 SetLastError(ERROR_MORE_DATA);
4967                 ret = FALSE;
4968             }
4969             else
4970             {
4971                 CRL_DIST_POINT_NAME *name = pvStructInfo;
4972
4973                 *pcbStructInfo = bytesNeeded;
4974                 if (dataLen)
4975                 {
4976                     name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
4977                     ret = CRYPT_AsnDecodeArray(&arrayDesc,
4978                      pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4979                      dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen,
4980                      NULL);
4981                 }
4982                 else
4983                     name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
4984             }
4985         }
4986     }
4987     else
4988     {
4989         SetLastError(CRYPT_E_ASN1_BADTAG);
4990         ret = FALSE;
4991     }
4992     return ret;
4993 }
4994
4995 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
4996  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4997 {
4998     struct AsnDecodeSequenceItem items[] = {
4999      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
5000        DistPointName), CRYPT_AsnDecodeDistPointName,
5001        sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
5002        DistPointName.u.FullName.rgAltEntry), 0 },
5003      { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
5004        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
5005        offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
5006      { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
5007        CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
5008        offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
5009     };
5010     CRL_DIST_POINT *point = pvStructInfo;
5011     BOOL ret;
5012
5013     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5014      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5015      pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
5016     return ret;
5017 }
5018
5019 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
5020  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5021  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5022 {
5023     BOOL ret;
5024
5025     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5026      pDecodePara, pvStructInfo, *pcbStructInfo);
5027
5028     __TRY
5029     {
5030         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5031          offsetof(CRL_DIST_POINTS_INFO, cDistPoint),
5032          offsetof(CRL_DIST_POINTS_INFO, rgDistPoint),
5033          sizeof(CRL_DIST_POINTS_INFO),
5034          CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
5035          offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
5036         CRL_DIST_POINTS_INFO *info = pvStructInfo;
5037
5038         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5039             info->rgDistPoint = (CRL_DIST_POINT *)(info + 1);
5040         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5041          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
5042     }
5043     __EXCEPT_PAGE_FAULT
5044     {
5045         SetLastError(STATUS_ACCESS_VIOLATION);
5046         ret = FALSE;
5047     }
5048     __ENDTRY
5049     return ret;
5050 }
5051
5052 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
5053  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5054  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5055 {
5056     BOOL ret;
5057
5058     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5059      pDecodePara, pvStructInfo, *pcbStructInfo);
5060
5061     __TRY
5062     {
5063         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5064          offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier),
5065          offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier),
5066          sizeof(CERT_ENHKEY_USAGE),
5067          CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
5068         CERT_ENHKEY_USAGE *usage = pvStructInfo;
5069
5070         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5071             usage->rgpszUsageIdentifier = (LPSTR *)(usage + 1);
5072         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5073          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
5074     }
5075     __EXCEPT_PAGE_FAULT
5076     {
5077         SetLastError(STATUS_ACCESS_VIOLATION);
5078         ret = FALSE;
5079     }
5080     __ENDTRY
5081     return ret;
5082 }
5083
5084 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
5085  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5086  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5087 {
5088     BOOL ret;
5089
5090     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5091      pDecodePara, pvStructInfo, *pcbStructInfo);
5092
5093     __TRY
5094     {
5095         struct AsnDecodeSequenceItem items[] = {
5096          { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
5097            DistPointName), CRYPT_AsnDecodeDistPointName,
5098            sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
5099            offsetof(CRL_ISSUING_DIST_POINT,
5100            DistPointName.u.FullName.rgAltEntry), 0 },
5101          { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
5102            fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5103            FALSE, 0 },
5104          { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
5105            fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5106            FALSE, 0 },
5107          { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
5108            OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
5109            sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
5110            OnlySomeReasonFlags.pbData), 0 },
5111          { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
5112            fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
5113         };
5114
5115         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5116          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5117          pcbStructInfo, NULL, NULL);
5118     }
5119     __EXCEPT_PAGE_FAULT
5120     {
5121         SetLastError(STATUS_ACCESS_VIOLATION);
5122         ret = FALSE;
5123     }
5124     __ENDTRY
5125     return ret;
5126 }
5127
5128 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
5129  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5130  DWORD *pcbDecoded)
5131 {
5132     BOOL ret;
5133     DWORD max, size = sizeof(max);
5134
5135     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5136      pvStructInfo, *pcbStructInfo, pcbDecoded);
5137
5138     if (!cbEncoded)
5139     {
5140         SetLastError(CRYPT_E_ASN1_EOD);
5141         return FALSE;
5142     }
5143     if (pbEncoded[0] != (ASN_CONTEXT | 1))
5144     {
5145         SetLastError(CRYPT_E_ASN1_BADTAG);
5146         return FALSE;
5147     }
5148     if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
5149      &max, &size, pcbDecoded)))
5150     {
5151         DWORD bytesNeeded = FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum);
5152
5153         if (!pvStructInfo)
5154             *pcbStructInfo = bytesNeeded;
5155         else if (*pcbStructInfo < bytesNeeded)
5156         {
5157             *pcbStructInfo = bytesNeeded;
5158             SetLastError(ERROR_MORE_DATA);
5159             ret = FALSE;
5160         }
5161         else
5162         {
5163             CERT_GENERAL_SUBTREE *subtree = CONTAINING_RECORD(pvStructInfo,
5164              CERT_GENERAL_SUBTREE, fMaximum);
5165
5166             *pcbStructInfo = bytesNeeded;
5167             /* The BOOL is implicit:  if the integer is present, then it's
5168              * TRUE.
5169              */
5170             subtree->fMaximum = TRUE;
5171             subtree->dwMaximum = max;
5172         }
5173     }
5174     TRACE("returning %d\n", ret);
5175     return ret;
5176 }
5177
5178 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
5179  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5180  DWORD *pcbDecoded)
5181 {
5182     BOOL ret;
5183     struct AsnDecodeSequenceItem items[] = {
5184      { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
5185        CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
5186        offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
5187      { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
5188        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
5189      { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
5190        CRYPT_AsnDecodeMaximum, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum),
5191        TRUE, FALSE, 0, 0 },
5192     };
5193     CERT_GENERAL_SUBTREE *subtree = pvStructInfo;
5194
5195     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5196      pvStructInfo, *pcbStructInfo, pcbDecoded);
5197
5198     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5199      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5200      pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
5201     if (pcbDecoded)
5202     {
5203         TRACE("%d\n", *pcbDecoded);
5204         if (*pcbDecoded < cbEncoded)
5205             TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
5206              *(pbEncoded + *pcbDecoded + 1));
5207     }
5208     TRACE("returning %d\n", ret);
5209     return ret;
5210 }
5211
5212 static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded,
5213  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5214  DWORD *pcbDecoded)
5215 {
5216     BOOL ret = TRUE;
5217     struct AsnArrayDescriptor arrayDesc = { 0,
5218      offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5219      offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree),
5220      MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5221                 cExcludedSubtree),
5222      CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5223      offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5224
5225     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5226      pvStructInfo, *pcbStructInfo, pcbDecoded);
5227
5228     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5229      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5230     return ret;
5231 }
5232
5233 static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded,
5234  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5235  DWORD *pcbDecoded)
5236 {
5237     BOOL ret = TRUE;
5238     struct AsnArrayDescriptor arrayDesc = { 0,
5239      offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5240      offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree),
5241      FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5242      CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5243      offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5244
5245     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5246      pvStructInfo, *pcbStructInfo, pcbDecoded);
5247
5248     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5249      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5250     return ret;
5251 }
5252
5253 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
5254  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5255  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5256 {
5257     BOOL ret = FALSE;
5258
5259     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5260      pDecodePara, pvStructInfo, *pcbStructInfo);
5261
5262     __TRY
5263     {
5264         struct AsnDecodeSequenceItem items[] = {
5265          { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
5266            offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5267            CRYPT_AsnDecodePermittedSubtree,
5268            MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5269            cExcludedSubtree), TRUE, TRUE,
5270            offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
5271          { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
5272            offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5273            CRYPT_AsnDecodeExcludedSubtree,
5274            FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5275            TRUE, TRUE,
5276            offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
5277         };
5278
5279         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5280          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5281          pcbStructInfo, NULL, NULL);
5282     }
5283     __EXCEPT_PAGE_FAULT
5284     {
5285         SetLastError(STATUS_ACCESS_VIOLATION);
5286     }
5287     __ENDTRY
5288     return ret;
5289 }
5290
5291 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
5292  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5293  DWORD *pcbDecoded)
5294 {
5295     BOOL ret;
5296     struct AsnDecodeSequenceItem items[] = {
5297      { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
5298        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
5299        Issuer.pbData) },
5300      { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
5301        CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
5302        TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
5303     };
5304     CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;
5305
5306     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5307      pvStructInfo, *pcbStructInfo, pcbDecoded);
5308
5309     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5310      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5311      pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
5312     if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
5313     {
5314         SetLastError(CRYPT_E_ASN1_CORRUPT);
5315         ret = FALSE;
5316     }
5317     TRACE("returning %d\n", ret);
5318     return ret;
5319 }
5320
5321 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
5322  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5323  DWORD *pcbDecoded)
5324 {
5325     CMSG_SIGNER_INFO *info = pvStructInfo;
5326     struct AsnDecodeSequenceItem items[] = {
5327      { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
5328        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5329      { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
5330        CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
5331        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
5332      { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
5333        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5334        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5335      { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5336        offsetof(CMSG_SIGNER_INFO, AuthAttrs),
5337        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5338        TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5339      { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
5340        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5341        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
5342        HashEncryptionAlgorithm.pszObjId), 0 },
5343      { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
5344        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5345        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
5346      { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5347        offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
5348        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5349        TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5350     };
5351     BOOL ret;
5352
5353     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5354      pvStructInfo, *pcbStructInfo);
5355
5356     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5357      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5358      pcbDecoded, info ? info->Issuer.pbData : NULL);
5359     return ret;
5360 }
5361
5362 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
5363  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5364  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5365 {
5366     BOOL ret = FALSE;
5367
5368     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5369      pDecodePara, pvStructInfo, *pcbStructInfo);
5370
5371     __TRY
5372     {
5373         ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
5374          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5375         if (ret && pvStructInfo)
5376         {
5377             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5378              pcbStructInfo, *pcbStructInfo);
5379             if (ret)
5380             {
5381                 CMSG_SIGNER_INFO *info;
5382
5383                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5384                     pvStructInfo = *(BYTE **)pvStructInfo;
5385                 info = pvStructInfo;
5386                 info->Issuer.pbData = ((BYTE *)info +
5387                  sizeof(CMSG_SIGNER_INFO));
5388                 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
5389                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5390                  pcbStructInfo, NULL);
5391                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5392                     CRYPT_FreeSpace(pDecodePara, info);
5393             }
5394         }
5395     }
5396     __EXCEPT_PAGE_FAULT
5397     {
5398         SetLastError(STATUS_ACCESS_VIOLATION);
5399     }
5400     __ENDTRY
5401     TRACE("returning %d\n", ret);
5402     return ret;
5403 }
5404
5405 static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded,
5406  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5407  DWORD *pcbDecoded)
5408 {
5409     BOOL ret;
5410     struct AsnArrayDescriptor arrayDesc = { 0,
5411      offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
5412      offsetof(CRYPT_SIGNED_INFO, rgCertEncoded),
5413      MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded),
5414      CRYPT_AsnDecodeCopyBytes,
5415      sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5416
5417     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5418      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5419
5420     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5421      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5422     return ret;
5423 }
5424
5425 static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded,
5426  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5427  DWORD *pcbDecoded)
5428 {
5429     BOOL ret;
5430     struct AsnArrayDescriptor arrayDesc = { 0,
5431      offsetof(CRYPT_SIGNED_INFO, cCrlEncoded),
5432      offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded),
5433      MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content),
5434      CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB),
5435      TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5436
5437     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5438      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5439
5440     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5441      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5442     return ret;
5443 }
5444
5445 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
5446  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5447  DWORD *pcbDecoded)
5448 {
5449     CERT_ID *id = pvStructInfo;
5450     BOOL ret = FALSE;
5451
5452     if (*pbEncoded == ASN_SEQUENCEOF)
5453     {
5454         ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
5455          id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
5456         if (ret)
5457         {
5458             if (id)
5459                 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5460             if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
5461                 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5462                  sizeof(CERT_ISSUER_SERIAL_NUMBER);
5463             else
5464                 *pcbStructInfo = sizeof(CERT_ID);
5465         }
5466     }
5467     else if (*pbEncoded == (ASN_CONTEXT | 0))
5468     {
5469         ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
5470          id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
5471         if (ret)
5472         {
5473             if (id)
5474                 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5475             if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
5476                 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5477                  sizeof(CRYPT_DATA_BLOB);
5478             else
5479                 *pcbStructInfo = sizeof(CERT_ID);
5480         }
5481     }
5482     else
5483         SetLastError(CRYPT_E_ASN1_BADTAG);
5484     return ret;
5485 }
5486
5487 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
5488  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5489  DWORD *pcbDecoded)
5490 {
5491     CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
5492     struct AsnDecodeSequenceItem items[] = {
5493      { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
5494        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5495      { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
5496        CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
5497        offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
5498      { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
5499        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5500        FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5501      { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5502        offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
5503        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5504        TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5505      { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
5506        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5507        FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
5508        HashEncryptionAlgorithm.pszObjId), 0 },
5509      { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
5510        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5511        FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
5512      { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5513        offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
5514        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5515        TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5516     };
5517     BOOL ret;
5518
5519     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5520      pvStructInfo, *pcbStructInfo);
5521
5522     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5523      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5524      pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
5525     return ret;
5526 }
5527
5528 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
5529  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5530  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5531 {
5532     BOOL ret = FALSE;
5533
5534     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5535      pDecodePara, pvStructInfo, *pcbStructInfo);
5536
5537     __TRY
5538     {
5539         ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
5540          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5541         if (ret && pvStructInfo)
5542         {
5543             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5544              pcbStructInfo, *pcbStructInfo);
5545             if (ret)
5546             {
5547                 CMSG_CMS_SIGNER_INFO *info;
5548
5549                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5550                     pvStructInfo = *(BYTE **)pvStructInfo;
5551                 info = pvStructInfo;
5552                 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
5553                  sizeof(CMSG_CMS_SIGNER_INFO));
5554                 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
5555                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5556                  pcbStructInfo, NULL);
5557                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5558                     CRYPT_FreeSpace(pDecodePara, info);
5559             }
5560         }
5561     }
5562     __EXCEPT_PAGE_FAULT
5563     {
5564         SetLastError(STATUS_ACCESS_VIOLATION);
5565     }
5566     __ENDTRY
5567     TRACE("returning %d\n", ret);
5568     return ret;
5569 }
5570
5571 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
5572  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5573 {
5574     BOOL ret;
5575     struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5576      offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5577      offsetof(CRYPT_SIGNED_INFO, rgSignerInfo),
5578      FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo),
5579      CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
5580      offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
5581
5582     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5583      pvStructInfo, *pcbStructInfo, pcbDecoded);
5584
5585     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5586      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5587     return ret;
5588 }
5589
5590 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5591  DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5592  CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
5593 {
5594     BOOL ret = FALSE;
5595     struct AsnDecodeSequenceItem items[] = {
5596      { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
5597        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5598      /* Placeholder for the hash algorithms - redundant with those in the
5599       * signers, so just ignore them.
5600       */
5601      { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5602      { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
5603        CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
5604        FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
5605      { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5606        offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded,
5607        MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE,
5608        offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
5609      { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5610        offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded,
5611        MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE,
5612        offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
5613      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5614        CRYPT_DecodeSignerArray,
5615        FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE,
5616        offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
5617     };
5618
5619     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5620      pDecodePara, signedInfo, *pcbSignedInfo);
5621
5622     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5623      pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
5624      NULL, NULL);
5625     TRACE("returning %d\n", ret);
5626     return ret;
5627 }
5628
5629 static BOOL CRYPT_AsnDecodeRecipientInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5630  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5631 {
5632     BOOL ret;
5633     CMSG_KEY_TRANS_RECIPIENT_INFO *info = pvStructInfo;
5634     struct AsnDecodeSequenceItem items[] = {
5635      { ASN_INTEGER, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, dwVersion),
5636        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5637      { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5638        RecipientId.u.IssuerSerialNumber), CRYPT_AsnDecodeIssuerSerialNumber,
5639        sizeof(CERT_ISSUER_SERIAL_NUMBER), FALSE, TRUE,
5640        offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5641        RecipientId.u.IssuerSerialNumber.Issuer.pbData), 0 },
5642      { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5643        KeyEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId,
5644        sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
5645        offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5646        KeyEncryptionAlgorithm.pszObjId), 0 },
5647      { ASN_OCTETSTRING, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, EncryptedKey),
5648        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
5649        offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, EncryptedKey.pbData), 0 },
5650     };
5651
5652     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5653      pvStructInfo, *pcbStructInfo, pcbDecoded);
5654
5655     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5656      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5657      pcbDecoded, info ? info->RecipientId.u.IssuerSerialNumber.Issuer.pbData :
5658      NULL);
5659     if (info)
5660         info->RecipientId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5661     TRACE("returning %d\n", ret);
5662     return ret;
5663 }
5664
5665 static BOOL CRYPT_DecodeRecipientInfoArray(const BYTE *pbEncoded,
5666  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5667  DWORD *pcbDecoded)
5668 {
5669     BOOL ret;
5670     struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5671      offsetof(CRYPT_ENVELOPED_DATA, cRecipientInfo),
5672      offsetof(CRYPT_ENVELOPED_DATA, rgRecipientInfo),
5673      MEMBERSIZE(CRYPT_ENVELOPED_DATA, cRecipientInfo, encryptedContentInfo),
5674      CRYPT_AsnDecodeRecipientInfo, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO), TRUE,
5675      offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5676      RecipientId.u.IssuerSerialNumber.Issuer.pbData) };
5677
5678     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5679      pvStructInfo, *pcbStructInfo, pcbDecoded);
5680
5681     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5682      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5683     TRACE("returning %d\n", ret);
5684     return ret;
5685 }
5686
5687 static BOOL CRYPT_AsnDecodeEncryptedContentInfo(const BYTE *pbEncoded,
5688  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5689  DWORD *pcbDecoded)
5690 {
5691     BOOL ret;
5692     CRYPT_ENCRYPTED_CONTENT_INFO *info = pvStructInfo;
5693     struct AsnDecodeSequenceItem items[] = {
5694      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5695        contentType), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
5696        FALSE, TRUE, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5697        contentType), 0 },
5698      { ASN_SEQUENCEOF, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5699        contentEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId,
5700        sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
5701        offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5702        contentEncryptionAlgorithm.pszObjId), 0 },
5703      { ASN_CONTEXT | 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5704        encryptedContent), CRYPT_AsnDecodeOctetsInternal,
5705        sizeof(CRYPT_DATA_BLOB), TRUE, TRUE,
5706        offsetof(CRYPT_ENCRYPTED_CONTENT_INFO, encryptedContent.pbData) },
5707     };
5708
5709     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5710      pvStructInfo, *pcbStructInfo, pcbDecoded);
5711
5712     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5713      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5714      pcbDecoded, info ? info->contentType : NULL);
5715     TRACE("returning %d\n", ret);
5716     return ret;
5717 }
5718
5719 BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
5720  DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5721  CRYPT_ENVELOPED_DATA *envelopedData, DWORD *pcbEnvelopedData)
5722 {
5723     BOOL ret;
5724     struct AsnDecodeSequenceItem items[] = {
5725      { ASN_INTEGER, offsetof(CRYPT_ENVELOPED_DATA, version),
5726        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5727      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ENVELOPED_DATA,
5728        cRecipientInfo), CRYPT_DecodeRecipientInfoArray,
5729        MEMBERSIZE(CRYPT_ENVELOPED_DATA, cRecipientInfo, encryptedContentInfo),
5730        FALSE, TRUE, offsetof(CRYPT_ENVELOPED_DATA, rgRecipientInfo), 0 },
5731      { ASN_SEQUENCEOF, offsetof(CRYPT_ENVELOPED_DATA, encryptedContentInfo),
5732        CRYPT_AsnDecodeEncryptedContentInfo,
5733        sizeof(CRYPT_ENCRYPTED_CONTENT_INFO), FALSE, TRUE,
5734        offsetof(CRYPT_ENVELOPED_DATA, encryptedContentInfo.contentType), 0 },
5735     };
5736
5737     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5738      pDecodePara, envelopedData, *pcbEnvelopedData);
5739
5740     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5741      pbEncoded, cbEncoded, dwFlags, pDecodePara, envelopedData,
5742      pcbEnvelopedData, NULL, NULL);
5743     TRACE("returning %d\n", ret);
5744     return ret;
5745 }
5746
5747 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
5748  LPCSTR lpszStructType)
5749 {
5750     CryptDecodeObjectExFunc decodeFunc = NULL;
5751
5752     if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
5753      && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
5754     {
5755         SetLastError(ERROR_FILE_NOT_FOUND);
5756         return NULL;
5757     }
5758     if (IS_INTOID(lpszStructType))
5759     {
5760         switch (LOWORD(lpszStructType))
5761         {
5762         case LOWORD(X509_CERT):
5763             decodeFunc = CRYPT_AsnDecodeCertSignedContent;
5764             break;
5765         case LOWORD(X509_CERT_TO_BE_SIGNED):
5766             decodeFunc = CRYPT_AsnDecodeCert;
5767             break;
5768         case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
5769             decodeFunc = CRYPT_AsnDecodeCRL;
5770             break;
5771         case LOWORD(X509_EXTENSIONS):
5772             decodeFunc = CRYPT_AsnDecodeExtensions;
5773             break;
5774         case LOWORD(X509_NAME_VALUE):
5775             decodeFunc = CRYPT_AsnDecodeNameValue;
5776             break;
5777         case LOWORD(X509_NAME):
5778             decodeFunc = CRYPT_AsnDecodeName;
5779             break;
5780         case LOWORD(X509_PUBLIC_KEY_INFO):
5781             decodeFunc = CRYPT_AsnDecodePubKeyInfo;
5782             break;
5783         case LOWORD(X509_AUTHORITY_KEY_ID):
5784             decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5785             break;
5786         case LOWORD(X509_ALTERNATE_NAME):
5787             decodeFunc = CRYPT_AsnDecodeAltName;
5788             break;
5789         case LOWORD(X509_BASIC_CONSTRAINTS):
5790             decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5791             break;
5792         case LOWORD(X509_BASIC_CONSTRAINTS2):
5793             decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5794             break;
5795         case LOWORD(X509_CERT_POLICIES):
5796             decodeFunc = CRYPT_AsnDecodeCertPolicies;
5797             break;
5798         case LOWORD(RSA_CSP_PUBLICKEYBLOB):
5799             decodeFunc = CRYPT_AsnDecodeRsaPubKey;
5800             break;
5801         case LOWORD(X509_UNICODE_NAME):
5802             decodeFunc = CRYPT_AsnDecodeUnicodeName;
5803             break;
5804         case LOWORD(PKCS_ATTRIBUTE):
5805             decodeFunc = CRYPT_AsnDecodePKCSAttribute;
5806             break;
5807         case LOWORD(X509_UNICODE_NAME_VALUE):
5808             decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
5809             break;
5810         case LOWORD(X509_OCTET_STRING):
5811             decodeFunc = CRYPT_AsnDecodeOctets;
5812             break;
5813         case LOWORD(X509_BITS):
5814         case LOWORD(X509_KEY_USAGE):
5815             decodeFunc = CRYPT_AsnDecodeBits;
5816             break;
5817         case LOWORD(X509_INTEGER):
5818             decodeFunc = CRYPT_AsnDecodeInt;
5819             break;
5820         case LOWORD(X509_MULTI_BYTE_INTEGER):
5821             decodeFunc = CRYPT_AsnDecodeInteger;
5822             break;
5823         case LOWORD(X509_MULTI_BYTE_UINT):
5824             decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
5825             break;
5826         case LOWORD(X509_ENUMERATED):
5827             decodeFunc = CRYPT_AsnDecodeEnumerated;
5828             break;
5829         case LOWORD(X509_CHOICE_OF_TIME):
5830             decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
5831             break;
5832         case LOWORD(X509_AUTHORITY_KEY_ID2):
5833             decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5834             break;
5835         case LOWORD(X509_AUTHORITY_INFO_ACCESS):
5836             decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5837             break;
5838         case LOWORD(PKCS_CONTENT_INFO):
5839             decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
5840             break;
5841         case LOWORD(X509_SEQUENCE_OF_ANY):
5842             decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
5843             break;
5844         case LOWORD(PKCS_UTC_TIME):
5845             decodeFunc = CRYPT_AsnDecodeUtcTime;
5846             break;
5847         case LOWORD(X509_CRL_DIST_POINTS):
5848             decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5849             break;
5850         case LOWORD(X509_ENHANCED_KEY_USAGE):
5851             decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5852             break;
5853         case LOWORD(PKCS_CTL):
5854             decodeFunc = CRYPT_AsnDecodeCTL;
5855             break;
5856         case LOWORD(PKCS_SMIME_CAPABILITIES):
5857             decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5858             break;
5859         case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
5860             decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5861             break;
5862         case LOWORD(PKCS_ATTRIBUTES):
5863             decodeFunc = CRYPT_AsnDecodePKCSAttributes;
5864             break;
5865         case LOWORD(X509_ISSUING_DIST_POINT):
5866             decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5867             break;
5868         case LOWORD(X509_NAME_CONSTRAINTS):
5869             decodeFunc = CRYPT_AsnDecodeNameConstraints;
5870             break;
5871         case LOWORD(X509_POLICY_MAPPINGS):
5872             decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5873             break;
5874         case LOWORD(X509_POLICY_CONSTRAINTS):
5875             decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
5876             break;
5877         case LOWORD(PKCS7_SIGNER_INFO):
5878             decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
5879             break;
5880         case LOWORD(CMS_SIGNER_INFO):
5881             decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
5882             break;
5883         }
5884     }
5885     else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
5886         decodeFunc = CRYPT_AsnDecodeExtensions;
5887     else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
5888         decodeFunc = CRYPT_AsnDecodeUtcTime;
5889     else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
5890         decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5891     else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
5892         decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5893     else if (!strcmp(lpszStructType, szOID_LEGACY_POLICY_MAPPINGS))
5894         decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5895     else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
5896         decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5897     else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
5898         decodeFunc = CRYPT_AsnDecodeEnumerated;
5899     else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
5900         decodeFunc = CRYPT_AsnDecodeBits;
5901     else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
5902         decodeFunc = CRYPT_AsnDecodeOctets;
5903     else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
5904         decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5905     else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
5906         decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5907     else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
5908         decodeFunc = CRYPT_AsnDecodeAltName;
5909     else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
5910         decodeFunc = CRYPT_AsnDecodeAltName;
5911     else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
5912         decodeFunc = CRYPT_AsnDecodeAltName;
5913     else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
5914         decodeFunc = CRYPT_AsnDecodeAltName;
5915     else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
5916         decodeFunc = CRYPT_AsnDecodeAltName;
5917     else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
5918         decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5919     else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
5920         decodeFunc = CRYPT_AsnDecodeCertPolicies;
5921     else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS))
5922         decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5923     else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS))
5924         decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
5925     else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
5926         decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5927     else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
5928         decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5929     else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
5930         decodeFunc = CRYPT_AsnDecodeNameConstraints;
5931     else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
5932         decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5933     else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
5934         decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5935     else if (!strcmp(lpszStructType, szOID_CTL))
5936         decodeFunc = CRYPT_AsnDecodeCTL;
5937     return decodeFunc;
5938 }
5939
5940 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
5941  LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5942 {
5943     static HCRYPTOIDFUNCSET set = NULL;
5944     CryptDecodeObjectFunc decodeFunc = NULL;
5945
5946     if (!set)
5947         set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
5948     CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5949      (void **)&decodeFunc, hFunc);
5950     return decodeFunc;
5951 }
5952
5953 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
5954  LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5955 {
5956     static HCRYPTOIDFUNCSET set = NULL;
5957     CryptDecodeObjectExFunc decodeFunc = NULL;
5958
5959     if (!set)
5960         set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
5961     CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5962      (void **)&decodeFunc, hFunc);
5963     return decodeFunc;
5964 }
5965
5966 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5967  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
5968  DWORD *pcbStructInfo)
5969 {
5970     BOOL ret = FALSE;
5971     CryptDecodeObjectFunc pCryptDecodeObject = NULL;
5972     CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
5973     HCRYPTOIDFUNCADDR hFunc = NULL;
5974
5975     TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
5976      debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
5977      pvStructInfo, pcbStructInfo);
5978
5979     if (!pvStructInfo && !pcbStructInfo)
5980     {
5981         SetLastError(ERROR_INVALID_PARAMETER);
5982         return FALSE;
5983     }
5984     if (cbEncoded > MAX_ENCODED_LEN)
5985     {
5986         SetLastError(CRYPT_E_ASN1_LARGE);
5987         return FALSE;
5988     }
5989
5990     if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
5991      lpszStructType)))
5992     {
5993         TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5994          debugstr_a(lpszStructType));
5995         pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
5996          lpszStructType, &hFunc);
5997         if (!pCryptDecodeObject)
5998             pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
5999              lpszStructType, &hFunc);
6000     }
6001     if (pCryptDecodeObject)
6002         ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6003          pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
6004     else if (pCryptDecodeObjectEx)
6005         ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
6006          pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
6007          pvStructInfo, pcbStructInfo);
6008     if (hFunc)
6009         CryptFreeOIDFunctionAddress(hFunc, 0);
6010     TRACE_(crypt)("returning %d\n", ret);
6011     return ret;
6012 }
6013
6014 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
6015  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
6016  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
6017 {
6018     BOOL ret = FALSE;
6019     CryptDecodeObjectExFunc decodeFunc;
6020     HCRYPTOIDFUNCADDR hFunc = NULL;
6021
6022     TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6023      dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
6024      cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
6025
6026     if (!pvStructInfo && !pcbStructInfo)
6027     {
6028         SetLastError(ERROR_INVALID_PARAMETER);
6029         return FALSE;
6030     }
6031     if (cbEncoded > MAX_ENCODED_LEN)
6032     {
6033         SetLastError(CRYPT_E_ASN1_LARGE);
6034         return FALSE;
6035     }
6036
6037     SetLastError(NOERROR);
6038     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
6039     {
6040         if (!pvStructInfo)
6041         {
6042             SetLastError(ERROR_INVALID_PARAMETER);
6043             return FALSE;
6044         }
6045         *(BYTE **)pvStructInfo = NULL;
6046     }
6047     decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
6048     if (!decodeFunc)
6049     {
6050         TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
6051          debugstr_a(lpszStructType));
6052         decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
6053          &hFunc);
6054     }
6055     if (decodeFunc)
6056         ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
6057          cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
6058     else
6059     {
6060         CryptDecodeObjectFunc pCryptDecodeObject =
6061          CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
6062
6063         /* Try CryptDecodeObject function.  Don't call CryptDecodeObject
6064          * directly, as that could cause an infinite loop.
6065          */
6066         if (pCryptDecodeObject)
6067         {
6068             if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
6069             {
6070                 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6071                  pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
6072                 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
6073                  pvStructInfo, pcbStructInfo, *pcbStructInfo)))
6074                 {
6075                     ret = pCryptDecodeObject(dwCertEncodingType,
6076                      lpszStructType, pbEncoded, cbEncoded, dwFlags,
6077                      *(BYTE **)pvStructInfo, pcbStructInfo);
6078                     if (!ret)
6079                         CRYPT_FreeSpace(pDecodePara, *(BYTE **)pvStructInfo);
6080                 }
6081             }
6082             else
6083                 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6084                  pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
6085         }
6086     }
6087     if (hFunc)
6088         CryptFreeOIDFunctionAddress(hFunc, 0);
6089     TRACE_(crypt)("returning %d\n", ret);
6090     return ret;
6091 }
6092
6093 BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
6094 {
6095     BOOL ret;
6096
6097     TRACE_(crypt)("(%p)\n", pPFX);
6098
6099     /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6100      * version integer of length 1 (3 encoded byes) and at least one other
6101      * datum (two encoded bytes), plus at least two bytes for the outer
6102      * sequence.  Thus, even an empty PFX blob is at least 7 bytes in length.
6103      */
6104     if (pPFX->cbData < 7)
6105         ret = FALSE;
6106     else if (pPFX->pbData[0] == ASN_SEQUENCE)
6107     {
6108         DWORD len;
6109
6110         if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
6111         {
6112             BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);
6113
6114             /* Need at least three bytes for the integer version */
6115             if (pPFX->cbData < 1 + lenLen + 3)
6116                 ret = FALSE;
6117             else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
6118              pPFX->pbData[1 + lenLen + 1] != 1 ||          /* Definite length */
6119              pPFX->pbData[1 + lenLen + 2] != 3)            /* PFX version */
6120                 ret = FALSE;
6121         }
6122     }
6123     else
6124         ret = FALSE;
6125     return ret;
6126 }
6127
6128 HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
6129  DWORD dwFlags)
6130 {
6131     FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);
6132     return NULL;
6133 }
6134
6135 BOOL WINAPI PFXVerifyPassword(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
6136  DWORD dwFlags)
6137 {
6138     FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);
6139     return FALSE;
6140 }