~ [ 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 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
100  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
101 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
102  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
103 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
104  * member has been initialized, doesn't do exception handling, and doesn't do
105  * memory allocation.  Also doesn't check tag, assumes the caller has checked
106  * it.
107  */
108 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
109  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
110  DWORD *pcbDecoded);
111 /* Like CRYPT_AsnDecodeInteger, but unsigned.  */
112 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
113  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
114  DWORD *pcbDecoded);
115 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
116  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
117  DWORD *pcbDecoded);
118 
119 /* Gets the number of length bytes from the given (leading) length byte */
120 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
121 
122 /* Helper function to get the encoded length of the data starting at pbEncoded,
123  * where pbEncoded[0] is the tag.  If the data are too short to contain a
124  * length or if the length is too large for cbEncoded, sets an appropriate
125  * error code and returns FALSE.  If the encoded length is unknown due to
126  * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
127  */
128 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
129  DWORD *len)
130 {
131     BOOL ret;
132 
133     if (cbEncoded <= 1)
134     {
135         SetLastError(CRYPT_E_ASN1_CORRUPT);
136         ret = FALSE;
137     }
138     else if (pbEncoded[1] <= 0x7f)
139     {
140         if (pbEncoded[1] + 1 > cbEncoded)
141         {
142             SetLastError(CRYPT_E_ASN1_EOD);
143             ret = FALSE;
144         }
145         else
146         {
147             *len = pbEncoded[1];
148             ret = TRUE;
149         }
150     }
151     else if (pbEncoded[1] == 0x80)
152     {
153         *len = CMSG_INDEFINITE_LENGTH;
154         ret = TRUE;
155     }
156     else
157     {
158         BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
159 
160         if (lenLen > sizeof(DWORD) + 1)
161         {
162             SetLastError(CRYPT_E_ASN1_LARGE);
163             ret = FALSE;
164         }
165         else if (lenLen + 2 > cbEncoded)
166         {
167             SetLastError(CRYPT_E_ASN1_CORRUPT);
168             ret = FALSE;
169         }
170         else
171         {
172             DWORD out = 0;
173 
174             pbEncoded += 2;
175             while (--lenLen)
176             {
177                 out <<= 8;
178                 out |= *pbEncoded++;
179             }
180             if (out + lenLen + 1 > cbEncoded)
181             {
182                 SetLastError(CRYPT_E_ASN1_EOD);
183                 ret = FALSE;
184             }
185             else
186             {
187                 *len = out;
188                 ret = TRUE;
189             }
190         }
191     }
192     return ret;
193 }
194 
195 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
196 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
197 {
198     BOOL ret;
199 
200     if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
201      *len == CMSG_INDEFINITE_LENGTH)
202     {
203         SetLastError(CRYPT_E_ASN1_CORRUPT);
204         ret = FALSE;
205     }
206     return ret;
207 }
208 
209 /* Helper function to check *pcbStructInfo, set it to the required size, and
210  * optionally to allocate memory.  Assumes pvStructInfo is not NULL.
211  * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
212  * pointer to the newly allocated memory.
213  */
214 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
215  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
216  DWORD bytesNeeded)
217 {
218     BOOL ret = TRUE;
219 
220     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
221     {
222         if (pDecodePara && pDecodePara->pfnAlloc)
223             *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
224         else
225             *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
226         if (!*(BYTE **)pvStructInfo)
227             ret = FALSE;
228         else
229             *pcbStructInfo = bytesNeeded;
230     }
231     else if (*pcbStructInfo < bytesNeeded)
232     {
233         *pcbStructInfo = bytesNeeded;
234         SetLastError(ERROR_MORE_DATA);
235         ret = FALSE;
236     }
237     else
238         *pcbStructInfo = bytesNeeded;
239     return ret;
240 }
241 
242 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara, LPVOID pv)
243 {
244     if (pDecodePara && pDecodePara->pfnFree)
245         pDecodePara->pfnFree(pv);
246     else
247         LocalFree(pv);
248 }
249 
250 /* Helper function to check *pcbStructInfo and set it to the required size.
251  * Assumes pvStructInfo is not NULL.
252  */
253 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
254 {
255     BOOL ret;
256 
257     if (*pcbStructInfo < bytesNeeded)
258     {
259         *pcbStructInfo = bytesNeeded;
260         SetLastError(ERROR_MORE_DATA);
261         ret = FALSE;
262     }
263     else
264     {
265         *pcbStructInfo = bytesNeeded;
266         ret = TRUE;
267     }
268     return ret;
269 }
270 
271 /* tag:
272  *     The expected tag of the item.  If tag is 0, decodeFunc is called
273  *     regardless of the tag value seen.
274  * offset:
275  *     A sequence is decoded into a struct.  The offset member is the
276  *     offset of this item within that struct.
277  * decodeFunc:
278  *     The decoder function to use.  If this is NULL, then the member isn't
279  *     decoded, but minSize space is reserved for it.
280  * minSize:
281  *     The minimum amount of space occupied after decoding.  You must set this.
282  * optional:
283  *     If true, and the tag doesn't match the expected tag for this item,
284  *     or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
285  *     filled with 0 for this member.
286  * hasPointer, pointerOffset:
287  *     If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
288  *     the offset within the struct of the data pointer (or to the
289  *     first data pointer, if more than one exist).
290  * size:
291  *     Used by CRYPT_AsnDecodeSequence, not for your use.
292  */
293 struct AsnDecodeSequenceItem
294 {
295     BYTE               tag;
296     DWORD              offset;
297     InternalDecodeFunc decodeFunc;
298     DWORD              minSize;
299     BOOL               optional;
300     BOOL               hasPointer;
301     DWORD              pointerOffset;
302     DWORD              size;
303 };
304 
305 /* Decodes the items in a sequence, where the items are described in items,
306  * the encoded data are in pbEncoded with length cbEncoded.  Decodes into
307  * pvStructInfo.  nextData is a pointer to the memory location at which the
308  * first decoded item with a dynamic pointer should point.
309  * Upon decoding, *cbDecoded is the total number of bytes decoded.
310  * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
311  */
312 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
313  DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
314  void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
315 {
316     BOOL ret;
317     DWORD i, decoded = 0;
318     const BYTE *ptr = pbEncoded;
319 
320     TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
321      cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
322 
323     for (i = 0, ret = TRUE; ret && i < cItem; i++)
324     {
325         if (cbEncoded - (ptr - pbEncoded) != 0)
326         {
327             DWORD itemLen;
328 
329             if ((ret = CRYPT_GetLengthIndefinite(ptr,
330              cbEncoded - (ptr - pbEncoded), &itemLen)))
331             {
332                 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
333 
334                 if (ptr[0] == items[i].tag || !items[i].tag)
335                 {
336                     DWORD itemEncodedLen;
337 
338                     if (itemLen == CMSG_INDEFINITE_LENGTH)
339                         itemEncodedLen = cbEncoded - (ptr - pbEncoded);
340                     else
341                         itemEncodedLen = 1 + itemLenBytes + itemLen;
342                     if (nextData && pvStructInfo && items[i].hasPointer)
343                     {
344                         TRACE("Setting next pointer to %p\n",
345                          nextData);
346                         *(BYTE **)((BYTE *)pvStructInfo +
347                          items[i].pointerOffset) = nextData;
348                     }
349                     if (items[i].decodeFunc)
350                     {
351                         DWORD itemDecoded;
352 
353                         if (pvStructInfo)
354                             TRACE("decoding item %d\n", i);
355                         else
356                             TRACE("sizing item %d\n", i);
357                         ret = items[i].decodeFunc(ptr, itemEncodedLen,
358                          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
359                          pvStructInfo ?  (BYTE *)pvStructInfo + items[i].offset
360                          : NULL, &items[i].size, &itemDecoded);
361                         if (ret)
362                         {
363                             /* Account for alignment padding */
364                             if (items[i].size % sizeof(DWORD_PTR))
365                                 items[i].size += sizeof(DWORD_PTR) -
366                                  items[i].size % sizeof(DWORD_PTR);
367                             TRACE("item %d size: %d\n", i, items[i].size);
368                             if (nextData && items[i].hasPointer &&
369                              items[i].size > items[i].minSize)
370                                 nextData += items[i].size - items[i].minSize;
371                             if (itemDecoded > itemEncodedLen)
372                             {
373                                 WARN("decoded length %d exceeds encoded %d\n",
374                                  itemDecoded, itemEncodedLen);
375                                 SetLastError(CRYPT_E_ASN1_CORRUPT);
376                                 ret = FALSE;
377                             }
378                             else
379                             {
380                                 if (itemLen == CMSG_INDEFINITE_LENGTH)
381                                 {
382                                     if (itemDecoded > itemEncodedLen - 2 ||
383                                      *(ptr + itemDecoded) != 0 ||
384                                      *(ptr + itemDecoded + 1) != 0)
385                                     {
386                                         TRACE("expected 0 TLV\n");
387                                         SetLastError(CRYPT_E_ASN1_CORRUPT);
388                                         ret = FALSE;
389                                     }
390                                     else
391                                         itemDecoded += 2;
392                                 }
393                                 if (ret)
394                                 {
395                                     ptr += itemDecoded;
396                                     decoded += itemDecoded;
397                                     TRACE("item %d: decoded %d bytes\n", i,
398                                      itemDecoded);
399                                 }
400                             }
401                         }
402                         else if (items[i].optional &&
403                          GetLastError() == CRYPT_E_ASN1_BADTAG)
404                         {
405                             TRACE("skipping optional item %d\n", i);
406                             items[i].size = items[i].minSize;
407                             SetLastError(NOERROR);
408                             ret = TRUE;
409                         }
410                         else
411                             TRACE("item %d failed: %08x\n", i,
412                              GetLastError());
413                     }
414                     else if (itemLen == CMSG_INDEFINITE_LENGTH)
415                     {
416                         ERR("can't use indefinite length encoding without a decoder\n");
417                         SetLastError(CRYPT_E_ASN1_CORRUPT);
418                         ret = FALSE;
419                     }
420                     else
421                     {
422                         TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
423                         ptr += itemEncodedLen;
424                         decoded += itemEncodedLen;
425                         items[i].size = items[i].minSize;
426                     }
427                 }
428                 else if (items[i].optional)
429                 {
430                     TRACE("skipping optional item %d\n", i);
431                     items[i].size = items[i].minSize;
432                 }
433                 else
434                 {
435                     TRACE("item %d: tag %02x doesn't match expected %02x\n",
436                      i, ptr[0], items[i].tag);
437                     SetLastError(CRYPT_E_ASN1_BADTAG);
438                     ret = FALSE;
439                 }
440             }
441         }
442         else if (items[i].optional)
443         {
444             TRACE("missing optional item %d, skipping\n", i);
445             items[i].size = items[i].minSize;
446         }
447         else
448         {
449             TRACE("not enough bytes for item %d, failing\n", i);
450             SetLastError(CRYPT_E_ASN1_CORRUPT);
451             ret = FALSE;
452         }
453     }
454     if (cbDecoded)
455         *cbDecoded = decoded;
456     TRACE("returning %d\n", ret);
457     return ret;
458 }
459 
460 /* This decodes an arbitrary sequence into a contiguous block of memory
461  * (basically, a struct.)  Each element being decoded is described by a struct
462  * AsnDecodeSequenceItem, see above.
463  * startingPointer is an optional pointer to the first place where dynamic
464  * data will be stored.  If you know the starting offset, you may pass it
465  * here.  Otherwise, pass NULL, and one will be inferred from the items.
466  */
467 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
468  DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
469  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
470  DWORD *pcbDecoded, void *startingPointer)
471 {
472     BOOL ret;
473 
474     TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
475      cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
476      startingPointer);
477 
478     if (pbEncoded[0] == ASN_SEQUENCE)
479     {
480         DWORD dataLen;
481 
482         if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
483         {
484             DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
485             const BYTE *ptr = pbEncoded + 1 + lenBytes;
486             BOOL indefinite = FALSE;
487 
488             cbEncoded -= 1 + lenBytes;
489             if (dataLen == CMSG_INDEFINITE_LENGTH)
490             {
491                 dataLen = cbEncoded;
492                 indefinite = TRUE;
493             }
494             else if (cbEncoded < dataLen)
495             {
496                 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
497                  cbEncoded);
498                 SetLastError(CRYPT_E_ASN1_CORRUPT);
499                 ret = FALSE;
500             }
501             if (ret)
502             {
503                 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
504                  ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
505                 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
506                 {
507                     if (cbDecoded > cbEncoded - 2)
508                     {
509                         /* Not enough space for 0 TLV */
510                         SetLastError(CRYPT_E_ASN1_CORRUPT);
511                         ret = FALSE;
512                     }
513                     else if (*(ptr + cbDecoded) != 0 ||
514                      *(ptr + cbDecoded + 1) != 0)
515                     {
516                         TRACE("expected 0 TLV\n");
517                         SetLastError(CRYPT_E_ASN1_CORRUPT);
518                         ret = FALSE;
519                     }
520                     else
521                         cbDecoded += 2;
522                 }
523             }
524             if (ret && !indefinite && cbDecoded != dataLen)
525             {
526                 TRACE("expected %d decoded, got %d, failing\n", dataLen,
527                  cbDecoded);
528                 SetLastError(CRYPT_E_ASN1_CORRUPT);
529                 ret = FALSE;
530             }
531             if (ret)
532             {
533                 DWORD i, bytesNeeded = 0, structSize = 0;
534 
535                 for (i = 0; i < cItem; i++)
536                 {
537                     bytesNeeded += items[i].size;
538                     structSize += items[i].minSize;
539                 }
540                 if (pcbDecoded)
541                     *pcbDecoded = 1 + lenBytes + cbDecoded;
542                 if (!pvStructInfo)
543                     *pcbStructInfo = bytesNeeded;
544                 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
545                  pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
546                 {
547                     BYTE *nextData;
548 
549                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
550                         pvStructInfo = *(BYTE **)pvStructInfo;
551                     if (startingPointer)
552                         nextData = (BYTE *)startingPointer;
553                     else
554                         nextData = (BYTE *)pvStructInfo + structSize;
555                     memset(pvStructInfo, 0, structSize);
556                     ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
557                      ptr, dataLen, dwFlags, pvStructInfo, nextData,
558                      &cbDecoded);
559                     if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
560                         CRYPT_FreeSpace(pDecodePara, pvStructInfo);
561                 }
562             }
563         }
564     }
565     else
566     {
567         SetLastError(CRYPT_E_ASN1_BADTAG);
568         ret = FALSE;
569     }
570     TRACE("returning %d (%08x)\n", ret, GetLastError());
571     return ret;
572 }
573 
574 /* tag:
575  *     The expected tag of the entire encoded array (usually a variant
576  *     of ASN_SETOF or ASN_SEQUENCEOF.)  If tag is 0, decodeFunc is called
577  *     regardless of the tag seen.
578  * decodeFunc:
579  *     used to decode each item in the array
580  * itemSize:
581  *      is the minimum size of each decoded item
582  * hasPointer:
583  *      indicates whether each item has a dynamic pointer
584  * pointerOffset:
585  *     indicates the offset within itemSize at which the pointer exists
586  */
587 struct AsnArrayDescriptor
588 {
589     BYTE               tag;
590     InternalDecodeFunc decodeFunc;
591     DWORD              itemSize;
592     BOOL               hasPointer;
593     DWORD              pointerOffset;
594 };
595 
596 struct AsnArrayItemSize
597 {
598     DWORD encodedLen;
599     DWORD size;
600 };
601 
602 /* Decodes an array of like types into a struct GenericArray.
603  * The layout and decoding of the array are described by a struct
604  * AsnArrayDescriptor.
605  */
606 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
607  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
608  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
609  DWORD *pcbDecoded, void *startingPointer)
610 {
611     BOOL ret = TRUE;
612 
613     TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
614      cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
615      startingPointer);
616 
617     if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
618     {
619         DWORD dataLen;
620 
621         if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
622         {
623             DWORD bytesNeeded, cItems = 0, decoded;
624             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
625             /* There can be arbitrarily many items, but there is often only one.
626              */
627             struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
628 
629             decoded = 1 + lenBytes;
630             bytesNeeded = sizeof(struct GenericArray);
631             if (dataLen)
632             {
633                 const BYTE *ptr;
634                 BOOL doneDecoding = FALSE;
635 
636                 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
637                 {
638                     if (dataLen == CMSG_INDEFINITE_LENGTH)
639                     {
640                         if (ptr[0] == 0)
641                         {
642                             doneDecoding = TRUE;
643                             if (ptr[1] != 0)
644                             {
645                                 SetLastError(CRYPT_E_ASN1_CORRUPT);
646                                 ret = FALSE;
647                             }
648                             else
649                                 decoded += 2;
650                         }
651                     }
652                     else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
653                         doneDecoding = TRUE;
654                     if (!doneDecoding)
655                     {
656                         DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
657 
658                         /* Each item decoded may not tolerate extraneous bytes,
659                          * so get the length of the next element if known.
660                          */
661                         if ((ret = CRYPT_GetLengthIndefinite(ptr,
662                          cbEncoded - (ptr - pbEncoded), &itemDataLen)))
663                         {
664                             if (itemDataLen == CMSG_INDEFINITE_LENGTH)
665                                 itemEncoded = cbEncoded - (ptr - pbEncoded);
666                             else
667                                 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
668                                  itemDataLen;
669                         }
670                         if (ret)
671                             ret = arrayDesc->decodeFunc(ptr, itemEncoded,
672                              dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
673                              &itemDecoded);
674                         if (ret)
675                         {
676                             cItems++;
677                             if (itemSizes != &itemSize)
678                                 itemSizes = CryptMemRealloc(itemSizes,
679                                  cItems * sizeof(struct AsnArrayItemSize));
680                             else if (cItems > 1)
681                             {
682                                 itemSizes =
683                                  CryptMemAlloc(
684                                  cItems * sizeof(struct AsnArrayItemSize));
685                                 if (itemSizes)
686                                     memcpy(itemSizes, &itemSize,
687                                      sizeof(itemSize));
688                             }
689                             if (itemSizes)
690                             {
691                                 decoded += itemDecoded;
692                                 itemSizes[cItems - 1].encodedLen = itemEncoded;
693                                 itemSizes[cItems - 1].size = size;
694                                 bytesNeeded += size;
695                                 ptr += itemEncoded;
696                             }
697                             else
698                                 ret = FALSE;
699                         }
700                     }
701                 }
702             }
703             if (ret)
704             {
705                 if (pcbDecoded)
706                     *pcbDecoded = decoded;
707                 if (!pvStructInfo)
708                     *pcbStructInfo = bytesNeeded;
709                 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
710                  pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
711                 {
712                     DWORD i;
713                     BYTE *nextData;
714                     const BYTE *ptr;
715                     struct GenericArray *array;
716 
717                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
718                         pvStructInfo = *(BYTE **)pvStructInfo;
719                     array = (struct GenericArray *)pvStructInfo;
720                     array->cItems = cItems;
721                     if (startingPointer)
722                         array->rgItems = startingPointer;
723                     else
724                         array->rgItems = (BYTE *)array +
725                          sizeof(struct GenericArray);
726                     nextData = array->rgItems +
727                      array->cItems * arrayDesc->itemSize;
728                     for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
729                      i < cItems && ptr - pbEncoded - 1 - lenBytes <
730                      dataLen; i++)
731                     {
732                         DWORD itemDecoded;
733 
734                         if (arrayDesc->hasPointer)
735                             *(BYTE **)(array->rgItems + i * arrayDesc->itemSize
736                              + arrayDesc->pointerOffset) = nextData;
737                         ret = arrayDesc->decodeFunc(ptr,
738                          itemSizes[i].encodedLen,
739                          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
740                          array->rgItems + i * arrayDesc->itemSize,
741                          &itemSizes[i].size, &itemDecoded);
742                         if (ret)
743                         {
744                             nextData += itemSizes[i].size - arrayDesc->itemSize;
745                             ptr += itemDecoded;
746                         }
747                     }
748                     if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
749                         CRYPT_FreeSpace(pDecodePara, pvStructInfo);
750                 }
751             }
752             if (itemSizes != &itemSize)
753                 CryptMemFree(itemSizes);
754         }
755     }
756     else
757     {
758         SetLastError(CRYPT_E_ASN1_BADTAG);
759         ret = FALSE;
760     }
761     return ret;
762 }
763 
764 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
765  * pvStructInfo.  The BLOB must be non-empty, otherwise the last error is set
766  * to CRYPT_E_ASN1_CORRUPT.
767  * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
768  * set!
769  */
770 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
771  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
772 {
773     BOOL ret;
774     DWORD dataLen;
775 
776     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
777     {
778         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
779         DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
780        
781         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
782             bytesNeeded += 1 + lenBytes + dataLen;
783 
784         if (pcbDecoded)
785             *pcbDecoded = 1 + lenBytes + dataLen;
786         if (!pvStructInfo)
787             *pcbStructInfo = bytesNeeded;
788         else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
789         {
790             CRYPT_DER_BLOB *blob;
791 
792             if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
793                 pvStructInfo = *(BYTE **)pvStructInfo;
794             blob = (CRYPT_DER_BLOB *)pvStructInfo;
795             blob->cbData = 1 + lenBytes + dataLen;
796             if (blob->cbData)
797             {
798                 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
799                     blob->pbData = (BYTE *)pbEncoded;
800                 else
801                 {
802                     assert(blob->pbData);
803                     memcpy(blob->pbData, pbEncoded, blob->cbData);
804                 }
805             }
806             else
807             {
808                 SetLastError(CRYPT_E_ASN1_CORRUPT);
809                 ret = FALSE;
810             }
811         }
812     }
813     return ret;
814 }
815 
816 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
817 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
818  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
819  DWORD *pcbDecoded)
820 {
821     BOOL ret;
822 
823     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
824      pvStructInfo, *pcbStructInfo, pcbDecoded);
825 
826     /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
827      * place.
828      */
829     ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
830      dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
831      pcbDecoded);
832     if (ret && pvStructInfo)
833     {
834         CRYPT_BIT_BLOB *blob = (CRYPT_BIT_BLOB *)pvStructInfo;
835 
836         if (blob->cbData)
837         {
838             DWORD i;
839             BYTE temp;
840 
841             for (i = 0; i < blob->cbData / 2; i++)
842             {
843                 temp = blob->pbData[i];
844                 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
845                 blob->pbData[blob->cbData - i - 1] = temp;
846             }
847         }
848     }
849     TRACE("returning %d (%08x)\n", ret, GetLastError());
850     return ret;
851 }
852 
853 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
854  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
855  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
856 {
857     BOOL ret = TRUE;
858 
859     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
860      pDecodePara, pvStructInfo, *pcbStructInfo);
861 
862     __TRY
863     {
864         struct AsnDecodeSequenceItem items[] = {
865          { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
866            CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
867            offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
868          { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
869            SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
870            sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
871            offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
872          { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
873            CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
874            offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
875         };
876 
877         if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
878             items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
879         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
880          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
881          pcbStructInfo, NULL, NULL);
882     }
883     __EXCEPT_PAGE_FAULT
884     {
885         SetLastError(STATUS_ACCESS_VIOLATION);
886         ret = FALSE;
887     }
888     __ENDTRY
889 
890     TRACE("Returning %d (%08x)\n", ret, GetLastError());
891     return ret;
892 }
893 
894 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
895  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
896 {
897     BOOL ret;
898     DWORD dataLen;
899 
900     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
901     {
902         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
903 
904         ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
905          dwFlags, pvStructInfo, pcbStructInfo, NULL);
906         if (pcbDecoded)
907             *pcbDecoded = 1 + lenBytes + dataLen;
908     }
909     return ret;
910 }
911 
912 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
913  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
914 {
915     BOOL ret;
916 
917     struct AsnDecodeSequenceItem items[] = {
918      { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
919        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
920      { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
921        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
922     };
923 
924     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
925      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
926      pcbDecoded, NULL);
927     return ret;
928 }
929 
930 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
931  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
932  DWORD *pcbDecoded)
933 {
934     BOOL ret;
935     DWORD dataLen;
936 
937     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
938     {
939         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
940 
941         ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded + 1 + lenBytes,
942          dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
943         if (ret && pcbDecoded)
944             *pcbDecoded = 1 + lenBytes + dataLen;
945     }
946     return ret;
947 }
948 
949 static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
950  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
951  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
952 {
953     BOOL ret = TRUE;
954     struct AsnDecodeSequenceItem items[] = {
955      { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
956        CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
957      { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
958        CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
959        TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
960      { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
961        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
962        FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
963      { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
964        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
965        Issuer.pbData) },
966      { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
967        CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
968        FALSE, 0 },
969      { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
970        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
971        Subject.pbData) },
972      { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
973        CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
974        FALSE, TRUE, offsetof(CERT_INFO,
975        SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
976      { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
977        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
978        offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
979      { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
980        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
981        offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
982      { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
983        CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
984        offsetof(CERT_INFO, rgExtension), 0 },
985     };
986 
987     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
988      pDecodePara, pvStructInfo, *pcbStructInfo);
989 
990     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
991      pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
992      NULL, NULL);
993     if (ret && pvStructInfo)
994     {
995         CERT_INFO *info;
996 
997         if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
998             info = *(CERT_INFO **)pvStructInfo;
999         else
1000             info = (CERT_INFO *)pvStructInfo;
1001         if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1002          !info->Subject.cbData)
1003         {
1004             SetLastError(CRYPT_E_ASN1_CORRUPT);
1005             /* Don't need to deallocate, because it should have failed on the
1006              * first pass (and no memory was allocated.)
1007              */
1008             ret = FALSE;
1009         }
1010     }
1011 
1012     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1013     return ret;
1014 }
1015 
1016 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1017  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1018  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1019 {
1020     BOOL ret = FALSE;
1021 
1022     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1023      pDecodePara, pvStructInfo, *pcbStructInfo);
1024 
1025     __TRY
1026     {
1027         DWORD size = 0;
1028 
1029         /* Unless told not to, first try to decode it as a signed cert. */
1030         if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1031         {
1032             PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1033 
1034             ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1035              X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1036              (BYTE *)&signedCert, &size);
1037             if (ret)
1038             {
1039                 size = 0;
1040                 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1041                  X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1042                  signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1043                  pvStructInfo, pcbStructInfo);
1044                 LocalFree(signedCert);
1045             }
1046         }
1047         /* Failing that, try it as an unsigned cert */
1048         if (!ret)
1049         {
1050             size = 0;
1051             ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1052              X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1053              pDecodePara, pvStructInfo, pcbStructInfo);
1054         }
1055     }
1056     __EXCEPT_PAGE_FAULT
1057     {
1058         SetLastError(STATUS_ACCESS_VIOLATION);
1059     }
1060     __ENDTRY
1061 
1062     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1063     return ret;
1064 }
1065 
1066 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1067  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1068 {
1069     BOOL ret;
1070     struct AsnDecodeSequenceItem items[] = {
1071      { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1072        CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1073        offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1074      { 0, offsetof(CRL_ENTRY, RevocationDate),
1075        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1076      { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1077        CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1078        offsetof(CRL_ENTRY, rgExtension), 0 },
1079     };
1080     PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo;
1081 
1082     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1083      *pcbStructInfo);
1084 
1085     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1086      pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1087      entry ? entry->SerialNumber.pbData : NULL);
1088     if (ret && entry && !entry->SerialNumber.cbData)
1089     {
1090         WARN("empty CRL entry serial number\n");
1091         SetLastError(CRYPT_E_ASN1_CORRUPT);
1092         ret = FALSE;
1093     }
1094     return ret;
1095 }
1096 
1097 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1098  * been set prior to calling.
1099  */
1100 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1101  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1102 {
1103     BOOL ret;
1104     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1105      CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1106      offsetof(CRL_ENTRY, SerialNumber.pbData) };
1107     struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
1108 
1109     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1110      pvStructInfo, *pcbStructInfo, pcbDecoded);
1111 
1112     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1113      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1114      entries ? entries->rgItems : NULL);
1115     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1116     return ret;
1117 }
1118 
1119 static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1120  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1121  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1122 {
1123     struct AsnDecodeSequenceItem items[] = {
1124      { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1125        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1126      { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1127        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1128        FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1129      { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1130        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1131        Issuer.pbData) },
1132      { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1133        sizeof(FILETIME), FALSE, FALSE, 0 },
1134      { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1135        sizeof(FILETIME), TRUE, FALSE, 0 },
1136      { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1137        CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE,
1138        offsetof(CRL_INFO, rgCRLEntry), 0 },
1139      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1140        CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1141        offsetof(CRL_INFO, rgExtension), 0 },
1142     };
1143     BOOL ret = TRUE;
1144 
1145     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1146      pDecodePara, pvStructInfo, *pcbStructInfo);
1147 
1148     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1149      pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1150      NULL, NULL);
1151 
1152     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1153     return ret;
1154 }
1155 
1156 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1157  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1158  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1159 {
1160     BOOL ret = FALSE;
1161 
1162     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1163      pDecodePara, pvStructInfo, *pcbStructInfo);
1164 
1165     __TRY
1166     {
1167         DWORD size = 0;
1168 
1169         /* Unless told not to, first try to decode it as a signed crl. */
1170         if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1171         {
1172             PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1173 
1174             ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1175              X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1176              (BYTE *)&signedCrl, &size);
1177             if (ret)
1178             {
1179                 size = 0;
1180                 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1181                  X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1182                  signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1183                  pvStructInfo, pcbStructInfo);
1184                 LocalFree(signedCrl);
1185             }
1186         }
1187         /* Failing that, try it as an unsigned crl */
1188         if (!ret)
1189         {
1190             size = 0;
1191             ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1192              X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1193              dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1194         }
1195     }
1196     __EXCEPT_PAGE_FAULT
1197     {
1198         SetLastError(STATUS_ACCESS_VIOLATION);
1199     }
1200     __ENDTRY
1201 
1202     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1203     return ret;
1204 }
1205 
1206 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1207  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1208 {
1209     BOOL ret = TRUE;
1210     DWORD dataLen;
1211 
1212     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1213      pvStructInfo, *pcbStructInfo);
1214 
1215     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1216     {
1217         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1218         DWORD bytesNeeded = sizeof(LPSTR);
1219 
1220         if (dataLen)
1221         {
1222             /* The largest possible string for the first two components
1223              * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1224              */
1225             char firstTwo[6];
1226             const BYTE *ptr;
1227 
1228             snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1229              pbEncoded[1 + lenBytes] / 40,
1230              pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1231              * 40);
1232             bytesNeeded += strlen(firstTwo) + 1;
1233             for (ptr = pbEncoded + 2 + lenBytes; ret &&
1234              ptr - pbEncoded - 1 - lenBytes < dataLen; )
1235             {
1236                 /* large enough for ".4000000" */
1237                 char str[9];
1238                 int val = 0;
1239 
1240                 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1241                  (*ptr & 0x80))
1242                 {
1243                     val <<= 7;
1244                     val |= *ptr & 0x7f;
1245                     ptr++;
1246                 }
1247                 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1248                  (*ptr & 0x80))
1249                 {
1250                     SetLastError(CRYPT_E_ASN1_CORRUPT);
1251                     ret = FALSE;
1252                 }
1253                 else
1254                 {
1255                     val <<= 7;
1256                     val |= *ptr++;
1257                     snprintf(str, sizeof(str), ".%d", val);
1258                     bytesNeeded += strlen(str);
1259                 }
1260             }
1261         }
1262         if (pcbDecoded)
1263             *pcbDecoded = 1 + lenBytes + dataLen;
1264         if (!pvStructInfo)
1265             *pcbStructInfo = bytesNeeded;
1266         else if (*pcbStructInfo < bytesNeeded)
1267         {
1268             *pcbStructInfo = bytesNeeded;
1269             SetLastError(ERROR_MORE_DATA);
1270             ret = FALSE;
1271         }
1272         else
1273         {
1274             if (dataLen)
1275             {
1276                 const BYTE *ptr;
1277                 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1278 
1279                 *pszObjId = 0;
1280                 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1281                  pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1282                  40) * 40);
1283                 pszObjId += strlen(pszObjId);
1284                 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1285                  ptr - pbEncoded - 1 - lenBytes < dataLen; )
1286                 {
1287                     int val = 0;
1288 
1289                     while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1290                      (*ptr & 0x80))
1291                     {
1292                         val <<= 7;
1293                         val |= *ptr & 0x7f;
1294                         ptr++;
1295                     }
1296                     val <<= 7;
1297                     val |= *ptr++;
1298                     sprintf(pszObjId, ".%d", val);
1299                     pszObjId += strlen(pszObjId);
1300                 }
1301             }
1302             else
1303                 *(LPSTR *)pvStructInfo = NULL;
1304             *pcbStructInfo = bytesNeeded;
1305         }
1306     }
1307     return ret;
1308 }
1309 
1310 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1311  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1312 {
1313     BOOL ret;
1314 
1315     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1316      pvStructInfo, *pcbStructInfo);
1317 
1318     if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1319         ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1320          pvStructInfo, pcbStructInfo, pcbDecoded);
1321     else
1322     {
1323         SetLastError(CRYPT_E_ASN1_BADTAG);
1324         ret = FALSE;
1325     }
1326     return ret;
1327 }
1328 
1329 /* Warning:  assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1330  * ahead of time!
1331  */
1332 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1333  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1334 {
1335     struct AsnDecodeSequenceItem items[] = {
1336      { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1337        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1338        offsetof(CERT_EXTENSION, pszObjId), 0 },
1339      { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1340        sizeof(BOOL), TRUE, FALSE, 0, 0 },
1341      { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1342        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1343        offsetof(CERT_EXTENSION, Value.pbData) },
1344     };
1345     BOOL ret = TRUE;
1346     PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo;
1347 
1348     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1349      *pcbStructInfo);
1350 
1351     if (ext)
1352         TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1353     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1354      pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1355      pcbDecoded, ext ? ext->pszObjId : NULL);
1356     if (ext)
1357         TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1358          debugstr_a(ext->pszObjId));
1359     TRACE("returning %d (%08x)\n", ret, GetLastError());
1360     return ret;
1361 }
1362 
1363 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
1364  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1365  DWORD *pcbDecoded)
1366 {
1367     BOOL ret = TRUE;
1368     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1369      CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1370      offsetof(CERT_EXTENSION, pszObjId) };
1371     PCERT_EXTENSIONS exts = (PCERT_EXTENSIONS)pvStructInfo;
1372 
1373     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1374      pvStructInfo, *pcbStructInfo, pcbDecoded);
1375 
1376     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1377      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1378      exts ? exts->rgExtension : NULL);
1379     return ret;
1380 }
1381 
1382 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1383  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1384  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1385 {
1386     BOOL ret = TRUE;
1387 
1388     __TRY
1389     {
1390         ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1391          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1392         if (ret && pvStructInfo)
1393         {
1394             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1395              pcbStructInfo, *pcbStructInfo);
1396             if (ret)
1397             {
1398                 CERT_EXTENSIONS *exts;
1399 
1400                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1401                     pvStructInfo = *(BYTE **)pvStructInfo;
1402                 exts = (CERT_EXTENSIONS *)pvStructInfo;
1403                 exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
1404                  sizeof(CERT_EXTENSIONS));
1405                 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1406                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1407                  pcbStructInfo, NULL);
1408             }
1409         }
1410     }
1411     __EXCEPT_PAGE_FAULT
1412     {
1413         SetLastError(STATUS_ACCESS_VIOLATION);
1414         ret = FALSE;
1415     }
1416     __ENDTRY
1417     return ret;
1418 }
1419 
1420 /* Warning: this assumes the address of value->Value.pbData is already set, in
1421  * order to avoid overwriting memory.  (In some cases, it may change it, if it
1422  * doesn't copy anything to memory.)  Be sure to set it correctly!
1423  */
1424 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1425  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1426  DWORD *pcbDecoded)
1427 {
1428     BOOL ret = TRUE;
1429     DWORD dataLen;
1430     CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1431 
1432     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1433     {
1434         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1435         DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1436 
1437         switch (pbEncoded[0])
1438         {
1439         case ASN_OCTETSTRING:
1440             valueType = CERT_RDN_OCTET_STRING;
1441             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1442                 bytesNeeded += dataLen;
1443             break;
1444         case ASN_NUMERICSTRING:
1445             valueType = CERT_RDN_NUMERIC_STRING;
1446             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1447                 bytesNeeded += dataLen;
1448             break;
1449         case ASN_PRINTABLESTRING:
1450             valueType = CERT_RDN_PRINTABLE_STRING;
1451             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1452                 bytesNeeded += dataLen;
1453             break;
1454         case ASN_IA5STRING:
1455             valueType = CERT_RDN_IA5_STRING;
1456             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1457                 bytesNeeded += dataLen;
1458             break;
1459         case ASN_T61STRING:
1460             valueType = CERT_RDN_T61_STRING;
1461             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1462                 bytesNeeded += dataLen;
1463             break;
1464         case ASN_VIDEOTEXSTRING:
1465             valueType = CERT_RDN_VIDEOTEX_STRING;
1466             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1467                 bytesNeeded += dataLen;
1468             break;
1469         case ASN_GRAPHICSTRING:
1470             valueType = CERT_RDN_GRAPHIC_STRING;
1471             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1472                 bytesNeeded += dataLen;
1473             break;
1474         case ASN_VISIBLESTRING:
1475             valueType = CERT_RDN_VISIBLE_STRING;
1476             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1477                 bytesNeeded += dataLen;
1478             break;
1479         case ASN_GENERALSTRING:
1480             valueType = CERT_RDN_GENERAL_STRING;
1481             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1482                 bytesNeeded += dataLen;
1483             break;
1484         case ASN_UNIVERSALSTRING:
1485             FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1486             SetLastError(CRYPT_E_ASN1_BADTAG);
1487             return FALSE;
1488         case ASN_BMPSTRING:
1489             valueType = CERT_RDN_BMP_STRING;
1490             bytesNeeded += dataLen;
1491             break;
1492         case ASN_UTF8STRING:
1493             valueType = CERT_RDN_UTF8_STRING;
1494             bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1495              (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1496             break;
1497         default:
1498             SetLastError(CRYPT_E_ASN1_BADTAG);
1499             return FALSE;
1500         }
1501 
1502         if (pcbDecoded)
1503             *pcbDecoded = 1 + lenBytes + dataLen;
1504         if (!value)
1505             *pcbStructInfo = bytesNeeded;
1506         else if (*pcbStructInfo < bytesNeeded)
1507         {
1508             *pcbStructInfo = bytesNeeded;
1509             SetLastError(ERROR_MORE_DATA);
1510             ret = FALSE;
1511         }
1512         else
1513         {
1514             *pcbStructInfo = bytesNeeded;
1515             value->dwValueType = valueType;
1516             if (dataLen)
1517             {
1518                 DWORD i;
1519 
1520                 assert(value->Value.pbData);
1521                 switch (pbEncoded[0])
1522                 {
1523                 case ASN_OCTETSTRING:
1524                 case ASN_NUMERICSTRING:
1525                 case ASN_PRINTABLESTRING:
1526                 case ASN_IA5STRING:
1527                 case ASN_T61STRING:
1528                 case ASN_VIDEOTEXSTRING:
1529                 case ASN_GRAPHICSTRING:
1530                 case ASN_VISIBLESTRING:
1531                 case ASN_GENERALSTRING:
1532                     value->Value.cbData = dataLen;
1533                     if (dataLen)
1534                     {
1535                         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1536                             memcpy(value->Value.pbData,
1537                              pbEncoded + 1 + lenBytes, dataLen);
1538                         else
1539                             value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1540                              lenBytes;
1541                     }
1542                     break;
1543                 case ASN_BMPSTRING:
1544                 {
1545                     LPWSTR str = (LPWSTR)value->Value.pbData;
1546 
1547                     value->Value.cbData = dataLen;
1548                     for (i = 0; i < dataLen / 2; i++)
1549                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1550                          pbEncoded[1 + lenBytes + 2 * i + 1];
1551                     break;
1552                 }
1553                 case ASN_UTF8STRING:
1554                 {
1555                     LPWSTR str = (LPWSTR)value->Value.pbData;
1556 
1557                     value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1558                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, 
1559                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1560                     break;
1561                 }
1562                 }
1563             }
1564             else
1565             {
1566                 value->Value.cbData = 0;
1567                 value->Value.pbData = NULL;
1568             }
1569         }
1570     }
1571     return ret;
1572 }
1573 
1574 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1575  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1576  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1577 {
1578     BOOL ret = TRUE;
1579 
1580     __TRY
1581     {
1582         ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1583          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1584         if (ret && pvStructInfo)
1585         {
1586             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1587              pcbStructInfo, *pcbStructInfo);
1588             if (ret)
1589             {
1590                 CERT_NAME_VALUE *value;
1591 
1592                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1593                     pvStructInfo = *(BYTE **)pvStructInfo;
1594                 value = (CERT_NAME_VALUE *)pvStructInfo;
1595                 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1596                 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1597                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1598                  pcbStructInfo, NULL);
1599             }
1600         }
1601     }
1602     __EXCEPT_PAGE_FAULT
1603     {
1604         SetLastError(STATUS_ACCESS_VIOLATION);
1605         ret = FALSE;
1606     }
1607     __ENDTRY
1608     return ret;
1609 }
1610 
1611 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1612  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1613  DWORD *pcbDecoded)
1614 {
1615     BOOL ret = TRUE;
1616     DWORD dataLen;
1617     CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1618 
1619     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1620     {
1621         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1622         DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1623 
1624         switch (pbEncoded[0])
1625         {
1626         case ASN_NUMERICSTRING:
1627             valueType = CERT_RDN_NUMERIC_STRING;
1628             bytesNeeded += dataLen * 2;
1629             break;
1630         case ASN_PRINTABLESTRING:
1631             valueType = CERT_RDN_PRINTABLE_STRING;
1632             bytesNeeded += dataLen * 2;
1633             break;
1634         case ASN_IA5STRING:
1635             valueType = CERT_RDN_IA5_STRING;
1636             bytesNeeded += dataLen * 2;
1637             break;
1638         case ASN_T61STRING:
1639             valueType = CERT_RDN_T61_STRING;
1640             bytesNeeded += dataLen * 2;
1641             break;
1642         case ASN_VIDEOTEXSTRING:
1643             valueType = CERT_RDN_VIDEOTEX_STRING;
1644             bytesNeeded += dataLen * 2;
1645             break;
1646         case ASN_GRAPHICSTRING:
1647             valueType = CERT_RDN_GRAPHIC_STRING;
1648             bytesNeeded += dataLen * 2;
1649             break;
1650         case ASN_VISIBLESTRING:
1651             valueType = CERT_RDN_VISIBLE_STRING;
1652             bytesNeeded += dataLen * 2;
1653             break;
1654         case ASN_GENERALSTRING:
1655             valueType = CERT_RDN_GENERAL_STRING;
1656             bytesNeeded += dataLen * 2;
1657             break;
1658         case ASN_UNIVERSALSTRING:
1659             valueType = CERT_RDN_UNIVERSAL_STRING;
1660             bytesNeeded += dataLen / 2;
1661             break;
1662         case ASN_BMPSTRING:
1663             valueType = CERT_RDN_BMP_STRING;
1664             bytesNeeded += dataLen;
1665             break;
1666         case ASN_UTF8STRING:
1667             valueType = CERT_RDN_UTF8_STRING;
1668             bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1669              (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1670             break;
1671         default:
1672             SetLastError(CRYPT_E_ASN1_BADTAG);
1673             return FALSE;
1674         }
1675 
1676         if (pcbDecoded)
1677             *pcbDecoded = 1 + lenBytes + dataLen;
1678         if (!value)
1679             *pcbStructInfo = bytesNeeded;
1680         else if (*pcbStructInfo < bytesNeeded)
1681         {
1682             *pcbStructInfo = bytesNeeded;
1683             SetLastError(ERROR_MORE_DATA);
1684             ret = FALSE;
1685         }
1686         else
1687         {
1688             *pcbStructInfo = bytesNeeded;
1689             value->dwValueType = valueType;
1690             if (dataLen)
1691             {
1692                 DWORD i;
1693                 LPWSTR str = (LPWSTR)value->Value.pbData;
1694 
1695                 assert(value->Value.pbData);
1696                 switch (pbEncoded[0])
1697                 {
1698                 case ASN_NUMERICSTRING:
1699                 case ASN_PRINTABLESTRING:
1700                 case ASN_IA5STRING:
1701                 case ASN_T61STRING:
1702                 case ASN_VIDEOTEXSTRING:
1703                 case ASN_GRAPHICSTRING:
1704                 case ASN_VISIBLESTRING:
1705                 case ASN_GENERALSTRING:
1706                     value->Value.cbData = dataLen * 2;
1707                     for (i = 0; i < dataLen; i++)
1708                         str[i] = pbEncoded[1 + lenBytes + i];
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                     break;
1716                 case ASN_BMPSTRING:
1717                     value->Value.cbData = dataLen;
1718                     for (i = 0; i < dataLen / 2; i++)
1719                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1720                          pbEncoded[1 + lenBytes + 2 * i + 1];
1721                     break;
1722                 case ASN_UTF8STRING:
1723                     value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1724                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1725                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1726                     break;
1727                 }
1728             }
1729             else
1730             {
1731                 value->Value.cbData = 0;
1732                 value->Value.pbData = NULL;
1733             }
1734         }
1735     }
1736     return ret;
1737 }
1738 
1739 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1740  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1741  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1742 {
1743     BOOL ret = TRUE;
1744 
1745     __TRY
1746     {
1747         ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1748          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1749         if (ret && pvStructInfo)
1750         {
1751             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1752              pcbStructInfo, *pcbStructInfo);
1753             if (ret)
1754             {
1755                 CERT_NAME_VALUE *value;
1756 
1757                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1758                     pvStructInfo = *(BYTE **)pvStructInfo;
1759                 value = (CERT_NAME_VALUE *)pvStructInfo;
1760                 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1761                 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1762                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1763                  pcbStructInfo, NULL);
1764             }
1765         }
1766     }
1767     __EXCEPT_PAGE_FAULT
1768     {
1769         SetLastError(STATUS_ACCESS_VIOLATION);
1770         ret = FALSE;
1771     }
1772     __ENDTRY
1773     return ret;
1774 }
1775 
1776 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1777  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1778 {
1779     BOOL ret;
1780     struct AsnDecodeSequenceItem items[] = {
1781      { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1782        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1783        offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1784      { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1785        CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1786        FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1787     };
1788     CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1789 
1790     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1791      pvStructInfo, *pcbStructInfo);
1792 
1793     if (attr)
1794         TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1795     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1796      pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1797      attr ? attr->pszObjId : NULL);
1798     if (attr)
1799     {
1800         TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1801          debugstr_a(attr->pszObjId));
1802         TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1803     }
1804     TRACE("returning %d (%08x)\n", ret, GetLastError());
1805     return ret;
1806 }
1807 
1808 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1809  DWORD dwFlags,  void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1810 {
1811     BOOL ret = TRUE;
1812     struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1813      CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1814      offsetof(CERT_RDN_ATTR, pszObjId) };
1815     PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1816 
1817     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1818      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1819      rdn ? rdn->rgRDNAttr : NULL);
1820     return ret;
1821 }
1822 
1823 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1824  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1825  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1826 {
1827     BOOL ret = TRUE;
1828 
1829     __TRY
1830     {
1831         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1832          CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1833          offsetof(CERT_RDN, rgRDNAttr) };
1834 
1835         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1836          pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1837     }
1838     __EXCEPT_PAGE_FAULT
1839     {
1840         SetLastError(STATUS_ACCESS_VIOLATION);
1841         ret = FALSE;
1842     }
1843     __ENDTRY
1844     return ret;
1845 }
1846 
1847 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1848  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1849  DWORD *pcbDecoded)
1850 {
1851     BOOL ret;
1852     struct AsnDecodeSequenceItem items[] = {
1853      { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1854        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1855        offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1856      { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1857        CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1858        FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1859     };
1860     CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1861 
1862     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1863      pvStructInfo, *pcbStructInfo);
1864 
1865     if (attr)
1866         TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1867     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1868      pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1869      attr ? attr->pszObjId : NULL);
1870     if (attr)
1871     {
1872         TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1873          debugstr_a(attr->pszObjId));
1874         TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1875     }
1876     TRACE("returning %d (%08x)\n", ret, GetLastError());
1877     return ret;
1878 }
1879 
1880 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1881  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1882 {
1883     BOOL ret = TRUE;
1884     struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1885      CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1886      offsetof(CERT_RDN_ATTR, pszObjId) };
1887     PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1888 
1889     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1890      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1891      rdn ? rdn->rgRDNAttr : NULL);
1892     return ret;
1893 }
1894 
1895 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1896  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1897  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1898 {
1899     BOOL ret = TRUE;
1900 
1901     __TRY
1902     {
1903         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1904          CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
1905          offsetof(CERT_RDN, rgRDNAttr) };
1906 
1907         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1908          pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1909     }
1910     __EXCEPT_PAGE_FAULT
1911     {
1912         SetLastError(STATUS_ACCESS_VIOLATION);
1913         ret = FALSE;
1914     }
1915     __ENDTRY
1916     return ret;
1917 }
1918 
1919 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
1920  DWORD *pcbDecoded)
1921 {
1922     BOOL ret = TRUE, done = FALSE;
1923     DWORD indefiniteNestingLevels = 0, decoded = 0;
1924 
1925     TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
1926 
1927     do {
1928         DWORD dataLen;
1929 
1930         if (!cbEncoded)
1931             done = TRUE;
1932         else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
1933          &dataLen)))
1934         {
1935             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1936 
1937             if (dataLen == CMSG_INDEFINITE_LENGTH)
1938             {
1939                 indefiniteNestingLevels++;
1940                 pbEncoded += 1 + lenBytes;
1941                 cbEncoded -= 1 + lenBytes;
1942                 decoded += 1 + lenBytes;
1943                 TRACE("indefiniteNestingLevels = %d\n",
1944                  indefiniteNestingLevels);
1945             }
1946             else
1947             {
1948                 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
1949                  indefiniteNestingLevels)
1950                 {
1951                     indefiniteNestingLevels--;
1952                     TRACE("indefiniteNestingLevels = %d\n",
1953                      indefiniteNestingLevels);
1954                 }
1955                 pbEncoded += 1 + lenBytes + dataLen;
1956                 cbEncoded -= 1 + lenBytes + dataLen;
1957                 decoded += 1 + lenBytes + dataLen;
1958                 if (!indefiniteNestingLevels)
1959                     done = TRUE;
1960             }
1961         }
1962     } while (ret && !done);
1963     /* If we haven't found all 0 TLVs, we haven't found the end */
1964     if (ret && indefiniteNestingLevels)
1965     {
1966         SetLastError(CRYPT_E_ASN1_EOD);
1967         ret = FALSE;
1968     }
1969     if (ret)
1970         *pcbDecoded = decoded;
1971     TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
1972     return ret;
1973 }
1974 
1975 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
1976  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1977  DWORD *pcbDecoded)
1978 {
1979     BOOL ret = TRUE;
1980     DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
1981 
1982     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1983      pvStructInfo, *pcbStructInfo);
1984 
1985     if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
1986     {
1987         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1988             bytesNeeded += encodedLen;
1989         if (!pvStructInfo)
1990             *pcbStructInfo = bytesNeeded;
1991         else if (*pcbStructInfo < bytesNeeded)
1992         {
1993             SetLastError(ERROR_MORE_DATA);
1994             *pcbStructInfo = bytesNeeded;
1995             ret = FALSE;
1996         }
1997         else
1998         {
1999             PCRYPT_OBJID_BLOB blob = (PCRYPT_OBJID_BLOB)pvStructInfo;
2000 
2001             *pcbStructInfo = bytesNeeded;
2002             blob->cbData = encodedLen;
2003             if (encodedLen)
2004             {
2005                 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2006                     blob->pbData = (LPBYTE)pbEncoded;
2007                 else
2008                 {
2009                     assert(blob->pbData);
2010                     memcpy(blob->pbData, pbEncoded, blob->cbData);
2011                 }
2012             }
2013             else
2014                 blob->pbData = NULL;
2015         }
2016         if (pcbDecoded)
2017             *pcbDecoded = encodedLen;
2018     }
2019     return ret;
2020 }
2021 
2022 static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded,
2023  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2024 {
2025     BOOL ret;
2026     struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
2027      sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2028     struct GenericArray *array = (struct GenericArray *)pvStructInfo;
2029 
2030     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2031      pvStructInfo, *pcbStructInfo, pcbDecoded);
2032 
2033     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2034      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2035      array ? array->rgItems : NULL);
2036     return ret;
2037 }
2038 
2039 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2040  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2041 {
2042     BOOL ret;
2043     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2044      CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2045     CTL_USAGE *usage = (CTL_USAGE *)pvStructInfo;
2046 
2047     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2048      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2049      usage ? usage->rgpszUsageIdentifier : NULL);
2050     return ret;
2051 }
2052 
2053 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2054  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2055 {
2056     struct AsnDecodeSequenceItem items[] = {
2057      { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2058        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2059        offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2060      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2061        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), FALSE,
2062        TRUE, offsetof(CTL_ENTRY, rgAttribute), 0 },
2063     };
2064     BOOL ret = TRUE;
2065     CTL_ENTRY *entry = (CTL_ENTRY *)pvStructInfo;
2066 
2067     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2068      *pcbStructInfo);
2069 
2070     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2071      pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2072      pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2073     return ret;
2074 }
2075 
2076 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2077  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2078 {
2079     BOOL ret;
2080     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2081      CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2082      offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2083     struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
2084 
2085     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2086      pvStructInfo, *pcbStructInfo, pcbDecoded);
2087 
2088     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2089      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2090      entries ? entries->rgItems : NULL);
2091     return ret;
2092 }
2093 
2094 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2095  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2096  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2097 {
2098     BOOL ret = FALSE;
2099 
2100     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2101      pDecodePara, pvStructInfo, *pcbStructInfo);
2102 
2103     __TRY
2104     {
2105         struct AsnDecodeSequenceItem items[] = {
2106          { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2107            CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2108          { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2109            CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2110            offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2111          { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2112            CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2113            TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2114          { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2115            CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2116            TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2117          { 0, offsetof(CTL_INFO, ThisUpdate),
2118            CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2119            0 },
2120          { 0, offsetof(CTL_INFO, NextUpdate),
2121            CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2122            0 },
2123          { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2124            CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2125            FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2126          { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2127            CRYPT_AsnDecodeCTLEntries, sizeof(struct GenericArray),
2128            TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2129          { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2130            CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
2131            offsetof(CTL_INFO, rgExtension), 0 },
2132         };
2133 
2134         TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2135          pDecodePara, pvStructInfo, *pcbStructInfo);
2136 
2137         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2138          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2139          pcbStructInfo, NULL, NULL);
2140     }
2141     __EXCEPT_PAGE_FAULT
2142     {
2143         SetLastError(STATUS_ACCESS_VIOLATION);
2144     }
2145     __ENDTRY
2146     return ret;
2147 }
2148 
2149 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2150  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2151  DWORD *pcbDecoded)
2152 {
2153     BOOL ret;
2154     struct AsnDecodeSequenceItem items[] = {
2155      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2156        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2157        offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2158      { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2159        CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2160        offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2161     };
2162     PCRYPT_SMIME_CAPABILITY capability = (PCRYPT_SMIME_CAPABILITY)pvStructInfo;
2163 
2164     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2165      pvStructInfo, *pcbStructInfo);
2166 
2167     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2168      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2169      pcbDecoded, capability ? capability->pszObjId : NULL);
2170     TRACE("returning %d\n", ret);
2171     return ret;
2172 }
2173 
2174 static BOOL CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE *pbEncoded,
2175  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2176  DWORD *pcbDecoded)
2177 {
2178     struct AsnArrayDescriptor arrayDesc = { 0,
2179      CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2180      offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2181     PCRYPT_SMIME_CAPABILITIES capabilities =
2182      (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
2183     BOOL ret;
2184 
2185     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2186      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2187      capabilities ? capabilities->rgCapability : NULL);
2188     return ret;
2189 }
2190 
2191 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2192  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2193  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2194 {
2195     BOOL ret = FALSE;
2196 
2197     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2198      pDecodePara, pvStructInfo, *pcbStructInfo);
2199 
2200     __TRY
2201     {
2202         DWORD bytesNeeded;
2203 
2204         if (!cbEncoded)
2205             SetLastError(CRYPT_E_ASN1_EOD);
2206         else if (pbEncoded[0] != ASN_SEQUENCEOF)
2207             SetLastError(CRYPT_E_ASN1_CORRUPT);
2208         else if ((ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2209          cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2210          NULL)))
2211         {
2212             if (!pvStructInfo)
2213                 *pcbStructInfo = bytesNeeded;
2214             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2215              pvStructInfo, pcbStructInfo, bytesNeeded)))
2216             {
2217                 PCRYPT_SMIME_CAPABILITIES capabilities;
2218 
2219                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2220                     pvStructInfo = *(BYTE **)pvStructInfo;
2221                 capabilities = (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
2222                 capabilities->rgCapability =
2223                  (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
2224                  sizeof(CRYPT_SMIME_CAPABILITIES));
2225                 ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2226                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2227                  &bytesNeeded, NULL);
2228             }
2229         }
2230     }
2231     __EXCEPT_PAGE_FAULT
2232     {
2233         SetLastError(STATUS_ACCESS_VIOLATION);
2234     }
2235     __ENDTRY
2236     TRACE("returning %d\n", ret);
2237     return ret;
2238 }
2239 
2240 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2241  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2242  DWORD *pcbDecoded)
2243 {
2244     BOOL ret;
2245     struct AsnDecodeSequenceItem items[] = {
2246      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2247        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2248        offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2249      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2250        CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE,
2251        offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2252     };
2253     PCRYPT_ATTRIBUTE attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2254 
2255     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2256      pvStructInfo, *pcbStructInfo);
2257 
2258     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2259      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2260      pcbDecoded, attr ? attr->pszObjId : NULL);
2261     TRACE("returning %d\n", ret);
2262     return ret;
2263 }
2264 
2265 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2266  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2267  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2268 {
2269     BOOL ret = FALSE;
2270 
2271     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2272      pDecodePara, pvStructInfo, *pcbStructInfo);
2273 
2274     __TRY
2275     {
2276         DWORD bytesNeeded;
2277 
2278         ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2279          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2280         if (ret)
2281         {
2282             if (!pvStructInfo)
2283                 *pcbStructInfo = bytesNeeded;
2284             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2285              pvStructInfo, pcbStructInfo, bytesNeeded)))
2286             {
2287                 PCRYPT_ATTRIBUTE attr;
2288 
2289                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2290                     pvStructInfo = *(BYTE **)pvStructInfo;
2291                 attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2292                 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2293                  sizeof(CRYPT_ATTRIBUTE));
2294                 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2295                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2296                  NULL);
2297             }
2298         }
2299     }
2300     __EXCEPT_PAGE_FAULT
2301     {
2302         SetLastError(STATUS_ACCESS_VIOLATION);
2303     }
2304     __ENDTRY
2305     TRACE("returning %d\n", ret);
2306     return ret;
2307 }
2308 
2309 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2310  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2311  DWORD *pcbDecoded)
2312 {
2313     struct AsnArrayDescriptor arrayDesc = { 0,
2314      CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2315      offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2316     PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2317     BOOL ret;
2318 
2319     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2320      NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
2321      NULL);
2322     return ret;
2323 }
2324 
2325 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2326  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2327  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2328 {
2329     BOOL ret = FALSE;
2330 
2331     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2332      pDecodePara, pvStructInfo, *pcbStructInfo);
2333 
2334     __TRY
2335     {
2336         DWORD bytesNeeded;
2337 
2338         if (!cbEncoded)
2339             SetLastError(CRYPT_E_ASN1_EOD);
2340         else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
2341             SetLastError(CRYPT_E_ASN1_CORRUPT);
2342         else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2343          cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2344          NULL)))
2345         {
2346             if (!pvStructInfo)
2347                 *pcbStructInfo = bytesNeeded;
2348             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2349              pvStructInfo, pcbStructInfo, bytesNeeded)))
2350             {
2351                 PCRYPT_ATTRIBUTES attrs;
2352 
2353                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2354                     pvStructInfo = *(BYTE **)pvStructInfo;
2355                 attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2356                 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
2357                  sizeof(CRYPT_ATTRIBUTES));
2358                 ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2359                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2360                  &bytesNeeded, NULL);
2361             }
2362         }
2363     }
2364     __EXCEPT_PAGE_FAULT
2365     {
2366         SetLastError(STATUS_ACCESS_VIOLATION);
2367     }
2368     __ENDTRY
2369     TRACE("returning %d\n", ret);
2370     return ret;
2371 }
2372 
2373 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2374  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2375 {
2376     CRYPT_ALGORITHM_IDENTIFIER *algo =
2377      (CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
2378     BOOL ret = TRUE;
2379     struct AsnDecodeSequenceItem items[] = {
2380      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2381        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2382        offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2383      { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2384        CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE, 
2385        offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2386     };
2387 
2388     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2389      pvStructInfo, *pcbStructInfo, pcbDecoded);
2390 
2391     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2392      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2393      pcbDecoded, algo ? algo->pszObjId : NULL);
2394     if (ret && pvStructInfo)
2395     {
2396         TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2397          debugstr_a(algo->pszObjId));
2398     }
2399     return ret;
2400 }
2401 
2402 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2403  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2404  DWORD *pcbDecoded)
2405 {
2406     BOOL ret = TRUE;
2407     struct AsnDecodeSequenceItem items[] = {
2408      { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2409        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2410        FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2411        Algorithm.pszObjId) },
2412      { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2413        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2414        offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2415     };
2416     PCERT_PUBLIC_KEY_INFO info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2417 
2418     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2419      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2420      pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2421     return ret;
2422 }
2423 
2424 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2425  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2426  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2427 {
2428     BOOL ret = TRUE;
2429 
2430     __TRY
2431     {
2432         DWORD bytesNeeded;
2433 
2434         if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2435          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2436         {
2437             if (!pvStructInfo)
2438                 *pcbStructInfo = bytesNeeded;
2439             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2440              pvStructInfo, pcbStructInfo, bytesNeeded)))
2441             {
2442                 PCERT_PUBLIC_KEY_INFO info;
2443 
2444                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2445                     pvStructInfo = *(BYTE **)pvStructInfo;
2446                 info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2447                 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2448                  sizeof(CERT_PUBLIC_KEY_INFO);
2449                 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2450                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2451                  &bytesNeeded, NULL);
2452             }
2453         }
2454     }
2455     __EXCEPT_PAGE_FAULT
2456     {
2457         SetLastError(STATUS_ACCESS_VIOLATION);
2458         ret = FALSE;
2459     }
2460     __ENDTRY
2461     return ret;
2462 }
2463 
2464 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2465  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2466 {
2467     BOOL ret;
2468 
2469     if (cbEncoded < 3)
2470     {
2471         SetLastError(CRYPT_E_ASN1_CORRUPT);
2472         return FALSE;
2473     }
2474     if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2475     {
2476         SetLastError(CRYPT_E_ASN1_CORRUPT);
2477         return FALSE;
2478     }
2479     if (pbEncoded[1] > 1)
2480     {
2481         SetLastError(CRYPT_E_ASN1_CORRUPT);
2482         return FALSE;
2483     }
2484     if (pcbDecoded)
2485         *pcbDecoded = 3;
2486     if (!pvStructInfo)
2487     {
2488         *pcbStructInfo = sizeof(BOOL);
2489         ret = TRUE;
2490     }
2491     else if (*pcbStructInfo < sizeof(BOOL))
2492     {
2493         *pcbStructInfo = sizeof(BOOL);
2494         SetLastError(ERROR_MORE_DATA);
2495         ret = FALSE;
2496     }
2497     else
2498     {
2499         *pcbStructInfo = sizeof(BOOL);
2500         *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2501         ret = TRUE;
2502     }
2503     TRACE("returning %d (%08x)\n", ret, GetLastError());
2504     return ret;
2505 }
2506 
2507 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2508  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2509 {
2510     PCERT_ALT_NAME_ENTRY entry = (PCERT_ALT_NAME_ENTRY)pvStructInfo;
2511     DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2512     BOOL ret;
2513 
2514     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2515      pvStructInfo, *pcbStructInfo);
2516 
2517     if (cbEncoded < 2)
2518     {
2519         SetLastError(CRYPT_E_ASN1_CORRUPT);
2520         return FALSE;
2521     }
2522     lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2523     if (1 + lenBytes > cbEncoded)
2524     {
2525         SetLastError(CRYPT_E_ASN1_CORRUPT);
2526         return FALSE;
2527     }
2528     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2529     {
2530         switch (pbEncoded[0] & ASN_TYPE_MASK)
2531         {
2532         case 1: /* rfc822Name */
2533         case 2: /* dNSName */
2534         case 6: /* uniformResourceIdentifier */
2535             bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2536             break;
2537         case 4: /* directoryName */
2538         case 7: /* iPAddress */
2539             bytesNeeded += dataLen;
2540             break;
2541         case 8: /* registeredID */
2542             ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2543              &dataLen, NULL);
2544             if (ret)
2545             {
2546                 /* FIXME: ugly, shouldn't need to know internals of OID decode
2547                  * function to use it.
2548                  */
2549                 bytesNeeded += dataLen - sizeof(LPSTR);
2550             }
2551             break;
2552         case 0: /* otherName */
2553             FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2554             SetLastError(CRYPT_E_ASN1_BADTAG);
2555             ret = FALSE;
2556             break;
2557         case 3: /* x400Address, unimplemented */
2558         case 5: /* ediPartyName, unimplemented */
2559             TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2560             SetLastError(CRYPT_E_ASN1_BADTAG);
2561             ret = FALSE;
2562             break;
2563         default:
2564             TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2565             SetLastError(CRYPT_E_ASN1_CORRUPT);
2566             ret = FALSE;
2567         }
2568         if (ret)
2569         {
2570             if (pcbDecoded)
2571                 *pcbDecoded = 1 + lenBytes + dataLen;
2572             if (!entry)
2573                 *pcbStructInfo = bytesNeeded;
2574             else if (*pcbStructInfo < bytesNeeded)
2575             {
2576                 *pcbStructInfo = bytesNeeded;
2577                 SetLastError(ERROR_MORE_DATA);
2578                 ret = FALSE;
2579             }
2580             else
2581             {
2582                 *pcbStructInfo = bytesNeeded;
2583                 /* MS used values one greater than the asn1 ones.. sigh */
2584                 entry->dwAltNameChoice = (pbEncoded[0] & 0x7f) + 1;
2585                 switch (pbEncoded[0] & ASN_TYPE_MASK)
2586                 {
2587                 case 1: /* rfc822Name */
2588                 case 2: /* dNSName */
2589                 case 6: /* uniformResourceIdentifier */
2590                 {
2591                     DWORD i;
2592 
2593                     for (i = 0; i < dataLen; i++)
2594                         entry->u.pwszURL[i] =
2595                          (WCHAR)pbEncoded[1 + lenBytes + i];
2596                     entry->u.pwszURL[i] = 0;
2597                     TRACE("URL is %p (%s)\n", entry->u.pwszURL,
2598                      debugstr_w(entry->u.pwszURL));
2599                     break;
2600                 }
2601                 case 4: /* directoryName */
2602                     entry->dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
2603                     /* The data are memory-equivalent with the IPAddress case,
2604                      * fall-through
2605                      */
2606                 case 7: /* iPAddress */
2607                     /* The next data pointer is in the pwszURL spot, that is,
2608                      * the first 4 bytes.  Need to move it to the next spot.
2609                      */
2610                     entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
2611                     entry->u.IPAddress.cbData = dataLen;
2612                     memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
2613                      dataLen);
2614                     break;
2615                 case 8: /* registeredID */
2616                     ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
2617                      &entry->u.pszRegisteredID, &dataLen, NULL);
2618                     break;
2619                 }
2620             }
2621         }
2622     }
2623     return ret;
2624 }
2625 
2626 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
2627  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2628  DWORD *pcbDecoded)
2629 {
2630     BOOL ret = TRUE;
2631     struct AsnArrayDescriptor arrayDesc = { 0,
2632      CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
2633      offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
2634     PCERT_ALT_NAME_INFO info = (PCERT_ALT_NAME_INFO)pvStructInfo;
2635 
2636     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2637      pvStructInfo, *pcbStructInfo, pcbDecoded);
2638 
2639     if (info)
2640         TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
2641     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2642      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2643      info ? info->rgAltEntry : NULL);
2644     return ret;
2645 }
2646 
2647 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2648 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
2649  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2650  DWORD *pcbDecoded)
2651 {
2652     BOOL ret;
2653 
2654     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
2655      pvStructInfo, *pcbStructInfo, pcbDecoded);
2656 
2657     /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2658      * place.
2659      */
2660     ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
2661      dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
2662      pcbDecoded);
2663     if (ret && pvStructInfo)
2664     {
2665         CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2666 
2667         if (blob->cbData)
2668         {
2669             DWORD i;
2670             BYTE temp;
2671 
2672             for (i = 0; i < blob->cbData / 2; i++)
2673             {
2674                 temp = blob->pbData[i];
2675                 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
2676                 blob->pbData[blob->cbData - i - 1] = temp;
2677             }
2678         }
2679     }
2680     TRACE("returning %d (%08x)\n", ret, GetLastError());
2681     return ret;
2682 }
2683 
2684 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
2685  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2686  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2687 {
2688     BOOL ret;
2689 
2690     __TRY
2691     {
2692         struct AsnDecodeSequenceItem items[] = {
2693          { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
2694            CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2695            TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
2696          { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2697            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
2698            CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
2699            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
2700          { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
2701            CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2702            sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2703            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
2704         };
2705 
2706         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2707          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2708          pcbStructInfo, NULL, NULL);
2709     }
2710     __EXCEPT_PAGE_FAULT
2711     {
2712         SetLastError(STATUS_ACCESS_VIOLATION);
2713         ret = FALSE;
2714     }
2715     __ENDTRY
2716     return ret;
2717 }
2718 
2719 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
2720  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2721  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2722 {
2723     BOOL ret;
2724 
2725     __TRY
2726     {
2727         struct AsnDecodeSequenceItem items[] = {
2728          { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
2729            CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2730            TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
2731          { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2732            offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
2733            CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
2734            TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2735            AuthorityCertIssuer.rgAltEntry), 0 },
2736          { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2737            AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2738            sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2739            offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2740            AuthorityCertSerialNumber.pbData), 0 },
2741         };
2742 
2743         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2744          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2745          pcbStructInfo, NULL, NULL);
2746     }
2747     __EXCEPT_PAGE_FAULT
2748     {
2749         SetLastError(STATUS_ACCESS_VIOLATION);
2750         ret = FALSE;
2751     }
2752     __ENDTRY
2753     return ret;
2754 }
2755 
2756 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
2757  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2758  DWORD *pcbDecoded)
2759 {
2760     struct AsnDecodeSequenceItem items[] = {
2761      { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
2762        CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
2763        offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
2764      { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
2765        CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
2766        TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
2767     };
2768     CERT_ACCESS_DESCRIPTION *descr = (CERT_ACCESS_DESCRIPTION *)pvStructInfo;
2769 
2770     return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2771      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2772      pcbDecoded, descr ? descr->pszAccessMethod : NULL);
2773 }
2774 
2775 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
2776  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2777  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2778 {
2779     BOOL ret;
2780 
2781     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2782      pDecodePara, pvStructInfo, *pcbStructInfo);
2783 
2784     __TRY
2785     {
2786         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2787          CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
2788          TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
2789 
2790         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2791          pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
2792     }
2793     __EXCEPT_PAGE_FAULT
2794     {
2795         SetLastError(STATUS_ACCESS_VIOLATION);
2796         ret = FALSE;
2797     }
2798     __ENDTRY
2799     return ret;
2800 }
2801 
2802 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
2803  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2804 {
2805     BOOL ret;
2806     DWORD dataLen;
2807 
2808     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2809      pvStructInfo, *pcbStructInfo, pcbDecoded);
2810 
2811     /* The caller has already checked the tag, no need to check it again.
2812      * Check the outer length is valid:
2813      */
2814     if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
2815     {
2816         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2817         DWORD innerLen;
2818 
2819         pbEncoded += 1 + lenBytes;
2820         cbEncoded -= 1 + lenBytes;
2821         if (dataLen == CMSG_INDEFINITE_LENGTH)
2822             cbEncoded -= 2; /* space for 0 TLV */
2823         /* Check the inner length is valid: */
2824         if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
2825         {
2826             DWORD decodedLen;
2827 
2828             ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
2829              pvStructInfo, pcbStructInfo, &decodedLen);
2830             if (dataLen == CMSG_INDEFINITE_LENGTH)
2831             {
2832                 if (*(pbEncoded + decodedLen) != 0 ||
2833                  *(pbEncoded + decodedLen + 1) != 0)
2834                 {
2835                     TRACE("expected 0 TLV, got {%02x,%02x}\n",
2836                      *(pbEncoded + decodedLen),
2837                      *(pbEncoded + decodedLen + 1));
2838                     SetLastError(CRYPT_E_ASN1_CORRUPT);
2839                     ret = FALSE;
2840                 }
2841                 else
2842                     decodedLen += 2;
2843             }
2844             if (ret && pcbDecoded)
2845             {
2846                 *pcbDecoded = 1 + lenBytes + decodedLen;
2847                 TRACE("decoded %d bytes\n", *pcbDecoded);
2848             }
2849         }
2850     }
2851     return ret;
2852 }
2853 
2854 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
2855  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2856  DWORD *pcbDecoded)
2857 {
2858     CRYPT_CONTENT_INFO *info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2859     struct AsnDecodeSequenceItem items[] = {
2860      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
2861        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2862        offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
2863      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
2864        offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
2865        sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
2866        offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
2867     };
2868     BOOL ret;
2869 
2870     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2871      pvStructInfo, *pcbStructInfo, pcbDecoded);
2872 
2873     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2874      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2875      pcbDecoded, info ? info->pszObjId : NULL);
2876     return ret;
2877 }
2878 
2879 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
2880  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2881  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2882 {
2883     BOOL ret = FALSE;
2884 
2885     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2886      pDecodePara, pvStructInfo, *pcbStructInfo);
2887 
2888     __TRY
2889     {
2890         ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
2891          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
2892         if (ret && pvStructInfo)
2893         {
2894             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
2895              pcbStructInfo, *pcbStructInfo);
2896             if (ret)
2897             {
2898                 CRYPT_CONTENT_INFO *info;
2899 
2900                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2901                     pvStructInfo = *(BYTE **)pvStructInfo;
2902                 info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2903                 info->pszObjId = (LPSTR)((BYTE *)info +
2904                  sizeof(CRYPT_CONTENT_INFO));
2905                 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
2906                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2907                  pcbStructInfo, NULL);
2908             }
2909         }
2910     }
2911     __EXCEPT_PAGE_FAULT
2912     {
2913         SetLastError(STATUS_ACCESS_VIOLATION);
2914     }
2915     __ENDTRY
2916     return ret;
2917 }
2918 
2919 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
2920  DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2921  CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
2922 {
2923     BOOL ret;
2924     struct AsnDecodeSequenceItem items[] = {
2925      { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
2926        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2927      { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
2928        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2929        FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
2930        0 },
2931      { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
2932        CRYPT_AsnDecodePKCSContentInfoInternal,
2933        sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
2934        ContentInfo.pszObjId), 0 },
2935      { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
2936        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
2937        offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
2938     };
2939 
2940     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2941      pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
2942      NULL, NULL);
2943     return ret;
2944 }
2945 
2946 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
2947  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2948  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2949 {
2950     BOOL ret = TRUE;
2951 
2952     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2953      pDecodePara, pvStructInfo, *pcbStructInfo);
2954 
2955     __TRY
2956     {
2957         DWORD bytesNeeded;
2958 
2959         if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2960          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2961         {
2962             if (!pvStructInfo)
2963                 *pcbStructInfo = bytesNeeded;
2964             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2965              pvStructInfo, pcbStructInfo, bytesNeeded)))
2966             {
2967                 CERT_ALT_NAME_INFO *name;
2968 
2969                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2970                     pvStructInfo = *(BYTE **)pvStructInfo;
2971                 name = (CERT_ALT_NAME_INFO *)pvStructInfo;
2972                 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
2973                  ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
2974                 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2975                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2976                  &bytesNeeded, NULL);
2977             }
2978         }
2979     }
2980     __EXCEPT_PAGE_FAULT
2981     {
2982         SetLastError(STATUS_ACCESS_VIOLATION);
2983         ret = FALSE;
2984     }
2985     __ENDTRY
2986     return ret;
2987 }
2988 
2989 struct PATH_LEN_CONSTRAINT
2990 {
2991     BOOL  fPathLenConstraint;
2992     DWORD dwPathLenConstraint;
2993 };
2994 
2995 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
2996  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2997  DWORD *pcbDecoded)
2998 {
2999     BOOL ret = TRUE;
3000     DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3001 
3002     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3003      pvStructInfo, *pcbStructInfo, pcbDecoded);
3004 
3005     if (!pvStructInfo)
3006     {
3007         ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3008          &size, pcbDecoded);
3009         *pcbStructInfo = bytesNeeded;
3010     }
3011     else if (*pcbStructInfo < bytesNeeded)
3012     {
3013         SetLastError(ERROR_MORE_DATA);
3014         *pcbStructInfo = bytesNeeded;
3015         ret = FALSE;
3016     }
3017     else
3018     {
3019         struct PATH_LEN_CONSTRAINT *constraint =
3020          (struct PATH_LEN_CONSTRAINT *)pvStructInfo;
3021 
3022         *pcbStructInfo = bytesNeeded;
3023         size = sizeof(constraint->dwPathLenConstraint);
3024         ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3025          &constraint->dwPathLenConstraint, &size, pcbDecoded);
3026         if (ret)
3027             constraint->fPathLenConstraint = TRUE;
3028         TRACE("got an int, dwPathLenConstraint is %d\n",
3029          constraint->dwPathLenConstraint);
3030     }
3031     TRACE("returning %d (%08x)\n", ret, GetLastError());
3032     return ret;
3033 }
3034 
3035 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3036  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3037  DWORD *pcbDecoded)
3038 {
3039     BOOL ret;
3040     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3041      CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3042      offsetof(CERT_NAME_BLOB, pbData) };
3043     struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
3044 
3045     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3046      pvStructInfo, *pcbStructInfo, pcbDecoded);
3047 
3048     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3049      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
3050      entries ? entries->rgItems : NULL);
3051     TRACE("Returning %d (%08x)\n", ret, GetLastError());
3052     return ret;
3053 }
3054 
3055 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3056  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3057  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3058 {
3059     BOOL ret;
3060 
3061     __TRY
3062     {
3063         struct AsnDecodeSequenceItem items[] = {
3064          { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3065            CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE, 
3066            offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3067          { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3068            fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3069            sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3070          { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3071            cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3072            sizeof(struct GenericArray), TRUE, TRUE,
3073            offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3074         };
3075 
3076         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3077          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3078          pcbStructInfo, NULL, NULL);
3079     }
3080     __EXCEPT_PAGE_FAULT
3081     {
3082         SetLastError(STATUS_ACCESS_VIOLATION);
3083         ret = FALSE;
3084     }
3085     __ENDTRY
3086     return ret;
3087 }
3088 
3089 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3090  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3091  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3092 {
3093     BOOL ret;
3094 
3095     __TRY
3096     {
3097         struct AsnDecodeSequenceItem items[] = {
3098          { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3099            CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3100          { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3101            fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3102            sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3103         };
3104 
3105         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3106          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3107          pcbStructInfo, NULL, NULL);
3108     }
3109     __EXCEPT_PAGE_FAULT
3110     {
3111         SetLastError(STATUS_ACCESS_VIOLATION);
3112         ret = FALSE;
3113     }
3114     __ENDTRY
3115     return ret;
3116 }
3117 
3118 #define RSA1_MAGIC 0x31415352
3119 
3120 struct DECODED_RSA_PUB_KEY
3121 {
3122     DWORD              pubexp;
3123     CRYPT_INTEGER_BLOB modulus;
3124 };
3125 
3126 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3127  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3128  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3129 {
3130     BOOL ret;
3131 
3132     __TRY
3133     {
3134         struct AsnDecodeSequenceItem items[] = {
3135          { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3136            CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3137            FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3138            0 },
3139          { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3140            CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3141         };
3142         struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3143         DWORD size = 0;
3144 
3145         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3146          pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3147          &size, NULL, NULL);
3148         if (ret)
3149         {
3150             DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3151              decodedKey->modulus.cbData;
3152 
3153             if (!pvStructInfo)
3154             {
3155                 *pcbStructInfo = bytesNeeded;
3156                 ret = TRUE;
3157             }
3158             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3159              pvStructInfo, pcbStructInfo, bytesNeeded)))
3160             {
3161                 BLOBHEADER *hdr;
3162                 RSAPUBKEY *rsaPubKey;
3163 
3164                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3165                     pvStructInfo = *(BYTE **)pvStructInfo;
3166                 hdr = (BLOBHEADER *)pvStructInfo;
3167                 hdr->bType = PUBLICKEYBLOB;
3168                 hdr->bVersion = CUR_BLOB_VERSION;
3169                 hdr->reserved = 0;
3170                 hdr->aiKeyAlg = CALG_RSA_KEYX;
3171                 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3172                  sizeof(BLOBHEADER));
3173                 rsaPubKey->magic = RSA1_MAGIC;
3174                 rsaPubKey->pubexp = decodedKey->pubexp;
3175                 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3176                 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3177                  sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3178                  decodedKey->modulus.cbData);
3179             }
3180             LocalFree(decodedKey);
3181         }
3182     }
3183     __EXCEPT_PAGE_FAULT
3184     {
3185         SetLastError(STATUS_ACCESS_VIOLATION);
3186         ret = FALSE;
3187     }
3188     __ENDTRY
3189     return ret;
3190 }
3191 
3192 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3193  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3194  DWORD *pcbDecoded)
3195 {
3196     BOOL ret;
3197     DWORD bytesNeeded, dataLen;
3198 
3199     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3200      pvStructInfo, *pcbStructInfo, pcbDecoded);
3201 
3202     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3203     {
3204         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3205 
3206         if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3207             bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3208         else
3209             bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3210         if (pcbDecoded)
3211             *pcbDecoded = 1 + lenBytes + dataLen;
3212         if (!pvStructInfo)
3213             *pcbStructInfo = bytesNeeded;
3214         else if (*pcbStructInfo < bytesNeeded)
3215         {
3216             SetLastError(ERROR_MORE_DATA);
3217             *pcbStructInfo = bytesNeeded;
3218             ret = FALSE;
3219         }
3220         else
3221         {
3222             CRYPT_DATA_BLOB *blob;
3223 
3224             *pcbStructInfo = bytesNeeded;
3225             blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3226             blob->cbData = dataLen;
3227             if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3228                 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
3229             else
3230             {
3231                 assert(blob->pbData);
3232                 if (blob->cbData)
3233                     memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
3234                      blob->cbData);
3235             }
3236         }
3237     }
3238     return ret;
3239 }
3240 
3241 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
3242  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3243  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3244 {
3245     BOOL ret;
3246 
3247     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3248      pDecodePara, pvStructInfo, *pcbStructInfo);
3249 
3250     __TRY
3251     {
3252         DWORD bytesNeeded;
3253 
3254         if (!cbEncoded)
3255         {
3256             SetLastError(CRYPT_E_ASN1_CORRUPT);
3257             ret = FALSE;
3258         }
3259         else if (pbEncoded[0] != ASN_OCTETSTRING)
3260         {
3261             SetLastError(CRYPT_E_ASN1_BADTAG);
3262             ret = FALSE;
3263         }
3264         else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3265          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3266         {
3267             if (!pvStructInfo)
3268                 *pcbStructInfo = bytesNeeded;
3269             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3270              pvStructInfo, pcbStructInfo, bytesNeeded)))
3271             {
3272                 CRYPT_DATA_BLOB *blob;
3273 
3274                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3275                     pvStructInfo = *(BYTE **)pvStructInfo;
3276                 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3277                 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3278                 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3279                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3280                  &bytesNeeded, NULL);
3281             }
3282         }
3283     }
3284     __EXCEPT_PAGE_FAULT
3285     {
3286         SetLastError(STATUS_ACCESS_VIOLATION);
3287         ret = FALSE;
3288     }
3289     __ENDTRY
3290     return ret;
3291 }
3292 
3293 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3294  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3295 {
3296     BOOL ret;
3297 
3298     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3299      pvStructInfo, *pcbStructInfo, pcbDecoded);
3300 
3301     if (pbEncoded[0] == ASN_BITSTRING)
3302     {
3303         DWORD bytesNeeded, dataLen;
3304         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3305 
3306         if ((ret =