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