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