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

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

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

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