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