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