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

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

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