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