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