xref: /reactos/dll/win32/crypt32/decode.c (revision 845faec4)
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_AsnDecodeOctets(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  const CRYPT_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(const CRYPT_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                 lenBytes += 2;
483             }
484             else if (cbEncoded < dataLen)
485             {
486                 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
487                  cbEncoded);
488                 SetLastError(CRYPT_E_ASN1_CORRUPT);
489                 ret = FALSE;
490             }
491             if (ret)
492             {
493                 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
494                  ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
495                 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
496                 {
497                     if (cbDecoded > cbEncoded - 2)
498                     {
499                         /* Not enough space for 0 TLV */
500                         SetLastError(CRYPT_E_ASN1_CORRUPT);
501                         ret = FALSE;
502                     }
503                     else if (*(ptr + cbDecoded) != 0 ||
504                      *(ptr + cbDecoded + 1) != 0)
505                     {
506                         TRACE("expected 0 TLV\n");
507                         SetLastError(CRYPT_E_ASN1_CORRUPT);
508                         ret = FALSE;
509                     }
510                     else
511                         cbDecoded += 2;
512                 }
513             }
514             if (ret && !indefinite && cbDecoded != dataLen)
515             {
516                 TRACE("expected %d decoded, got %d, failing\n", dataLen,
517                  cbDecoded);
518                 SetLastError(CRYPT_E_ASN1_CORRUPT);
519                 ret = FALSE;
520             }
521             if (ret)
522             {
523                 DWORD i, bytesNeeded = 0, structSize = 0;
524 
525                 for (i = 0; i < cItem; i++)
526                 {
527                     if (items[i].size > items[i].minSize)
528                         bytesNeeded += items[i].size - items[i].minSize;
529                     structSize = max( structSize, items[i].offset + items[i].minSize );
530                 }
531                 bytesNeeded += structSize;
532                 if (pcbDecoded)
533                     *pcbDecoded = 1 + lenBytes + cbDecoded;
534                 if (!pvStructInfo)
535                     *pcbStructInfo = bytesNeeded;
536                 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
537                  pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
538                 {
539                     BYTE *nextData;
540 
541                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
542                         pvStructInfo = *(BYTE **)pvStructInfo;
543                     if (startingPointer)
544                         nextData = startingPointer;
545                     else
546                         nextData = (BYTE *)pvStructInfo + structSize;
547                     memset(pvStructInfo, 0, structSize);
548                     ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
549                      ptr, dataLen, dwFlags, pvStructInfo, nextData,
550                      &cbDecoded);
551                     if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
552                         CRYPT_FreeSpace(pDecodePara, pvStructInfo);
553                 }
554             }
555         }
556     }
557     else
558     {
559         SetLastError(CRYPT_E_ASN1_BADTAG);
560         ret = FALSE;
561     }
562     TRACE("returning %d (%08x)\n", ret, GetLastError());
563     return ret;
564 }
565 
566 /* tag:
567  *     The expected tag of the entire encoded array (usually a variant
568  *     of ASN_SETOF or ASN_SEQUENCEOF.)  If tag is 0, decodeFunc is called
569  *     regardless of the tag seen.
570  * countOffset:
571  *     The offset within the outer structure at which the count exists.
572  *     For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
573  *     while CRYPT_ATTRIBUTE has countOffset ==
574  *     offsetof(CRYPT_ATTRIBUTE, cValue).
575  * arrayOffset:
576  *     The offset within the outer structure at which the array pointer exists.
577  *     For example, CRYPT_ATTRIBUTES has arrayOffset ==
578  *     offsetof(CRYPT_ATTRIBUTES, rgAttr).
579  * minArraySize:
580  *     The minimum size of the decoded array.  On WIN32, this is always 8:
581  *     sizeof(DWORD) + sizeof(void *).  On WIN64, it can be larger due to
582  *     alignment.
583  * decodeFunc:
584  *     used to decode each item in the array
585  * itemSize:
586  *      is the minimum size of each decoded item
587  * hasPointer:
588  *      indicates whether each item has a dynamic pointer
589  * pointerOffset:
590  *     indicates the offset within itemSize at which the pointer exists
591  */
592 struct AsnArrayDescriptor
593 {
594     BYTE               tag;
595     DWORD              countOffset;
596     DWORD              arrayOffset;
597     DWORD              minArraySize;
598     InternalDecodeFunc decodeFunc;
599     DWORD              itemSize;
600     BOOL               hasPointer;
601     DWORD              pointerOffset;
602 };
603 
604 struct AsnArrayItemSize
605 {
606     DWORD encodedLen;
607     DWORD size;
608 };
609 
610 /* Decodes an array of like types into a structure described by a struct
611  * AsnArrayDescriptor.
612  */
613 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
614  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
615  const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
616  DWORD *pcbDecoded)
617 {
618     BOOL ret = TRUE;
619 
620     TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded,
621      cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
622 
623     if (!cbEncoded)
624     {
625         SetLastError(CRYPT_E_ASN1_EOD);
626         ret = FALSE;
627     }
628     else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
629     {
630         DWORD dataLen;
631 
632         if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
633         {
634             DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded;
635             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
636             /* There can be arbitrarily many items, but there is often only one.
637              */
638             struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
639 
640             decoded = 1 + lenBytes;
641             if (dataLen)
642             {
643                 const BYTE *ptr;
644                 BOOL doneDecoding = FALSE;
645 
646                 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
647                 {
648                     if (dataLen == CMSG_INDEFINITE_LENGTH)
649                     {
650                         if (ptr[0] == 0)
651                         {
652                             doneDecoding = TRUE;
653                             if (ptr[1] != 0)
654                             {
655                                 SetLastError(CRYPT_E_ASN1_CORRUPT);
656                                 ret = FALSE;
657                             }
658                             else
659                                 decoded += 2;
660                         }
661                     }
662                     else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
663                         doneDecoding = TRUE;
664                     if (!doneDecoding)
665                     {
666                         DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
667 
668                         /* Each item decoded may not tolerate extraneous bytes,
669                          * so get the length of the next element if known.
670                          */
671                         if ((ret = CRYPT_GetLengthIndefinite(ptr,
672                          cbEncoded - (ptr - pbEncoded), &itemDataLen)))
673                         {
674                             if (itemDataLen == CMSG_INDEFINITE_LENGTH)
675                                 itemEncoded = cbEncoded - (ptr - pbEncoded);
676                             else
677                                 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
678                                  itemDataLen;
679                         }
680                         if (ret)
681                             ret = arrayDesc->decodeFunc(ptr, itemEncoded,
682                              dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
683                              &itemDecoded);
684                         if (ret)
685                         {
686                             cItems++;
687                             if (itemSizes != &itemSize)
688                                 itemSizes = CryptMemRealloc(itemSizes,
689                                  cItems * sizeof(struct AsnArrayItemSize));
690                             else if (cItems > 1)
691                             {
692                                 itemSizes =
693                                  CryptMemAlloc(
694                                  cItems * sizeof(struct AsnArrayItemSize));
695                                 if (itemSizes)
696                                     *itemSizes = itemSize;
697                             }
698                             if (itemSizes)
699                             {
700                                 decoded += itemDecoded;
701                                 itemSizes[cItems - 1].encodedLen = itemEncoded;
702                                 itemSizes[cItems - 1].size = size;
703                                 bytesNeeded += size;
704                                 ptr += itemEncoded;
705                             }
706                             else
707                                 ret = FALSE;
708                         }
709                     }
710                 }
711             }
712             if (ret)
713             {
714                 if (pcbDecoded)
715                     *pcbDecoded = decoded;
716                 if (!pvStructInfo)
717                     *pcbStructInfo = bytesNeeded;
718                 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
719                  pvStructInfo, pcbStructInfo, bytesNeeded)))
720                 {
721                     DWORD i, *pcItems;
722                     BYTE *nextData;
723                     const BYTE *ptr;
724                     void *rgItems;
725 
726                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
727                         pvStructInfo = *(void **)pvStructInfo;
728                     pcItems = pvStructInfo;
729                     *pcItems = cItems;
730                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
731                     {
732                         rgItems = (BYTE *)pvStructInfo +
733                          arrayDesc->minArraySize;
734                         *(void **)((BYTE *)pcItems -
735                          arrayDesc->countOffset + arrayDesc->arrayOffset) =
736                          rgItems;
737                     }
738                     else
739                         rgItems = *(void **)((BYTE *)pcItems -
740                          arrayDesc->countOffset + arrayDesc->arrayOffset);
741                     nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize;
742                     for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
743                      i < cItems && ptr - pbEncoded - 1 - lenBytes <
744                      dataLen; i++)
745                     {
746                         DWORD itemDecoded;
747 
748                         if (arrayDesc->hasPointer)
749                             *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize
750                              + arrayDesc->pointerOffset) = nextData;
751                         ret = arrayDesc->decodeFunc(ptr,
752                          itemSizes[i].encodedLen,
753                          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
754                          (BYTE *)rgItems + i * arrayDesc->itemSize,
755                          &itemSizes[i].size, &itemDecoded);
756                         if (ret)
757                         {
758                             nextData += itemSizes[i].size - arrayDesc->itemSize;
759                             ptr += itemDecoded;
760                         }
761                     }
762                     if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
763                         CRYPT_FreeSpace(pDecodePara, pvStructInfo);
764                 }
765             }
766             if (itemSizes != &itemSize)
767                 CryptMemFree(itemSizes);
768         }
769     }
770     else
771     {
772         SetLastError(CRYPT_E_ASN1_BADTAG);
773         ret = FALSE;
774     }
775     return ret;
776 }
777 
778 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
779  * pvStructInfo.  The BLOB must be non-empty, otherwise the last error is set
780  * to CRYPT_E_ASN1_CORRUPT.
781  * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
782  * set!
783  */
784 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
785  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
786 {
787     BOOL ret;
788     DWORD dataLen;
789 
790     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
791     {
792         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
793         DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
794 
795         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
796             bytesNeeded += 1 + lenBytes + dataLen;
797 
798         if (pcbDecoded)
799             *pcbDecoded = 1 + lenBytes + dataLen;
800         if (!pvStructInfo)
801             *pcbStructInfo = bytesNeeded;
802         else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
803         {
804             CRYPT_DER_BLOB *blob;
805 
806             if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
807                 pvStructInfo = *(BYTE **)pvStructInfo;
808             blob = pvStructInfo;
809             blob->cbData = 1 + lenBytes + dataLen;
810             if (blob->cbData)
811             {
812                 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
813                     blob->pbData = (BYTE *)pbEncoded;
814                 else
815                 {
816                     assert(blob->pbData);
817                     memcpy(blob->pbData, pbEncoded, blob->cbData);
818                 }
819             }
820             else
821             {
822                 SetLastError(CRYPT_E_ASN1_CORRUPT);
823                 ret = FALSE;
824             }
825         }
826     }
827     return ret;
828 }
829 
830 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
831 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
832  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
833  DWORD *pcbDecoded)
834 {
835     BOOL ret;
836 
837     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
838      pvStructInfo, *pcbStructInfo, pcbDecoded);
839 
840     /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
841      * place.
842      */
843     ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
844      dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
845      pcbDecoded);
846     if (ret && pvStructInfo)
847     {
848         CRYPT_BIT_BLOB *blob = pvStructInfo;
849 
850         if (blob->cbData)
851         {
852             DWORD i;
853             BYTE temp;
854 
855             for (i = 0; i < blob->cbData / 2; i++)
856             {
857                 temp = blob->pbData[i];
858                 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
859                 blob->pbData[blob->cbData - i - 1] = temp;
860             }
861         }
862     }
863     TRACE("returning %d (%08x)\n", ret, GetLastError());
864     return ret;
865 }
866 
867 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
868  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
869  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
870 {
871     BOOL ret = TRUE;
872 
873     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
874      pDecodePara, pvStructInfo, *pcbStructInfo);
875 
876     __TRY
877     {
878         struct AsnDecodeSequenceItem items[] = {
879          { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
880            CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
881            offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
882          { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
883            SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
884            sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
885            offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
886          { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
887            CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
888            offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
889         };
890 
891         if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
892             items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
893         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
894          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
895          pcbStructInfo, NULL, NULL);
896     }
897     __EXCEPT_PAGE_FAULT
898     {
899         SetLastError(STATUS_ACCESS_VIOLATION);
900         ret = FALSE;
901     }
902     __ENDTRY
903 
904     TRACE("Returning %d (%08x)\n", ret, GetLastError());
905     return ret;
906 }
907 
908 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
909  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
910 {
911     BOOL ret;
912     DWORD dataLen;
913 
914     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
915     {
916         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
917 
918         ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
919          dwFlags, pvStructInfo, pcbStructInfo, NULL);
920         if (pcbDecoded)
921             *pcbDecoded = 1 + lenBytes + dataLen;
922     }
923     return ret;
924 }
925 
926 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
927  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
928 {
929     BOOL ret;
930 
931     struct AsnDecodeSequenceItem items[] = {
932      { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
933        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
934      { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
935        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
936     };
937 
938     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
939      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
940      pcbDecoded, NULL);
941     return ret;
942 }
943 
944 static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded,
945  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
946  DWORD *pcbDecoded)
947 {
948     BOOL ret = TRUE;
949     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
950      offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
951      FINALMEMBERSIZE(CERT_INFO, cExtension),
952      CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
953      offsetof(CERT_EXTENSION, pszObjId) };
954 
955     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
956      pvStructInfo, *pcbStructInfo, pcbDecoded);
957 
958     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
959      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
960     return ret;
961 }
962 
963 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
964  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
965  DWORD *pcbDecoded)
966 {
967     BOOL ret;
968     DWORD dataLen;
969 
970     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
971     {
972         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
973 
974         ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes,
975          dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
976         if (ret && pcbDecoded)
977             *pcbDecoded = 1 + lenBytes + dataLen;
978     }
979     return ret;
980 }
981 
982 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
983  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
984  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
985 {
986     BOOL ret = TRUE;
987     struct AsnDecodeSequenceItem items[] = {
988      { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
989        CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
990      { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
991        CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
992        TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
993      { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
994        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
995        FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
996      { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
997        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
998        Issuer.pbData) },
999      { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
1000        CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
1001        FALSE, 0 },
1002      { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
1003        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
1004        Subject.pbData) },
1005      { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
1006        CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
1007        FALSE, TRUE, offsetof(CERT_INFO,
1008        SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
1009      { ASN_CONTEXT | 1, offsetof(CERT_INFO, IssuerUniqueId),
1010        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1011        offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
1012      { ASN_CONTEXT | 2, offsetof(CERT_INFO, SubjectUniqueId),
1013        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1014        offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
1015      { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
1016        CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension),
1017        TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
1018     };
1019 
1020     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1021      pDecodePara, pvStructInfo, *pcbStructInfo);
1022 
1023     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1024      pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1025      NULL, NULL);
1026     if (ret && pvStructInfo)
1027     {
1028         CERT_INFO *info;
1029 
1030         if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1031             info = *(CERT_INFO **)pvStructInfo;
1032         else
1033             info = pvStructInfo;
1034         if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1035          !info->Subject.cbData)
1036         {
1037             SetLastError(CRYPT_E_ASN1_CORRUPT);
1038             /* Don't need to deallocate, because it should have failed on the
1039              * first pass (and no memory was allocated.)
1040              */
1041             ret = FALSE;
1042         }
1043     }
1044 
1045     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1046     return ret;
1047 }
1048 
1049 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1050  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1051  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1052 {
1053     BOOL ret = FALSE;
1054 
1055     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1056      pDecodePara, pvStructInfo, *pcbStructInfo);
1057 
1058     __TRY
1059     {
1060         DWORD size = 0;
1061 
1062         /* Unless told not to, first try to decode it as a signed cert. */
1063         if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1064         {
1065             PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1066 
1067             ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1068              X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1069              &signedCert, &size);
1070             if (ret)
1071             {
1072                 size = 0;
1073                 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1074                  X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1075                  signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1076                  pvStructInfo, pcbStructInfo);
1077                 LocalFree(signedCert);
1078             }
1079         }
1080         /* Failing that, try it as an unsigned cert */
1081         if (!ret)
1082         {
1083             size = 0;
1084             ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1085              X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1086              pDecodePara, pvStructInfo, pcbStructInfo);
1087         }
1088     }
1089     __EXCEPT_PAGE_FAULT
1090     {
1091         SetLastError(STATUS_ACCESS_VIOLATION);
1092     }
1093     __ENDTRY
1094 
1095     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1096     return ret;
1097 }
1098 
1099 static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded,
1100  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1101  DWORD *pcbDecoded)
1102 {
1103     BOOL ret = TRUE;
1104     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1105      offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
1106      FINALMEMBERSIZE(CRL_ENTRY, cExtension),
1107      CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1108      offsetof(CERT_EXTENSION, pszObjId) };
1109 
1110     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1111      pvStructInfo, *pcbStructInfo, pcbDecoded);
1112 
1113     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1114      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1115     return ret;
1116 }
1117 
1118 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1119  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1120 {
1121     BOOL ret;
1122     struct AsnDecodeSequenceItem items[] = {
1123      { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1124        CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1125        offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1126      { 0, offsetof(CRL_ENTRY, RevocationDate),
1127        CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1128      { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1129        CRYPT_AsnDecodeCRLEntryExtensions,
1130        FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
1131        offsetof(CRL_ENTRY, rgExtension), 0 },
1132     };
1133     PCRL_ENTRY entry = pvStructInfo;
1134 
1135     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1136      *pcbStructInfo);
1137 
1138     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1139      pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1140      entry ? entry->SerialNumber.pbData : NULL);
1141     if (ret && entry && !entry->SerialNumber.cbData)
1142     {
1143         WARN("empty CRL entry serial number\n");
1144         SetLastError(CRYPT_E_ASN1_CORRUPT);
1145         ret = FALSE;
1146     }
1147     return ret;
1148 }
1149 
1150 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1151  * whose rgCRLEntry member has been set prior to calling.
1152  */
1153 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1154  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1155 {
1156     BOOL ret;
1157     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1158      offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
1159      MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1160      CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1161      offsetof(CRL_ENTRY, SerialNumber.pbData) };
1162 
1163     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1164      pvStructInfo, *pcbStructInfo, pcbDecoded);
1165 
1166     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1167      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1168     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1169     return ret;
1170 }
1171 
1172 static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded,
1173  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1174  DWORD *pcbDecoded)
1175 {
1176     BOOL ret = TRUE;
1177     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1178      offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
1179      FINALMEMBERSIZE(CRL_INFO, cExtension),
1180      CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1181      offsetof(CERT_EXTENSION, pszObjId) };
1182 
1183     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1184      pvStructInfo, *pcbStructInfo, pcbDecoded);
1185 
1186     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1187      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1188     return ret;
1189 }
1190 
1191 static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded,
1192  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1193  DWORD *pcbDecoded)
1194 {
1195     BOOL ret;
1196     DWORD dataLen;
1197 
1198     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1199     {
1200         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1201 
1202         ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes,
1203          dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1204         if (ret && pcbDecoded)
1205             *pcbDecoded = 1 + lenBytes + dataLen;
1206     }
1207     return ret;
1208 }
1209 
1210 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1211  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1212  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1213 {
1214     struct AsnDecodeSequenceItem items[] = {
1215      { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1216        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1217      { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1218        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1219        FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1220      { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1221        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1222        Issuer.pbData) },
1223      { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1224        sizeof(FILETIME), FALSE, FALSE, 0 },
1225      { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1226        sizeof(FILETIME), TRUE, FALSE, 0 },
1227      { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1228        CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1229        TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
1230      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1231        CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension),
1232        TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
1233     };
1234     BOOL ret = TRUE;
1235 
1236     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1237      pDecodePara, pvStructInfo, *pcbStructInfo);
1238 
1239     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1240      pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1241      NULL, NULL);
1242 
1243     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1244     return ret;
1245 }
1246 
1247 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1248  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1249  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1250 {
1251     BOOL ret = FALSE;
1252 
1253     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1254      pDecodePara, pvStructInfo, *pcbStructInfo);
1255 
1256     __TRY
1257     {
1258         DWORD size = 0;
1259 
1260         /* Unless told not to, first try to decode it as a signed crl. */
1261         if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1262         {
1263             PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1264 
1265             ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1266              X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1267              &signedCrl, &size);
1268             if (ret)
1269             {
1270                 size = 0;
1271                 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1272                  X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1273                  signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1274                  pvStructInfo, pcbStructInfo);
1275                 LocalFree(signedCrl);
1276             }
1277         }
1278         /* Failing that, try it as an unsigned crl */
1279         if (!ret)
1280         {
1281             size = 0;
1282             ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1283              X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1284              dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1285         }
1286     }
1287     __EXCEPT_PAGE_FAULT
1288     {
1289         SetLastError(STATUS_ACCESS_VIOLATION);
1290     }
1291     __ENDTRY
1292 
1293     TRACE("Returning %d (%08x)\n", ret, GetLastError());
1294     return ret;
1295 }
1296 
1297 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1298  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1299 {
1300     BOOL ret = TRUE;
1301     DWORD dataLen;
1302 
1303     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1304      pvStructInfo, *pcbStructInfo);
1305 
1306     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1307     {
1308         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1309         DWORD bytesNeeded = sizeof(LPSTR);
1310 
1311         if (dataLen)
1312         {
1313             const BYTE *ptr;
1314             char str[32];
1315 
1316             snprintf(str, sizeof(str), "%d.%d",
1317              pbEncoded[1 + lenBytes] / 40,
1318              pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1319              * 40);
1320             bytesNeeded += strlen(str) + 1;
1321             for (ptr = pbEncoded + 2 + lenBytes; ret &&
1322              ptr - pbEncoded - 1 - lenBytes < dataLen; )
1323             {
1324                 int val = 0;
1325 
1326                 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1327                  (*ptr & 0x80))
1328                 {
1329                     val <<= 7;
1330                     val |= *ptr & 0x7f;
1331                     ptr++;
1332                 }
1333                 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1334                  (*ptr & 0x80))
1335                 {
1336                     SetLastError(CRYPT_E_ASN1_CORRUPT);
1337                     ret = FALSE;
1338                 }
1339                 else
1340                 {
1341                     val <<= 7;
1342                     val |= *ptr++;
1343                     snprintf(str, sizeof(str), ".%d", val);
1344                     bytesNeeded += strlen(str);
1345                 }
1346             }
1347         }
1348         if (pcbDecoded)
1349             *pcbDecoded = 1 + lenBytes + dataLen;
1350         if (!pvStructInfo)
1351             *pcbStructInfo = bytesNeeded;
1352         else if (*pcbStructInfo < bytesNeeded)
1353         {
1354             *pcbStructInfo = bytesNeeded;
1355             SetLastError(ERROR_MORE_DATA);
1356             ret = FALSE;
1357         }
1358         else
1359         {
1360             if (dataLen)
1361             {
1362                 const BYTE *ptr;
1363                 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1364 
1365                 *pszObjId = 0;
1366                 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1367                  pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1368                  40) * 40);
1369                 pszObjId += strlen(pszObjId);
1370                 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1371                  ptr - pbEncoded - 1 - lenBytes < dataLen; )
1372                 {
1373                     int val = 0;
1374 
1375                     while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1376                      (*ptr & 0x80))
1377                     {
1378                         val <<= 7;
1379                         val |= *ptr & 0x7f;
1380                         ptr++;
1381                     }
1382                     val <<= 7;
1383                     val |= *ptr++;
1384                     sprintf(pszObjId, ".%d", val);
1385                     pszObjId += strlen(pszObjId);
1386                 }
1387             }
1388             else
1389                 *(LPSTR *)pvStructInfo = NULL;
1390             *pcbStructInfo = bytesNeeded;
1391         }
1392     }
1393     return ret;
1394 }
1395 
1396 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1397  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1398 {
1399     BOOL ret;
1400 
1401     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1402      pvStructInfo, *pcbStructInfo);
1403 
1404     if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1405         ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1406          pvStructInfo, pcbStructInfo, pcbDecoded);
1407     else
1408     {
1409         SetLastError(CRYPT_E_ASN1_BADTAG);
1410         ret = FALSE;
1411     }
1412     return ret;
1413 }
1414 
1415 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1416  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1417 {
1418     struct AsnDecodeSequenceItem items[] = {
1419      { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1420        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1421        offsetof(CERT_EXTENSION, pszObjId), 0 },
1422      { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1423        sizeof(BOOL), TRUE, FALSE, 0, 0 },
1424      { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1425        CRYPT_AsnDecodeOctets, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1426        offsetof(CERT_EXTENSION, Value.pbData) },
1427     };
1428     BOOL ret = TRUE;
1429     PCERT_EXTENSION ext = pvStructInfo;
1430 
1431     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1432      *pcbStructInfo);
1433 
1434     if (ext)
1435         TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1436     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1437      pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1438      pcbDecoded, ext ? ext->pszObjId : NULL);
1439     if (ext)
1440         TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1441          debugstr_a(ext->pszObjId));
1442     TRACE("returning %d (%08x)\n", ret, GetLastError());
1443     return ret;
1444 }
1445 
1446 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1447  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1448  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1449 {
1450     BOOL ret = TRUE;
1451 
1452     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1453      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1454 
1455     __TRY
1456     {
1457         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1458          offsetof(CERT_EXTENSIONS, cExtension),
1459          offsetof(CERT_EXTENSIONS, rgExtension),
1460          sizeof(CERT_EXTENSIONS),
1461          CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1462          offsetof(CERT_EXTENSION, pszObjId) };
1463         CERT_EXTENSIONS *exts = pvStructInfo;
1464 
1465         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1466             exts->rgExtension = (CERT_EXTENSION *)(exts + 1);
1467         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1468          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1469     }
1470     __EXCEPT_PAGE_FAULT
1471     {
1472         SetLastError(STATUS_ACCESS_VIOLATION);
1473         ret = FALSE;
1474     }
1475     __ENDTRY
1476     return ret;
1477 }
1478 
1479 /* Warning: this assumes the address of value->Value.pbData is already set, in
1480  * order to avoid overwriting memory.  (In some cases, it may change it, if it
1481  * doesn't copy anything to memory.)  Be sure to set it correctly!
1482  */
1483 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1484  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1485  DWORD *pcbDecoded)
1486 {
1487     BOOL ret = TRUE;
1488     DWORD dataLen;
1489     CERT_NAME_VALUE *value = pvStructInfo;
1490 
1491     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1492     {
1493         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1494         DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1495 
1496         switch (pbEncoded[0])
1497         {
1498         case ASN_OCTETSTRING:
1499             valueType = CERT_RDN_OCTET_STRING;
1500             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1501                 bytesNeeded += dataLen;
1502             break;
1503         case ASN_NUMERICSTRING:
1504             valueType = CERT_RDN_NUMERIC_STRING;
1505             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1506                 bytesNeeded += dataLen;
1507             break;
1508         case ASN_PRINTABLESTRING:
1509             valueType = CERT_RDN_PRINTABLE_STRING;
1510             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1511                 bytesNeeded += dataLen;
1512             break;
1513         case ASN_IA5STRING:
1514             valueType = CERT_RDN_IA5_STRING;
1515             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1516                 bytesNeeded += dataLen;
1517             break;
1518         case ASN_T61STRING:
1519             valueType = CERT_RDN_T61_STRING;
1520             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1521                 bytesNeeded += dataLen;
1522             break;
1523         case ASN_VIDEOTEXSTRING:
1524             valueType = CERT_RDN_VIDEOTEX_STRING;
1525             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1526                 bytesNeeded += dataLen;
1527             break;
1528         case ASN_GRAPHICSTRING:
1529             valueType = CERT_RDN_GRAPHIC_STRING;
1530             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1531                 bytesNeeded += dataLen;
1532             break;
1533         case ASN_VISIBLESTRING:
1534             valueType = CERT_RDN_VISIBLE_STRING;
1535             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1536                 bytesNeeded += dataLen;
1537             break;
1538         case ASN_GENERALSTRING:
1539             valueType = CERT_RDN_GENERAL_STRING;
1540             if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1541                 bytesNeeded += dataLen;
1542             break;
1543         case ASN_UNIVERSALSTRING:
1544             FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1545             SetLastError(CRYPT_E_ASN1_BADTAG);
1546             return FALSE;
1547         case ASN_BMPSTRING:
1548             valueType = CERT_RDN_BMP_STRING;
1549             bytesNeeded += dataLen;
1550             break;
1551         case ASN_UTF8STRING:
1552             valueType = CERT_RDN_UTF8_STRING;
1553             bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1554              (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1555             break;
1556         default:
1557             SetLastError(CRYPT_E_ASN1_BADTAG);
1558             return FALSE;
1559         }
1560 
1561         if (pcbDecoded)
1562             *pcbDecoded = 1 + lenBytes + dataLen;
1563         if (!value)
1564             *pcbStructInfo = bytesNeeded;
1565         else if (*pcbStructInfo < bytesNeeded)
1566         {
1567             *pcbStructInfo = bytesNeeded;
1568             SetLastError(ERROR_MORE_DATA);
1569             ret = FALSE;
1570         }
1571         else
1572         {
1573             *pcbStructInfo = bytesNeeded;
1574             value->dwValueType = valueType;
1575             if (dataLen)
1576             {
1577                 DWORD i;
1578 
1579                 assert(value->Value.pbData);
1580                 switch (pbEncoded[0])
1581                 {
1582                 case ASN_OCTETSTRING:
1583                 case ASN_NUMERICSTRING:
1584                 case ASN_PRINTABLESTRING:
1585                 case ASN_IA5STRING:
1586                 case ASN_T61STRING:
1587                 case ASN_VIDEOTEXSTRING:
1588                 case ASN_GRAPHICSTRING:
1589                 case ASN_VISIBLESTRING:
1590                 case ASN_GENERALSTRING:
1591                     value->Value.cbData = dataLen;
1592                     if (dataLen)
1593                     {
1594                         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1595                             memcpy(value->Value.pbData,
1596                              pbEncoded + 1 + lenBytes, dataLen);
1597                         else
1598                             value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1599                              lenBytes;
1600                     }
1601                     break;
1602                 case ASN_BMPSTRING:
1603                 {
1604                     LPWSTR str = (LPWSTR)value->Value.pbData;
1605 
1606                     value->Value.cbData = dataLen;
1607                     for (i = 0; i < dataLen / 2; i++)
1608                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1609                          pbEncoded[1 + lenBytes + 2 * i + 1];
1610                     break;
1611                 }
1612                 case ASN_UTF8STRING:
1613                 {
1614                     LPWSTR str = (LPWSTR)value->Value.pbData;
1615 
1616                     value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1617                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1618                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1619                     break;
1620                 }
1621                 }
1622             }
1623             else
1624             {
1625                 value->Value.cbData = 0;
1626                 value->Value.pbData = NULL;
1627             }
1628         }
1629     }
1630     return ret;
1631 }
1632 
1633 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1634  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1635  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1636 {
1637     BOOL ret = TRUE;
1638 
1639     __TRY
1640     {
1641         ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1642          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1643         if (ret && pvStructInfo)
1644         {
1645             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1646              pcbStructInfo, *pcbStructInfo);
1647             if (ret)
1648             {
1649                 CERT_NAME_VALUE *value;
1650 
1651                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1652                     pvStructInfo = *(BYTE **)pvStructInfo;
1653                 value = pvStructInfo;
1654                 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1655                 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1656                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1657                  pcbStructInfo, NULL);
1658                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1659                     CRYPT_FreeSpace(pDecodePara, value);
1660             }
1661         }
1662     }
1663     __EXCEPT_PAGE_FAULT
1664     {
1665         SetLastError(STATUS_ACCESS_VIOLATION);
1666         ret = FALSE;
1667     }
1668     __ENDTRY
1669     return ret;
1670 }
1671 
1672 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1673  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1674  DWORD *pcbDecoded)
1675 {
1676     BOOL ret = TRUE;
1677     DWORD dataLen;
1678     CERT_NAME_VALUE *value = pvStructInfo;
1679 
1680     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1681     {
1682         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1683         DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1684 
1685         switch (pbEncoded[0])
1686         {
1687         case ASN_NUMERICSTRING:
1688             valueType = CERT_RDN_NUMERIC_STRING;
1689             if (dataLen)
1690                 bytesNeeded += (dataLen + 1) * 2;
1691             break;
1692         case ASN_PRINTABLESTRING:
1693             valueType = CERT_RDN_PRINTABLE_STRING;
1694             if (dataLen)
1695                 bytesNeeded += (dataLen + 1) * 2;
1696             break;
1697         case ASN_IA5STRING:
1698             valueType = CERT_RDN_IA5_STRING;
1699             if (dataLen)
1700                 bytesNeeded += (dataLen + 1) * 2;
1701             break;
1702         case ASN_T61STRING:
1703             valueType = CERT_RDN_T61_STRING;
1704             if (dataLen)
1705                 bytesNeeded += (dataLen + 1) * 2;
1706             break;
1707         case ASN_VIDEOTEXSTRING:
1708             valueType = CERT_RDN_VIDEOTEX_STRING;
1709             if (dataLen)
1710                 bytesNeeded += (dataLen + 1) * 2;
1711             break;
1712         case ASN_GRAPHICSTRING:
1713             valueType = CERT_RDN_GRAPHIC_STRING;
1714             if (dataLen)
1715                 bytesNeeded += (dataLen + 1) * 2;
1716             break;
1717         case ASN_VISIBLESTRING:
1718             valueType = CERT_RDN_VISIBLE_STRING;
1719             if (dataLen)
1720                 bytesNeeded += (dataLen + 1) * 2;
1721             break;
1722         case ASN_GENERALSTRING:
1723             valueType = CERT_RDN_GENERAL_STRING;
1724             if (dataLen)
1725                 bytesNeeded += (dataLen + 1) * 2;
1726             break;
1727         case ASN_UNIVERSALSTRING:
1728             valueType = CERT_RDN_UNIVERSAL_STRING;
1729             if (dataLen)
1730                 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1731             break;
1732         case ASN_BMPSTRING:
1733             valueType = CERT_RDN_BMP_STRING;
1734             if (dataLen)
1735                 bytesNeeded += dataLen + sizeof(WCHAR);
1736             break;
1737         case ASN_UTF8STRING:
1738             valueType = CERT_RDN_UTF8_STRING;
1739             if (dataLen)
1740                 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1741                  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1742             break;
1743         default:
1744             SetLastError(CRYPT_E_ASN1_BADTAG);
1745             return FALSE;
1746         }
1747 
1748         if (pcbDecoded)
1749             *pcbDecoded = 1 + lenBytes + dataLen;
1750         if (!value)
1751             *pcbStructInfo = bytesNeeded;
1752         else if (*pcbStructInfo < bytesNeeded)
1753         {
1754             *pcbStructInfo = bytesNeeded;
1755             SetLastError(ERROR_MORE_DATA);
1756             ret = FALSE;
1757         }
1758         else
1759         {
1760             *pcbStructInfo = bytesNeeded;
1761             value->dwValueType = valueType;
1762             if (dataLen)
1763             {
1764                 DWORD i;
1765                 LPWSTR str = (LPWSTR)value->Value.pbData;
1766 
1767                 assert(value->Value.pbData);
1768                 switch (pbEncoded[0])
1769                 {
1770                 case ASN_NUMERICSTRING:
1771                 case ASN_PRINTABLESTRING:
1772                 case ASN_IA5STRING:
1773                 case ASN_T61STRING:
1774                 case ASN_VIDEOTEXSTRING:
1775                 case ASN_GRAPHICSTRING:
1776                 case ASN_VISIBLESTRING:
1777                 case ASN_GENERALSTRING:
1778                     value->Value.cbData = dataLen * 2;
1779                     for (i = 0; i < dataLen; i++)
1780                         str[i] = pbEncoded[1 + lenBytes + i];
1781                     str[i] = 0;
1782                     break;
1783                 case ASN_UNIVERSALSTRING:
1784                     value->Value.cbData = dataLen / 2;
1785                     for (i = 0; i < dataLen / 4; i++)
1786                         str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1787                          | pbEncoded[1 + lenBytes + 2 * i + 3];
1788                     str[i] = 0;
1789                     break;
1790                 case ASN_BMPSTRING:
1791                     value->Value.cbData = dataLen;
1792                     for (i = 0; i < dataLen / 2; i++)
1793                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1794                          pbEncoded[1 + lenBytes + 2 * i + 1];
1795                     str[i] = 0;
1796                     break;
1797                 case ASN_UTF8STRING:
1798                     value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1799                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1800                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
1801                     *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
1802                     value->Value.cbData += sizeof(WCHAR);
1803                     break;
1804                 }
1805             }
1806             else
1807             {
1808                 value->Value.cbData = 0;
1809                 value->Value.pbData = NULL;
1810             }
1811         }
1812     }
1813     return ret;
1814 }
1815 
1816 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1817  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1818  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1819 {
1820     BOOL ret = TRUE;
1821 
1822     __TRY
1823     {
1824         ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1825          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1826         if (ret && pvStructInfo)
1827         {
1828             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1829              pcbStructInfo, *pcbStructInfo);
1830             if (ret)
1831             {
1832                 CERT_NAME_VALUE *value;
1833 
1834                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1835                     pvStructInfo = *(BYTE **)pvStructInfo;
1836                 value = pvStructInfo;
1837                 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1838                 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1839                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1840                  pcbStructInfo, NULL);
1841                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1842                     CRYPT_FreeSpace(pDecodePara, value);
1843             }
1844         }
1845     }
1846     __EXCEPT_PAGE_FAULT
1847     {
1848         SetLastError(STATUS_ACCESS_VIOLATION);
1849         ret = FALSE;
1850     }
1851     __ENDTRY
1852     return ret;
1853 }
1854 
1855 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1856  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1857 {
1858     BOOL ret;
1859     struct AsnDecodeSequenceItem items[] = {
1860      { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1861        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1862        offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1863      { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1864        CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1865        FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1866     };
1867     CERT_RDN_ATTR *attr = pvStructInfo;
1868 
1869     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1870      pvStructInfo, *pcbStructInfo);
1871 
1872     if (attr)
1873         TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1874     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1875      pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1876      attr ? attr->pszObjId : NULL);
1877     if (attr)
1878     {
1879         TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1880          debugstr_a(attr->pszObjId));
1881         TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1882     }
1883     TRACE("returning %d (%08x)\n", ret, GetLastError());
1884     return ret;
1885 }
1886 
1887 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1888  DWORD dwFlags,  void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1889 {
1890     BOOL ret = TRUE;
1891     struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1892      offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1893      sizeof(CERT_RDN),
1894      CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1895      offsetof(CERT_RDN_ATTR, pszObjId) };
1896 
1897     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1898      NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1899     return ret;
1900 }
1901 
1902 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1903  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1904  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1905 {
1906     BOOL ret = TRUE;
1907 
1908     __TRY
1909     {
1910         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1911          offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
1912          sizeof(CERT_NAME_INFO),
1913          CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1914          offsetof(CERT_RDN, rgRDNAttr) };
1915         DWORD bytesNeeded = 0;
1916 
1917         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1918          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
1919          NULL);
1920         if (ret)
1921         {
1922             if (!pvStructInfo)
1923                 *pcbStructInfo = bytesNeeded;
1924             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
1925              pvStructInfo, pcbStructInfo, bytesNeeded)))
1926             {
1927                 CERT_NAME_INFO *info;
1928 
1929                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1930                     pvStructInfo = *(BYTE **)pvStructInfo;
1931                 info = pvStructInfo;
1932                 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
1933                  sizeof(CERT_NAME_INFO));
1934                 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1935                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
1936                  &bytesNeeded, NULL);
1937                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1938                     CRYPT_FreeSpace(pDecodePara, info);
1939             }
1940         }
1941     }
1942     __EXCEPT_PAGE_FAULT
1943     {
1944         SetLastError(STATUS_ACCESS_VIOLATION);
1945         ret = FALSE;
1946     }
1947     __ENDTRY
1948     return ret;
1949 }
1950 
1951 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1952  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1953  DWORD *pcbDecoded)
1954 {
1955     BOOL ret;
1956     struct AsnDecodeSequenceItem items[] = {
1957      { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1958        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1959        offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1960      { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1961        CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1962        FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1963     };
1964     CERT_RDN_ATTR *attr = pvStructInfo;
1965 
1966     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1967      pvStructInfo, *pcbStructInfo);
1968 
1969     if (attr)
1970         TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1971     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1972      pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1973      attr ? attr->pszObjId : NULL);
1974     if (attr)
1975     {
1976         TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1977          debugstr_a(attr->pszObjId));
1978         TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1979     }
1980     TRACE("returning %d (%08x)\n", ret, GetLastError());
1981     return ret;
1982 }
1983 
1984 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1985  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1986 {
1987     BOOL ret = TRUE;
1988     struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1989      offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1990      sizeof(CERT_RDN),
1991      CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1992      offsetof(CERT_RDN_ATTR, pszObjId) };
1993 
1994     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1995      NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1996     return ret;
1997 }
1998 
1999 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
2000  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2001  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2002 {
2003     BOOL ret = TRUE;
2004 
2005     __TRY
2006     {
2007         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2008          offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
2009          sizeof(CERT_NAME_INFO),
2010          CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
2011          offsetof(CERT_RDN, rgRDNAttr) };
2012         DWORD bytesNeeded = 0;
2013 
2014         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2015          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
2016          NULL);
2017         if (ret)
2018         {
2019             if (!pvStructInfo)
2020                 *pcbStructInfo = bytesNeeded;
2021             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2022              pvStructInfo, pcbStructInfo, bytesNeeded)))
2023             {
2024                 CERT_NAME_INFO *info;
2025 
2026                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2027                     pvStructInfo = *(BYTE **)pvStructInfo;
2028                 info = pvStructInfo;
2029                 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
2030                  sizeof(CERT_NAME_INFO));
2031                 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2032                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
2033                  &bytesNeeded, NULL);
2034                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2035                     CRYPT_FreeSpace(pDecodePara, info);
2036             }
2037         }
2038     }
2039     __EXCEPT_PAGE_FAULT
2040     {
2041         SetLastError(STATUS_ACCESS_VIOLATION);
2042         ret = FALSE;
2043     }
2044     __ENDTRY
2045     return ret;
2046 }
2047 
2048 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
2049  DWORD *pcbDecoded)
2050 {
2051     BOOL ret = TRUE, done = FALSE;
2052     DWORD indefiniteNestingLevels = 0, decoded = 0;
2053 
2054     TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2055 
2056     do {
2057         DWORD dataLen;
2058 
2059         if (!cbEncoded)
2060             done = TRUE;
2061         else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2062          &dataLen)))
2063         {
2064             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2065 
2066             if (dataLen == CMSG_INDEFINITE_LENGTH)
2067             {
2068                 indefiniteNestingLevels++;
2069                 pbEncoded += 1 + lenBytes;
2070                 cbEncoded -= 1 + lenBytes;
2071                 decoded += 1 + lenBytes;
2072                 TRACE("indefiniteNestingLevels = %d\n",
2073                  indefiniteNestingLevels);
2074             }
2075             else
2076             {
2077                 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2078                  indefiniteNestingLevels)
2079                 {
2080                     indefiniteNestingLevels--;
2081                     TRACE("indefiniteNestingLevels = %d\n",
2082                      indefiniteNestingLevels);
2083                 }
2084                 pbEncoded += 1 + lenBytes + dataLen;
2085                 cbEncoded -= 1 + lenBytes + dataLen;
2086                 decoded += 1 + lenBytes + dataLen;
2087                 if (!indefiniteNestingLevels)
2088                     done = TRUE;
2089             }
2090         }
2091     } while (ret && !done);
2092     /* If we haven't found all 0 TLVs, we haven't found the end */
2093     if (ret && indefiniteNestingLevels)
2094     {
2095         SetLastError(CRYPT_E_ASN1_EOD);
2096         ret = FALSE;
2097     }
2098     if (ret)
2099         *pcbDecoded = decoded;
2100     TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2101     return ret;
2102 }
2103 
2104 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
2105  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2106  DWORD *pcbDecoded)
2107 {
2108     BOOL ret = TRUE;
2109     DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2110 
2111     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2112      pvStructInfo, *pcbStructInfo);
2113 
2114     if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2115     {
2116         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
2117             bytesNeeded += encodedLen;
2118         if (!pvStructInfo)
2119             *pcbStructInfo = bytesNeeded;
2120         else if (*pcbStructInfo < bytesNeeded)
2121         {
2122             SetLastError(ERROR_MORE_DATA);
2123             *pcbStructInfo = bytesNeeded;
2124             ret = FALSE;
2125         }
2126         else
2127         {
2128             PCRYPT_OBJID_BLOB blob = pvStructInfo;
2129 
2130             *pcbStructInfo = bytesNeeded;
2131             blob->cbData = encodedLen;
2132             if (encodedLen)
2133             {
2134                 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2135                     blob->pbData = (LPBYTE)pbEncoded;
2136                 else
2137                 {
2138                     assert(blob->pbData);
2139                     memcpy(blob->pbData, pbEncoded, blob->cbData);
2140                 }
2141             }
2142             else
2143                 blob->pbData = NULL;
2144         }
2145         if (pcbDecoded)
2146             *pcbDecoded = encodedLen;
2147     }
2148     return ret;
2149 }
2150 
2151 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2152  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2153 {
2154     BOOL ret;
2155     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2156      offsetof(CTL_USAGE, cUsageIdentifier),
2157      offsetof(CTL_USAGE, rgpszUsageIdentifier),
2158      sizeof(CTL_USAGE),
2159      CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2160 
2161     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2162      NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2163     return ret;
2164 }
2165 
2166 static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded,
2167  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2168  DWORD *pcbDecoded)
2169 {
2170     struct AsnArrayDescriptor arrayDesc = { 0,
2171      offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
2172      FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
2173      CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2174      offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2175     BOOL ret;
2176 
2177     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2178      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2179     return ret;
2180 }
2181 
2182 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2183  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2184 {
2185     struct AsnDecodeSequenceItem items[] = {
2186      { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2187        CRYPT_AsnDecodeOctets, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2188        offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2189      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2190        CRYPT_AsnDecodeCTLEntryAttributes,
2191        FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
2192        offsetof(CTL_ENTRY, rgAttribute), 0 },
2193     };
2194     BOOL ret = TRUE;
2195     CTL_ENTRY *entry = pvStructInfo;
2196 
2197     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2198      *pcbStructInfo);
2199 
2200     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2201      pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2202      pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2203     return ret;
2204 }
2205 
2206 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2207  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2208 {
2209     BOOL ret;
2210     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2211      offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
2212      FINALMEMBERSIZE(CTL_INFO, cExtension),
2213      CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2214      offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2215 
2216     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2217      pvStructInfo, *pcbStructInfo, pcbDecoded);
2218 
2219     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2220      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2221     return ret;
2222 }
2223 
2224 static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded,
2225  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2226  DWORD *pcbDecoded)
2227 {
2228     BOOL ret = TRUE;
2229     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2230      offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
2231      FINALMEMBERSIZE(CTL_INFO, cExtension),
2232      CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
2233      offsetof(CERT_EXTENSION, pszObjId) };
2234 
2235     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2236      pvStructInfo, *pcbStructInfo, pcbDecoded);
2237 
2238     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2239      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2240     return ret;
2241 }
2242 
2243 static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded,
2244  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2245  DWORD *pcbDecoded)
2246 {
2247     BOOL ret;
2248     DWORD dataLen;
2249 
2250     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2251     {
2252         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2253 
2254         ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes,
2255          dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
2256         if (ret && pcbDecoded)
2257             *pcbDecoded = 1 + lenBytes + dataLen;
2258     }
2259     return ret;
2260 }
2261 
2262 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2263  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2264  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2265 {
2266     BOOL ret = FALSE;
2267 
2268     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2269      pDecodePara, pvStructInfo, *pcbStructInfo);
2270 
2271     __TRY
2272     {
2273         struct AsnDecodeSequenceItem items[] = {
2274          { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2275            CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2276          { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2277            CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2278            offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2279          { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2280            CRYPT_AsnDecodeOctets, sizeof(CRYPT_DATA_BLOB), TRUE,
2281            TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2282          { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2283            CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2284            TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2285          { 0, offsetof(CTL_INFO, ThisUpdate),
2286            CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2287            0 },
2288          { 0, offsetof(CTL_INFO, NextUpdate),
2289            CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2290            0 },
2291          { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2292            CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2293            FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2294          { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2295            CRYPT_AsnDecodeCTLEntries,
2296            MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2297            TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2298          { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2299            CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension),
2300            TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
2301         };
2302 
2303         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2304          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2305          pcbStructInfo, NULL, NULL);
2306     }
2307     __EXCEPT_PAGE_FAULT
2308     {
2309         SetLastError(STATUS_ACCESS_VIOLATION);
2310     }
2311     __ENDTRY
2312     return ret;
2313 }
2314 
2315 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2316  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2317  DWORD *pcbDecoded)
2318 {
2319     BOOL ret;
2320     struct AsnDecodeSequenceItem items[] = {
2321      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2322        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2323        offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2324      { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2325        CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2326        offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2327     };
2328     PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2329 
2330     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2331      pvStructInfo, *pcbStructInfo);
2332 
2333     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2334      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2335      pcbDecoded, capability ? capability->pszObjId : NULL);
2336     TRACE("returning %d\n", ret);
2337     return ret;
2338 }
2339 
2340 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2341  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2342  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2343 {
2344     BOOL ret = FALSE;
2345 
2346     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2347      pDecodePara, pvStructInfo, *pcbStructInfo);
2348 
2349     __TRY
2350     {
2351         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2352          offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
2353          offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
2354          sizeof(CRYPT_SMIME_CAPABILITIES),
2355          CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2356          offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2357         CRYPT_SMIME_CAPABILITIES *capabilities = pvStructInfo;
2358 
2359         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2360             capabilities->rgCapability = (CRYPT_SMIME_CAPABILITY *)(capabilities + 1);
2361         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2362          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2363     }
2364     __EXCEPT_PAGE_FAULT
2365     {
2366         SetLastError(STATUS_ACCESS_VIOLATION);
2367     }
2368     __ENDTRY
2369     TRACE("returning %d\n", ret);
2370     return ret;
2371 }
2372 
2373 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2374  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2375  DWORD *pcbDecoded)
2376 {
2377     BOOL ret = TRUE;
2378     DWORD dataLen;
2379     LPSTR *pStr = pvStructInfo;
2380 
2381     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2382     {
2383         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2384         DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2385 
2386         if (pbEncoded[0] != ASN_IA5STRING)
2387         {
2388             SetLastError(CRYPT_E_ASN1_CORRUPT);
2389             ret = FALSE;
2390         }
2391         else
2392         {
2393             bytesNeeded += dataLen;
2394             if (pcbDecoded)
2395                 *pcbDecoded = 1 + lenBytes + dataLen;
2396             if (!pvStructInfo)
2397                 *pcbStructInfo = bytesNeeded;
2398             else if (*pcbStructInfo < bytesNeeded)
2399             {
2400                 *pcbStructInfo = bytesNeeded;
2401                 SetLastError(ERROR_MORE_DATA);
2402                 ret = FALSE;
2403             }
2404             else
2405             {
2406                 *pcbStructInfo = bytesNeeded;
2407                 if (dataLen)
2408                 {
2409                     LPSTR str = *pStr;
2410 
2411                     assert(str);
2412                     memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2413                     str[dataLen] = 0;
2414                 }
2415                 else
2416                     *pStr = NULL;
2417             }
2418         }
2419     }
2420     return ret;
2421 }
2422 
2423 static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded,
2424  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2425  DWORD *pcbDecoded)
2426 {
2427     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2428      offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2429      offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers),
2430      FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2431      CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2432     BOOL ret;
2433 
2434     TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2435      pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2436 
2437     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2438      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2439     TRACE("returning %d\n", ret);
2440     return ret;
2441 }
2442 
2443 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2444  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2445  DWORD *pcbDecoded)
2446 {
2447     BOOL ret;
2448     struct AsnDecodeSequenceItem items[] = {
2449      { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2450        pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2451        offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2452      { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2453        cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
2454        FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2455        FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2456        rgNoticeNumbers), 0 },
2457     };
2458     DWORD bytesNeeded = 0;
2459 
2460     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2461      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2462 
2463     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2464      pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2465      NULL);
2466     if (ret)
2467     {
2468         /* The caller is expecting a pointer to a
2469          * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2470          * CRYPT_AsnDecodeSequence is decoding a
2471          * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.  Increment the bytes
2472          * needed, and decode again if the requisite space is available.
2473          */
2474         bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2475         if (!pvStructInfo)
2476             *pcbStructInfo = bytesNeeded;
2477         else if (*pcbStructInfo < bytesNeeded)
2478         {
2479             *pcbStructInfo = bytesNeeded;
2480             SetLastError(ERROR_MORE_DATA);
2481             ret = FALSE;
2482         }
2483         else
2484         {
2485             PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2486 
2487             *pcbStructInfo = bytesNeeded;
2488             /* The pointer (pvStructInfo) passed in points to the first dynamic
2489              * pointer, so use it as the pointer to the
2490              * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2491              * appropriate offset for the first dynamic pointer within the
2492              * notice reference by pointing to the first memory location past
2493              * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2494              */
2495             noticeRef =
2496              *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2497             noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2498              sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2499             ret = CRYPT_AsnDecodeSequence(items,
2500              sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2501              NULL, noticeRef, &bytesNeeded, pcbDecoded,
2502              noticeRef->pszOrganization);
2503         }
2504     }
2505     TRACE("returning %d\n", ret);
2506     return ret;
2507 }
2508 
2509 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2510  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2511  DWORD *pcbDecoded)
2512 {
2513     BOOL ret = TRUE;
2514     DWORD dataLen;
2515 
2516     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2517     {
2518         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2519         DWORD bytesNeeded = sizeof(LPWSTR);
2520 
2521         switch (pbEncoded[0])
2522         {
2523         case ASN_NUMERICSTRING:
2524             if (dataLen)
2525                 bytesNeeded += (dataLen + 1) * 2;
2526             break;
2527         case ASN_PRINTABLESTRING:
2528             if (dataLen)
2529                 bytesNeeded += (dataLen + 1) * 2;
2530             break;
2531         case ASN_IA5STRING:
2532             if (dataLen)
2533                 bytesNeeded += (dataLen + 1) * 2;
2534             break;
2535         case ASN_T61STRING:
2536             if (dataLen)
2537                 bytesNeeded += (dataLen + 1) * 2;
2538             break;
2539         case ASN_VIDEOTEXSTRING:
2540             if (dataLen)
2541                 bytesNeeded += (dataLen + 1) * 2;
2542             break;
2543         case ASN_GRAPHICSTRING:
2544             if (dataLen)
2545                 bytesNeeded += (dataLen + 1) * 2;
2546             break;
2547         case ASN_VISIBLESTRING:
2548             if (dataLen)
2549                 bytesNeeded += (dataLen + 1) * 2;
2550             break;
2551         case ASN_GENERALSTRING:
2552             if (dataLen)
2553                 bytesNeeded += (dataLen + 1) * 2;
2554             break;
2555         case ASN_UNIVERSALSTRING:
2556             if (dataLen)
2557                 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2558             break;
2559         case ASN_BMPSTRING:
2560             if (dataLen)
2561                 bytesNeeded += dataLen + sizeof(WCHAR);
2562             break;
2563         case ASN_UTF8STRING:
2564             if (dataLen)
2565                 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2566                  (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2567             break;
2568         default:
2569             SetLastError(CRYPT_E_ASN1_BADTAG);
2570             return FALSE;
2571         }
2572 
2573         if (pcbDecoded)
2574             *pcbDecoded = 1 + lenBytes + dataLen;
2575         if (!pvStructInfo)
2576             *pcbStructInfo = bytesNeeded;
2577         else if (*pcbStructInfo < bytesNeeded)
2578         {
2579             *pcbStructInfo = bytesNeeded;
2580             SetLastError(ERROR_MORE_DATA);
2581             ret = FALSE;
2582         }
2583         else
2584         {
2585             LPWSTR *pStr = pvStructInfo;
2586 
2587             *pcbStructInfo = bytesNeeded;
2588             if (dataLen)
2589             {
2590                 DWORD i;
2591                 LPWSTR str = *(LPWSTR *)pStr;
2592 
2593                 assert(str);
2594                 switch (pbEncoded[0])
2595                 {
2596                 case ASN_NUMERICSTRING:
2597                 case ASN_PRINTABLESTRING:
2598                 case ASN_IA5STRING:
2599                 case ASN_T61STRING:
2600                 case ASN_VIDEOTEXSTRING:
2601                 case ASN_GRAPHICSTRING:
2602                 case ASN_VISIBLESTRING:
2603                 case ASN_GENERALSTRING:
2604                     for (i = 0; i < dataLen; i++)
2605                         str[i] = pbEncoded[1 + lenBytes + i];
2606                     str[i] = 0;
2607                     break;
2608                 case ASN_UNIVERSALSTRING:
2609                     for (i = 0; i < dataLen / 4; i++)
2610                         str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2611                          | pbEncoded[1 + lenBytes + 2 * i + 3];
2612                     str[i] = 0;
2613                     break;
2614                 case ASN_BMPSTRING:
2615                     for (i = 0; i < dataLen / 2; i++)
2616                         str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2617                          pbEncoded[1 + lenBytes + 2 * i + 1];
2618                     str[i] = 0;
2619                     break;
2620                 case ASN_UTF8STRING:
2621                 {
2622                     int len = MultiByteToWideChar(CP_UTF8, 0,
2623                      (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2624                      str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2625                     str[len] = 0;
2626                     break;
2627                 }
2628                 }
2629             }
2630             else
2631                 *pStr = NULL;
2632         }
2633     }
2634     return ret;
2635 }
2636 
2637 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2638  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2639  DWORD *pcbStructInfo, DWORD *pcbDecoded)
2640 {
2641     BOOL ret;
2642     struct AsnDecodeSequenceItem items[] = {
2643      { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2644        pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2645        sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2646        offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2647      { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2648        CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2649        offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2650     };
2651     PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2652 
2653     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2654      pvStructInfo, *pcbStructInfo);
2655 
2656     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2657      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2658      pcbDecoded, notice ? notice->pNoticeReference : NULL);
2659     TRACE("returning %d\n", ret);
2660     return ret;
2661 }
2662 
2663 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2664  DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2665  DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2666  void *pvStructInfo, DWORD *pcbStructInfo)
2667 {
2668     BOOL ret = FALSE;
2669 
2670     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2671      pDecodePara, pvStructInfo, *pcbStructInfo);
2672 
2673     __TRY
2674     {
2675         DWORD bytesNeeded = 0;
2676 
2677         ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2678          cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2679          NULL);
2680         if (ret)
2681         {
2682             if (!pvStructInfo)
2683                 *pcbStructInfo = bytesNeeded;
2684             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2685              pvStructInfo, pcbStructInfo, bytesNeeded)))
2686             {
2687                 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2688 
2689                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2690                     pvStructInfo = *(BYTE **)pvStructInfo;
2691                 notice = pvStructInfo;
2692                 notice->pNoticeReference =
2693                  (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2694                  ((BYTE *)pvStructInfo +
2695                  sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2696                 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2697                  pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2698                  pvStructInfo, &bytesNeeded, NULL);
2699                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2700                     CRYPT_FreeSpace(pDecodePara, notice);
2701             }
2702         }
2703     }
2704     __EXCEPT_PAGE_FAULT
2705     {
2706         SetLastError(STATUS_ACCESS_VIOLATION);
2707     }
2708     __ENDTRY
2709     TRACE("returning %d\n", ret);
2710     return ret;
2711 }
2712 
2713 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
2714  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2715  DWORD *pcbDecoded)
2716 {
2717     BOOL ret;
2718     struct AsnArrayDescriptor arrayDesc = { 0,
2719      offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
2720      FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue),
2721      CRYPT_AsnDecodeCopyBytes,
2722      sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2723 
2724     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2725      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
2726 
2727     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2728      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2729     return ret;
2730 }
2731 
2732 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2733  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2734  DWORD *pcbDecoded)
2735 {
2736     BOOL ret;
2737     struct AsnDecodeSequenceItem items[] = {
2738      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2739        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2740        offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2741      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2742        CRYPT_AsnDecodePKCSAttributeValue,
2743        FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
2744        TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2745     };
2746     PCRYPT_ATTRIBUTE attr = pvStructInfo;
2747 
2748     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2749      pvStructInfo, *pcbStructInfo);
2750 
2751     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2752      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2753      pcbDecoded, attr ? attr->pszObjId : NULL);
2754     TRACE("returning %d\n", ret);
2755     return ret;
2756 }
2757 
2758 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2759  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2760  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2761 {
2762     BOOL ret = FALSE;
2763 
2764     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2765      pDecodePara, pvStructInfo, *pcbStructInfo);
2766 
2767     __TRY
2768     {
2769         DWORD bytesNeeded = 0;
2770 
2771         ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2772          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2773         if (ret)
2774         {
2775             if (!pvStructInfo)
2776                 *pcbStructInfo = bytesNeeded;
2777             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2778              pvStructInfo, pcbStructInfo, bytesNeeded)))
2779             {
2780                 PCRYPT_ATTRIBUTE attr;
2781 
2782                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2783                     pvStructInfo = *(BYTE **)pvStructInfo;
2784                 attr = pvStructInfo;
2785                 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2786                  sizeof(CRYPT_ATTRIBUTE));
2787                 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2788                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2789                  NULL);
2790                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2791                     CRYPT_FreeSpace(pDecodePara, attr);
2792             }
2793         }
2794     }
2795     __EXCEPT_PAGE_FAULT
2796     {
2797         SetLastError(STATUS_ACCESS_VIOLATION);
2798     }
2799     __ENDTRY
2800     TRACE("returning %d\n", ret);
2801     return ret;
2802 }
2803 
2804 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2805  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2806  DWORD *pcbDecoded)
2807 {
2808     struct AsnArrayDescriptor arrayDesc = { 0,
2809      offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2810      sizeof(CRYPT_ATTRIBUTES),
2811      CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2812      offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2813     BOOL ret;
2814 
2815     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2816      NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2817     return ret;
2818 }
2819 
2820 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2821  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2822  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2823 {
2824     BOOL ret = FALSE;
2825 
2826     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2827      pDecodePara, pvStructInfo, *pcbStructInfo);
2828 
2829     __TRY
2830     {
2831         struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2832          offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2833          sizeof(CRYPT_ATTRIBUTES),
2834          CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
2835          TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2836         CRYPT_ATTRIBUTES *attrs = pvStructInfo;
2837 
2838         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2839             attrs->rgAttr = (CRYPT_ATTRIBUTE *)(attrs + 1);
2840         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2841          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2842     }
2843     __EXCEPT_PAGE_FAULT
2844     {
2845         SetLastError(STATUS_ACCESS_VIOLATION);
2846     }
2847     __ENDTRY
2848     TRACE("returning %d\n", ret);
2849     return ret;
2850 }
2851 
2852 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2853  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2854 {
2855     CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2856     BOOL ret = TRUE;
2857     struct AsnDecodeSequenceItem items[] = {
2858      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2859        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2860        offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2861      { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2862        CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2863        offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2864     };
2865 
2866     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2867      pvStructInfo, *pcbStructInfo, pcbDecoded);
2868 
2869     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2870      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2871      pcbDecoded, algo ? algo->pszObjId : NULL);
2872     if (ret && pvStructInfo)
2873     {
2874         TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2875          debugstr_a(algo->pszObjId));
2876     }
2877     return ret;
2878 }
2879 
2880 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2881  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2882  DWORD *pcbDecoded)
2883 {
2884     BOOL ret = TRUE;
2885     struct AsnDecodeSequenceItem items[] = {
2886      { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2887        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2888        FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2889        Algorithm.pszObjId) },
2890      { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2891        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2892        offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2893     };
2894     PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2895 
2896     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2897      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2898      pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2899     return ret;
2900 }
2901 
2902 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2903  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2904  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2905 {
2906     BOOL ret = TRUE;
2907 
2908     __TRY
2909     {
2910         DWORD bytesNeeded = 0;
2911 
2912         if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2913          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2914         {
2915             if (!pvStructInfo)
2916                 *pcbStructInfo = bytesNeeded;
2917             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2918              pvStructInfo, pcbStructInfo, bytesNeeded)))
2919             {
2920                 PCERT_PUBLIC_KEY_INFO info;
2921 
2922                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2923                     pvStructInfo = *(BYTE **)pvStructInfo;
2924                 info = pvStructInfo;
2925                 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2926                  sizeof(CERT_PUBLIC_KEY_INFO);
2927                 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2928                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2929                  &bytesNeeded, NULL);
2930                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2931                     CRYPT_FreeSpace(pDecodePara, info);
2932             }
2933         }
2934     }
2935     __EXCEPT_PAGE_FAULT
2936     {
2937         SetLastError(STATUS_ACCESS_VIOLATION);
2938         ret = FALSE;
2939     }
2940     __ENDTRY
2941     return ret;
2942 }
2943 
2944 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2945  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2946 {
2947     BOOL ret;
2948 
2949     if (cbEncoded < 3)
2950     {
2951         SetLastError(CRYPT_E_ASN1_CORRUPT);
2952         return FALSE;
2953     }
2954     if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2955     {
2956         SetLastError(CRYPT_E_ASN1_CORRUPT);
2957         return FALSE;
2958     }
2959     if (pbEncoded[1] > 1)
2960     {
2961         SetLastError(CRYPT_E_ASN1_CORRUPT);
2962         return FALSE;
2963     }
2964     if (pcbDecoded)
2965         *pcbDecoded = 3;
2966     if (!pvStructInfo)
2967     {
2968         *pcbStructInfo = sizeof(BOOL);
2969         ret = TRUE;
2970     }
2971     else if (*pcbStructInfo < sizeof(BOOL))
2972     {
2973         *pcbStructInfo = sizeof(BOOL);
2974         SetLastError(ERROR_MORE_DATA);
2975         ret = FALSE;
2976     }
2977     else
2978     {
2979         *pcbStructInfo = sizeof(BOOL);
2980         *(BOOL *)pvStructInfo = pbEncoded[2] != 0;
2981         ret = TRUE;
2982     }
2983     TRACE("returning %d (%08x)\n", ret, GetLastError());
2984     return ret;
2985 }
2986 
2987 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2988  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2989 {
2990     PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2991     DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2992     BOOL ret;
2993 
2994     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2995      pvStructInfo, *pcbStructInfo);
2996 
2997     if (cbEncoded < 2)
2998     {
2999         SetLastError(CRYPT_E_ASN1_CORRUPT);
3000         return FALSE;
3001     }
3002     lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3003     if (1 + lenBytes > cbEncoded)
3004     {
3005         SetLastError(CRYPT_E_ASN1_CORRUPT);
3006         return FALSE;
3007     }
3008     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3009     {
3010         switch (pbEncoded[0] & ASN_TYPE_MASK)
3011         {
3012         case 1: /* rfc822Name */
3013         case 2: /* dNSName */
3014         case 6: /* uniformResourceIdentifier */
3015             if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen))
3016             {
3017                 SetLastError(CRYPT_E_ASN1_RULE);
3018                 ret = FALSE;
3019             }
3020             else
3021                 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
3022             break;
3023         case 4: /* directoryName */
3024         case 7: /* iPAddress */
3025             bytesNeeded += dataLen;
3026             break;
3027         case 8: /* registeredID */
3028             ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
3029              &dataLen, NULL);
3030             if (ret)
3031             {
3032                 /* FIXME: ugly, shouldn't need to know internals of OID decode
3033                  * function to use it.
3034                  */
3035                 bytesNeeded += dataLen - sizeof(LPSTR);
3036             }
3037             break;
3038         case 0: /* otherName */
3039             FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
3040             SetLastError(CRYPT_E_ASN1_BADTAG);
3041             ret = FALSE;
3042             break;
3043         case 3: /* x400Address, unimplemented */
3044         case 5: /* ediPartyName, unimplemented */
3045             TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
3046             SetLastError(CRYPT_E_ASN1_BADTAG);
3047             ret = FALSE;
3048             break;
3049         default:
3050             TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
3051             SetLastError(CRYPT_E_ASN1_CORRUPT);
3052             ret = FALSE;
3053         }
3054         if (ret)
3055         {
3056             if (pcbDecoded)
3057                 *pcbDecoded = 1 + lenBytes + dataLen;
3058             if (!entry)
3059                 *pcbStructInfo = bytesNeeded;
3060             else if (*pcbStructInfo < bytesNeeded)
3061             {
3062                 *pcbStructInfo = bytesNeeded;
3063                 SetLastError(ERROR_MORE_DATA);
3064                 ret = FALSE;
3065             }
3066             else
3067             {
3068                 *pcbStructInfo = bytesNeeded;
3069                 /* MS used values one greater than the asn1 ones.. sigh */
3070                 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
3071                 switch (pbEncoded[0] & ASN_TYPE_MASK)
3072                 {
3073                 case 1: /* rfc822Name */
3074                 case 2: /* dNSName */
3075                 case 6: /* uniformResourceIdentifier */
3076                 {
3077                     DWORD i;
3078 
3079                     for (i = 0; i < dataLen; i++)
3080                         entry->u.pwszURL[i] =
3081                          (WCHAR)pbEncoded[1 + lenBytes + i];
3082                     entry->u.pwszURL[i] = 0;
3083                     TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3084                      debugstr_w(entry->u.pwszURL));
3085                     break;
3086                 }
3087                 case 4: /* directoryName */
3088                     /* The data are memory-equivalent with the IPAddress case,
3089                      * fall-through
3090                      */
3091                 case 7: /* iPAddress */
3092                     /* The next data pointer is in the pwszURL spot, that is,
3093                      * the first 4 bytes.  Need to move it to the next spot.
3094                      */
3095                     entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3096                     entry->u.IPAddress.cbData = dataLen;
3097                     memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3098                      dataLen);
3099                     break;
3100                 case 8: /* registeredID */
3101                     ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
3102                      &entry->u.pszRegisteredID, &dataLen, NULL);
3103                     break;
3104                 }
3105             }
3106         }
3107     }
3108     return ret;
3109 }
3110 
3111 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
3112  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3113  DWORD *pcbDecoded)
3114 {
3115     BOOL ret;
3116     struct AsnArrayDescriptor arrayDesc = { 0,
3117      offsetof(CERT_ALT_NAME_INFO, cAltEntry),
3118      offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
3119      sizeof(CERT_ALT_NAME_INFO),
3120      CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3121      offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3122 
3123     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3124      pvStructInfo, *pcbStructInfo, pcbDecoded);
3125 
3126     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3127      NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3128     return ret;
3129 }
3130 
3131 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3132  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3133  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3134 {
3135     BOOL ret;
3136 
3137     __TRY
3138     {
3139         struct AsnDecodeSequenceItem items[] = {
3140          { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3141            CRYPT_AsnDecodeOctets, sizeof(CRYPT_DATA_BLOB),
3142            TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3143          { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3144            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3145            CRYPT_AsnDecodeOctets, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3146            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3147          { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3148            CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3149            sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3150            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3151         };
3152 
3153         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3154          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3155          pcbStructInfo, NULL, NULL);
3156     }
3157     __EXCEPT_PAGE_FAULT
3158     {
3159         SetLastError(STATUS_ACCESS_VIOLATION);
3160         ret = FALSE;
3161     }
3162     __ENDTRY
3163     return ret;
3164 }
3165 
3166 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3167  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3168  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3169 {
3170     BOOL ret;
3171 
3172     __TRY
3173     {
3174         struct AsnDecodeSequenceItem items[] = {
3175          { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3176            CRYPT_AsnDecodeOctets, sizeof(CRYPT_DATA_BLOB),
3177            TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3178          { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3179            offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3180            CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3181            TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3182            AuthorityCertIssuer.rgAltEntry), 0 },
3183          { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3184            AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3185            sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3186            offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3187            AuthorityCertSerialNumber.pbData), 0 },
3188         };
3189 
3190         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3191          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3192          pcbStructInfo, NULL, NULL);
3193     }
3194     __EXCEPT_PAGE_FAULT
3195     {
3196         SetLastError(STATUS_ACCESS_VIOLATION);
3197         ret = FALSE;
3198     }
3199     __ENDTRY
3200     return ret;
3201 }
3202 
3203 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3204  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3205  DWORD *pcbDecoded)
3206 {
3207     struct AsnDecodeSequenceItem items[] = {
3208      { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3209        CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3210        offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3211      { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3212        CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3213        TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3214     };
3215     CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3216 
3217     return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3218      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3219      pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3220 }
3221 
3222 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3223  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3224  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3225 {
3226     BOOL ret;
3227 
3228     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3229      pDecodePara, pvStructInfo, *pcbStructInfo);
3230 
3231     __TRY
3232     {
3233         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3234          offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr),
3235          offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr),
3236          sizeof(CERT_AUTHORITY_INFO_ACCESS),
3237          CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3238          TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3239         CERT_AUTHORITY_INFO_ACCESS *info = pvStructInfo;
3240 
3241         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3242             info->rgAccDescr = (CERT_ACCESS_DESCRIPTION *)(info + 1);
3243         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3244          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3245     }
3246     __EXCEPT_PAGE_FAULT
3247     {
3248         SetLastError(STATUS_ACCESS_VIOLATION);
3249         ret = FALSE;
3250     }
3251     __ENDTRY
3252     return ret;
3253 }
3254 
3255 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3256  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3257 {
3258     BOOL ret;
3259     DWORD dataLen;
3260 
3261     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3262      pvStructInfo, *pcbStructInfo, pcbDecoded);
3263 
3264     /* The caller has already checked the tag, no need to check it again.
3265      * Check the outer length is valid:
3266      */
3267     if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3268     {
3269         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3270         DWORD innerLen;
3271 
3272         pbEncoded += 1 + lenBytes;
3273         cbEncoded -= 1 + lenBytes;
3274         if (dataLen == CMSG_INDEFINITE_LENGTH)
3275             cbEncoded -= 2; /* space for 0 TLV */
3276         /* Check the inner length is valid: */
3277         if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3278         {
3279             DWORD decodedLen;
3280 
3281             ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3282              pvStructInfo, pcbStructInfo, &decodedLen);
3283             if (dataLen == CMSG_INDEFINITE_LENGTH)
3284             {
3285                 if (*(pbEncoded + decodedLen) != 0 ||
3286                  *(pbEncoded + decodedLen + 1) != 0)
3287                 {
3288                     TRACE("expected 0 TLV, got {%02x,%02x}\n",
3289                      *(pbEncoded + decodedLen),
3290                      *(pbEncoded + decodedLen + 1));
3291                     SetLastError(CRYPT_E_ASN1_CORRUPT);
3292                     ret = FALSE;
3293                 }
3294                 else
3295                     decodedLen += 2;
3296             }
3297             if (ret && pcbDecoded)
3298             {
3299                 *pcbDecoded = 1 + lenBytes + decodedLen;
3300                 TRACE("decoded %d bytes\n", *pcbDecoded);
3301             }
3302         }
3303     }
3304     return ret;
3305 }
3306 
3307 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3308  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3309  DWORD *pcbDecoded)
3310 {
3311     CRYPT_CONTENT_INFO *info = pvStructInfo;
3312     struct AsnDecodeSequenceItem items[] = {
3313      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3314        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3315        offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3316      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3317        offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3318        sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3319        offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3320     };
3321     BOOL ret;
3322 
3323     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3324      pvStructInfo, *pcbStructInfo, pcbDecoded);
3325 
3326     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3327      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3328      pcbDecoded, info ? info->pszObjId : NULL);
3329     return ret;
3330 }
3331 
3332 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3333  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3334  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3335 {
3336     BOOL ret = FALSE;
3337 
3338     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3339      pDecodePara, pvStructInfo, *pcbStructInfo);
3340 
3341     __TRY
3342     {
3343         ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3344          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3345         if (ret && pvStructInfo)
3346         {
3347             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3348              pcbStructInfo, *pcbStructInfo);
3349             if (ret)
3350             {
3351                 CRYPT_CONTENT_INFO *info;
3352 
3353                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3354                     pvStructInfo = *(BYTE **)pvStructInfo;
3355                 info = pvStructInfo;
3356                 info->pszObjId = (LPSTR)((BYTE *)info +
3357                  sizeof(CRYPT_CONTENT_INFO));
3358                 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3359                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3360                  pcbStructInfo, NULL);
3361                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3362                     CRYPT_FreeSpace(pDecodePara, info);
3363             }
3364         }
3365     }
3366     __EXCEPT_PAGE_FAULT
3367     {
3368         SetLastError(STATUS_ACCESS_VIOLATION);
3369     }
3370     __ENDTRY
3371     return ret;
3372 }
3373 
3374 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3375  DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3376  CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3377 {
3378     BOOL ret;
3379     struct AsnDecodeSequenceItem items[] = {
3380      { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3381        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3382      { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3383        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3384        FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3385        0 },
3386      { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3387        CRYPT_AsnDecodePKCSContentInfoInternal,
3388        sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3389        ContentInfo.pszObjId), 0 },
3390      { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3391        CRYPT_AsnDecodeOctets, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3392        offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3393     };
3394 
3395     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3396      pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3397      NULL, NULL);
3398     return ret;
3399 }
3400 
3401 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3402  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3403  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3404 {
3405     BOOL ret = TRUE;
3406 
3407     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3408      pDecodePara, pvStructInfo, *pcbStructInfo);
3409 
3410     __TRY
3411     {
3412         DWORD bytesNeeded = 0;
3413 
3414         if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3415          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3416         {
3417             if (!pvStructInfo)
3418                 *pcbStructInfo = bytesNeeded;
3419             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3420              pvStructInfo, pcbStructInfo, bytesNeeded)))
3421             {
3422                 CERT_ALT_NAME_INFO *name;
3423 
3424                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3425                     pvStructInfo = *(BYTE **)pvStructInfo;
3426                 name = pvStructInfo;
3427                 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3428                  ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3429                 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3430                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3431                  &bytesNeeded, NULL);
3432                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3433                     CRYPT_FreeSpace(pDecodePara, name);
3434             }
3435         }
3436     }
3437     __EXCEPT_PAGE_FAULT
3438     {
3439         SetLastError(STATUS_ACCESS_VIOLATION);
3440         ret = FALSE;
3441     }
3442     __ENDTRY
3443     return ret;
3444 }
3445 
3446 struct PATH_LEN_CONSTRAINT
3447 {
3448     BOOL  fPathLenConstraint;
3449     DWORD dwPathLenConstraint;
3450 };
3451 
3452 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3453  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3454  DWORD *pcbDecoded)
3455 {
3456     BOOL ret = TRUE;
3457     DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3458 
3459     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3460      pvStructInfo, *pcbStructInfo, pcbDecoded);
3461 
3462     if (!pvStructInfo)
3463     {
3464         ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3465          &size, pcbDecoded);
3466         *pcbStructInfo = bytesNeeded;
3467     }
3468     else if (*pcbStructInfo < bytesNeeded)
3469     {
3470         SetLastError(ERROR_MORE_DATA);
3471         *pcbStructInfo = bytesNeeded;
3472         ret = FALSE;
3473     }
3474     else
3475     {
3476         struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3477 
3478         *pcbStructInfo = bytesNeeded;
3479         size = sizeof(constraint->dwPathLenConstraint);
3480         ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3481          &constraint->dwPathLenConstraint, &size, pcbDecoded);
3482         if (ret)
3483             constraint->fPathLenConstraint = TRUE;
3484         TRACE("got an int, dwPathLenConstraint is %d\n",
3485          constraint->dwPathLenConstraint);
3486     }
3487     TRACE("returning %d (%08x)\n", ret, GetLastError());
3488     return ret;
3489 }
3490 
3491 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3492  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3493  DWORD *pcbDecoded)
3494 {
3495     BOOL ret;
3496     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3497      offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3498      offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
3499      FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3500      CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3501      offsetof(CERT_NAME_BLOB, pbData) };
3502 
3503     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3504      pvStructInfo, *pcbStructInfo, pcbDecoded);
3505 
3506     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3507      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3508     TRACE("Returning %d (%08x)\n", ret, GetLastError());
3509     return ret;
3510 }
3511 
3512 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3513  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3514  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3515 {
3516     BOOL ret;
3517 
3518     __TRY
3519     {
3520         struct AsnDecodeSequenceItem items[] = {
3521          { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3522            CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3523            offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3524          { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3525            fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3526            sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3527          { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3528            cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3529            FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3530            TRUE, TRUE,
3531            offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3532         };
3533 
3534         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3535          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3536          pcbStructInfo, NULL, NULL);
3537     }
3538     __EXCEPT_PAGE_FAULT
3539     {
3540         SetLastError(STATUS_ACCESS_VIOLATION);
3541         ret = FALSE;
3542     }
3543     __ENDTRY
3544     return ret;
3545 }
3546 
3547 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3548  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3549  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3550 {
3551     BOOL ret;
3552 
3553     __TRY
3554     {
3555         struct AsnDecodeSequenceItem items[] = {
3556          { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3557            CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3558          { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3559            fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3560            sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3561         };
3562 
3563         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3564          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3565          pcbStructInfo, NULL, NULL);
3566     }
3567     __EXCEPT_PAGE_FAULT
3568     {
3569         SetLastError(STATUS_ACCESS_VIOLATION);
3570         ret = FALSE;
3571     }
3572     __ENDTRY
3573     return ret;
3574 }
3575 
3576 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
3577  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3578  DWORD *pcbDecoded)
3579 {
3580     struct AsnDecodeSequenceItem items[] = {
3581      { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
3582        pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3583        FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3584        0 },
3585      { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3586        CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3587        offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3588     };
3589     BOOL ret;
3590     CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3591 
3592     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3593      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3594 
3595     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3596      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3597      pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3598     return ret;
3599 }
3600 
3601 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
3602  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3603  DWORD *pcbDecoded)
3604 {
3605     BOOL ret;
3606     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3607      offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3608      offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
3609      FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
3610      CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
3611      offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3612 
3613     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3614      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3615 
3616     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3617      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3618     TRACE("Returning %d (%08x)\n", ret, GetLastError());
3619     return ret;
3620 }
3621 
3622 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
3623  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3624 {
3625     struct AsnDecodeSequenceItem items[] = {
3626      { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3627        CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3628        offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3629      { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3630        CRYPT_AsnDecodePolicyQualifiers,
3631        FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE,
3632        TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3633     };
3634     CERT_POLICY_INFO *info = pvStructInfo;
3635     BOOL ret;
3636 
3637     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3638      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3639 
3640     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3641      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3642      pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
3643     return ret;
3644 }
3645 
3646 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
3647  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3648  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3649 {
3650     BOOL ret = FALSE;
3651 
3652     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3653      pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3654 
3655     __TRY
3656     {
3657         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3658          offsetof(CERT_POLICIES_INFO, cPolicyInfo),
3659          offsetof(CERT_POLICIES_INFO, rgPolicyInfo),
3660          sizeof(CERT_POLICIES_INFO),
3661          CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
3662          offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
3663         CERT_POLICIES_INFO *info = pvStructInfo;
3664 
3665         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3666             info->rgPolicyInfo = (CERT_POLICY_INFO *)(info + 1);
3667 
3668         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3669          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3670     }
3671     __EXCEPT_PAGE_FAULT
3672     {
3673         SetLastError(STATUS_ACCESS_VIOLATION);
3674     }
3675     __ENDTRY
3676     return ret;
3677 }
3678 
3679 static BOOL CRYPT_AsnDecodeCertPolicyMapping(const BYTE *pbEncoded,
3680  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3681  DWORD *pcbDecoded)
3682 {
3683     struct AsnDecodeSequenceItem items[] = {
3684      { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
3685        pszIssuerDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3686        FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy), 0 },
3687      { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
3688        pszSubjectDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3689        FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszSubjectDomainPolicy), 0 },
3690     };
3691     CERT_POLICY_MAPPING *mapping = pvStructInfo;
3692     BOOL ret;
3693 
3694     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3695      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3696 
3697     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3698      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3699      pcbDecoded, mapping ? mapping->pszIssuerDomainPolicy : NULL);
3700     return ret;
3701 }
3702 
3703 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType,
3704  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3705  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3706 {
3707     BOOL ret = FALSE;
3708 
3709     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3710      pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3711 
3712     __TRY
3713     {
3714         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3715          offsetof(CERT_POLICY_MAPPINGS_INFO, cPolicyMapping),
3716          offsetof(CERT_POLICY_MAPPINGS_INFO, rgPolicyMapping),
3717          sizeof(CERT_POLICY_MAPPING),
3718          CRYPT_AsnDecodeCertPolicyMapping, sizeof(CERT_POLICY_MAPPING), TRUE,
3719          offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy) };
3720         CERT_POLICY_MAPPINGS_INFO *info = pvStructInfo;
3721 
3722         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3723             info->rgPolicyMapping = (CERT_POLICY_MAPPING *)(info + 1);
3724         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3725          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3726     }
3727     __EXCEPT_PAGE_FAULT
3728     {
3729         SetLastError(STATUS_ACCESS_VIOLATION);
3730     }
3731     __ENDTRY
3732     return ret;
3733 }
3734 
3735 static BOOL CRYPT_AsnDecodeRequireExplicit(const BYTE *pbEncoded,
3736  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3737  DWORD *pcbDecoded)
3738 {
3739     BOOL ret;
3740     DWORD skip, size = sizeof(skip);
3741 
3742     if (!cbEncoded)
3743     {
3744         SetLastError(CRYPT_E_ASN1_EOD);
3745         return FALSE;
3746     }
3747     if (pbEncoded[0] != (ASN_CONTEXT | 0))
3748     {
3749         SetLastError(CRYPT_E_ASN1_BADTAG);
3750         return FALSE;
3751     }
3752     if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3753      &skip, &size, pcbDecoded)))
3754     {
3755         DWORD bytesNeeded = MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
3756          fRequireExplicitPolicy, fInhibitPolicyMapping);
3757 
3758         if (!pvStructInfo)
3759             *pcbStructInfo = bytesNeeded;
3760         else if (*pcbStructInfo < bytesNeeded)
3761         {
3762             *pcbStructInfo = bytesNeeded;
3763             SetLastError(ERROR_MORE_DATA);
3764             ret = FALSE;
3765         }
3766         else
3767         {
3768             CERT_POLICY_CONSTRAINTS_INFO *info = CONTAINING_RECORD(pvStructInfo,
3769               CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy);
3770 
3771             *pcbStructInfo = bytesNeeded;
3772             /* The BOOL is implicit:  if the integer is present, then it's
3773              * TRUE.
3774              */
3775             info->fRequireExplicitPolicy = TRUE;
3776             info->dwRequireExplicitPolicySkipCerts = skip;
3777         }
3778     }
3779     return ret;
3780 }
3781 
3782 static BOOL CRYPT_AsnDecodeInhibitMapping(const BYTE *pbEncoded,
3783  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3784  DWORD *pcbDecoded)
3785 {
3786     BOOL ret;
3787     DWORD skip, size = sizeof(skip);
3788 
3789     if (!cbEncoded)
3790     {
3791         SetLastError(CRYPT_E_ASN1_EOD);
3792         return FALSE;
3793     }
3794     if (pbEncoded[0] != (ASN_CONTEXT | 1))
3795     {
3796         SetLastError(CRYPT_E_ASN1_BADTAG);
3797         return FALSE;
3798     }
3799     if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3800      &skip, &size, pcbDecoded)))
3801     {
3802         DWORD bytesNeeded = FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
3803          fInhibitPolicyMapping);
3804 
3805         if (!pvStructInfo)
3806             *pcbStructInfo = bytesNeeded;
3807         else if (*pcbStructInfo < bytesNeeded)
3808         {
3809             *pcbStructInfo = bytesNeeded;
3810             SetLastError(ERROR_MORE_DATA);
3811             ret = FALSE;
3812         }
3813         else
3814         {
3815             CERT_POLICY_CONSTRAINTS_INFO *info = CONTAINING_RECORD(pvStructInfo,
3816               CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping);
3817 
3818             *pcbStructInfo = bytesNeeded;
3819             /* The BOOL is implicit:  if the integer is present, then it's
3820              * TRUE.
3821              */
3822             info->fInhibitPolicyMapping = TRUE;
3823             info->dwInhibitPolicyMappingSkipCerts = skip;
3824         }
3825     }
3826     return ret;
3827 }
3828 
3829 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints(
3830  DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
3831  DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3832  void *pvStructInfo, DWORD *pcbStructInfo)
3833 {
3834     BOOL ret = FALSE;
3835 
3836     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3837      pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3838 
3839     __TRY
3840     {
3841         struct AsnDecodeSequenceItem items[] = {
3842          { ASN_CONTEXT | 0,
3843            offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy),
3844            CRYPT_AsnDecodeRequireExplicit,
3845            MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy,
3846            fInhibitPolicyMapping), TRUE, FALSE, 0, 0 },
3847          { ASN_CONTEXT | 1,
3848            offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3849            CRYPT_AsnDecodeInhibitMapping,
3850            FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3851            TRUE, FALSE, 0, 0 },
3852         };
3853 
3854         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3855          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3856          pcbStructInfo, NULL, NULL);
3857     }
3858     __EXCEPT_PAGE_FAULT
3859     {
3860         SetLastError(STATUS_ACCESS_VIOLATION);
3861     }
3862     __ENDTRY
3863     return ret;
3864 }
3865 
3866 #define RSA1_MAGIC 0x31415352
3867 
3868 struct DECODED_RSA_PUB_KEY
3869 {
3870     DWORD              pubexp;
3871     CRYPT_INTEGER_BLOB modulus;
3872 };
3873 
3874 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3875  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3876  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3877 {
3878     BOOL ret;
3879 
3880     __TRY
3881     {
3882         struct AsnDecodeSequenceItem items[] = {
3883          { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3884            CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3885            FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3886            0 },
3887          { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3888            CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3889         };
3890         struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3891         DWORD size = 0;
3892 
3893         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3894          pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3895          &size, NULL, NULL);
3896         if (ret)
3897         {
3898             DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3899              decodedKey->modulus.cbData;
3900 
3901             if (!pvStructInfo)
3902             {
3903                 *pcbStructInfo = bytesNeeded;
3904                 ret = TRUE;
3905             }
3906             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3907              pvStructInfo, pcbStructInfo, bytesNeeded)))
3908             {
3909                 BLOBHEADER *hdr;
3910                 RSAPUBKEY *rsaPubKey;
3911 
3912                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3913                     pvStructInfo = *(BYTE **)pvStructInfo;
3914                 hdr = pvStructInfo;
3915                 hdr->bType = PUBLICKEYBLOB;
3916                 hdr->bVersion = CUR_BLOB_VERSION;
3917                 hdr->reserved = 0;
3918                 hdr->aiKeyAlg = CALG_RSA_KEYX;
3919                 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3920                  sizeof(BLOBHEADER));
3921                 rsaPubKey->magic = RSA1_MAGIC;
3922                 rsaPubKey->pubexp = decodedKey->pubexp;
3923                 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3924                 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3925                  sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3926                  decodedKey->modulus.cbData);
3927             }
3928             LocalFree(decodedKey);
3929         }
3930     }
3931     __EXCEPT_PAGE_FAULT
3932     {
3933         SetLastError(STATUS_ACCESS_VIOLATION);
3934         ret = FALSE;
3935     }
3936     __ENDTRY
3937     return ret;
3938 }
3939 
3940 #define RSA2_MAGIC 0x32415352
3941 
3942 struct DECODED_RSA_PRIV_KEY
3943 {
3944     DWORD              version;
3945     DWORD              pubexp;
3946     CRYPT_INTEGER_BLOB modulus;
3947     CRYPT_INTEGER_BLOB privexp;
3948     CRYPT_INTEGER_BLOB prime1;
3949     CRYPT_INTEGER_BLOB prime2;
3950     CRYPT_INTEGER_BLOB exponent1;
3951     CRYPT_INTEGER_BLOB exponent2;
3952     CRYPT_INTEGER_BLOB coefficient;
3953 };
3954 
3955 static BOOL WINAPI CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType,
3956  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3957  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3958 {
3959     BOOL ret;
3960     DWORD halflen;
3961 
3962     __TRY
3963     {
3964         struct AsnDecodeSequenceItem items[] = {
3965          { ASN_INTEGER, offsetof(struct DECODED_RSA_PRIV_KEY, version),
3966            CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3967          { ASN_INTEGER, offsetof(struct DECODED_RSA_PRIV_KEY, modulus),
3968            CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3969            FALSE, TRUE, offsetof(struct DECODED_RSA_PRIV_KEY, modulus.pbData),
3970            0 },
3971          { ASN_INTEGER, offsetof(struct DECODED_RSA_PRIV_KEY, pubexp),
3972            CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3973          { ASN_INTEGER, offsetof(struct DECODED_RSA_PRIV_KEY, privexp),
3974            CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3975            FALSE, TRUE, offsetof(struct DECODED_RSA_PRIV_KEY, privexp.pbData),
3976            0 },
3977          { ASN_INTEGER, offsetof(struct DECODED_RSA_PRIV_KEY, prime1),
3978            CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3979            FALSE, TRUE, offsetof(struct DECODED_RSA_PRIV_KEY, prime1.pbData),
3980            0 },
3981          { ASN_INTEGER, offsetof(struct DECODED_RSA_PRIV_KEY, prime2),
3982            CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3983            FALSE, TRUE, offsetof(struct DECODED_RSA_PRIV_KEY, prime2.pbData),
3984            0 },
3985          { ASN_INTEGER, offsetof(struct DECODED_RSA_PRIV_KEY, exponent1),
3986            CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3987            FALSE, TRUE, offsetof(struct DECODED_RSA_PRIV_KEY, exponent1.pbData),
3988            0 },
3989          { ASN_INTEGER, offsetof(struct DECODED_RSA_PRIV_KEY, exponent2),
3990            CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3991            FALSE, TRUE, offsetof(struct DECODED_RSA_PRIV_KEY, exponent2.pbData),
3992            0 },
3993          { ASN_INTEGER, offsetof(struct DECODED_RSA_PRIV_KEY, coefficient),
3994            CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3995            FALSE, TRUE, offsetof(struct DECODED_RSA_PRIV_KEY, coefficient.pbData),
3996            0 },
3997         };
3998         struct DECODED_RSA_PRIV_KEY *decodedKey = NULL;
3999         DWORD size = 0;
4000 
4001         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4002          pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
4003          &size, NULL, NULL);
4004         if (ret)
4005         {
4006             halflen = decodedKey->prime1.cbData;
4007             if (halflen < decodedKey->prime2.cbData)
4008                 halflen = decodedKey->prime2.cbData;
4009             if (halflen < decodedKey->exponent1.cbData)
4010                 halflen = decodedKey->exponent1.cbData;
4011             if (halflen < decodedKey->exponent2.cbData)
4012                 halflen = decodedKey->exponent2.cbData;
4013             if (halflen < decodedKey->coefficient.cbData)
4014                 halflen = decodedKey->coefficient.cbData;
4015             if (halflen * 2 < decodedKey->modulus.cbData)
4016                 halflen = decodedKey->modulus.cbData / 2 + decodedKey->modulus.cbData % 2;
4017             if (halflen * 2 < decodedKey->privexp.cbData)
4018                 halflen = decodedKey->privexp.cbData / 2 + decodedKey->privexp.cbData % 2;
4019 
4020             if (ret)
4021             {
4022                 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
4023                  (halflen * 9);
4024 
4025                 if (!pvStructInfo)
4026                 {
4027                     *pcbStructInfo = bytesNeeded;
4028                     ret = TRUE;
4029                 }
4030                 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4031                  pvStructInfo, pcbStructInfo, bytesNeeded)))
4032                 {
4033                     BLOBHEADER *hdr;
4034                     RSAPUBKEY *rsaPubKey;
4035                     BYTE *vardata;
4036 
4037                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4038                         pvStructInfo = *(BYTE **)pvStructInfo;
4039 
4040                     hdr = pvStructInfo;
4041                     hdr->bType = PRIVATEKEYBLOB;
4042                     hdr->bVersion = CUR_BLOB_VERSION;
4043                     hdr->reserved = 0;
4044                     hdr->aiKeyAlg = CALG_RSA_KEYX;
4045 
4046                     rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
4047                      sizeof(BLOBHEADER));
4048                     rsaPubKey->magic = RSA2_MAGIC;
4049                     rsaPubKey->pubexp = decodedKey->pubexp;
4050                     rsaPubKey->bitlen = halflen * 16;
4051 
4052                     vardata = (BYTE*)(rsaPubKey + 1);
4053                     memset(vardata, 0, halflen * 9);
4054                     memcpy(vardata,
4055                      decodedKey->modulus.pbData, decodedKey->modulus.cbData);
4056                     memcpy(vardata + halflen * 2,
4057                      decodedKey->prime1.pbData, decodedKey->prime1.cbData);
4058                     memcpy(vardata + halflen * 3,
4059                      decodedKey->prime2.pbData, decodedKey->prime2.cbData);
4060                     memcpy(vardata + halflen * 4,
4061                      decodedKey->exponent1.pbData, decodedKey->exponent1.cbData);
4062                     memcpy(vardata + halflen * 5,
4063                      decodedKey->exponent2.pbData, decodedKey->exponent2.cbData);
4064                     memcpy(vardata + halflen * 6,
4065                      decodedKey->coefficient.pbData, decodedKey->coefficient.cbData);
4066                     memcpy(vardata + halflen * 7,
4067                      decodedKey->privexp.pbData, decodedKey->privexp.cbData);
4068                 }
4069             }
4070 
4071             LocalFree(decodedKey);
4072         }
4073     }
4074     __EXCEPT_PAGE_FAULT
4075     {
4076         SetLastError(STATUS_ACCESS_VIOLATION);
4077         ret = FALSE;
4078     }
4079     __ENDTRY
4080     return ret;
4081 }
4082 
4083 static BOOL CRYPT_AsnDecodeOctets(const BYTE *pbEncoded,
4084  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4085  DWORD *pcbDecoded)
4086 {
4087     BOOL ret;
4088     DWORD bytesNeeded, dataLen;
4089 
4090     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4091      pvStructInfo, *pcbStructInfo, pcbDecoded);
4092 
4093     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4094     {
4095         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4096 
4097         if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4098             bytesNeeded = sizeof(CRYPT_DATA_BLOB);
4099         else
4100             bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
4101         if (pcbDecoded)
4102             *pcbDecoded = 1 + lenBytes + dataLen;
4103         if (!pvStructInfo)
4104             *pcbStructInfo = bytesNeeded;
4105         else if (*pcbStructInfo < bytesNeeded)
4106         {
4107             SetLastError(ERROR_MORE_DATA);
4108             *pcbStructInfo = bytesNeeded;
4109             ret = FALSE;
4110         }
4111         else
4112         {
4113             CRYPT_DATA_BLOB *blob;
4114 
4115             *pcbStructInfo = bytesNeeded;
4116             blob = pvStructInfo;
4117             blob->cbData = dataLen;
4118             if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4119                 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
4120             else
4121             {
4122                 assert(blob->pbData);
4123                 if (blob->cbData)
4124                     memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
4125                      blob->cbData);
4126             }
4127         }
4128     }
4129     return ret;
4130 }
4131 
4132 static BOOL CRYPT_AsnDecodeOctetStringInternal(const BYTE *encoded, DWORD encoded_size,
4133     DWORD flags, void *buf, DWORD *buf_size, DWORD *ret_decoded)
4134 {
4135     DWORD decoded = 0, indefinite_len_depth = 0, len_size, len, bytes_needed;
4136     CRYPT_DATA_BLOB *blob;
4137     const BYTE *string;
4138 
4139     while (encoded[0] == (ASN_CONSTRUCTOR | ASN_OCTETSTRING))
4140     {
4141         if (!CRYPT_GetLengthIndefinite(encoded, encoded_size, &len))
4142             return FALSE;
4143 
4144         len_size = GET_LEN_BYTES(encoded[1]);
4145         encoded += 1 + len_size;
4146         encoded_size -= 1 + len_size;
4147         decoded += 1 + len_size;
4148 
4149         if (len == CMSG_INDEFINITE_LENGTH)
4150         {
4151             indefinite_len_depth++;
4152             if (encoded_size < 2)
4153             {
4154                 SetLastError(CRYPT_E_ASN1_EOD);
4155                 return FALSE;
4156             }
4157             encoded_size -= 2;
4158             decoded += 2;
4159         }
4160     }
4161 
4162     if (encoded[0] != ASN_OCTETSTRING)
4163     {
4164         WARN("Unexpected tag %02x\n", encoded[0]);
4165         SetLastError(CRYPT_E_ASN1_BADTAG);
4166         return FALSE;
4167     }
4168 
4169     if (!CRYPT_GetLen(encoded, encoded_size, &len))
4170         return FALSE;
4171     len_size = GET_LEN_BYTES(encoded[1]);
4172     decoded += 1 + len_size + len;
4173     encoded_size -= 1 + len_size;
4174 
4175     if (len > encoded_size)
4176     {
4177         SetLastError(CRYPT_E_ASN1_EOD);
4178         return FALSE;
4179     }
4180     if (ret_decoded)
4181         *ret_decoded = decoded;
4182 
4183     encoded += 1 + len_size;
4184     string = encoded;
4185     encoded += len;
4186 
4187     while (indefinite_len_depth--)
4188     {
4189         if (encoded[0] || encoded[1])
4190         {
4191             TRACE("expected 0 TLV, got %02x %02x\n", encoded[0], encoded[1]);
4192             SetLastError(CRYPT_E_ASN1_CORRUPT);
4193             return FALSE;
4194         }
4195     }
4196 
4197     bytes_needed = sizeof(*blob);
4198     if (!(flags & CRYPT_DECODE_NOCOPY_FLAG)) bytes_needed += len;
4199     if (!buf)
4200     {
4201         *buf_size = bytes_needed;
4202         return TRUE;
4203     }
4204     if (*buf_size < bytes_needed)
4205     {
4206         SetLastError(ERROR_MORE_DATA);
4207         *buf_size = bytes_needed;
4208         return FALSE;
4209     }
4210 
4211     *buf_size = bytes_needed;
4212     blob = buf;
4213     blob->cbData = len;
4214     if (flags & CRYPT_DECODE_NOCOPY_FLAG)
4215         blob->pbData = (BYTE*)string;
4216     else if (blob->cbData)
4217         memcpy(blob->pbData, string, blob->cbData);
4218 
4219     if (ret_decoded)
4220         *ret_decoded = decoded;
4221     return TRUE;
4222 }
4223 
4224 static BOOL WINAPI CRYPT_AsnDecodeOctetString(DWORD dwCertEncodingType,
4225  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4226  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4227 {
4228     BOOL ret;
4229 
4230     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4231      pDecodePara, pvStructInfo, *pcbStructInfo);
4232 
4233     if (!cbEncoded)
4234     {
4235         SetLastError(CRYPT_E_ASN1_CORRUPT);
4236         return FALSE;
4237     }
4238 
4239     __TRY
4240     {
4241         DWORD bytesNeeded = 0;
4242 
4243         if ((ret = CRYPT_AsnDecodeOctetStringInternal(pbEncoded, cbEncoded,
4244          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4245         {
4246             if (!pvStructInfo)
4247                 *pcbStructInfo = bytesNeeded;
4248             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4249              pvStructInfo, pcbStructInfo, bytesNeeded)))
4250             {
4251                 CRYPT_DATA_BLOB *blob;
4252 
4253                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4254                     pvStructInfo = *(BYTE **)pvStructInfo;
4255                 blob = pvStructInfo;
4256                 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
4257                 ret = CRYPT_AsnDecodeOctetStringInternal(pbEncoded, cbEncoded,
4258                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4259                  &bytesNeeded, NULL);
4260                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4261                     CRYPT_FreeSpace(pDecodePara, blob);
4262             }
4263         }
4264     }
4265     __EXCEPT_PAGE_FAULT
4266     {
4267         SetLastError(STATUS_ACCESS_VIOLATION);
4268         ret = FALSE;
4269     }
4270     __ENDTRY
4271     return ret;
4272 }
4273 
4274 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4275  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4276 {
4277     BOOL ret;
4278     DWORD bytesNeeded, dataLen;
4279     BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4280 
4281     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
4282      pvStructInfo, *pcbStructInfo, pcbDecoded);
4283 
4284     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4285     {
4286         if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4287             bytesNeeded = sizeof(CRYPT_BIT_BLOB);
4288         else
4289             bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
4290         if (pcbDecoded)
4291             *pcbDecoded = 1 + lenBytes + dataLen;
4292         if (!pvStructInfo)
4293             *pcbStructInfo = bytesNeeded;
4294         else if (*pcbStructInfo < bytesNeeded)
4295         {
4296             *pcbStructInfo = bytesNeeded;
4297             SetLastError(ERROR_MORE_DATA);
4298             ret = FALSE;
4299         }
4300         else
4301         {
4302             CRYPT_BIT_BLOB *blob;
4303 
4304             *pcbStructInfo = bytesNeeded;
4305             blob = pvStructInfo;
4306             blob->cbData = dataLen - 1;
4307             blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
4308             if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4309             {
4310                 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
4311             }
4312             else
4313             {
4314                 assert(blob->pbData);
4315                 if (blob->cbData)
4316                 {
4317                     BYTE mask = 0xff << blob->cUnusedBits;
4318 
4319                     memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
4320                      blob->cbData);
4321                     blob->pbData[blob->cbData - 1] &= mask;
4322                 }
4323             }
4324         }
4325     }
4326     return ret;
4327 }
4328 
4329 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
4330  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4331  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4332 {
4333     BOOL ret;
4334 
4335     TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
4336      pDecodePara, pvStructInfo, pcbStructInfo);
4337 
4338     __TRY
4339     {
4340         DWORD bytesNeeded = 0;
4341 
4342         if (!cbEncoded)
4343         {
4344             SetLastError(CRYPT_E_ASN1_CORRUPT);
4345             ret = FALSE;
4346         }
4347         else if (pbEncoded[0] != ASN_BITSTRING)
4348         {
4349             SetLastError(CRYPT_E_ASN1_BADTAG);
4350             ret = FALSE;
4351         }
4352         else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4353          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4354         {
4355             if (!pvStructInfo)
4356                 *pcbStructInfo = bytesNeeded;
4357             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4358              pvStructInfo, pcbStructInfo, bytesNeeded)))
4359             {
4360                 CRYPT_BIT_BLOB *blob;
4361 
4362                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4363                     pvStructInfo = *(BYTE **)pvStructInfo;
4364                 blob = pvStructInfo;
4365                 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
4366                 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4367                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4368                  &bytesNeeded, NULL);
4369                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4370                     CRYPT_FreeSpace(pDecodePara, blob);
4371             }
4372         }
4373     }
4374     __EXCEPT_PAGE_FAULT
4375     {
4376         SetLastError(STATUS_ACCESS_VIOLATION);
4377         ret = FALSE;
4378     }
4379     __ENDTRY
4380     TRACE("returning %d (%08x)\n", ret, GetLastError());
4381     return ret;
4382 }
4383 
4384 /* Ignores tag.  Only allows integers 4 bytes or smaller in size. */
4385 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4386  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4387 {
4388     BOOL ret;
4389     DWORD dataLen;
4390 
4391     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4392     {
4393         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4394 
4395         if (pcbDecoded)
4396             *pcbDecoded = 1 + lenBytes + dataLen;
4397         if (dataLen > sizeof(int))
4398         {
4399             SetLastError(CRYPT_E_ASN1_LARGE);
4400             ret = FALSE;
4401         }
4402         else if (!pvStructInfo)
4403             *pcbStructInfo = sizeof(int);
4404         else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
4405         {
4406             int val, i;
4407 
4408             if (dataLen && pbEncoded[1 + lenBytes] & 0x80)
4409             {
4410                 /* initialize to a negative value to sign-extend */
4411                 val = -1;
4412             }
4413             else
4414                 val = 0;
4415             for (i = 0; i < dataLen; i++)
4416             {
4417                 val <<= 8;
4418                 val |= pbEncoded[1 + lenBytes + i];
4419             }
4420             memcpy(pvStructInfo, &val, sizeof(int));
4421         }
4422     }
4423     return ret;
4424 }
4425 
4426 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
4427  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4428  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4429 {
4430     BOOL ret;
4431 
4432     __TRY
4433     {
4434         DWORD bytesNeeded = 0;
4435 
4436         if (!cbEncoded)
4437         {
4438             SetLastError(CRYPT_E_ASN1_EOD);
4439             ret = FALSE;
4440         }
4441         else if (pbEncoded[0] != ASN_INTEGER)
4442         {
4443             SetLastError(CRYPT_E_ASN1_BADTAG);
4444             ret = FALSE;
4445         }
4446         else
4447             ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4448              dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4449         if (ret)
4450         {
4451             if (!pvStructInfo)
4452                 *pcbStructInfo = bytesNeeded;
4453             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4454              pvStructInfo, pcbStructInfo, bytesNeeded)))
4455             {
4456                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4457                     pvStructInfo = *(BYTE **)pvStructInfo;
4458                 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4459                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4460                  &bytesNeeded, NULL);
4461                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4462                     CRYPT_FreeSpace(pDecodePara, pvStructInfo);
4463             }
4464         }
4465     }
4466     __EXCEPT_PAGE_FAULT
4467     {
4468         SetLastError(STATUS_ACCESS_VIOLATION);
4469         ret = FALSE;
4470     }
4471     __ENDTRY
4472     return ret;
4473 }
4474 
4475 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
4476  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4477  DWORD *pcbDecoded)
4478 {
4479     BOOL ret;
4480     DWORD bytesNeeded, dataLen;
4481 
4482     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4483     {
4484         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4485 
4486         bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4487         if (pcbDecoded)
4488             *pcbDecoded = 1 + lenBytes + dataLen;
4489         if (!pvStructInfo)
4490             *pcbStructInfo = bytesNeeded;
4491         else if (*pcbStructInfo < bytesNeeded)
4492         {
4493             *pcbStructInfo = bytesNeeded;
4494             SetLastError(ERROR_MORE_DATA);
4495             ret = FALSE;
4496         }
4497         else
4498         {
4499             CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4500 
4501             *pcbStructInfo = bytesNeeded;
4502             blob->cbData = dataLen;
4503             assert(blob->pbData);
4504             if (blob->cbData)
4505             {
4506                 DWORD i;
4507 
4508                 for (i = 0; i < blob->cbData; i++)
4509                 {
4510                     blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4511                      dataLen - i - 1);
4512                 }
4513             }
4514         }
4515     }
4516     return ret;
4517 }
4518 
4519 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
4520  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4521  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4522 {
4523     BOOL ret;
4524 
4525     __TRY
4526     {
4527         DWORD bytesNeeded = 0;
4528 
4529         if (pbEncoded[0] != ASN_INTEGER)
4530         {
4531             SetLastError(CRYPT_E_ASN1_BADTAG);
4532             ret = FALSE;
4533         }
4534         else
4535             ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4536              dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4537         if (ret)
4538         {
4539             if (!pvStructInfo)
4540                 *pcbStructInfo = bytesNeeded;
4541             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4542              pvStructInfo, pcbStructInfo, bytesNeeded)))
4543             {
4544                 CRYPT_INTEGER_BLOB *blob;
4545 
4546                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4547                     pvStructInfo = *(BYTE **)pvStructInfo;
4548                 blob = pvStructInfo;
4549                 blob->pbData = (BYTE *)pvStructInfo +
4550                  sizeof(CRYPT_INTEGER_BLOB);
4551                 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4552                  dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4553                  &bytesNeeded, NULL);
4554                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4555                     CRYPT_FreeSpace(pDecodePara, blob);
4556             }
4557         }
4558     }
4559     __EXCEPT_PAGE_FAULT
4560     {
4561         SetLastError(STATUS_ACCESS_VIOLATION);
4562         ret = FALSE;
4563     }
4564     __ENDTRY
4565     return ret;
4566 }
4567 
4568 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
4569  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4570  DWORD *pcbDecoded)
4571 {
4572     BOOL ret;
4573 
4574     if (pbEncoded[0] == ASN_INTEGER)
4575     {
4576         DWORD bytesNeeded, dataLen;
4577 
4578         if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4579         {
4580             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4581 
4582             if (pcbDecoded)
4583                 *pcbDecoded = 1 + lenBytes + dataLen;
4584             bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4585             if (!pvStructInfo)
4586                 *pcbStructInfo = bytesNeeded;
4587             else if (*pcbStructInfo < bytesNeeded)
4588             {
4589                 *pcbStructInfo = bytesNeeded;
4590                 SetLastError(ERROR_MORE_DATA);
4591                 ret = FALSE;
4592             }
4593             else
4594             {
4595                 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4596 
4597                 *pcbStructInfo = bytesNeeded;
4598                 blob->cbData = dataLen;
4599                 assert(blob->pbData);
4600                 /* remove leading zero byte if it exists */
4601                 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
4602                 {
4603                     blob->cbData--;
4604                     blob->pbData++;
4605                 }
4606                 if (blob->cbData)
4607                 {
4608                     DWORD i;
4609 
4610                     for (i = 0; i < blob->cbData; i++)
4611                     {
4612                         blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4613                          dataLen - i - 1);
4614                     }
4615                 }
4616             }
4617         }
4618     }
4619     else
4620     {
4621         SetLastError(CRYPT_E_ASN1_BADTAG);
4622         ret = FALSE;
4623     }
4624     return ret;
4625 }
4626 
4627 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
4628  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4629  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4630 {
4631     BOOL ret;
4632 
4633     __TRY
4634     {
4635         DWORD bytesNeeded = 0;
4636 
4637         if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
4638          dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4639         {
4640             if (!pvStructInfo)
4641                 *pcbStructInfo = bytesNeeded;
4642             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4643              pvStructInfo, pcbStructInfo, bytesNeeded)))
4644             {
4645                 CRYPT_INTEGER_BLOB *blob;
4646 
4647                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4648                     pvStructInfo = *(BYTE **)pvStructInfo;
4649                 blob = pvStructInfo;
4650                 blob->pbData = (BYTE *)pvStructInfo +
4651                  sizeof(CRYPT_INTEGER_BLOB);
4652                 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
4653                  cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4654                  &bytesNeeded, NULL);
4655                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4656                     CRYPT_FreeSpace(pDecodePara, blob);
4657             }
4658         }
4659     }
4660     __EXCEPT_PAGE_FAULT
4661     {
4662         SetLastError(STATUS_ACCESS_VIOLATION);
4663         ret = FALSE;
4664     }
4665     __ENDTRY
4666     return ret;
4667 }
4668 
4669 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
4670  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4671  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4672 {
4673     BOOL ret;
4674 
4675     if (!pvStructInfo)
4676     {
4677         *pcbStructInfo = sizeof(int);
4678         return TRUE;
4679     }
4680     __TRY
4681     {
4682         if (pbEncoded[0] == ASN_ENUMERATED)
4683         {
4684             unsigned int val = 0, i;
4685 
4686             if (cbEncoded <= 1)
4687             {
4688                 SetLastError(CRYPT_E_ASN1_EOD);
4689                 ret = FALSE;
4690             }
4691             else if (pbEncoded[1] == 0)
4692             {
4693                 SetLastError(CRYPT_E_ASN1_CORRUPT);
4694                 ret = FALSE;
4695             }
4696             else
4697             {
4698                 /* A little strange looking, but we have to accept a sign byte:
4699                  * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff.  Also,
4700                  * assuming a small length is okay here, it has to be in short
4701                  * form.
4702                  */
4703                 if (pbEncoded[1] > sizeof(unsigned int) + 1)
4704                 {
4705                     SetLastError(CRYPT_E_ASN1_LARGE);
4706                     return FALSE;
4707                 }
4708                 for (i = 0; i < pbEncoded[1]; i++)
4709                 {
4710                     val <<= 8;
4711                     val |= pbEncoded[2 + i];
4712                 }
4713                 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4714                  pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
4715                 {
4716                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4717                         pvStructInfo = *(BYTE **)pvStructInfo;
4718                     memcpy(pvStructInfo, &val, sizeof(unsigned int));
4719                 }
4720             }
4721         }
4722         else
4723         {
4724             SetLastError(CRYPT_E_ASN1_BADTAG);
4725             ret = FALSE;
4726         }
4727     }
4728     __EXCEPT_PAGE_FAULT
4729     {
4730         SetLastError(STATUS_ACCESS_VIOLATION);
4731         ret = FALSE;
4732     }
4733     __ENDTRY
4734     return ret;
4735 }
4736 
4737 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4738  * if it fails.
4739  */
4740 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4741  do { \
4742     BYTE i; \
4743  \
4744     (word) = 0; \
4745     for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4746     { \
4747         if (!isdigit(*(pbEncoded))) \
4748         { \
4749             SetLastError(CRYPT_E_ASN1_CORRUPT); \
4750             ret = FALSE; \
4751         } \
4752         else \
4753         { \
4754             (word) *= 10; \
4755             (word) += *(pbEncoded)++ - '0'; \
4756         } \
4757     } \
4758  } while (0)
4759 
4760 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
4761  SYSTEMTIME *sysTime)
4762 {
4763     BOOL ret = TRUE;
4764 
4765     if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
4766     {
4767         WORD hours, minutes = 0;
4768         BYTE sign = *pbEncoded++;
4769 
4770         len--;
4771         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
4772         if (ret && hours >= 24)
4773         {
4774             SetLastError(CRYPT_E_ASN1_CORRUPT);
4775             ret = FALSE;
4776         }
4777         else if (len >= 2)
4778         {
4779             CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
4780             if (ret && minutes >= 60)
4781             {
4782                 SetLastError(CRYPT_E_ASN1_CORRUPT);
4783                 ret = FALSE;
4784             }
4785         }
4786         if (ret)
4787         {
4788             if (sign == '+')
4789             {
4790                 sysTime->wHour += hours;
4791                 sysTime->wMinute += minutes;
4792             }
4793             else
4794             {
4795                 if (hours > sysTime->wHour)
4796                 {
4797                     sysTime->wDay--;
4798                     sysTime->wHour = 24 - (hours - sysTime->wHour);
4799                 }
4800                 else
4801                     sysTime->wHour -= hours;
4802                 if (minutes > sysTime->wMinute)
4803                 {
4804                     sysTime->wHour--;
4805                     sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
4806                 }
4807                 else
4808                     sysTime->wMinute -= minutes;
4809             }
4810         }
4811     }
4812     return ret;
4813 }
4814 
4815 #define MIN_ENCODED_TIME_LENGTH 10
4816 
4817 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
4818  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4819  DWORD *pcbDecoded)
4820 {
4821     BOOL ret = FALSE;
4822 
4823     if (pbEncoded[0] == ASN_UTCTIME)
4824     {
4825         if (cbEncoded <= 1)
4826             SetLastError(CRYPT_E_ASN1_EOD);
4827         else if (pbEncoded[1] > 0x7f)
4828         {
4829             /* long-form date strings really can't be valid */
4830             SetLastError(CRYPT_E_ASN1_CORRUPT);
4831         }
4832         else
4833         {
4834             SYSTEMTIME sysTime = { 0 };
4835             BYTE len = pbEncoded[1];
4836 
4837             if (len < MIN_ENCODED_TIME_LENGTH)
4838                 SetLastError(CRYPT_E_ASN1_CORRUPT);
4839             else
4840             {
4841                 ret = TRUE;
4842                 if (pcbDecoded)
4843                     *pcbDecoded = 2 + len;
4844                 pbEncoded += 2;
4845                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
4846                 if (sysTime.wYear >= 50)
4847                     sysTime.wYear += 1900;
4848                 else
4849                     sysTime.wYear += 2000;
4850                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4851                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4852                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4853                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
4854                 if (ret && len > 0)
4855                 {
4856                     if (len >= 2 && isdigit(*pbEncoded) &&
4857                      isdigit(*(pbEncoded + 1)))
4858                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4859                          sysTime.wSecond);
4860                     else if (isdigit(*pbEncoded))
4861                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
4862                          sysTime.wSecond);
4863                     if (ret)
4864                         ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4865                          &sysTime);
4866                 }
4867                 if (ret)
4868                 {
4869                     if (!pvStructInfo)
4870                         *pcbStructInfo = sizeof(FILETIME);
4871                     else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4872                      sizeof(FILETIME))))
4873                         ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4874                 }
4875             }
4876         }
4877     }
4878     else
4879         SetLastError(CRYPT_E_ASN1_BADTAG);
4880     return ret;
4881 }
4882 
4883 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
4884  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4885  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4886 {
4887     BOOL ret = FALSE;
4888 
4889     __TRY
4890     {
4891         DWORD bytesNeeded = 0;
4892 
4893         ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4894          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4895         if (ret)
4896         {
4897             if (!pvStructInfo)
4898                 *pcbStructInfo = bytesNeeded;
4899             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
4900              pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
4901             {
4902                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4903                     pvStructInfo = *(BYTE **)pvStructInfo;
4904                 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4905                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4906                  &bytesNeeded, NULL);
4907                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4908                     CRYPT_FreeSpace(pDecodePara, pvStructInfo);
4909             }
4910         }
4911     }
4912     __EXCEPT_PAGE_FAULT
4913     {
4914         SetLastError(STATUS_ACCESS_VIOLATION);
4915     }
4916     __ENDTRY
4917     return ret;
4918 }
4919 
4920 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
4921  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4922  DWORD *pcbDecoded)
4923 {
4924     BOOL ret = FALSE;
4925 
4926     if (pbEncoded[0] == ASN_GENERALTIME)
4927     {
4928         if (cbEncoded <= 1)
4929             SetLastError(CRYPT_E_ASN1_EOD);
4930         else if (pbEncoded[1] > 0x7f)
4931         {
4932             /* long-form date strings really can't be valid */
4933             SetLastError(CRYPT_E_ASN1_CORRUPT);
4934         }
4935         else
4936         {
4937             BYTE len = pbEncoded[1];
4938 
4939             if (len < MIN_ENCODED_TIME_LENGTH)
4940                 SetLastError(CRYPT_E_ASN1_CORRUPT);
4941             else
4942             {
4943                 SYSTEMTIME sysTime = { 0 };
4944 
4945                 ret = TRUE;
4946                 if (pcbDecoded)
4947                     *pcbDecoded = 2 + len;
4948                 pbEncoded += 2;
4949                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
4950                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4951                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4952                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4953                 if (ret && len > 0)
4954                 {
4955                     CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4956                      sysTime.wMinute);
4957                     if (ret && len > 0)
4958                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4959                          sysTime.wSecond);
4960                     if (ret && len > 0 && (*pbEncoded == '.' ||
4961                      *pbEncoded == ','))
4962                     {
4963                         BYTE digits;
4964 
4965                         pbEncoded++;
4966                         len--;
4967                         /* workaround macro weirdness */
4968                         digits = min(len, 3);
4969                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
4970                          sysTime.wMilliseconds);
4971                     }
4972                     if (ret)
4973                         ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4974                          &sysTime);
4975                 }
4976                 if (ret)
4977                 {
4978                     if (!pvStructInfo)
4979                         *pcbStructInfo = sizeof(FILETIME);
4980                     else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4981                      sizeof(FILETIME))))
4982                         ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4983                 }
4984             }
4985         }
4986     }
4987     else
4988         SetLastError(CRYPT_E_ASN1_BADTAG);
4989     return ret;
4990 }
4991 
4992 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
4993  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4994  DWORD *pcbDecoded)
4995 {
4996     BOOL ret;
4997     InternalDecodeFunc decode = NULL;
4998 
4999     if (pbEncoded[0] == ASN_UTCTIME)
5000         decode = CRYPT_AsnDecodeUtcTimeInternal;
5001     else if (pbEncoded[0] == ASN_GENERALTIME)
5002         decode = CRYPT_AsnDecodeGeneralizedTime;
5003     if (decode)
5004         ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
5005          pcbStructInfo, pcbDecoded);
5006     else
5007     {
5008         SetLastError(CRYPT_E_ASN1_BADTAG);
5009         ret = FALSE;
5010     }
5011     return ret;
5012 }
5013 
5014 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
5015  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5016  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5017 {
5018     BOOL ret;
5019 
5020     __TRY
5021     {
5022         DWORD bytesNeeded = 0;
5023 
5024         ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
5025          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
5026         if (ret)
5027         {
5028             if (!pvStructInfo)
5029                 *pcbStructInfo = bytesNeeded;
5030             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
5031              pvStructInfo, pcbStructInfo, bytesNeeded)))
5032             {
5033                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5034                     pvStructInfo = *(BYTE **)pvStructInfo;
5035                 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
5036                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5037                  &bytesNeeded, NULL);
5038                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5039                     CRYPT_FreeSpace(pDecodePara, pvStructInfo);
5040             }
5041         }
5042     }
5043     __EXCEPT_PAGE_FAULT
5044     {
5045         SetLastError(STATUS_ACCESS_VIOLATION);
5046         ret = FALSE;
5047     }
5048     __ENDTRY
5049     return ret;
5050 }
5051 
5052 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
5053  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5054  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5055 {
5056     BOOL ret = TRUE;
5057 
5058     __TRY
5059     {
5060         if (pbEncoded[0] == ASN_SEQUENCEOF)
5061         {
5062             DWORD bytesNeeded, dataLen, remainingLen, cValue;
5063 
5064             if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
5065             {
5066                 BYTE lenBytes;
5067                 const BYTE *ptr;
5068 
5069                 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
5070                 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
5071                 cValue = 0;
5072                 ptr = pbEncoded + 1 + lenBytes;
5073                 remainingLen = dataLen;
5074                 while (ret && remainingLen)
5075                 {
5076                     DWORD nextLen;
5077 
5078                     ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
5079                     if (ret)
5080                     {
5081                         DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
5082 
5083                         remainingLen -= 1 + nextLenBytes + nextLen;
5084                         ptr += 1 + nextLenBytes + nextLen;
5085                         bytesNeeded += sizeof(CRYPT_DER_BLOB);
5086                         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
5087                             bytesNeeded += 1 + nextLenBytes + nextLen;
5088                         cValue++;
5089                     }
5090                 }
5091                 if (ret)
5092                 {
5093                     CRYPT_SEQUENCE_OF_ANY *seq;
5094                     BYTE *nextPtr;
5095                     DWORD i;
5096 
5097                     if (!pvStructInfo)
5098                         *pcbStructInfo = bytesNeeded;
5099                     else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
5100                      pvStructInfo, pcbStructInfo, bytesNeeded)))
5101                     {
5102                         if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5103                             pvStructInfo = *(BYTE **)pvStructInfo;
5104                         seq = pvStructInfo;
5105                         seq->cValue = cValue;
5106                         seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
5107                          sizeof(*seq));
5108                         nextPtr = (BYTE *)seq->rgValue +
5109                          cValue * sizeof(CRYPT_DER_BLOB);
5110                         ptr = pbEncoded + 1 + lenBytes;
5111                         remainingLen = dataLen;
5112                         i = 0;
5113                         while (ret && remainingLen)
5114                         {
5115                             DWORD nextLen;
5116 
5117                             ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
5118                             if (ret)
5119                             {
5120                                 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
5121 
5122                                 seq->rgValue[i].cbData = 1 + nextLenBytes +
5123                                  nextLen;
5124                                 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
5125                                     seq->rgValue[i].pbData = (BYTE *)ptr;
5126                                 else
5127                                 {
5128                                     seq->rgValue[i].pbData = nextPtr;
5129                                     memcpy(nextPtr, ptr, 1 + nextLenBytes +
5130                                      nextLen);
5131                                     nextPtr += 1 + nextLenBytes + nextLen;
5132                                 }
5133                                 remainingLen -= 1 + nextLenBytes + nextLen;
5134                                 ptr += 1 + nextLenBytes + nextLen;
5135                                 i++;
5136                             }
5137                         }
5138                         if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5139                             CRYPT_FreeSpace(pDecodePara, seq);
5140                     }
5141                 }
5142             }
5143         }
5144         else
5145         {
5146             SetLastError(CRYPT_E_ASN1_BADTAG);
5147             ret = FALSE;
5148         }
5149     }
5150     __EXCEPT_PAGE_FAULT
5151     {
5152         SetLastError(STATUS_ACCESS_VIOLATION);
5153         ret = FALSE;
5154     }
5155     __ENDTRY
5156     return ret;
5157 }
5158 
5159 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
5160  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5161  DWORD *pcbDecoded)
5162 {
5163     BOOL ret;
5164 
5165     if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
5166     {
5167         DWORD bytesNeeded = 0, dataLen;
5168 
5169         if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
5170         {
5171             struct AsnArrayDescriptor arrayDesc = {
5172              ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
5173              offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry),
5174              offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry),
5175              FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u),
5176              CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
5177              offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
5178             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
5179             DWORD nameLen;
5180 
5181             if (dataLen)
5182             {
5183                 ret = CRYPT_AsnDecodeArray(&arrayDesc,
5184                  pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
5185                  dwFlags, NULL, NULL, &nameLen, NULL);
5186                 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
5187                  FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u);
5188             }
5189             else
5190                 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
5191             if (pcbDecoded)
5192                 *pcbDecoded = 1 + lenBytes + dataLen;
5193             if (!pvStructInfo)
5194                 *pcbStructInfo = bytesNeeded;
5195             else if (*pcbStructInfo < bytesNeeded)
5196             {
5197                 *pcbStructInfo = bytesNeeded;
5198                 SetLastError(ERROR_MORE_DATA);
5199                 ret = FALSE;
5200             }
5201             else
5202             {
5203                 CRL_DIST_POINT_NAME *name = pvStructInfo;
5204 
5205                 *pcbStructInfo = bytesNeeded;
5206                 if (dataLen)
5207                 {
5208                     name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
5209                     ret = CRYPT_AsnDecodeArray(&arrayDesc,
5210                      pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
5211                      dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen,
5212                      NULL);
5213                 }
5214                 else
5215                     name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
5216             }
5217         }
5218     }
5219     else
5220     {
5221         SetLastError(CRYPT_E_ASN1_BADTAG);
5222         ret = FALSE;
5223     }
5224     return ret;
5225 }
5226 
5227 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
5228  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5229 {
5230     struct AsnDecodeSequenceItem items[] = {
5231      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
5232        DistPointName), CRYPT_AsnDecodeDistPointName,
5233        sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
5234        DistPointName.u.FullName.rgAltEntry), 0 },
5235      { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
5236        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
5237        offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
5238      { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
5239        CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
5240        offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
5241     };
5242     CRL_DIST_POINT *point = pvStructInfo;
5243     BOOL ret;
5244 
5245     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5246      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5247      pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
5248     return ret;
5249 }
5250 
5251 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
5252  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5253  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5254 {
5255     BOOL ret;
5256 
5257     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5258      pDecodePara, pvStructInfo, *pcbStructInfo);
5259 
5260     __TRY
5261     {
5262         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5263          offsetof(CRL_DIST_POINTS_INFO, cDistPoint),
5264          offsetof(CRL_DIST_POINTS_INFO, rgDistPoint),
5265          sizeof(CRL_DIST_POINTS_INFO),
5266          CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
5267          offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
5268         CRL_DIST_POINTS_INFO *info = pvStructInfo;
5269 
5270         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5271             info->rgDistPoint = (CRL_DIST_POINT *)(info + 1);
5272         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5273          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
5274     }
5275     __EXCEPT_PAGE_FAULT
5276     {
5277         SetLastError(STATUS_ACCESS_VIOLATION);
5278         ret = FALSE;
5279     }
5280     __ENDTRY
5281     return ret;
5282 }
5283 
5284 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
5285  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5286  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5287 {
5288     BOOL ret;
5289 
5290     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5291      pDecodePara, pvStructInfo, *pcbStructInfo);
5292 
5293     __TRY
5294     {
5295         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5296          offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier),
5297          offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier),
5298          sizeof(CERT_ENHKEY_USAGE),
5299          CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
5300         CERT_ENHKEY_USAGE *usage = pvStructInfo;
5301 
5302         if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5303             usage->rgpszUsageIdentifier = (LPSTR *)(usage + 1);
5304         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5305          dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
5306     }
5307     __EXCEPT_PAGE_FAULT
5308     {
5309         SetLastError(STATUS_ACCESS_VIOLATION);
5310         ret = FALSE;
5311     }
5312     __ENDTRY
5313     return ret;
5314 }
5315 
5316 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
5317  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5318  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5319 {
5320     BOOL ret;
5321 
5322     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5323      pDecodePara, pvStructInfo, *pcbStructInfo);
5324 
5325     __TRY
5326     {
5327         struct AsnDecodeSequenceItem items[] = {
5328          { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
5329            DistPointName), CRYPT_AsnDecodeDistPointName,
5330            sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
5331            offsetof(CRL_ISSUING_DIST_POINT,
5332            DistPointName.u.FullName.rgAltEntry), 0 },
5333          { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
5334            fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5335            FALSE, 0 },
5336          { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
5337            fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5338            FALSE, 0 },
5339          { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
5340            OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
5341            sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
5342            OnlySomeReasonFlags.pbData), 0 },
5343          { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
5344            fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
5345         };
5346 
5347         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5348          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5349          pcbStructInfo, NULL, NULL);
5350     }
5351     __EXCEPT_PAGE_FAULT
5352     {
5353         SetLastError(STATUS_ACCESS_VIOLATION);
5354         ret = FALSE;
5355     }
5356     __ENDTRY
5357     return ret;
5358 }
5359 
5360 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
5361  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5362  DWORD *pcbDecoded)
5363 {
5364     BOOL ret;
5365     DWORD max, size = sizeof(max);
5366 
5367     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5368      pvStructInfo, *pcbStructInfo, pcbDecoded);
5369 
5370     if (!cbEncoded)
5371     {
5372         SetLastError(CRYPT_E_ASN1_EOD);
5373         return FALSE;
5374     }
5375     if (pbEncoded[0] != (ASN_CONTEXT | 1))
5376     {
5377         SetLastError(CRYPT_E_ASN1_BADTAG);
5378         return FALSE;
5379     }
5380     if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
5381      &max, &size, pcbDecoded)))
5382     {
5383         DWORD bytesNeeded = FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum);
5384 
5385         if (!pvStructInfo)
5386             *pcbStructInfo = bytesNeeded;
5387         else if (*pcbStructInfo < bytesNeeded)
5388         {
5389             *pcbStructInfo = bytesNeeded;
5390             SetLastError(ERROR_MORE_DATA);
5391             ret = FALSE;
5392         }
5393         else
5394         {
5395             CERT_GENERAL_SUBTREE *subtree = CONTAINING_RECORD(pvStructInfo,
5396              CERT_GENERAL_SUBTREE, fMaximum);
5397 
5398             *pcbStructInfo = bytesNeeded;
5399             /* The BOOL is implicit:  if the integer is present, then it's
5400              * TRUE.
5401              */
5402             subtree->fMaximum = TRUE;
5403             subtree->dwMaximum = max;
5404         }
5405     }
5406     TRACE("returning %d\n", ret);
5407     return ret;
5408 }
5409 
5410 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
5411  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5412  DWORD *pcbDecoded)
5413 {
5414     BOOL ret;
5415     struct AsnDecodeSequenceItem items[] = {
5416      { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
5417        CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
5418        offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
5419      { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
5420        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
5421      { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
5422        CRYPT_AsnDecodeMaximum, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum),
5423        TRUE, FALSE, 0, 0 },
5424     };
5425     CERT_GENERAL_SUBTREE *subtree = pvStructInfo;
5426 
5427     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5428      pvStructInfo, *pcbStructInfo, pcbDecoded);
5429 
5430     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5431      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5432      pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
5433     if (pcbDecoded)
5434     {
5435         TRACE("%d\n", *pcbDecoded);
5436         if (*pcbDecoded < cbEncoded)
5437             TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
5438              *(pbEncoded + *pcbDecoded + 1));
5439     }
5440     TRACE("returning %d\n", ret);
5441     return ret;
5442 }
5443 
5444 static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded,
5445  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5446  DWORD *pcbDecoded)
5447 {
5448     BOOL ret = TRUE;
5449     struct AsnArrayDescriptor arrayDesc = { 0,
5450      offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5451      offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree),
5452      MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5453                 cExcludedSubtree),
5454      CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5455      offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5456 
5457     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5458      pvStructInfo, *pcbStructInfo, pcbDecoded);
5459 
5460     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5461      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5462     return ret;
5463 }
5464 
5465 static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded,
5466  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5467  DWORD *pcbDecoded)
5468 {
5469     BOOL ret = TRUE;
5470     struct AsnArrayDescriptor arrayDesc = { 0,
5471      offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5472      offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree),
5473      FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5474      CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5475      offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5476 
5477     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5478      pvStructInfo, *pcbStructInfo, pcbDecoded);
5479 
5480     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5481      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5482     return ret;
5483 }
5484 
5485 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
5486  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5487  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5488 {
5489     BOOL ret = FALSE;
5490 
5491     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5492      pDecodePara, pvStructInfo, *pcbStructInfo);
5493 
5494     __TRY
5495     {
5496         struct AsnDecodeSequenceItem items[] = {
5497          { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
5498            offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5499            CRYPT_AsnDecodePermittedSubtree,
5500            MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5501            cExcludedSubtree), TRUE, TRUE,
5502            offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
5503          { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
5504            offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5505            CRYPT_AsnDecodeExcludedSubtree,
5506            FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5507            TRUE, TRUE,
5508            offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
5509         };
5510 
5511         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5512          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5513          pcbStructInfo, NULL, NULL);
5514     }
5515     __EXCEPT_PAGE_FAULT
5516     {
5517         SetLastError(STATUS_ACCESS_VIOLATION);
5518     }
5519     __ENDTRY
5520     return ret;
5521 }
5522 
5523 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
5524  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5525  DWORD *pcbDecoded)
5526 {
5527     BOOL ret;
5528     struct AsnDecodeSequenceItem items[] = {
5529      { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
5530        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
5531        Issuer.pbData) },
5532      { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
5533        CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
5534        TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
5535     };
5536     CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;
5537 
5538     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5539      pvStructInfo, *pcbStructInfo, pcbDecoded);
5540 
5541     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5542      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5543      pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
5544     if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
5545     {
5546         SetLastError(CRYPT_E_ASN1_CORRUPT);
5547         ret = FALSE;
5548     }
5549     TRACE("returning %d\n", ret);
5550     return ret;
5551 }
5552 
5553 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
5554  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5555  DWORD *pcbDecoded)
5556 {
5557     CMSG_SIGNER_INFO *info = pvStructInfo;
5558     struct AsnDecodeSequenceItem items[] = {
5559      { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
5560        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5561      { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
5562        CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
5563        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
5564      { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
5565        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5566        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5567      { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5568        offsetof(CMSG_SIGNER_INFO, AuthAttrs),
5569        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5570        TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5571      { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
5572        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5573        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
5574        HashEncryptionAlgorithm.pszObjId), 0 },
5575      { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
5576        CRYPT_AsnDecodeOctets, sizeof(CRYPT_DER_BLOB),
5577        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
5578      { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5579        offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
5580        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5581        TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5582     };
5583     BOOL ret;
5584 
5585     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5586      pvStructInfo, *pcbStructInfo);
5587 
5588     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5589      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5590      pcbDecoded, info ? info->Issuer.pbData : NULL);
5591     return ret;
5592 }
5593 
5594 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
5595  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5596  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5597 {
5598     BOOL ret = FALSE;
5599 
5600     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5601      pDecodePara, pvStructInfo, *pcbStructInfo);
5602 
5603     __TRY
5604     {
5605         ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
5606          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5607         if (ret && pvStructInfo)
5608         {
5609             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5610              pcbStructInfo, *pcbStructInfo);
5611             if (ret)
5612             {
5613                 CMSG_SIGNER_INFO *info;
5614 
5615                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5616                     pvStructInfo = *(BYTE **)pvStructInfo;
5617                 info = pvStructInfo;
5618                 info->Issuer.pbData = ((BYTE *)info +
5619                  sizeof(CMSG_SIGNER_INFO));
5620                 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
5621                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5622                  pcbStructInfo, NULL);
5623                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5624                     CRYPT_FreeSpace(pDecodePara, info);
5625             }
5626         }
5627     }
5628     __EXCEPT_PAGE_FAULT
5629     {
5630         SetLastError(STATUS_ACCESS_VIOLATION);
5631     }
5632     __ENDTRY
5633     TRACE("returning %d\n", ret);
5634     return ret;
5635 }
5636 
5637 static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded,
5638  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5639  DWORD *pcbDecoded)
5640 {
5641     BOOL ret;
5642     struct AsnArrayDescriptor arrayDesc = { 0,
5643      offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
5644      offsetof(CRYPT_SIGNED_INFO, rgCertEncoded),
5645      MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded),
5646      CRYPT_AsnDecodeCopyBytes,
5647      sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5648 
5649     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5650      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5651 
5652     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5653      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5654     return ret;
5655 }
5656 
5657 static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded,
5658  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5659  DWORD *pcbDecoded)
5660 {
5661     BOOL ret;
5662     struct AsnArrayDescriptor arrayDesc = { 0,
5663      offsetof(CRYPT_SIGNED_INFO, cCrlEncoded),
5664      offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded),
5665      MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content),
5666      CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB),
5667      TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5668 
5669     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5670      pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5671 
5672     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5673      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5674     return ret;
5675 }
5676 
5677 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
5678  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5679  DWORD *pcbDecoded)
5680 {
5681     CERT_ID *id = pvStructInfo;
5682     BOOL ret = FALSE;
5683 
5684     if (*pbEncoded == ASN_SEQUENCEOF)
5685     {
5686         ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
5687          id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
5688         if (ret)
5689         {
5690             if (id)
5691                 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5692             if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
5693                 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5694                  sizeof(CERT_ISSUER_SERIAL_NUMBER);
5695             else
5696                 *pcbStructInfo = sizeof(CERT_ID);
5697         }
5698     }
5699     else if (*pbEncoded == (ASN_CONTEXT | 0))
5700     {
5701         ret = CRYPT_AsnDecodeOctets(pbEncoded, cbEncoded, dwFlags,
5702          id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
5703         if (ret)
5704         {
5705             if (id)
5706                 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5707             if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
5708                 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5709                  sizeof(CRYPT_DATA_BLOB);
5710             else
5711                 *pcbStructInfo = sizeof(CERT_ID);
5712         }
5713     }
5714     else
5715         SetLastError(CRYPT_E_ASN1_BADTAG);
5716     return ret;
5717 }
5718 
5719 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
5720  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5721  DWORD *pcbDecoded)
5722 {
5723     CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
5724     struct AsnDecodeSequenceItem items[] = {
5725      { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
5726        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5727      { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
5728        CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
5729        offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
5730      { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
5731        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5732        FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5733      { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5734        offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
5735        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5736        TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5737      /* FIXME: Tests show that CertOpenStore accepts such certificates, but
5738       * how exactly should they be interpreted? */
5739      { ASN_CONSTRUCTOR | ASN_UNIVERSAL | 0x11, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5740      { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
5741        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5742        FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
5743        HashEncryptionAlgorithm.pszObjId), 0 },
5744      { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
5745        CRYPT_AsnDecodeOctets, sizeof(CRYPT_DER_BLOB),
5746        FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
5747      { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5748        offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
5749        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5750        TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5751     };
5752     BOOL ret;
5753 
5754     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5755      pvStructInfo, *pcbStructInfo);
5756 
5757     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5758      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5759      pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
5760     return ret;
5761 }
5762 
5763 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
5764  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5765  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5766 {
5767     BOOL ret = FALSE;
5768 
5769     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5770      pDecodePara, pvStructInfo, *pcbStructInfo);
5771 
5772     __TRY
5773     {
5774         ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
5775          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5776         if (ret && pvStructInfo)
5777         {
5778             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5779              pcbStructInfo, *pcbStructInfo);
5780             if (ret)
5781             {
5782                 CMSG_CMS_SIGNER_INFO *info;
5783 
5784                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5785                     pvStructInfo = *(BYTE **)pvStructInfo;
5786                 info = pvStructInfo;
5787                 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
5788                  sizeof(CMSG_CMS_SIGNER_INFO));
5789                 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
5790                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5791                  pcbStructInfo, NULL);
5792                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5793                     CRYPT_FreeSpace(pDecodePara, info);
5794             }
5795         }
5796     }
5797     __EXCEPT_PAGE_FAULT
5798     {
5799         SetLastError(STATUS_ACCESS_VIOLATION);
5800     }
5801     __ENDTRY
5802     TRACE("returning %d\n", ret);
5803     return ret;
5804 }
5805 
5806 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
5807  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5808 {
5809     BOOL ret;
5810     struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5811      offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5812      offsetof(CRYPT_SIGNED_INFO, rgSignerInfo),
5813      FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo),
5814      CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
5815      offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
5816 
5817     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5818      pvStructInfo, *pcbStructInfo, pcbDecoded);
5819 
5820     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5821      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5822     return ret;
5823 }
5824 
5825 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5826  DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5827  CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
5828 {
5829     BOOL ret = FALSE;
5830     struct AsnDecodeSequenceItem items[] = {
5831      { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
5832        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5833      /* Placeholder for the hash algorithms - redundant with those in the
5834       * signers, so just ignore them.
5835       */
5836      { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5837      { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
5838        CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
5839        FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
5840      { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5841        offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded,
5842        MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE,
5843        offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
5844      { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5845        offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded,
5846        MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE,
5847        offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
5848      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5849        CRYPT_DecodeSignerArray,
5850        FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE,
5851        offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
5852     };
5853 
5854     TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded, cbEncoded, dwFlags,
5855      pDecodePara, signedInfo, pcbSignedInfo);
5856 
5857     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5858      pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
5859      NULL, NULL);
5860     TRACE("returning %d\n", ret);
5861     return ret;
5862 }
5863 
5864 static BOOL CRYPT_AsnDecodeRecipientInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5865  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5866 {
5867     BOOL ret;
5868     CMSG_KEY_TRANS_RECIPIENT_INFO *info = pvStructInfo;
5869     struct AsnDecodeSequenceItem items[] = {
5870      { ASN_INTEGER, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, dwVersion),
5871        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5872      { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5873        RecipientId.u.IssuerSerialNumber), CRYPT_AsnDecodeIssuerSerialNumber,
5874        sizeof(CERT_ISSUER_SERIAL_NUMBER), FALSE, TRUE,
5875        offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5876        RecipientId.u.IssuerSerialNumber.Issuer.pbData), 0 },
5877      { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5878        KeyEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId,
5879        sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
5880        offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5881        KeyEncryptionAlgorithm.pszObjId), 0 },
5882      { ASN_OCTETSTRING, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, EncryptedKey),
5883        CRYPT_AsnDecodeOctets, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
5884        offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, EncryptedKey.pbData), 0 },
5885     };
5886 
5887     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5888      pvStructInfo, *pcbStructInfo, pcbDecoded);
5889 
5890     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5891      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5892      pcbDecoded, info ? info->RecipientId.u.IssuerSerialNumber.Issuer.pbData :
5893      NULL);
5894     if (info)
5895         info->RecipientId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5896     TRACE("returning %d\n", ret);
5897     return ret;
5898 }
5899 
5900 static BOOL CRYPT_DecodeRecipientInfoArray(const BYTE *pbEncoded,
5901  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5902  DWORD *pcbDecoded)
5903 {
5904     BOOL ret;
5905     struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5906      offsetof(CRYPT_ENVELOPED_DATA, cRecipientInfo),
5907      offsetof(CRYPT_ENVELOPED_DATA, rgRecipientInfo),
5908      MEMBERSIZE(CRYPT_ENVELOPED_DATA, cRecipientInfo, encryptedContentInfo),
5909      CRYPT_AsnDecodeRecipientInfo, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO), TRUE,
5910      offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5911      RecipientId.u.IssuerSerialNumber.Issuer.pbData) };
5912 
5913     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5914      pvStructInfo, *pcbStructInfo, pcbDecoded);
5915 
5916     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5917      dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5918     TRACE("returning %d\n", ret);
5919     return ret;
5920 }
5921 
5922 static BOOL CRYPT_AsnDecodeEncryptedContentInfo(const BYTE *pbEncoded,
5923  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5924  DWORD *pcbDecoded)
5925 {
5926     BOOL ret;
5927     CRYPT_ENCRYPTED_CONTENT_INFO *info = pvStructInfo;
5928     struct AsnDecodeSequenceItem items[] = {
5929      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5930        contentType), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
5931        FALSE, TRUE, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5932        contentType), 0 },
5933      { ASN_SEQUENCEOF, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5934        contentEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId,
5935        sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
5936        offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5937        contentEncryptionAlgorithm.pszObjId), 0 },
5938      { ASN_CONTEXT | 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5939        encryptedContent), CRYPT_AsnDecodeOctets,
5940        sizeof(CRYPT_DATA_BLOB), TRUE, TRUE,
5941        offsetof(CRYPT_ENCRYPTED_CONTENT_INFO, encryptedContent.pbData) },
5942     };
5943 
5944     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5945      pvStructInfo, *pcbStructInfo, pcbDecoded);
5946 
5947     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5948      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5949      pcbDecoded, info ? info->contentType : NULL);
5950     TRACE("returning %d\n", ret);
5951     return ret;
5952 }
5953 
5954 BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
5955  DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5956  CRYPT_ENVELOPED_DATA *envelopedData, DWORD *pcbEnvelopedData)
5957 {
5958     BOOL ret;
5959     struct AsnDecodeSequenceItem items[] = {
5960      { ASN_INTEGER, offsetof(CRYPT_ENVELOPED_DATA, version),
5961        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5962      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ENVELOPED_DATA,
5963        cRecipientInfo), CRYPT_DecodeRecipientInfoArray,
5964        MEMBERSIZE(CRYPT_ENVELOPED_DATA, cRecipientInfo, encryptedContentInfo),
5965        FALSE, TRUE, offsetof(CRYPT_ENVELOPED_DATA, rgRecipientInfo), 0 },
5966      { ASN_SEQUENCEOF, offsetof(CRYPT_ENVELOPED_DATA, encryptedContentInfo),
5967        CRYPT_AsnDecodeEncryptedContentInfo,
5968        sizeof(CRYPT_ENCRYPTED_CONTENT_INFO), FALSE, TRUE,
5969        offsetof(CRYPT_ENVELOPED_DATA, encryptedContentInfo.contentType), 0 },
5970     };
5971 
5972     TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded, cbEncoded, dwFlags,
5973      pDecodePara, envelopedData, pcbEnvelopedData);
5974 
5975     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5976      pbEncoded, cbEncoded, dwFlags, pDecodePara, envelopedData,
5977      pcbEnvelopedData, NULL, NULL);
5978     TRACE("returning %d\n", ret);
5979     return ret;
5980 }
5981 
5982 static BOOL WINAPI CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType,
5983  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5984  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5985 {
5986     DWORD bytesNeeded = 0;
5987     BOOL ret;
5988 
5989     __TRY
5990     {
5991         ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
5992                                          NULL, &bytesNeeded, NULL);
5993         if (ret)
5994         {
5995             if (!pvStructInfo)
5996                 *pcbStructInfo = bytesNeeded;
5997             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
5998             {
5999                 LPSTR *info;
6000 
6001                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
6002                     pvStructInfo = *(BYTE **)pvStructInfo;
6003 
6004                 info = pvStructInfo;
6005                 *info = (void *)((BYTE *)info + sizeof(*info));
6006                 ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
6007                                                  pvStructInfo, &bytesNeeded, NULL);
6008                 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
6009                     CRYPT_FreeSpace(pDecodePara, info);
6010             }
6011         }
6012     }
6013     __EXCEPT_PAGE_FAULT
6014     {
6015         SetLastError(STATUS_ACCESS_VIOLATION);
6016         ret = FALSE;
6017     }
6018     __ENDTRY
6019     return ret;
6020 }
6021 
6022 static BOOL WINAPI CRYPT_AsnDecodeEccSignature(DWORD dwCertEncodingType,
6023  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
6024  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
6025 {
6026     BOOL ret;
6027     struct AsnDecodeSequenceItem items[] = {
6028      { ASN_INTEGER, offsetof(CERT_ECC_SIGNATURE, r),
6029        CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_UINT_BLOB), FALSE,
6030        TRUE, offsetof(CERT_ECC_SIGNATURE, r.pbData), 0 },
6031      { ASN_INTEGER, offsetof(CERT_ECC_SIGNATURE, s),
6032        CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_UINT_BLOB), FALSE,
6033        TRUE, offsetof(CERT_ECC_SIGNATURE, s.pbData), 0 },
6034     };
6035 
6036     __TRY
6037     {
6038         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
6039          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
6040          pcbStructInfo, NULL, NULL);
6041     }
6042     __EXCEPT_PAGE_FAULT
6043     {
6044         SetLastError(STATUS_ACCESS_VIOLATION);
6045         ret = FALSE;
6046     }
6047     __ENDTRY
6048     return ret;
6049 }
6050 
6051 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
6052  LPCSTR lpszStructType)
6053 {
6054     CryptDecodeObjectExFunc decodeFunc = NULL;
6055 
6056     if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
6057      && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
6058     {
6059         SetLastError(ERROR_FILE_NOT_FOUND);
6060         return NULL;
6061     }
6062     if (IS_INTOID(lpszStructType))
6063     {
6064         switch (LOWORD(lpszStructType))
6065         {
6066         case LOWORD(X509_CERT):
6067             decodeFunc = CRYPT_AsnDecodeCertSignedContent;
6068             break;
6069         case LOWORD(X509_CERT_TO_BE_SIGNED):
6070             decodeFunc = CRYPT_AsnDecodeCert;
6071             break;
6072         case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
6073             decodeFunc = CRYPT_AsnDecodeCRL;
6074             break;
6075         case LOWORD(X509_EXTENSIONS):
6076             decodeFunc = CRYPT_AsnDecodeExtensions;
6077             break;
6078         case LOWORD(X509_NAME_VALUE):
6079             decodeFunc = CRYPT_AsnDecodeNameValue;
6080             break;
6081         case LOWORD(X509_NAME):
6082             decodeFunc = CRYPT_AsnDecodeName;
6083             break;
6084         case LOWORD(X509_PUBLIC_KEY_INFO):
6085             decodeFunc = CRYPT_AsnDecodePubKeyInfo;
6086             break;
6087         case LOWORD(X509_AUTHORITY_KEY_ID):
6088             decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
6089             break;
6090         case LOWORD(X509_ALTERNATE_NAME):
6091             decodeFunc = CRYPT_AsnDecodeAltName;
6092             break;
6093         case LOWORD(X509_BASIC_CONSTRAINTS):
6094             decodeFunc = CRYPT_AsnDecodeBasicConstraints;
6095             break;
6096         case LOWORD(X509_BASIC_CONSTRAINTS2):
6097             decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
6098             break;
6099         case LOWORD(X509_CERT_POLICIES):
6100             decodeFunc = CRYPT_AsnDecodeCertPolicies;
6101             break;
6102         case LOWORD(RSA_CSP_PUBLICKEYBLOB):
6103             decodeFunc = CRYPT_AsnDecodeRsaPubKey;
6104             break;
6105         case LOWORD(PKCS_RSA_PRIVATE_KEY):
6106             decodeFunc = CRYPT_AsnDecodeRsaPrivKey;
6107             break;
6108         case LOWORD(X509_UNICODE_NAME):
6109             decodeFunc = CRYPT_AsnDecodeUnicodeName;
6110             break;
6111         case LOWORD(PKCS_ATTRIBUTE):
6112             decodeFunc = CRYPT_AsnDecodePKCSAttribute;
6113             break;
6114         case LOWORD(X509_UNICODE_NAME_VALUE):
6115             decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
6116             break;
6117         case LOWORD(X509_OCTET_STRING):
6118             decodeFunc = CRYPT_AsnDecodeOctetString;
6119             break;
6120         case LOWORD(X509_BITS):
6121         case LOWORD(X509_KEY_USAGE):
6122             decodeFunc = CRYPT_AsnDecodeBits;
6123             break;
6124         case LOWORD(X509_INTEGER):
6125             decodeFunc = CRYPT_AsnDecodeInt;
6126             break;
6127         case LOWORD(X509_MULTI_BYTE_INTEGER):
6128             decodeFunc = CRYPT_AsnDecodeInteger;
6129             break;
6130         case LOWORD(X509_MULTI_BYTE_UINT):
6131             decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
6132             break;
6133         case LOWORD(X509_ENUMERATED):
6134             decodeFunc = CRYPT_AsnDecodeEnumerated;
6135             break;
6136         case LOWORD(X509_CHOICE_OF_TIME):
6137             decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
6138             break;
6139         case LOWORD(X509_AUTHORITY_KEY_ID2):
6140             decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
6141             break;
6142         case LOWORD(X509_AUTHORITY_INFO_ACCESS):
6143             decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
6144             break;
6145         case LOWORD(PKCS_CONTENT_INFO):
6146             decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
6147             break;
6148         case LOWORD(X509_SEQUENCE_OF_ANY):
6149             decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
6150             break;
6151         case LOWORD(PKCS_UTC_TIME):
6152             decodeFunc = CRYPT_AsnDecodeUtcTime;
6153             break;
6154         case LOWORD(X509_CRL_DIST_POINTS):
6155             decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
6156             break;
6157         case LOWORD(X509_ENHANCED_KEY_USAGE):
6158             decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
6159             break;
6160         case LOWORD(PKCS_CTL):
6161             decodeFunc = CRYPT_AsnDecodeCTL;
6162             break;
6163         case LOWORD(PKCS_SMIME_CAPABILITIES):
6164             decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
6165             break;
6166         case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
6167             decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
6168             break;
6169         case LOWORD(PKCS_ATTRIBUTES):
6170             decodeFunc = CRYPT_AsnDecodePKCSAttributes;
6171             break;
6172         case LOWORD(X509_ISSUING_DIST_POINT):
6173             decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
6174             break;
6175         case LOWORD(X509_NAME_CONSTRAINTS):
6176             decodeFunc = CRYPT_AsnDecodeNameConstraints;
6177             break;
6178         case LOWORD(X509_POLICY_MAPPINGS):
6179             decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
6180             break;
6181         case LOWORD(X509_POLICY_CONSTRAINTS):
6182             decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
6183             break;
6184         case LOWORD(PKCS7_SIGNER_INFO):
6185             decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
6186             break;
6187         case LOWORD(CMS_SIGNER_INFO):
6188             decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
6189             break;
6190         case LOWORD(X509_OBJECT_IDENTIFIER):
6191             decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
6192             break;
6193         case LOWORD(X509_ECC_SIGNATURE):
6194             decodeFunc = CRYPT_AsnDecodeEccSignature;
6195             break;
6196         }
6197     }
6198     else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
6199         decodeFunc = CRYPT_AsnDecodeExtensions;
6200     else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
6201         decodeFunc = CRYPT_AsnDecodeUtcTime;
6202     else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
6203         decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
6204     else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
6205         decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
6206     else if (!strcmp(lpszStructType, szOID_LEGACY_POLICY_MAPPINGS))
6207         decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
6208     else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
6209         decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
6210     else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
6211         decodeFunc = CRYPT_AsnDecodeEnumerated;
6212     else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
6213         decodeFunc = CRYPT_AsnDecodeBits;
6214     else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
6215         decodeFunc = CRYPT_AsnDecodeOctetString;
6216     else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
6217         decodeFunc = CRYPT_AsnDecodeBasicConstraints;
6218     else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
6219         decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
6220     else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
6221         decodeFunc = CRYPT_AsnDecodeAltName;
6222     else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
6223         decodeFunc = CRYPT_AsnDecodeAltName;
6224     else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
6225         decodeFunc = CRYPT_AsnDecodeAltName;
6226     else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
6227         decodeFunc = CRYPT_AsnDecodeAltName;
6228     else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
6229         decodeFunc = CRYPT_AsnDecodeAltName;
6230     else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
6231         decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
6232     else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
6233         decodeFunc = CRYPT_AsnDecodeCertPolicies;
6234     else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS))
6235         decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
6236     else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS))
6237         decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
6238     else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
6239         decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
6240     else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
6241         decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
6242     else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
6243         decodeFunc = CRYPT_AsnDecodeNameConstraints;
6244     else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
6245         decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
6246     else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
6247         decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
6248     else if (!strcmp(lpszStructType, szOID_CTL))
6249         decodeFunc = CRYPT_AsnDecodeCTL;
6250     else if (!strcmp(lpszStructType, szOID_ECC_PUBLIC_KEY))
6251         decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
6252     return decodeFunc;
6253 }
6254 
6255 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
6256  LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
6257 {
6258     static HCRYPTOIDFUNCSET set = NULL;
6259     CryptDecodeObjectFunc decodeFunc = NULL;
6260 
6261     if (!set)
6262         set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
6263     CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
6264      (void **)&decodeFunc, hFunc);
6265     return decodeFunc;
6266 }
6267 
6268 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
6269  LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
6270 {
6271     static HCRYPTOIDFUNCSET set = NULL;
6272     CryptDecodeObjectExFunc decodeFunc = NULL;
6273 
6274     if (!set)
6275         set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
6276     CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
6277      (void **)&decodeFunc, hFunc);
6278     return decodeFunc;
6279 }
6280 
6281 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
6282  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
6283  DWORD *pcbStructInfo)
6284 {
6285     BOOL ret = FALSE;
6286     CryptDecodeObjectFunc pCryptDecodeObject = NULL;
6287     CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
6288     HCRYPTOIDFUNCADDR hFunc = NULL;
6289 
6290     TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
6291      debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
6292      pvStructInfo, pcbStructInfo);
6293 
6294     if (!pvStructInfo && !pcbStructInfo)
6295     {
6296         SetLastError(ERROR_INVALID_PARAMETER);
6297         return FALSE;
6298     }
6299     if (cbEncoded > MAX_ENCODED_LEN)
6300     {
6301         SetLastError(CRYPT_E_ASN1_LARGE);
6302         return FALSE;
6303     }
6304 
6305     if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
6306      lpszStructType)))
6307     {
6308         TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
6309          debugstr_a(lpszStructType));
6310         pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
6311          lpszStructType, &hFunc);
6312         if (!pCryptDecodeObject)
6313             pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
6314              lpszStructType, &hFunc);
6315     }
6316     if (pCryptDecodeObject)
6317         ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6318          pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
6319     else if (pCryptDecodeObjectEx)
6320         ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
6321          pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
6322          pvStructInfo, pcbStructInfo);
6323     if (hFunc)
6324         CryptFreeOIDFunctionAddress(hFunc, 0);
6325     TRACE_(crypt)("returning %d\n", ret);
6326     return ret;
6327 }
6328 
6329 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
6330  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
6331  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
6332 {
6333     BOOL ret = FALSE;
6334     CryptDecodeObjectExFunc decodeFunc;
6335     HCRYPTOIDFUNCADDR hFunc = NULL;
6336 
6337     TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6338      dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
6339      cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
6340 
6341     if (!pvStructInfo && !pcbStructInfo)
6342     {
6343         SetLastError(ERROR_INVALID_PARAMETER);
6344         return FALSE;
6345     }
6346     if (cbEncoded > MAX_ENCODED_LEN)
6347     {
6348         SetLastError(CRYPT_E_ASN1_LARGE);
6349         return FALSE;
6350     }
6351 
6352     SetLastError(NOERROR);
6353     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
6354     {
6355         if (!pvStructInfo)
6356         {
6357             SetLastError(ERROR_INVALID_PARAMETER);
6358             return FALSE;
6359         }
6360         *(BYTE **)pvStructInfo = NULL;
6361     }
6362     decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
6363     if (!decodeFunc)
6364     {
6365         TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
6366          debugstr_a(lpszStructType));
6367         decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
6368          &hFunc);
6369     }
6370     if (decodeFunc)
6371         ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
6372          cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
6373     else
6374     {
6375         CryptDecodeObjectFunc pCryptDecodeObject =
6376          CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
6377 
6378         /* Try CryptDecodeObject function.  Don't call CryptDecodeObject
6379          * directly, as that could cause an infinite loop.
6380          */
6381         if (pCryptDecodeObject)
6382         {
6383             if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
6384             {
6385                 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6386                  pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
6387                 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
6388                  pvStructInfo, pcbStructInfo, *pcbStructInfo)))
6389                 {
6390                     ret = pCryptDecodeObject(dwCertEncodingType,
6391                      lpszStructType, pbEncoded, cbEncoded, dwFlags,
6392                      *(BYTE **)pvStructInfo, pcbStructInfo);
6393                     if (!ret)
6394                         CRYPT_FreeSpace(pDecodePara, *(BYTE **)pvStructInfo);
6395                 }
6396             }
6397             else
6398                 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6399                  pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
6400         }
6401     }
6402     if (hFunc)
6403         CryptFreeOIDFunctionAddress(hFunc, 0);
6404     TRACE_(crypt)("returning %d\n", ret);
6405     return ret;
6406 }
6407 
6408 BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
6409 {
6410     BOOL ret;
6411 
6412     TRACE_(crypt)("(%p)\n", pPFX);
6413 
6414     /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6415      * version integer of length 1 (3 encoded byes) and at least one other
6416      * datum (two encoded bytes), plus at least two bytes for the outer
6417      * sequence.  Thus, even an empty PFX blob is at least 7 bytes in length.
6418      */
6419     if (pPFX->cbData < 7)
6420         ret = FALSE;
6421     else if (pPFX->pbData[0] == ASN_SEQUENCE)
6422     {
6423         DWORD len;
6424 
6425         if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
6426         {
6427             BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);
6428 
6429             /* Need at least three bytes for the integer version */
6430             if (pPFX->cbData < 1 + lenLen + 3)
6431                 ret = FALSE;
6432             else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
6433              pPFX->pbData[1 + lenLen + 1] != 1 ||          /* Definite length */
6434              pPFX->pbData[1 + lenLen + 2] != 3)            /* PFX version */
6435                 ret = FALSE;
6436         }
6437     }
6438     else
6439         ret = FALSE;
6440     return ret;
6441 }
6442 
6443 HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
6444  DWORD dwFlags)
6445 {
6446     FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);
6447     return NULL;
6448 }
6449 
6450 BOOL WINAPI PFXVerifyPassword(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
6451  DWORD dwFlags)
6452 {
6453     FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);
6454     return FALSE;
6455 }
6456