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