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