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