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