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