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