~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/crypt32/decode.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  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 = startingPointer;
541                     else
542                         nextData = (BYTE *)pvStructInfo + structSize;
543                     memset(pvStructInfo, 0, structSize);
544                     ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
545                      ptr, dataLen, dwFlags, pvStructInfo, nextData,
546                      &cbDecoded);
547                     if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
548                         CRYPT_FreeSpace(pDecodePara, pvStructInfo);
549                 }
550             }
551         }
552     }
553     else
554     {
555         SetLastError(CRYPT_E_ASN1_BADTAG);
556         ret = FALSE;
557     }
558     TRACE("returning %d (%08x)\n", ret, GetLastError());
559     return ret;
560 }
561 
562 /* tag:
563  *     The expected tag of the entire encoded array (usually a variant
564  *     of ASN_SETOF or ASN_SEQUENCEOF.)  If tag is 0, decodeFunc is called
565  *     regardless of the tag seen.
566  * decodeFunc:
567  *     used to decode each item in the array
568  * itemSize:
569  *      is the minimum size of each decoded item
570  * hasPointer:
571  *      indicates whether each item has a dynamic pointer
572  * pointerOffset:
573  *     indicates the offset within itemSize at which the pointer exists
574  */
575 struct AsnArrayDescriptor
576 {
577     BYTE               tag;
578     InternalDecodeFunc decodeFunc;
579     DWORD              itemSize;
580     BOOL               hasPointer;
581     DWORD              pointerOffset;
582 };
583 
584 struct AsnArrayItemSize
585 {
586     DWORD encodedLen;
587     DWORD size;
588 };
589 
590 /* Decodes an array of like types into a struct GenericArray.
591  * The layout and decoding of the array are described by a struct
592  * AsnArrayDescriptor.
593  */
594 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
595  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
596  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
597  DWORD *pcbDecoded, void *startingPointer)
598 {
599     BOOL ret = TRUE;
600 
601     TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
602      cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
603      startingPointer);
604 
605     if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
606     {
607         DWORD dataLen;
608 
609         if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
610         {
611             DWORD bytesNeeded, cItems = 0, decoded;
612             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
613             /* There can be arbitrarily many items, but there is often only one.
614              */
615             struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
616 
617             decoded = 1 + lenBytes;
618             bytesNeeded = sizeof(struct GenericArray);
619             if (dataLen)
620             {
621                 const BYTE *ptr;
622                 BOOL doneDecoding = FALSE;
623 
624                 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
625                 {
626                     if (dataLen == CMSG_INDEFINITE_LENGTH)
627                     {
628                         if (ptr[0] == 0)
629                         {
630                             doneDecoding = TRUE;
631                             if (ptr[1] != 0)
632                             {
633                                 SetLastError(CRYPT_E_ASN1_CORRUPT);
634                                 ret = FALSE;
635                             }
636                             else
637                                 decoded += 2;
638                         }
639                     }
640                     else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
641                         doneDecoding = TRUE;
642                     if (!doneDecoding)
643                     {
644                         DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
645 
646                         /* Each item decoded may not tolerate extraneous bytes,
647                          * so get the length of the next element if known.
648                          */
649                         if ((ret = CRYPT_GetLengthIndefinite(ptr,
650                          cbEncoded - (ptr - pbEncoded), &itemDataLen)))
651                         {
652                             if (itemDataLen == CMSG_INDEFINITE_LENGTH)
653                                 itemEncoded = cbEncoded - (ptr - pbEncoded);
654                             else
655                                 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
656                                  itemDataLen;
657                         }
658                         if (ret)
659                             ret = arrayDesc->decodeFunc(ptr, itemEncoded,
660                              dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
661                              &itemDecoded);
662                         if (ret)
663                         {
664                             cItems++;
665                             if (itemSizes != &itemSize)
666                                 itemSizes = CryptMemRealloc(itemSizes,
667                                  cItems * sizeof(struct AsnArrayItemSize));
668                             else if (cItems > 1)
669                             {
670                                 itemSizes =
671                                  CryptMemAlloc(
672                                  cItems * sizeof(struct AsnArrayItemSize));
673                                 if (itemSizes)
674                                     memcpy(itemSizes, &itemSize,
675                                      sizeof(itemSize));
676                             }
677                             if (itemSizes)
678                             {
679                                 decoded += itemDecoded;
680                                 itemSizes[cItems - 1].encodedLen = itemEncoded;
681                                 itemSizes[cItems - 1].size = size;
682                                 bytesNeeded += size;
683                                 ptr += itemEncoded;
684                             }
685                             else
686                                 ret = FALSE;
687                         }
688                     }
689                 }
690             }
691             if (ret)
692             {
693                 if (pcbDecoded)
694                     *pcbDecoded = decoded;
695                 if (!pvStructInfo)
696                     *pcbStructInfo = bytesNeeded;
697                 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
698                  pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
699                 {
700                     DWORD i;
701                     BYTE *nextData;
702                     const BYTE *ptr;
703                     struct GenericArray *array;
704 
705                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
706                         pvStructInfo = *(BYTE **)pvStructInfo;
707                     array = pvStructInfo;
708                     array->cItems = cItems;
709                     if (startingPointer)
710                         array->rgItems = startingPointer;
711                     else
712                         array->rgItems = (BYTE *)array +
713                          sizeof(struct GenericArray);
714                     nextData = array->rgItems +
715                      array->cItems * arrayDesc->itemSize;
716                     for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
717                      i < cItems && ptr - pbEncoded - 1 - lenBytes <
718                      dataLen; i++)
719                     {
720                         DWORD itemDecoded;
721 
722                         if (arrayDesc->hasPointer)
723                             *(BYTE **)(array->rgItems + i * arrayDesc->itemSize
724                              + arrayDesc->pointerOffset) = nextData;
725                         ret = arrayDesc->decodeFunc(ptr,
726                          itemSizes[i].encodedLen,
727                          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
728                          array->rgItems + i * arrayDesc->itemSize,
729                          &itemSizes[i].size, &itemDecoded);
730                         if (ret)
731                         {
732                             nextData += itemSizes[i].size - arrayDesc->itemSize;
733                             ptr += itemDecoded;
734                         }
735                     }
736                     if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
737                         CRYPT_FreeSpace(pDecodePara, pvStructInfo);
738                 }
739             }
740             if (itemSizes != &itemSize)
741                 CryptMemFree(itemSizes);
742         }
743     }
744     else
745     {
746         SetLastError(CRYPT_E_ASN1_BADTAG);
747         ret = FALSE;
748     }
749     return ret;
750 }
751 
752 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
753  * pvStructInfo.  The BLOB must be non-empty, otherwise the last error is set
754  * to CRYPT_E_ASN1_CORRUPT.
755  * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
756  * set!
757  */
758 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
759  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
760 {
761     BOOL ret;
762     DWORD dataLen;
763 
764     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
765     {
766         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
767         DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
768        
769         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
770             bytesNeeded += 1 + lenBytes + dataLen;
771 
772         if (pcbDecoded)
773             *pcbDecoded = 1 + lenBytes + dataLen;
774         if (!pvStructInfo)
775             *pcbStructInfo = bytesNeeded;
776         else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
777         {
778             CRYPT_DER_BLOB *blob;
779 
780             if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
781                 pvStructInfo = *(BYTE **)pvStructInfo;
782             blob = pvStructInfo;
783             blob->cbData = 1 + lenBytes + dataLen;
784             if (blob->cbData)
785             {
786                 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
787                     blob->pbData = (BYTE *)pbEncoded;
788                 else
789                 {
790                     assert(blob->pbData);
791                     memcpy(blob->pbData, pbEncoded, blob->cbData);
792                 }
793             }
794             else
795             {
796                 SetLastError(CRYPT_E_ASN1_CORRUPT);
797                 ret = FALSE;
798             }
799         }
800     }
801     return ret;
802 }
803 
804 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
805 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
806  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
807  DWORD *pcbDecoded)
808 {
809     BOOL ret;
810 
811     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
812      pvStructInfo, *pcbStructInfo, pcbDecoded);
813 
814     /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
815      * place.
816      */
817     ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
818      dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
819      pcbDecoded);
820     if (ret && pvStructInfo)
821     {
822         CRYPT_BIT_BLOB *blob = pvStructInfo;
823 
824         if (blob->cbData)
825         {
826             DWORD i;
827             BYTE temp;
828 
829             for (i = 0; i < blob->cbData / 2; i++)
830             {
831                 temp = blob->pbData[i];
832                 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
833                 blob->pbData[blob->cbData - i - 1] = temp;
834             }
835         }
836     }
837     TRACE("returning %d (%08x)\n", ret, GetLastError());
838     return ret;
839 }
840 
841 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
842  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
843  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
844 {
845     BOOL ret = TRUE;
846 
847     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
848      pDecodePara, pvStructInfo, *pcbStructInfo);
849 
850     __TRY
851     {
852         struct AsnDecodeSequenceItem items[] = {
853          { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
854            CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
855            offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
856          { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
857            SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
858            sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
859            offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
860          { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
861            CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
862            offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
863         };
864 
865         if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
866             items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
867         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
868          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
869          pcbStructInfo, NULL, NULL);
870     }
871     __EXCEPT_PAGE_FAULT
872     {
873         SetLastError(STATUS_ACCESS_VIOLATION);
874         ret = FALSE;
875     }
876     __ENDTRY
877 
878     TRACE("Returning %d (%08x)\n", ret, GetLastError());
879     return ret;
880 }
881 
882 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
883  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
884 {
885     BOOL ret;
886     DWORD dataLen;
887 
888     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
889     {
890         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
891 
892         ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
893          dwFlags, pvStructInfo, pcbStructInfo, NULL);
894         if (pcbDecoded)
895             *pcbDecoded = 1 + lenBytes + dataLen;
896     }
897     return ret;
898 }
899 
900 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
901  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
902 {
903     BOOL ret;
904 
905     struct AsnDecodeSequenceItem items[] = {
906      { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
907        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
908      { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
909        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
910     };
911 
912     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
913      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
914      pcbDecoded, NULL);
915     return ret;
916 }
917 
918 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
919  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
920  DWORD *pcbDecoded)
921 {
922     BOOL ret;
923     DWORD dataLen;
924 
925     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
926     {
927         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
928 
929         ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded + 1 + lenBytes,
930          dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
931         if (ret && pcbDecoded)
932             *pcbDecoded = 1 + lenBytes + dataLen;
933     }
934     return ret;
935 }
936 
937 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
938  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
939  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
940 {
941     BOOL ret = TRUE;
942     struct AsnDecodeSequenceItem items[] = {
943      { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
944        CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
945      { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
946        CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
947        TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
948      { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
949        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
950        FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
951      { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
952        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
953        Issuer.pbData) },
954      { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
955        CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
956        FALSE, 0 },
957      { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
958        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
959        Subject.pbData) },
960      { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
961        CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
962        FALSE, TRUE, offsetof(CERT_INFO,
963        SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
964      { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
965        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
966        offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
967      { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
968        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
969        offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
970      { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
971        CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
972        offsetof(CERT_INFO, rgExtension), 0 },
973     };
974 
975     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
976      pDecodePara, pvStructInfo, *pcbStructInfo);
977 
978     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
979      pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
980      NULL, NULL);
981     if (ret && pvStructInfo)
982     {
983         CERT_INFO *info;
984 
985         if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
986             info = *(CERT_INFO **)pvStructInfo;
987         else
988             info = pvStructInfo;
989         if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
990          !info->Subject.cbData)
991         {
992             SetLastError(CRYPT_E_ASN1_CORRUPT);
993             /* Don't need to deallocate, because it should have failed on the
994              * first pass (and no memory was allocated.)
995              */
996             ret = FALSE;
997         }
998     }
999 
1000     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1001     return ret;
1002 }
1003 
1004 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1005  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1006  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1007 {
1008     BOOL ret = FALSE;
1009 
1010     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1011      pDecodePara, pvStructInfo, *pcbStructInfo);
1012 
1013     __TRY
1014     {
1015         DWORD size = 0;
1016 
1017         /* Unless told not to, first try to decode it as a signed cert. */
1018         if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1019         {
1020             PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1021 
1022             ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1023              X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1024              &signedCert, &size);
1025             if (ret)
1026             {
1027                 size = 0;
1028                 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1029                  X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1030                  signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1031                  pvStructInfo, pcbStructInfo);
1032                 LocalFree(signedCert);
1033             }
1034         }
1035         /* Failing that, try it as an unsigned cert */
1036         if (!ret)
1037         {
1038             size = 0;
1039             ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1040              X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1041              pDecodePara, pvStructInfo, pcbStructInfo);
1042         }
1043     }
1044     __EXCEPT_PAGE_FAULT
1045     {
1046         SetLastError(STATUS_ACCESS_VIOLATION);
1047     }
1048     __ENDTRY
1049 
1050     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1051     return ret;
1052 }
1053 
1054 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1055  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1056 {
1057     BOOL ret;
1058     struct AsnDecodeSequenceItem items[] = {
1059      { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1060        CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1061        offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1062      { 0, offsetof(CRL_ENTRY, RevocationDate),
1063        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1064      { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1065        CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1066        offsetof(CRL_ENTRY, rgExtension), 0 },
1067     };
1068     PCRL_ENTRY entry = pvStructInfo;
1069 
1070     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1071      *pcbStructInfo);
1072 
1073     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1074      pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1075      entry ? entry->SerialNumber.pbData : NULL);
1076     if (ret && entry && !entry->SerialNumber.cbData)
1077     {
1078         WARN("empty CRL entry serial number\n");
1079         SetLastError(CRYPT_E_ASN1_CORRUPT);
1080         ret = FALSE;
1081     }
1082     return ret;
1083 }
1084 
1085 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1086  * been set prior to calling.
1087  */
1088 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1089  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1090 {
1091     BOOL ret;
1092     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1093      CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1094      offsetof(CRL_ENTRY, SerialNumber.pbData) };
1095     struct GenericArray *entries = pvStructInfo;
1096 
1097     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1098      pvStructInfo, *pcbStructInfo, pcbDecoded);
1099 
1100     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1101      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1102      entries ? entries->rgItems : NULL);
1103     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1104     return ret;
1105 }
1106 
1107 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1108  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1109  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1110 {
1111     struct AsnDecodeSequenceItem items[] = {
1112      { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1113        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1114      { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1115        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1116        FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1117      { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1118        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1119        Issuer.pbData) },
1120      { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1121        sizeof(FILETIME), FALSE, FALSE, 0 },
1122      { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1123        sizeof(FILETIME), TRUE, FALSE, 0 },
1124      { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1125        CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE,
1126        offsetof(CRL_INFO, rgCRLEntry), 0 },
1127      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1128        CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1129        offsetof(CRL_INFO, rgExtension), 0 },
1130     };
1131     BOOL ret = TRUE;
1132 
1133     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1134      pDecodePara, pvStructInfo, *pcbStructInfo);
1135 
1136     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1137      pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1138      NULL, NULL);
1139 
1140     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1141     return ret;
1142 }
1143 
1144 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1145  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1146  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1147 {
1148     BOOL ret = FALSE;
1149 
1150     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1151      pDecodePara, pvStructInfo, *pcbStructInfo);
1152 
1153     __TRY
1154     {
1155         DWORD size = 0;
1156 
1157         /* Unless told not to, first try to decode it as a signed crl. */
1158         if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1159         {
1160             PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1161 
1162             ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1163              X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1164              &signedCrl, &size);
1165             if (ret)
1166             {
1167                 size = 0;
1168                 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1169                  X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1170                  signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1171                  pvStructInfo, pcbStructInfo);
1172                 LocalFree(signedCrl);
1173             }
1174         }
1175         /* Failing that, try it as an unsigned crl */
1176         if (!ret)
1177         {
1178             size = 0;
1179             ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1180              X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1181              dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1182         }
1183     }
1184     __EXCEPT_PAGE_FAULT
1185     {
1186         SetLastError(STATUS_ACCESS_VIOLATION);
1187     }
1188     __ENDTRY
1189 
1190     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1191     return ret;
1192 }
1193 
1194 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1195  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1196 {
1197     BOOL ret = TRUE;
1198     DWORD dataLen;
1199 
1200     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1201      pvStructInfo, *pcbStructInfo);
1202 
1203     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1204     {
1205         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1206         DWORD bytesNeeded = sizeof(LPSTR);
1207 
1208         if (dataLen)
1209         {
1210             /* The largest possible string for the first two components
1211              * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1212              */
1213             char firstTwo[6];
1214             const BYTE *ptr;
1215 
1216             snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1217              pbEncoded[1 + lenBytes] / 40,
1218              pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1219              * 40);
1220             bytesNeeded += strlen(firstTwo) + 1;
1221             for (ptr = pbEncoded + 2 + lenBytes; ret &&
1222              ptr - pbEncoded - 1 - lenBytes < dataLen; )
1223             {
1224                 /* large enough for ".4000000" */
1225                 char str[9];
1226                 int val = 0;
1227 
1228                 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1229                  (*ptr & 0x80))
1230                 {
1231                     val <<= 7;
1232                     val |= *ptr & 0x7f;
1233                     ptr++;
1234                 }
1235                 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1236                  (*ptr & 0x80))
1237                 {
1238                     SetLastError(CRYPT_E_ASN1_CORRUPT);
1239                     ret = FALSE;
1240                 }
1241                 else
1242                 {
1243                     val <<= 7;
1244                     val |= *ptr++;
1245                     snprintf(str, sizeof(str), ".%d", val);
1246                     bytesNeeded += strlen(str);
1247                 }
1248             }
1249         }
1250         if (pcbDecoded)
1251             *pcbDecoded = 1 + lenBytes + dataLen;
1252         if (!pvStructInfo)
1253             *pcbStructInfo = bytesNeeded;
1254         else if (*pcbStructInfo < bytesNeeded)
1255         {
1256             *pcbStructInfo = bytesNeeded;
1257             SetLastError(ERROR_MORE_DATA);
1258             ret = FALSE;
1259         }
1260         else
1261         {
1262             if (dataLen)
1263             {
1264                 const BYTE *ptr;
1265                 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1266 
1267                 *pszObjId = 0;
1268                 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1269                  pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1270                  40) * 40);
1271                 pszObjId += strlen(pszObjId);
1272                 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1273                  ptr - pbEncoded - 1 - lenBytes < dataLen; )
1274                 {
1275                     int val = 0;
1276 
1277                     while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1278                      (*ptr & 0x80))
1279                     {
1280                         val <<= 7;
1281                         val |= *ptr & 0x7f;
1282                         ptr++;
1283                     }
1284                     val <<= 7;
1285                     val |= *ptr++;
1286                     sprintf(pszObjId, ".%d", val);
1287                     pszObjId += strlen(pszObjId);
1288                 }
1289             }
1290             else
1291                 *(LPSTR *)pvStructInfo = NULL;
1292             *pcbStructInfo = bytesNeeded;
1293         }
1294     }
1295     return ret;
1296 }
1297 
1298 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1299  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1300 {
1301     BOOL ret;
1302 
1303     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1304      pvStructInfo, *pcbStructInfo);
1305 
1306     if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1307         ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1308          pvStructInfo, pcbStructInfo, pcbDecoded);
1309     else
1310     {
1311         SetLastError(CRYPT_E_ASN1_BADTAG);
1312         ret = FALSE;
1313     }
1314     return ret;
1315 }
1316 
1317 /* Warning:  assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1318  * ahead of time!
1319  */
1320 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1321  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1322 {
1323     struct AsnDecodeSequenceItem items[] = {
1324      { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1325        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1326        offsetof(CERT_EXTENSION, pszObjId), 0 },
1327      { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1328        sizeof(BOOL), TRUE, FALSE, 0, 0 },
1329      { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1330        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1331        offsetof(CERT_EXTENSION, Value.pbData) },
1332     };
1333     BOOL ret = TRUE;
1334     PCERT_EXTENSION ext = pvStructInfo;
1335 
1336     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1337      *pcbStructInfo);
1338 
1339     if (ext)
1340         TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1341     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1342      pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1343      pcbDecoded, ext ? ext->pszObjId : NULL);
1344     if (ext)
1345         TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1346          debugstr_a(ext->pszObjId));
1347     TRACE("returning %d (%08x)\n", ret, GetLastError());
1348     return ret;
1349 }
1350 
1351 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
1352  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1353  DWORD *pcbDecoded)
1354 {
1355     BOOL ret = TRUE;
1356     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1357      CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1358      offsetof(CERT_EXTENSION, pszObjId) };
1359     PCERT_EXTENSIONS exts = pvStructInfo;
1360 
1361     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1362      pvStructInfo, *pcbStructInfo, pcbDecoded);
1363 
1364     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1365      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1366      exts ? exts->rgExtension : NULL);
1367     return ret;
1368 }
1369 
1370 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1371  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1372  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1373 {
1374     BOOL ret = TRUE;
1375 
1376     __TRY
1377     {
1378         ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1379          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1380         if (ret && pvStructInfo)
1381         {
1382             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1383              pcbStructInfo, *pcbStructInfo);
1384             if (ret)
1385             {
1386                 CERT_EXTENSIONS *exts;
1387 
1388                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1389                     pvStructInfo = *(BYTE **)pvStructInfo;
1390                 exts = pvStructInfo;
1391                 exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
1392                  sizeof(CERT_EXTENSIONS));
1393                 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1394                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1395                  pcbStructInfo, NULL);
1396             }
1397         }
1398     }
1399     __EXCEPT_PAGE_FAULT
1400     {
1401         SetLastError(STATUS_ACCESS_VIOLATION);
1402         ret = FALSE;
1403     }
1404     __ENDTRY
1405     return ret;
1406 }
1407 
1408 /* Warning: this assumes the address of value->Value.pbData is already set, in
1409  * order to avoid overwriting memory.  (In some cases, it may change it, if it
1410  * doesn't copy anything to memory.)  Be sure to set it correctly!
1411  */
1412 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1413  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1414  DWORD *pcbDecoded)
1415 {
1416     BOOL ret = TRUE;
1417     DWORD dataLen;
1418     CERT_NAME_VALUE *value = pvStructInfo;
1419 
1420     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1421     {
1422         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1423         DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1424 
1425         switch (pbEncoded[0])
1426         {
1427         case ASN_OCTETSTRING:
1428             valueType = CERT_RDN_OCTET_STRING;
1429             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1430                 bytesNeeded += dataLen;
1431             break;
1432         case ASN_NUMERICSTRING:
1433             valueType = CERT_RDN_NUMERIC_STRING;
1434             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1435                 bytesNeeded += dataLen;
1436             break;
1437         case ASN_PRINTABLESTRING:
1438             valueType = CERT_RDN_PRINTABLE_STRING;
1439             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1440                 bytesNeeded += dataLen;
1441             break;
1442         case ASN_IA5STRING:
1443             valueType = CERT_RDN_IA5_STRING;
1444             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1445                 bytesNeeded += dataLen;
1446             break;
1447         case ASN_T61STRING:
1448             valueType = CERT_RDN_T61_STRING;
1449             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1450                 bytesNeeded += dataLen;
1451             break;
1452         case ASN_VIDEOTEXSTRING:
1453             valueType = CERT_RDN_VIDEOTEX_STRING;
1454             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1455                 bytesNeeded += dataLen;
1456             break;
1457         case ASN_GRAPHICSTRING:
1458             valueType = CERT_RDN_GRAPHIC_STRING;
1459             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1460                 bytesNeeded += dataLen;
1461             break;
1462         case ASN_VISIBLESTRING:
1463             valueType = CERT_RDN_VISIBLE_STRING;
1464             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1465                 bytesNeeded += dataLen;
1466             break;
1467         case ASN_GENERALSTRING:
1468             valueType = CERT_RDN_GENERAL_STRING;
1469             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1470                 bytesNeeded += dataLen;
1471             break;
1472         case ASN_UNIVERSALSTRING:
1473             FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1474             SetLastError(CRYPT_E_ASN1_BADTAG);
1475             return FALSE;
1476         case ASN_BMPSTRING:
1477             valueType = CERT_RDN_BMP_STRING;
1478             bytesNeeded += dataLen;
1479             break;
1480         case ASN_UTF8STRING:
1481             valueType = CERT_RDN_UTF8_STRING;
1482             bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1483              (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1484             break;
1485         default:
1486             SetLastError(CRYPT_E_ASN1_BADTAG);
1487             return FALSE;
1488         }
1489 
1490         if (pcbDecoded)
1491             *pcbDecoded = 1 + lenBytes + dataLen;
1492         if (!value)
1493             *pcbStructInfo = bytesNeeded;
1494         else if (*pcbStructInfo < bytesNeeded)
1495         {
1496             *pcbStructInfo = bytesNeeded;
1497             SetLastError(ERROR_MORE_DATA);
1498             ret = FALSE;
1499         }
1500         else
1501         {
1502             *pcbStructInfo = bytesNeeded;
1503             value->dwValueType = valueType;
1504             if (dataLen)
1505             {
1506                 DWORD i;
1507 
1508                 assert(value->Value.pbData);
1509                 switch (pbEncoded[0])
1510                 {
1511                 case ASN_OCTETSTRING:
1512                 case ASN_NUMERICSTRING:
1513                 case ASN_PRINTABLESTRING:
1514                 case ASN_IA5STRING:
1515                 case ASN_T61STRING:
1516                 case ASN_VIDEOTEXSTRING:
1517                 case ASN_GRAPHICSTRING:
1518                 case ASN_VISIBLESTRING:
1519                 case ASN_GENERALSTRING:
1520                     value->Value.cbData = dataLen;
1521                     if (dataLen)
1522                     {
1523                         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1524                             memcpy(value->Value.pbData,
1525                              pbEncoded + 1 + lenBytes, dataLen);
1526                         else
1527                             value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1528                              lenBytes;
1529                     }
1530                     break;
1531                 case ASN_BMPSTRING:
1532                 {
1533                     LPWSTR str = (LPWSTR)value->Value.pbData;
1534 
1535                     value->Value.cbData = dataLen;
1536                     for (i = 0; i < dataLen / 2; i++)
1537                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1538                          pbEncoded[1 + lenBytes + 2 * i + 1];
1539                     break;
1540                 }
1541                 case ASN_UTF8STRING:
1542                 {
1543                     LPWSTR str = (LPWSTR)value->Value.pbData;
1544 
1545                     value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1546                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, 
1547                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1548                     break;
1549                 }
1550                 }
1551             }
1552             else
1553             {
1554                 value->Value.cbData = 0;
1555                 value->Value.pbData = NULL;
1556             }
1557         }
1558     }
1559     return ret;
1560 }
1561 
1562 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1563  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1564  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1565 {
1566     BOOL ret = TRUE;
1567 
1568     __TRY
1569     {
1570         ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1571          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1572         if (ret && pvStructInfo)
1573         {
1574             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1575              pcbStructInfo, *pcbStructInfo);
1576             if (ret)
1577             {
1578                 CERT_NAME_VALUE *value;
1579 
1580                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1581                     pvStructInfo = *(BYTE **)pvStructInfo;
1582                 value = pvStructInfo;
1583                 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1584                 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1585                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1586                  pcbStructInfo, NULL);
1587             }
1588         }
1589     }
1590     __EXCEPT_PAGE_FAULT
1591     {
1592         SetLastError(STATUS_ACCESS_VIOLATION);
1593         ret = FALSE;
1594     }
1595     __ENDTRY
1596     return ret;
1597 }
1598 
1599 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1600  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1601  DWORD *pcbDecoded)
1602 {
1603     BOOL ret = TRUE;
1604     DWORD dataLen;
1605     CERT_NAME_VALUE *value = pvStructInfo;
1606 
1607     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1608     {
1609         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1610         DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1611 
1612         switch (pbEncoded[0])
1613         {
1614         case ASN_NUMERICSTRING:
1615             valueType = CERT_RDN_NUMERIC_STRING;
1616             if (dataLen)
1617                 bytesNeeded += (dataLen + 1) * 2;
1618             break;
1619         case ASN_PRINTABLESTRING:
1620             valueType = CERT_RDN_PRINTABLE_STRING;
1621             if (dataLen)
1622                 bytesNeeded += (dataLen + 1) * 2;
1623             break;
1624         case ASN_IA5STRING:
1625             valueType = CERT_RDN_IA5_STRING;
1626             if (dataLen)
1627                 bytesNeeded += (dataLen + 1) * 2;
1628             break;
1629         case ASN_T61STRING:
1630             valueType = CERT_RDN_T61_STRING;
1631             if (dataLen)
1632                 bytesNeeded += (dataLen + 1) * 2;
1633             break;
1634         case ASN_VIDEOTEXSTRING:
1635             valueType = CERT_RDN_VIDEOTEX_STRING;
1636             if (dataLen)
1637                 bytesNeeded += (dataLen + 1) * 2;
1638             break;
1639         case ASN_GRAPHICSTRING:
1640             valueType = CERT_RDN_GRAPHIC_STRING;
1641             if (dataLen)
1642                 bytesNeeded += (dataLen + 1) * 2;
1643             break;
1644         case ASN_VISIBLESTRING:
1645             valueType = CERT_RDN_VISIBLE_STRING;
1646             if (dataLen)
1647                 bytesNeeded += (dataLen + 1) * 2;
1648             break;
1649         case ASN_GENERALSTRING:
1650             valueType = CERT_RDN_GENERAL_STRING;
1651             if (dataLen)
1652                 bytesNeeded += (dataLen + 1) * 2;
1653             break;
1654         case ASN_UNIVERSALSTRING:
1655             valueType = CERT_RDN_UNIVERSAL_STRING;
1656             if (dataLen)
1657                 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1658             break;
1659         case ASN_BMPSTRING:
1660             valueType = CERT_RDN_BMP_STRING;
1661             if (dataLen)
1662                 bytesNeeded += dataLen + sizeof(WCHAR);
1663             break;
1664         case ASN_UTF8STRING:
1665             valueType = CERT_RDN_UTF8_STRING;
1666             if (dataLen)
1667                 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1668                  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1669             break;
1670         default:
1671             SetLastError(CRYPT_E_ASN1_BADTAG);
1672             return FALSE;
1673         }
1674 
1675         if (pcbDecoded)
1676             *pcbDecoded = 1 + lenBytes + dataLen;
1677         if (!value)
1678             *pcbStructInfo = bytesNeeded;
1679         else if (*pcbStructInfo < bytesNeeded)
1680         {
1681             *pcbStructInfo = bytesNeeded;
1682             SetLastError(ERROR_MORE_DATA);
1683             ret = FALSE;
1684         }
1685         else
1686         {
1687             *pcbStructInfo = bytesNeeded;
1688             value->dwValueType = valueType;
1689             if (dataLen)
1690             {
1691                 DWORD i;
1692                 LPWSTR str = (LPWSTR)value->Value.pbData;
1693 
1694                 assert(value->Value.pbData);
1695                 switch (pbEncoded[0])
1696                 {
1697                 case ASN_NUMERICSTRING:
1698                 case ASN_PRINTABLESTRING:
1699                 case ASN_IA5STRING:
1700                 case ASN_T61STRING:
1701                 case ASN_VIDEOTEXSTRING:
1702                 case ASN_GRAPHICSTRING:
1703                 case ASN_VISIBLESTRING:
1704                 case ASN_GENERALSTRING:
1705                     value->Value.cbData = dataLen * 2;
1706                     for (i = 0; i < dataLen; i++)
1707                         str[i] = pbEncoded[1 + lenBytes + i];
1708                     str[i] = 0;
1709                     break;
1710                 case ASN_UNIVERSALSTRING:
1711                     value->Value.cbData = dataLen / 2;
1712                     for (i = 0; i < dataLen / 4; i++)
1713                         str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1714                          | pbEncoded[1 + lenBytes + 2 * i + 3];
1715                     str[i] = 0;
1716                     break;
1717                 case ASN_BMPSTRING:
1718                     value->Value.cbData = dataLen;
1719                     for (i = 0; i < dataLen / 2; i++)
1720                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1721                          pbEncoded[1 + lenBytes + 2 * i + 1];
1722                     str[i] = 0;
1723                     break;
1724                 case ASN_UTF8STRING:
1725                     value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1726                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1727                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = pvStructInfo;
2187     BOOL ret;
2188 
2189     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2190      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2191      capabilities ? capabilities->rgCapability : NULL);
2192     return ret;
2193 }
2194 
2195 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2196  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2197  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2198 {
2199     BOOL ret = FALSE;
2200 
2201     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2202      pDecodePara, pvStructInfo, *pcbStructInfo);
2203 
2204     __TRY
2205     {
2206         DWORD bytesNeeded;
2207 
2208         if (!cbEncoded)
2209             SetLastError(CRYPT_E_ASN1_EOD);
2210         else if (pbEncoded[0] != ASN_SEQUENCEOF)
2211             SetLastError(CRYPT_E_ASN1_CORRUPT);
2212         else if ((ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2213          cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2214          NULL)))
2215         {
2216             if (!pvStructInfo)
2217                 *pcbStructInfo = bytesNeeded;
2218             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2219              pvStructInfo, pcbStructInfo, bytesNeeded)))
2220             {
2221                 PCRYPT_SMIME_CAPABILITIES capabilities;
2222 
2223                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2224                     pvStructInfo = *(BYTE **)pvStructInfo;
2225                 capabilities = pvStructInfo;
2226                 capabilities->rgCapability =
2227                  (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
2228                  sizeof(CRYPT_SMIME_CAPABILITIES));
2229                 ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2230                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2231                  &bytesNeeded, NULL);
2232             }
2233         }
2234     }
2235     __EXCEPT_PAGE_FAULT
2236     {
2237         SetLastError(STATUS_ACCESS_VIOLATION);
2238     }
2239     __ENDTRY
2240     TRACE("returning %d\n", ret);
2241     return ret;
2242 }
2243 
2244 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2245  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2246  DWORD *pcbDecoded)
2247 {
2248     BOOL ret = TRUE;
2249     DWORD dataLen;
2250     LPSTR *pStr = pvStructInfo;
2251 
2252     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2253     {
2254         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2255         DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2256 
2257         if (pbEncoded[0] != ASN_IA5STRING)
2258         {
2259             SetLastError(CRYPT_E_ASN1_CORRUPT);
2260             ret = FALSE;
2261         }
2262         else
2263         {
2264             bytesNeeded += dataLen;
2265             if (pcbDecoded)
2266                 *pcbDecoded = 1 + lenBytes + dataLen;
2267             if (!pvStructInfo)
2268                 *pcbStructInfo = bytesNeeded;
2269             else if (*pcbStructInfo < bytesNeeded)
2270             {
2271                 *pcbStructInfo = bytesNeeded;
2272                 SetLastError(ERROR_MORE_DATA);
2273                 ret = FALSE;
2274             }
2275             else
2276             {
2277                 *pcbStructInfo = bytesNeeded;
2278                 if (dataLen)
2279                 {
2280                     LPSTR str = *pStr;
2281 
2282                     assert(str);
2283                     memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2284                     str[dataLen] = 0;
2285                 }
2286                 else
2287                     *pStr = NULL;
2288             }
2289         }
2290     }
2291     return ret;
2292 }
2293 
2294 static BOOL CRYPT_AsnDecodeIntArray(const BYTE *pbEncoded,
2295  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2296  DWORD *pcbDecoded)
2297 {
2298     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2299      CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2300     struct GenericArray *array = pvStructInfo;
2301     BOOL ret;
2302 
2303     TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2304      pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2305 
2306     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2307      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2308      array ? array->rgItems : NULL);
2309     TRACE("returning %d\n", ret);
2310     return ret;
2311 }
2312 
2313 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2314  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2315  DWORD *pcbDecoded)
2316 {
2317     BOOL ret;
2318     struct AsnDecodeSequenceItem items[] = {
2319      { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2320        pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2321        offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2322      { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2323        cNoticeNumbers), CRYPT_AsnDecodeIntArray, sizeof(struct GenericArray),
2324        FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2325        rgNoticeNumbers), 0 },
2326     };
2327     DWORD bytesNeeded;
2328 
2329     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2330      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2331 
2332     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2333      pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2334      NULL);
2335     if (ret)
2336     {
2337         /* The caller is expecting a pointer to a
2338          * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2339          * CRYPT_AsnDecodeSequence is decoding a
2340          * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.  Increment the bytes
2341          * needed, and decode again if the requisite space is available.
2342          */
2343         bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2344         if (!pvStructInfo)
2345             *pcbStructInfo = bytesNeeded;
2346         else if (*pcbStructInfo < bytesNeeded)
2347         {
2348             *pcbStructInfo = bytesNeeded;
2349             SetLastError(ERROR_MORE_DATA);
2350             ret = FALSE;
2351         }
2352         else
2353         {
2354             PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2355 
2356             *pcbStructInfo = bytesNeeded;
2357             /* The pointer (pvStructInfo) passed in points to the first dynamic
2358              * pointer, so use it as the pointer to the
2359              * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2360              * appropriate offset for the first dynamic pointer within the
2361              * notice reference by pointing to the first memory location past
2362              * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2363              */
2364             noticeRef =
2365              *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2366             noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2367              sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2368             ret = CRYPT_AsnDecodeSequence(items,
2369              sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2370              NULL, noticeRef, &bytesNeeded, pcbDecoded,
2371              noticeRef->pszOrganization);
2372         }
2373     }
2374     TRACE("returning %d\n", ret);
2375     return ret;
2376 }
2377 
2378 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2379  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2380  DWORD *pcbDecoded)
2381 {
2382     BOOL ret = TRUE;
2383     DWORD dataLen;
2384 
2385     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2386     {
2387         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2388         DWORD bytesNeeded = sizeof(LPWSTR);
2389 
2390         switch (pbEncoded[0])
2391         {
2392         case ASN_NUMERICSTRING:
2393             if (dataLen)
2394                 bytesNeeded += (dataLen + 1) * 2;
2395             break;
2396         case ASN_PRINTABLESTRING:
2397             if (dataLen)
2398                 bytesNeeded += (dataLen + 1) * 2;
2399             break;
2400         case ASN_IA5STRING:
2401             if (dataLen)
2402                 bytesNeeded += (dataLen + 1) * 2;
2403             break;
2404         case ASN_T61STRING:
2405             if (dataLen)
2406                 bytesNeeded += (dataLen + 1) * 2;
2407             break;
2408         case ASN_VIDEOTEXSTRING:
2409             if (dataLen)
2410                 bytesNeeded += (dataLen + 1) * 2;
2411             break;
2412         case ASN_GRAPHICSTRING:
2413             if (dataLen)
2414                 bytesNeeded += (dataLen + 1) * 2;
2415             break;
2416         case ASN_VISIBLESTRING:
2417             if (dataLen)
2418                 bytesNeeded += (dataLen + 1) * 2;
2419             break;
2420         case ASN_GENERALSTRING:
2421             if (dataLen)
2422                 bytesNeeded += (dataLen + 1) * 2;
2423             break;
2424         case ASN_UNIVERSALSTRING:
2425             if (dataLen)
2426                 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2427             break;
2428         case ASN_BMPSTRING:
2429             if (dataLen)
2430                 bytesNeeded += dataLen + sizeof(WCHAR);
2431             break;
2432         case ASN_UTF8STRING:
2433             if (dataLen)
2434                 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2435                  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2436             break;
2437         default:
2438             SetLastError(CRYPT_E_ASN1_BADTAG);
2439             return FALSE;
2440         }
2441 
2442         if (pcbDecoded)
2443             *pcbDecoded = 1 + lenBytes + dataLen;
2444         if (!pvStructInfo)
2445             *pcbStructInfo = bytesNeeded;
2446         else if (*pcbStructInfo < bytesNeeded)
2447         {
2448             *pcbStructInfo = bytesNeeded;
2449             SetLastError(ERROR_MORE_DATA);
2450             ret = FALSE;
2451         }
2452         else
2453         {
2454             LPWSTR *pStr = pvStructInfo;
2455 
2456             *pcbStructInfo = bytesNeeded;
2457             if (dataLen)
2458             {
2459                 DWORD i;
2460                 LPWSTR str = *(LPWSTR *)pStr;
2461 
2462                 assert(str);
2463                 switch (pbEncoded[0])
2464                 {
2465                 case ASN_NUMERICSTRING:
2466                 case ASN_PRINTABLESTRING:
2467                 case ASN_IA5STRING:
2468                 case ASN_T61STRING:
2469                 case ASN_VIDEOTEXSTRING:
2470                 case ASN_GRAPHICSTRING:
2471                 case ASN_VISIBLESTRING:
2472                 case ASN_GENERALSTRING:
2473                     for (i = 0; i < dataLen; i++)
2474                         str[i] = pbEncoded[1 + lenBytes + i];
2475                     str[i] = 0;
2476                     break;
2477                 case ASN_UNIVERSALSTRING:
2478                     for (i = 0; i < dataLen / 4; i++)
2479                         str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2480                          | pbEncoded[1 + lenBytes + 2 * i + 3];
2481                     str[i] = 0;
2482                     break;
2483                 case ASN_BMPSTRING:
2484                     for (i = 0; i < dataLen / 2; i++)
2485                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2486                          pbEncoded[1 + lenBytes + 2 * i + 1];
2487                     str[i] = 0;
2488                     break;
2489                 case ASN_UTF8STRING:
2490                 {
2491                     int len = MultiByteToWideChar(CP_UTF8, 0,
2492                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2493                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2494                     str[len] = 0;
2495                     break;
2496                 }
2497                 }
2498             }
2499             else
2500                 *pStr = NULL;
2501         }
2502     }
2503     return ret;
2504 }
2505 
2506 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2507  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2508  DWORD *pcbStructInfo, DWORD *pcbDecoded)
2509 {
2510     BOOL ret;
2511     struct AsnDecodeSequenceItem items[] = {
2512      { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2513        pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2514        sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2515        offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2516      { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2517        CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2518        offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2519     };
2520     PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2521 
2522     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2523      pvStructInfo, *pcbStructInfo);
2524 
2525     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2526      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2527      pcbDecoded, notice ? notice->pNoticeReference : NULL);
2528     TRACE("returning %d\n", ret);
2529     return ret;
2530 }
2531 
2532 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2533  DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2534  DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2535  void *pvStructInfo, DWORD *pcbStructInfo)
2536 {
2537     BOOL ret = FALSE;
2538 
2539     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2540      pDecodePara, pvStructInfo, *pcbStructInfo);
2541 
2542     __TRY
2543     {
2544         DWORD bytesNeeded;
2545 
2546         ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2547          cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2548          NULL);
2549         if (ret)
2550         {
2551             if (!pvStructInfo)
2552                 *pcbStructInfo = bytesNeeded;
2553             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2554              pvStructInfo, pcbStructInfo, bytesNeeded)))
2555             {
2556                 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2557 
2558                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2559                     pvStructInfo = *(BYTE **)pvStructInfo;
2560                 notice = pvStructInfo;
2561                 notice->pNoticeReference =
2562                  (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2563                  ((BYTE *)pvStructInfo +
2564                  sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2565                 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2566                  pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2567                  pvStructInfo, &bytesNeeded, NULL);
2568             }
2569         }
2570     }
2571     __EXCEPT_PAGE_FAULT
2572     {
2573         SetLastError(STATUS_ACCESS_VIOLATION);
2574     }
2575     __ENDTRY
2576     TRACE("returning %d\n", ret);
2577     return ret;
2578 }
2579 
2580 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2581  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2582  DWORD *pcbDecoded)
2583 {
2584     BOOL ret;
2585     struct AsnDecodeSequenceItem items[] = {
2586      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2587        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2588        offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2589      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2590        CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE,
2591        offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2592     };
2593     PCRYPT_ATTRIBUTE attr = pvStructInfo;
2594 
2595     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2596      pvStructInfo, *pcbStructInfo);
2597 
2598     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2599      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2600      pcbDecoded, attr ? attr->pszObjId : NULL);
2601     TRACE("returning %d\n", ret);
2602     return ret;
2603 }
2604 
2605 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2606  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2607  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2608 {
2609     BOOL ret = FALSE;
2610 
2611     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2612      pDecodePara, pvStructInfo, *pcbStructInfo);
2613 
2614     __TRY
2615     {
2616         DWORD bytesNeeded;
2617 
2618         ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2619          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2620         if (ret)
2621         {
2622             if (!pvStructInfo)
2623                 *pcbStructInfo = bytesNeeded;
2624             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2625              pvStructInfo, pcbStructInfo, bytesNeeded)))
2626             {
2627                 PCRYPT_ATTRIBUTE attr;
2628 
2629                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2630                     pvStructInfo = *(BYTE **)pvStructInfo;
2631                 attr = pvStructInfo;
2632                 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2633                  sizeof(CRYPT_ATTRIBUTE));
2634                 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2635                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2636                  NULL);
2637             }
2638         }
2639     }
2640     __EXCEPT_PAGE_FAULT
2641     {
2642         SetLastError(STATUS_ACCESS_VIOLATION);
2643     }
2644     __ENDTRY
2645     TRACE("returning %d\n", ret);
2646     return ret;
2647 }
2648 
2649 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2650  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2651  DWORD *pcbDecoded)
2652 {
2653     struct AsnArrayDescriptor arrayDesc = { 0,
2654      CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2655      offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2656     PCRYPT_ATTRIBUTES attrs = pvStructInfo;
2657     BOOL ret;
2658 
2659     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2660      NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
2661      NULL);
2662     return ret;
2663 }
2664 
2665 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2666  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2667  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2668 {
2669     BOOL ret = FALSE;
2670 
2671     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2672      pDecodePara, pvStructInfo, *pcbStructInfo);
2673 
2674     __TRY
2675     {
2676         DWORD bytesNeeded;
2677 
2678         if (!cbEncoded)
2679             SetLastError(CRYPT_E_ASN1_EOD);
2680         else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
2681             SetLastError(CRYPT_E_ASN1_CORRUPT);
2682         else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2683          cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2684          NULL)))
2685         {
2686             if (!pvStructInfo)
2687                 *pcbStructInfo = bytesNeeded;
2688             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2689              pvStructInfo, pcbStructInfo, bytesNeeded)))
2690             {
2691                 PCRYPT_ATTRIBUTES attrs;
2692 
2693                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2694                     pvStructInfo = *(BYTE **)pvStructInfo;
2695                 attrs = pvStructInfo;
2696                 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
2697                  sizeof(CRYPT_ATTRIBUTES));
2698                 ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2699                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2700                  &bytesNeeded, NULL);
2701             }
2702         }
2703     }
2704     __EXCEPT_PAGE_FAULT
2705     {
2706         SetLastError(STATUS_ACCESS_VIOLATION);
2707     }
2708     __ENDTRY
2709     TRACE("returning %d\n", ret);
2710     return ret;
2711 }
2712 
2713 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2714  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2715 {
2716     CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2717     BOOL ret = TRUE;
2718     struct AsnDecodeSequenceItem items[] = {
2719      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2720        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2721        offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2722      { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2723        CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE, 
2724        offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2725     };
2726 
2727     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2728      pvStructInfo, *pcbStructInfo, pcbDecoded);
2729 
2730     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2731      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2732      pcbDecoded, algo ? algo->pszObjId : NULL);
2733     if (ret && pvStructInfo)
2734     {
2735         TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2736          debugstr_a(algo->pszObjId));
2737     }
2738     return ret;
2739 }
2740 
2741 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2742  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2743  DWORD *pcbDecoded)
2744 {
2745     BOOL ret = TRUE;
2746     struct AsnDecodeSequenceItem items[] = {
2747      { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2748        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2749        FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2750        Algorithm.pszObjId) },
2751      { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2752        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2753        offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2754     };
2755     PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2756 
2757     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2758      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2759      pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2760     return ret;
2761 }
2762 
2763 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2764  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2765  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2766 {
2767     BOOL ret = TRUE;
2768 
2769     __TRY
2770     {
2771         DWORD bytesNeeded;
2772 
2773         if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2774          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2775         {
2776             if (!pvStructInfo)
2777                 *pcbStructInfo = bytesNeeded;
2778             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2779              pvStructInfo, pcbStructInfo, bytesNeeded)))
2780             {
2781                 PCERT_PUBLIC_KEY_INFO info;
2782 
2783                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2784                     pvStructInfo = *(BYTE **)pvStructInfo;
2785                 info = pvStructInfo;
2786                 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2787                  sizeof(CERT_PUBLIC_KEY_INFO);
2788                 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2789                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2790                  &bytesNeeded, NULL);
2791             }
2792         }
2793     }
2794     __EXCEPT_PAGE_FAULT
2795     {
2796         SetLastError(STATUS_ACCESS_VIOLATION);
2797         ret = FALSE;
2798     }
2799     __ENDTRY
2800     return ret;
2801 }
2802 
2803 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2804  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2805 {
2806     BOOL ret;
2807 
2808     if (cbEncoded < 3)
2809     {
2810         SetLastError(CRYPT_E_ASN1_CORRUPT);
2811         return FALSE;
2812     }
2813     if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2814     {
2815         SetLastError(CRYPT_E_ASN1_CORRUPT);
2816         return FALSE;
2817     }
2818     if (pbEncoded[1] > 1)
2819     {
2820         SetLastError(CRYPT_E_ASN1_CORRUPT);
2821         return FALSE;
2822     }
2823     if (pcbDecoded)
2824         *pcbDecoded = 3;
2825     if (!pvStructInfo)
2826     {
2827         *pcbStructInfo = sizeof(BOOL);
2828         ret = TRUE;
2829     }
2830     else if (*pcbStructInfo < sizeof(BOOL))
2831     {
2832         *pcbStructInfo = sizeof(BOOL);
2833         SetLastError(ERROR_MORE_DATA);
2834         ret = FALSE;
2835     }
2836     else
2837     {
2838         *pcbStructInfo = sizeof(BOOL);
2839         *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2840         ret = TRUE;
2841     }
2842     TRACE("returning %d (%08x)\n", ret, GetLastError());
2843     return ret;
2844 }
2845 
2846 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2847  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2848 {
2849     PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2850     DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2851     BOOL ret;
2852 
2853     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2854      pvStructInfo, *pcbStructInfo);
2855 
2856     if (cbEncoded < 2)
2857     {
2858         SetLastError(CRYPT_E_ASN1_CORRUPT);
2859         return FALSE;
2860     }
2861     lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2862     if (1 + lenBytes > cbEncoded)
2863     {
2864         SetLastError(CRYPT_E_ASN1_CORRUPT);
2865         return FALSE;
2866     }
2867     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2868     {
2869         switch (pbEncoded[0] & ASN_TYPE_MASK)
2870         {
2871         case 1: /* rfc822Name */
2872         case 2: /* dNSName */
2873         case 6: /* uniformResourceIdentifier */
2874             bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2875             break;
2876         case 4: /* directoryName */
2877         case 7: /* iPAddress */
2878             bytesNeeded += dataLen;
2879             break;
2880         case 8: /* registeredID */
2881             ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2882              &dataLen, NULL);
2883             if (ret)
2884             {
2885                 /* FIXME: ugly, shouldn't need to know internals of OID decode
2886                  * function to use it.
2887                  */
2888                 bytesNeeded += dataLen - sizeof(LPSTR);
2889             }
2890             break;
2891         case 0: /* otherName */
2892             FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2893             SetLastError(CRYPT_E_ASN1_BADTAG);
2894             ret = FALSE;
2895             break;
2896         case 3: /* x400Address, unimplemented */
2897         case 5: /* ediPartyName, unimplemented */
2898             TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2899             SetLastError(CRYPT_E_ASN1_BADTAG);
2900             ret = FALSE;
2901             break;
2902         default:
2903             TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2904             SetLastError(CRYPT_E_ASN1_CORRUPT);
2905             ret = FALSE;
2906         }
2907         if (ret)
2908         {
2909             if (pcbDecoded)
2910                 *pcbDecoded = 1 + lenBytes + dataLen;
2911             if (!entry)
2912                 *pcbStructInfo = bytesNeeded;
2913             else if (*pcbStructInfo < bytesNeeded)
2914             {
2915                 *pcbStructInfo = bytesNeeded;
2916                 SetLastError(ERROR_MORE_DATA);
2917                 ret = FALSE;
2918             }
2919             else
2920             {
2921                 *pcbStructInfo = bytesNeeded;
2922                 /* MS used values one greater than the asn1 ones.. sigh */
2923                 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
2924                 switch (pbEncoded[0] & ASN_TYPE_MASK)
2925                 {
2926                 case 1: /* rfc822Name */
2927                 case 2: /* dNSName */
2928                 case 6: /* uniformResourceIdentifier */
2929                 {
2930                     DWORD i;
2931 
2932                     for (i = 0; i < dataLen; i++)
2933                         entry->u.pwszURL[i] =
2934                          (WCHAR)pbEncoded[1 + lenBytes + i];
2935                     entry->u.pwszURL[i] = 0;
2936                     TRACE("URL is %p (%s)\n", entry->u.pwszURL,
2937                      debugstr_w(entry->u.pwszURL));
2938                     break;
2939                 }
2940                 case 4: /* directoryName */
2941                     /* The data are memory-equivalent with the IPAddress case,
2942                      * fall-through
2943                      */
2944                 case 7: /* iPAddress */
2945                     /* The next data pointer is in the pwszURL spot, that is,
2946                      * the first 4 bytes.  Need to move it to the next spot.
2947                      */
2948                     entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
2949                     entry->u.IPAddress.cbData = dataLen;
2950                     memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
2951                      dataLen);
2952                     break;
2953                 case 8: /* registeredID */
2954                     ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
2955                      &entry->u.pszRegisteredID, &dataLen, NULL);
2956                     break;
2957                 }
2958             }
2959         }
2960     }
2961     return ret;
2962 }
2963 
2964 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
2965  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2966  DWORD *pcbDecoded)
2967 {
2968     BOOL ret = TRUE;
2969     struct AsnArrayDescriptor arrayDesc = { 0,
2970      CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
2971      offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
2972     PCERT_ALT_NAME_INFO info = pvStructInfo;
2973 
2974     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2975      pvStructInfo, *pcbStructInfo, pcbDecoded);
2976 
2977     if (info)
2978         TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
2979     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2980      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2981      info ? info->rgAltEntry : NULL);
2982     return ret;
2983 }
2984 
2985 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2986 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
2987  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2988  DWORD *pcbDecoded)
2989 {
2990     BOOL ret;
2991 
2992     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
2993      pvStructInfo, *pcbStructInfo, pcbDecoded);
2994 
2995     /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2996      * place.
2997      */
2998     ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
2999      dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
3000      pcbDecoded);
3001     if (ret && pvStructInfo)
3002     {
3003         CRYPT_DATA_BLOB *blob = pvStructInfo;
3004 
3005         if (blob->cbData)
3006         {
3007             DWORD i;
3008             BYTE temp;
3009 
3010             for (i = 0; i < blob->cbData / 2; i++)
3011             {
3012                 temp = blob->pbData[i];
3013                 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
3014                 blob->pbData[blob->cbData - i - 1] = temp;
3015             }
3016         }
3017     }
3018     TRACE("returning %d (%08x)\n", ret, GetLastError());
3019     return ret;
3020 }
3021 
3022 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3023  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3024  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3025 {
3026     BOOL ret;
3027 
3028     __TRY
3029     {
3030         struct AsnDecodeSequenceItem items[] = {
3031          { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3032            CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3033            TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3034          { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3035            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3036            CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3037            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3038          { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3039            CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3040            sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3041            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3042         };
3043 
3044         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3045          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3046          pcbStructInfo, NULL, NULL);
3047     }
3048     __EXCEPT_PAGE_FAULT
3049     {
3050         SetLastError(STATUS_ACCESS_VIOLATION);
3051         ret = FALSE;
3052     }
3053     __ENDTRY
3054     return ret;
3055 }
3056 
3057 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3058  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3059  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3060 {
3061     BOOL ret;
3062 
3063     __TRY
3064     {
3065         struct AsnDecodeSequenceItem items[] = {
3066          { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3067            CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3068            TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3069          { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3070            offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3071            CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3072            TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3073            AuthorityCertIssuer.rgAltEntry), 0 },
3074          { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3075            AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3076            sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3077            offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3078            AuthorityCertSerialNumber.pbData), 0 },
3079         };
3080 
3081         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3082          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3083          pcbStructInfo, NULL, NULL);
3084     }
3085     __EXCEPT_PAGE_FAULT
3086     {
3087         SetLastError(STATUS_ACCESS_VIOLATION);
3088         ret = FALSE;
3089     }
3090     __ENDTRY
3091     return ret;
3092 }
3093 
3094 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3095  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3096  DWORD *pcbDecoded)
3097 {
3098     struct AsnDecodeSequenceItem items[] = {
3099      { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3100        CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3101        offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3102      { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3103        CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3104        TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3105     };
3106     CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3107 
3108     return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3109      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3110      pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3111 }
3112 
3113 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3114  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3115  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3116 {
3117     BOOL ret;
3118 
3119     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3120      pDecodePara, pvStructInfo, *pcbStructInfo);
3121 
3122     __TRY
3123     {
3124         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3125          CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3126          TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3127 
3128         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3129          pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
3130     }
3131     __EXCEPT_PAGE_FAULT
3132     {
3133         SetLastError(STATUS_ACCESS_VIOLATION);
3134         ret = FALSE;
3135     }
3136     __ENDTRY
3137     return ret;
3138 }
3139 
3140 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3141  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3142 {
3143     BOOL ret;
3144     DWORD dataLen;
3145 
3146     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3147      pvStructInfo, *pcbStructInfo, pcbDecoded);
3148 
3149     /* The caller has already checked the tag, no need to check it again.
3150      * Check the outer length is valid:
3151      */
3152     if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3153     {
3154         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3155         DWORD innerLen;
3156 
3157         pbEncoded += 1 + lenBytes;
3158         cbEncoded -= 1 + lenBytes;
3159         if (dataLen == CMSG_INDEFINITE_LENGTH)
3160             cbEncoded -= 2; /* space for 0 TLV */
3161         /* Check the inner length is valid: */
3162         if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3163         {
3164             DWORD decodedLen;
3165 
3166             ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3167              pvStructInfo, pcbStructInfo, &decodedLen);
3168             if (dataLen == CMSG_INDEFINITE_LENGTH)
3169             {
3170                 if (*(pbEncoded + decodedLen) != 0 ||
3171                  *(pbEncoded + decodedLen + 1) != 0)
3172                 {
3173                     TRACE("expected 0 TLV, got {%02x,%02x}\n",
3174                      *(pbEncoded + decodedLen),
3175                      *(pbEncoded + decodedLen + 1));
3176                     SetLastError(CRYPT_E_ASN1_CORRUPT);
3177                     ret = FALSE;
3178                 }
3179                 else
3180                     decodedLen += 2;
3181             }
3182             if (ret && pcbDecoded)
3183             {
3184                 *pcbDecoded = 1 + lenBytes + decodedLen;
3185                 TRACE("decoded %d bytes\n", *pcbDecoded);
3186             }
3187         }
3188     }
3189     return ret;
3190 }
3191 
3192 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3193  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3194  DWORD *pcbDecoded)
3195 {
3196     CRYPT_CONTENT_INFO *info = pvStructInfo;
3197     struct AsnDecodeSequenceItem items[] = {
3198      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3199        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3200        offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3201      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3202        offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3203        sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3204        offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3205     };
3206     BOOL ret;
3207 
3208     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3209      pvStructInfo, *pcbStructInfo, pcbDecoded);
3210 
3211     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3212      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3213      pcbDecoded, info ? info->pszObjId : NULL);
3214     return ret;
3215 }
3216 
3217 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3218  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3219  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3220 {
3221     BOOL ret = FALSE;
3222 
3223     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3224      pDecodePara, pvStructInfo, *pcbStructInfo);
3225 
3226     __TRY
3227     {
3228         ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3229          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3230         if (ret && pvStructInfo)
3231         {
3232             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3233              pcbStructInfo, *pcbStructInfo);
3234             if (ret)
3235             {
3236                 CRYPT_CONTENT_INFO *info;
3237 
3238                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3239                     pvStructInfo = *(BYTE **)pvStructInfo;
3240                 info = pvStructInfo;
3241                 info->pszObjId = (LPSTR)((BYTE *)info +
3242                  sizeof(CRYPT_CONTENT_INFO));
3243                 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3244                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3245                  pcbStructInfo, NULL);
3246             }
3247         }
3248     }
3249     __EXCEPT_PAGE_FAULT
3250     {
3251         SetLastError(STATUS_ACCESS_VIOLATION);
3252     }
3253     __ENDTRY
3254     return ret;
3255 }
3256 
3257 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3258  DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3259  CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3260 {
3261     BOOL ret;
3262     struct AsnDecodeSequenceItem items[] = {
3263      { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3264        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3265      { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3266        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3267        FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3268        0 },
3269      { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3270        CRYPT_AsnDecodePKCSContentInfoInternal,
3271        sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3272        ContentInfo.pszObjId), 0 },
3273      { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3274        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3275        offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3276     };
3277 
3278     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3279      pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3280      NULL, NULL);
3281     return ret;
3282 }
3283 
3284 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3285  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3286<