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