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