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