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