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