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