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