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