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