crypt32: Allow messages to be opened when compiled with CMSG_SIGNED_ENCODE_INFO_HAS_C...
[wine] / dlls / crypt32 / decode.c
1 /*
2  * Copyright 2005-2008 Juan Lang
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  * This file implements ASN.1 DER decoding of a limited set of types.
19  * It isn't a full ASN.1 implementation.  Microsoft implements BER
20  * encoding of many of the basic types in msasn1.dll, but that interface isn't
21  * implemented, so I implement them here.
22  *
23  * References:
24  * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25  * (available online, look for a PDF copy as the HTML versions tend to have
26  * translation errors.)
27  *
28  * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
29  *
30  * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
31  */
32
33 #include "config.h"
34 #include "wine/port.h"
35
36 #include <assert.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40
41 #define NONAMELESSUNION
42
43 #include "windef.h"
44 #include "winbase.h"
45 #include "wincrypt.h"
46 #include "winnls.h"
47 #include "snmp.h"
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
51
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
54
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK  0x1f
57
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt);
60
61 struct GenericArray
62 {
63     DWORD cItems;
64     BYTE *rgItems;
65 };
66
67 typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *,
68  DWORD, DWORD, void *, DWORD *);
69 typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *,
70  DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *);
71
72 /* Internal decoders don't do memory allocation or exception handling, and
73  * they report how many bytes they decoded.
74  */
75 typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded,
76  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
77
78 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
79  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
80  DWORD *pcbDecoded);
81 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
82  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
83  DWORD *pcbDecoded);
84 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
85  * time, doesn't do memory allocation, and doesn't do exception handling.
86  */
87 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
88  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
89  DWORD *pcbDecoded);
90 /* Assumes algo->Parameters.pbData is set ahead of time. */
91 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
92  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
93 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
94  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
95 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
96 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
97  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
98  DWORD *pcbDecoded);
99 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
100  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
101 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
102  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
103 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
104  * member has been initialized, doesn't do exception handling, and doesn't do
105  * memory allocation.  Also doesn't check tag, assumes the caller has checked
106  * it.
107  */
108 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
109  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
110  DWORD *pcbDecoded);
111 /* Like CRYPT_AsnDecodeInteger, but unsigned.  */
112 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
113  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
114  DWORD *pcbDecoded);
115
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         *pcbStructInfo = sizeof(BOOL);
2289         *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2290         ret = TRUE;
2291     }
2292     TRACE("returning %d (%08x)\n", ret, GetLastError());
2293     return ret;
2294 }
2295
2296 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2297  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2298 {
2299     PCERT_ALT_NAME_ENTRY entry = (PCERT_ALT_NAME_ENTRY)pvStructInfo;
2300     DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2301     BOOL ret;
2302
2303     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2304      pvStructInfo, *pcbStructInfo);
2305
2306     if (cbEncoded < 2)
2307     {
2308         SetLastError(CRYPT_E_ASN1_CORRUPT);
2309         return FALSE;
2310     }
2311     lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2312     if (1 + lenBytes > cbEncoded)
2313     {
2314         SetLastError(CRYPT_E_ASN1_CORRUPT);
2315         return FALSE;
2316     }
2317     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2318     {
2319         switch (pbEncoded[0] & ASN_TYPE_MASK)
2320         {
2321         case 1: /* rfc822Name */
2322         case 2: /* dNSName */
2323         case 6: /* uniformResourceIdentifier */
2324             bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2325             break;
2326         case 4: /* directoryName */
2327         case 7: /* iPAddress */
2328             bytesNeeded += dataLen;
2329             break;
2330         case 8: /* registeredID */
2331             ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2332              &dataLen, NULL);
2333             if (ret)
2334             {
2335                 /* FIXME: ugly, shouldn't need to know internals of OID decode
2336                  * function to use it.
2337                  */
2338                 bytesNeeded += dataLen - sizeof(LPSTR);
2339             }
2340             break;
2341         case 0: /* otherName */
2342             FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2343             SetLastError(CRYPT_E_ASN1_BADTAG);
2344             ret = FALSE;
2345             break;
2346         case 3: /* x400Address, unimplemented */
2347         case 5: /* ediPartyName, unimplemented */
2348             TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2349             SetLastError(CRYPT_E_ASN1_BADTAG);
2350             ret = FALSE;
2351             break;
2352         default:
2353             TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2354             SetLastError(CRYPT_E_ASN1_CORRUPT);
2355             ret = FALSE;
2356         }
2357         if (ret)
2358         {
2359             if (pcbDecoded)
2360                 *pcbDecoded = 1 + lenBytes + dataLen;
2361             if (!entry)
2362                 *pcbStructInfo = bytesNeeded;
2363             else if (*pcbStructInfo < bytesNeeded)
2364             {
2365                 *pcbStructInfo = bytesNeeded;
2366                 SetLastError(ERROR_MORE_DATA);
2367                 ret = FALSE;
2368             }
2369             else
2370             {
2371                 *pcbStructInfo = bytesNeeded;
2372                 /* MS used values one greater than the asn1 ones.. sigh */
2373                 entry->dwAltNameChoice = (pbEncoded[0] & 0x7f) + 1;
2374                 switch (pbEncoded[0] & ASN_TYPE_MASK)
2375                 {
2376                 case 1: /* rfc822Name */
2377                 case 2: /* dNSName */
2378                 case 6: /* uniformResourceIdentifier */
2379                 {
2380                     DWORD i;
2381
2382                     for (i = 0; i < dataLen; i++)
2383                         entry->u.pwszURL[i] =
2384                          (WCHAR)pbEncoded[1 + lenBytes + i];
2385                     entry->u.pwszURL[i] = 0;
2386                     TRACE("URL is %p (%s)\n", entry->u.pwszURL,
2387                      debugstr_w(entry->u.pwszURL));
2388                     break;
2389                 }
2390                 case 4: /* directoryName */
2391                     entry->dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
2392                     /* The data are memory-equivalent with the IPAddress case,
2393                      * fall-through
2394                      */
2395                 case 7: /* iPAddress */
2396                     /* The next data pointer is in the pwszURL spot, that is,
2397                      * the first 4 bytes.  Need to move it to the next spot.
2398                      */
2399                     entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
2400                     entry->u.IPAddress.cbData = dataLen;
2401                     memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
2402                      dataLen);
2403                     break;
2404                 case 8: /* registeredID */
2405                     ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
2406                      &entry->u.pszRegisteredID, &dataLen, NULL);
2407                     break;
2408                 }
2409             }
2410         }
2411     }
2412     return ret;
2413 }
2414
2415 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
2416  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2417  DWORD *pcbDecoded)
2418 {
2419     BOOL ret = TRUE;
2420     struct AsnArrayDescriptor arrayDesc = { 0,
2421      CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
2422      offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
2423     PCERT_ALT_NAME_INFO info = (PCERT_ALT_NAME_INFO)pvStructInfo;
2424
2425     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2426      pvStructInfo, *pcbStructInfo, pcbDecoded);
2427
2428     if (info)
2429         TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
2430     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2431      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2432      info ? info->rgAltEntry : NULL);
2433     return ret;
2434 }
2435
2436 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2437 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
2438  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2439  DWORD *pcbDecoded)
2440 {
2441     BOOL ret;
2442
2443     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
2444      pvStructInfo, *pcbStructInfo, pcbDecoded);
2445
2446     /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2447      * place.
2448      */
2449     ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
2450      dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
2451      pcbDecoded);
2452     if (ret && pvStructInfo)
2453     {
2454         CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2455
2456         if (blob->cbData)
2457         {
2458             DWORD i;
2459             BYTE temp;
2460
2461             for (i = 0; i < blob->cbData / 2; i++)
2462             {
2463                 temp = blob->pbData[i];
2464                 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
2465                 blob->pbData[blob->cbData - i - 1] = temp;
2466             }
2467         }
2468     }
2469     TRACE("returning %d (%08x)\n", ret, GetLastError());
2470     return ret;
2471 }
2472
2473 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
2474  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2475  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2476 {
2477     BOOL ret;
2478
2479     __TRY
2480     {
2481         struct AsnDecodeSequenceItem items[] = {
2482          { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
2483            CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2484            TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
2485          { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2486            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
2487            CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
2488            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
2489          { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
2490            CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2491            sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2492            offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
2493         };
2494
2495         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2496          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2497          pcbStructInfo, NULL, NULL);
2498     }
2499     __EXCEPT_PAGE_FAULT
2500     {
2501         SetLastError(STATUS_ACCESS_VIOLATION);
2502         ret = FALSE;
2503     }
2504     __ENDTRY
2505     return ret;
2506 }
2507
2508 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
2509  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2510  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2511 {
2512     BOOL ret;
2513
2514     __TRY
2515     {
2516         struct AsnDecodeSequenceItem items[] = {
2517          { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
2518            CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2519            TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
2520          { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2521            offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
2522            CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
2523            TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2524            AuthorityCertIssuer.rgAltEntry), 0 },
2525          { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2526            AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2527            sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2528            offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2529            AuthorityCertSerialNumber.pbData), 0 },
2530         };
2531
2532         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2533          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2534          pcbStructInfo, NULL, NULL);
2535     }
2536     __EXCEPT_PAGE_FAULT
2537     {
2538         SetLastError(STATUS_ACCESS_VIOLATION);
2539         ret = FALSE;
2540     }
2541     __ENDTRY
2542     return ret;
2543 }
2544
2545 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
2546  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2547 {
2548     BOOL ret;
2549     DWORD dataLen;
2550
2551     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2552      pvStructInfo, *pcbStructInfo, pcbDecoded);
2553
2554     /* The caller has already checked the tag, no need to check it again.
2555      * Check the outer length is valid:
2556      */
2557     if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
2558     {
2559         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2560         DWORD innerLen;
2561
2562         pbEncoded += 1 + lenBytes;
2563         cbEncoded -= 1 + lenBytes;
2564         if (dataLen == CMSG_INDEFINITE_LENGTH)
2565             cbEncoded -= 2; /* space for 0 TLV */
2566         /* Check the inner length is valid: */
2567         if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
2568         {
2569             DWORD decodedLen;
2570
2571             ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
2572              pvStructInfo, pcbStructInfo, &decodedLen);
2573             if (dataLen == CMSG_INDEFINITE_LENGTH)
2574             {
2575                 if (*(pbEncoded + decodedLen) != 0 ||
2576                  *(pbEncoded + decodedLen + 1) != 0)
2577                 {
2578                     TRACE("expected 0 TLV, got {%02x,%02x}\n",
2579                      *(pbEncoded + decodedLen),
2580                      *(pbEncoded + decodedLen + 1));
2581                     SetLastError(CRYPT_E_ASN1_CORRUPT);
2582                     ret = FALSE;
2583                 }
2584                 else
2585                     decodedLen += 2;
2586             }
2587             if (ret && pcbDecoded)
2588             {
2589                 *pcbDecoded = 1 + lenBytes + decodedLen;
2590                 TRACE("decoded %d bytes\n", *pcbDecoded);
2591             }
2592         }
2593     }
2594     return ret;
2595 }
2596
2597 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
2598  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2599  DWORD *pcbDecoded)
2600 {
2601     CRYPT_CONTENT_INFO *info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2602     struct AsnDecodeSequenceItem items[] = {
2603      { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
2604        CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2605        offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
2606      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
2607        offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
2608        sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
2609        offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
2610     };
2611     BOOL ret;
2612
2613     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2614      pvStructInfo, *pcbStructInfo, pcbDecoded);
2615
2616     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2617      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2618      pcbDecoded, info ? info->pszObjId : NULL);
2619     return ret;
2620 }
2621
2622 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
2623  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2624  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2625 {
2626     BOOL ret = FALSE;
2627
2628     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2629      pDecodePara, pvStructInfo, *pcbStructInfo);
2630
2631     __TRY
2632     {
2633         ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
2634          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
2635         if (ret && pvStructInfo)
2636         {
2637             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
2638              pcbStructInfo, *pcbStructInfo);
2639             if (ret)
2640             {
2641                 CRYPT_CONTENT_INFO *info;
2642
2643                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2644                     pvStructInfo = *(BYTE **)pvStructInfo;
2645                 info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2646                 info->pszObjId = (LPSTR)((BYTE *)info +
2647                  sizeof(CRYPT_CONTENT_INFO));
2648                 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
2649                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2650                  pcbStructInfo, NULL);
2651             }
2652         }
2653     }
2654     __EXCEPT_PAGE_FAULT
2655     {
2656         SetLastError(STATUS_ACCESS_VIOLATION);
2657     }
2658     __ENDTRY
2659     return ret;
2660 }
2661
2662 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
2663  DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2664  CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
2665 {
2666     BOOL ret;
2667     struct AsnDecodeSequenceItem items[] = {
2668      { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
2669        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2670      { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
2671        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2672        FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
2673        0 },
2674      { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
2675        CRYPT_AsnDecodePKCSContentInfoInternal,
2676        sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
2677        ContentInfo.pszObjId), 0 },
2678      { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
2679        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
2680        offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
2681     };
2682
2683     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2684      pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
2685      NULL, NULL);
2686     return ret;
2687 }
2688
2689 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
2690  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2691  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2692 {
2693     BOOL ret = TRUE;
2694
2695     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2696      pDecodePara, pvStructInfo, *pcbStructInfo);
2697
2698     __TRY
2699     {
2700         DWORD bytesNeeded;
2701
2702         if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2703          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2704         {
2705             if (!pvStructInfo)
2706                 *pcbStructInfo = bytesNeeded;
2707             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2708              pvStructInfo, pcbStructInfo, bytesNeeded)))
2709             {
2710                 CERT_ALT_NAME_INFO *name;
2711
2712                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2713                     pvStructInfo = *(BYTE **)pvStructInfo;
2714                 name = (CERT_ALT_NAME_INFO *)pvStructInfo;
2715                 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
2716                  ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
2717                 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2718                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2719                  &bytesNeeded, NULL);
2720             }
2721         }
2722     }
2723     __EXCEPT_PAGE_FAULT
2724     {
2725         SetLastError(STATUS_ACCESS_VIOLATION);
2726         ret = FALSE;
2727     }
2728     __ENDTRY
2729     return ret;
2730 }
2731
2732 struct PATH_LEN_CONSTRAINT
2733 {
2734     BOOL  fPathLenConstraint;
2735     DWORD dwPathLenConstraint;
2736 };
2737
2738 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
2739  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2740  DWORD *pcbDecoded)
2741 {
2742     BOOL ret = TRUE;
2743     DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
2744
2745     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2746      pvStructInfo, *pcbStructInfo, pcbDecoded);
2747
2748     if (!pvStructInfo)
2749     {
2750         ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
2751          &size, pcbDecoded);
2752         *pcbStructInfo = bytesNeeded;
2753     }
2754     else if (*pcbStructInfo < bytesNeeded)
2755     {
2756         SetLastError(ERROR_MORE_DATA);
2757         *pcbStructInfo = bytesNeeded;
2758         ret = FALSE;
2759     }
2760     else
2761     {
2762         struct PATH_LEN_CONSTRAINT *constraint =
2763          (struct PATH_LEN_CONSTRAINT *)pvStructInfo;
2764
2765         *pcbStructInfo = bytesNeeded;
2766         size = sizeof(constraint->dwPathLenConstraint);
2767         ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
2768          &constraint->dwPathLenConstraint, &size, pcbDecoded);
2769         if (ret)
2770             constraint->fPathLenConstraint = TRUE;
2771         TRACE("got an int, dwPathLenConstraint is %d\n",
2772          constraint->dwPathLenConstraint);
2773     }
2774     TRACE("returning %d (%08x)\n", ret, GetLastError());
2775     return ret;
2776 }
2777
2778 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
2779  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2780  DWORD *pcbDecoded)
2781 {
2782     BOOL ret;
2783     struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2784      CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
2785      offsetof(CERT_NAME_BLOB, pbData) };
2786     struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
2787
2788     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2789      pvStructInfo, *pcbStructInfo, pcbDecoded);
2790
2791     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2792      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2793      entries ? entries->rgItems : NULL);
2794     TRACE("Returning %d (%08x)\n", ret, GetLastError());
2795     return ret;
2796 }
2797
2798 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
2799  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2800  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2801 {
2802     BOOL ret;
2803
2804     __TRY
2805     {
2806         struct AsnDecodeSequenceItem items[] = {
2807          { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
2808            CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE, 
2809            offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
2810          { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
2811            fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
2812            sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
2813          { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
2814            cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
2815            sizeof(struct GenericArray), TRUE, TRUE,
2816            offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
2817         };
2818
2819         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2820          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2821          pcbStructInfo, NULL, NULL);
2822     }
2823     __EXCEPT_PAGE_FAULT
2824     {
2825         SetLastError(STATUS_ACCESS_VIOLATION);
2826         ret = FALSE;
2827     }
2828     __ENDTRY
2829     return ret;
2830 }
2831
2832 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
2833  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2834  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2835 {
2836     BOOL ret;
2837
2838     __TRY
2839     {
2840         struct AsnDecodeSequenceItem items[] = {
2841          { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
2842            CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
2843          { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
2844            fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
2845            sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
2846         };
2847
2848         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2849          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2850          pcbStructInfo, NULL, NULL);
2851     }
2852     __EXCEPT_PAGE_FAULT
2853     {
2854         SetLastError(STATUS_ACCESS_VIOLATION);
2855         ret = FALSE;
2856     }
2857     __ENDTRY
2858     return ret;
2859 }
2860
2861 #define RSA1_MAGIC 0x31415352
2862
2863 struct DECODED_RSA_PUB_KEY
2864 {
2865     DWORD              pubexp;
2866     CRYPT_INTEGER_BLOB modulus;
2867 };
2868
2869 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
2870  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2871  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2872 {
2873     BOOL ret;
2874
2875     __TRY
2876     {
2877         struct AsnDecodeSequenceItem items[] = {
2878          { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
2879            CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2880            FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
2881            0 },
2882          { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
2883            CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2884         };
2885         struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
2886         DWORD size = 0;
2887
2888         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2889          pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
2890          &size, NULL, NULL);
2891         if (ret)
2892         {
2893             DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2894              decodedKey->modulus.cbData;
2895
2896             if (!pvStructInfo)
2897             {
2898                 *pcbStructInfo = bytesNeeded;
2899                 ret = TRUE;
2900             }
2901             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2902              pvStructInfo, pcbStructInfo, bytesNeeded)))
2903             {
2904                 BLOBHEADER *hdr;
2905                 RSAPUBKEY *rsaPubKey;
2906
2907                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2908                     pvStructInfo = *(BYTE **)pvStructInfo;
2909                 hdr = (BLOBHEADER *)pvStructInfo;
2910                 hdr->bType = PUBLICKEYBLOB;
2911                 hdr->bVersion = CUR_BLOB_VERSION;
2912                 hdr->reserved = 0;
2913                 hdr->aiKeyAlg = CALG_RSA_KEYX;
2914                 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
2915                  sizeof(BLOBHEADER));
2916                 rsaPubKey->magic = RSA1_MAGIC;
2917                 rsaPubKey->pubexp = decodedKey->pubexp;
2918                 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
2919                 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
2920                  sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
2921                  decodedKey->modulus.cbData);
2922             }
2923             LocalFree(decodedKey);
2924         }
2925     }
2926     __EXCEPT_PAGE_FAULT
2927     {
2928         SetLastError(STATUS_ACCESS_VIOLATION);
2929         ret = FALSE;
2930     }
2931     __ENDTRY
2932     return ret;
2933 }
2934
2935 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
2936  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2937  DWORD *pcbDecoded)
2938 {
2939     BOOL ret;
2940     DWORD bytesNeeded, dataLen;
2941
2942     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2943      pvStructInfo, *pcbStructInfo, pcbDecoded);
2944
2945     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2946     {
2947         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2948
2949         if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2950             bytesNeeded = sizeof(CRYPT_DATA_BLOB);
2951         else
2952             bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
2953         if (pcbDecoded)
2954             *pcbDecoded = 1 + lenBytes + dataLen;
2955         if (!pvStructInfo)
2956             *pcbStructInfo = bytesNeeded;
2957         else if (*pcbStructInfo < bytesNeeded)
2958         {
2959             SetLastError(ERROR_MORE_DATA);
2960             *pcbStructInfo = bytesNeeded;
2961             ret = FALSE;
2962         }
2963         else
2964         {
2965             CRYPT_DATA_BLOB *blob;
2966
2967             *pcbStructInfo = bytesNeeded;
2968             blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2969             blob->cbData = dataLen;
2970             if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2971                 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
2972             else
2973             {
2974                 assert(blob->pbData);
2975                 if (blob->cbData)
2976                     memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
2977                      blob->cbData);
2978             }
2979         }
2980     }
2981     return ret;
2982 }
2983
2984 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
2985  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2986  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2987 {
2988     BOOL ret;
2989
2990     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2991      pDecodePara, pvStructInfo, *pcbStructInfo);
2992
2993     __TRY
2994     {
2995         DWORD bytesNeeded;
2996
2997         if (!cbEncoded)
2998         {
2999             SetLastError(CRYPT_E_ASN1_CORRUPT);
3000             ret = FALSE;
3001         }
3002         else if (pbEncoded[0] != ASN_OCTETSTRING)
3003         {
3004             SetLastError(CRYPT_E_ASN1_BADTAG);
3005             ret = FALSE;
3006         }
3007         else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3008          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3009         {
3010             if (!pvStructInfo)
3011                 *pcbStructInfo = bytesNeeded;
3012             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3013              pvStructInfo, pcbStructInfo, bytesNeeded)))
3014             {
3015                 CRYPT_DATA_BLOB *blob;
3016
3017                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3018                     pvStructInfo = *(BYTE **)pvStructInfo;
3019                 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3020                 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3021                 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3022                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3023                  &bytesNeeded, NULL);
3024             }
3025         }
3026     }
3027     __EXCEPT_PAGE_FAULT
3028     {
3029         SetLastError(STATUS_ACCESS_VIOLATION);
3030         ret = FALSE;
3031     }
3032     __ENDTRY
3033     return ret;
3034 }
3035
3036 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3037  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3038 {
3039     BOOL ret;
3040
3041     TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3042      pvStructInfo, *pcbStructInfo, pcbDecoded);
3043
3044     if (pbEncoded[0] == ASN_BITSTRING)
3045     {
3046         DWORD bytesNeeded, dataLen;
3047         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3048
3049         if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3050         {
3051             if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3052                 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
3053             else
3054                 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
3055             if (pcbDecoded)
3056                 *pcbDecoded = 1 + lenBytes + dataLen;
3057             if (!pvStructInfo)
3058                 *pcbStructInfo = bytesNeeded;
3059             else if (*pcbStructInfo < bytesNeeded)
3060             {
3061                 *pcbStructInfo = bytesNeeded;
3062                 SetLastError(ERROR_MORE_DATA);
3063                 ret = FALSE;
3064             }
3065             else
3066             {
3067                 CRYPT_BIT_BLOB *blob;
3068
3069                 *pcbStructInfo = bytesNeeded;
3070                 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3071                 blob->cbData = dataLen - 1;
3072                 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
3073                 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3074                 {
3075                     blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
3076                 }
3077                 else
3078                 {
3079                     assert(blob->pbData);
3080                     if (blob->cbData)
3081                     {
3082                         BYTE mask = 0xff << blob->cUnusedBits;
3083
3084                         memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
3085                          blob->cbData);
3086                         blob->pbData[blob->cbData - 1] &= mask;
3087                     }
3088                 }
3089             }
3090         }
3091     }
3092     else
3093     {
3094         SetLastError(CRYPT_E_ASN1_BADTAG);
3095         ret = FALSE;
3096     }
3097     TRACE("returning %d (%08x)\n", ret, GetLastError());
3098     return ret;
3099 }
3100
3101 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
3102  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3103  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3104 {
3105     BOOL ret;
3106
3107     TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
3108      pDecodePara, pvStructInfo, pcbStructInfo);
3109
3110     __TRY
3111     {
3112         DWORD bytesNeeded;
3113
3114         if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3115          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3116         {
3117             if (!pvStructInfo)
3118                 *pcbStructInfo = bytesNeeded;
3119             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3120              pvStructInfo, pcbStructInfo, bytesNeeded)))
3121             {
3122                 CRYPT_BIT_BLOB *blob;
3123
3124                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3125                     pvStructInfo = *(BYTE **)pvStructInfo;
3126                 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3127                 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
3128                 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3129                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3130                  &bytesNeeded, NULL);
3131             }
3132         }
3133     }
3134     __EXCEPT_PAGE_FAULT
3135     {
3136         SetLastError(STATUS_ACCESS_VIOLATION);
3137         ret = FALSE;
3138     }
3139     __ENDTRY
3140     TRACE("returning %d (%08x)\n", ret, GetLastError());
3141     return ret;
3142 }
3143
3144 /* Ignores tag.  Only allows integers 4 bytes or smaller in size. */
3145 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3146  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3147 {
3148     BOOL ret;
3149     BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
3150     CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
3151     DWORD size = sizeof(buf);
3152
3153     blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
3154     ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, buf,
3155      &size, pcbDecoded);
3156     if (ret)
3157     {
3158         if (!pvStructInfo)
3159             *pcbStructInfo = sizeof(int);
3160         else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
3161         {
3162             int val, i;
3163
3164             if (blob->pbData[blob->cbData - 1] & 0x80)
3165             {
3166                 /* initialize to a negative value to sign-extend */
3167                 val = -1;
3168             }
3169             else
3170                 val = 0;
3171             for (i = 0; i < blob->cbData; i++)
3172             {
3173                 val <<= 8;
3174                 val |= blob->pbData[blob->cbData - i - 1];
3175             }
3176             memcpy(pvStructInfo, &val, sizeof(int));
3177         }
3178     }
3179     else if (GetLastError() == ERROR_MORE_DATA)
3180         SetLastError(CRYPT_E_ASN1_LARGE);
3181     return ret;
3182 }
3183
3184 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
3185  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3186  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3187 {
3188     BOOL ret;
3189
3190     __TRY
3191     {
3192         DWORD bytesNeeded;
3193
3194         if (!cbEncoded)
3195         {
3196             SetLastError(CRYPT_E_ASN1_CORRUPT);
3197             ret = FALSE;
3198         }
3199         else if (pbEncoded[0] != ASN_INTEGER)
3200         {
3201             SetLastError(CRYPT_E_ASN1_BADTAG);
3202             ret = FALSE;
3203         }
3204         else
3205             ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3206              dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3207         if (ret)
3208         {
3209             if (!pvStructInfo)
3210                 *pcbStructInfo = bytesNeeded;
3211             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3212              pvStructInfo, pcbStructInfo, bytesNeeded)))
3213             {
3214                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3215                     pvStructInfo = *(BYTE **)pvStructInfo;
3216                 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3217                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3218                  &bytesNeeded, NULL);
3219             }
3220         }
3221     }
3222     __EXCEPT_PAGE_FAULT
3223     {
3224         SetLastError(STATUS_ACCESS_VIOLATION);
3225         ret = FALSE;
3226     }
3227     __ENDTRY
3228     return ret;
3229 }
3230
3231 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
3232  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3233  DWORD *pcbDecoded)
3234 {
3235     BOOL ret;
3236     DWORD bytesNeeded, dataLen;
3237
3238     if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3239     {
3240         BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3241
3242         bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3243         if (pcbDecoded)
3244             *pcbDecoded = 1 + lenBytes + dataLen;
3245         if (!pvStructInfo)
3246             *pcbStructInfo = bytesNeeded;
3247         else if (*pcbStructInfo < bytesNeeded)
3248         {
3249             *pcbStructInfo = bytesNeeded;
3250             SetLastError(ERROR_MORE_DATA);
3251             ret = FALSE;
3252         }
3253         else
3254         {
3255             CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3256
3257             *pcbStructInfo = bytesNeeded;
3258             blob->cbData = dataLen;
3259             assert(blob->pbData);
3260             if (blob->cbData)
3261             {
3262                 DWORD i;
3263
3264                 for (i = 0; i < blob->cbData; i++)
3265                 {
3266                     blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3267                      dataLen - i - 1);
3268                 }
3269             }
3270         }
3271     }
3272     return ret;
3273 }
3274
3275 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
3276  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3277  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3278 {
3279     BOOL ret;
3280
3281     __TRY
3282     {
3283         DWORD bytesNeeded;
3284
3285         if (pbEncoded[0] != ASN_INTEGER)
3286         {
3287             SetLastError(CRYPT_E_ASN1_BADTAG);
3288             ret = FALSE;
3289         }
3290         else
3291             ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3292              dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3293         if (ret)
3294         {
3295             if (!pvStructInfo)
3296                 *pcbStructInfo = bytesNeeded;
3297             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3298              pvStructInfo, pcbStructInfo, bytesNeeded)))
3299             {
3300                 CRYPT_INTEGER_BLOB *blob;
3301
3302                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3303                     pvStructInfo = *(BYTE **)pvStructInfo;
3304                 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3305                 blob->pbData = (BYTE *)pvStructInfo +
3306                  sizeof(CRYPT_INTEGER_BLOB);
3307                 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3308                  dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
3309                  &bytesNeeded, NULL);
3310             }
3311         }
3312     }
3313     __EXCEPT_PAGE_FAULT
3314     {
3315         SetLastError(STATUS_ACCESS_VIOLATION);
3316         ret = FALSE;
3317     }
3318     __ENDTRY
3319     return ret;
3320 }
3321
3322 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
3323  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3324  DWORD *pcbDecoded)
3325 {
3326     BOOL ret;
3327
3328     if (pbEncoded[0] == ASN_INTEGER)
3329     {
3330         DWORD bytesNeeded, dataLen;
3331
3332         if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3333         {
3334             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3335
3336             if (pcbDecoded)
3337                 *pcbDecoded = 1 + lenBytes + dataLen;
3338             bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3339             if (!pvStructInfo)
3340                 *pcbStructInfo = bytesNeeded;
3341             else if (*pcbStructInfo < bytesNeeded)
3342             {
3343                 *pcbStructInfo = bytesNeeded;
3344                 SetLastError(ERROR_MORE_DATA);
3345                 ret = FALSE;
3346             }
3347             else
3348             {
3349                 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3350
3351                 *pcbStructInfo = bytesNeeded;
3352                 blob->cbData = dataLen;
3353                 assert(blob->pbData);
3354                 /* remove leading zero byte if it exists */
3355                 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
3356                 {
3357                     blob->cbData--;
3358                     blob->pbData++;
3359                 }
3360                 if (blob->cbData)
3361                 {
3362                     DWORD i;
3363
3364                     for (i = 0; i < blob->cbData; i++)
3365                     {
3366                         blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3367                          dataLen - i - 1);
3368                     }
3369                 }
3370             }
3371         }
3372     }
3373     else
3374     {
3375         SetLastError(CRYPT_E_ASN1_BADTAG);
3376         ret = FALSE;
3377     }
3378     return ret;
3379 }
3380
3381 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
3382  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3383  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3384 {
3385     BOOL ret;
3386
3387     __TRY
3388     {
3389         DWORD bytesNeeded;
3390
3391         if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
3392          dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3393         {
3394             if (!pvStructInfo)
3395                 *pcbStructInfo = bytesNeeded;
3396             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3397              pvStructInfo, pcbStructInfo, bytesNeeded)))
3398             {
3399                 CRYPT_INTEGER_BLOB *blob;
3400
3401                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3402                     pvStructInfo = *(BYTE **)pvStructInfo;
3403                 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3404                 blob->pbData = (BYTE *)pvStructInfo +
3405                  sizeof(CRYPT_INTEGER_BLOB);
3406                 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
3407                  cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
3408                  &bytesNeeded, NULL);
3409             }
3410         }
3411     }
3412     __EXCEPT_PAGE_FAULT
3413     {
3414         SetLastError(STATUS_ACCESS_VIOLATION);
3415         ret = FALSE;
3416     }
3417     __ENDTRY
3418     return ret;
3419 }
3420
3421 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
3422  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3423  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3424 {
3425     BOOL ret;
3426
3427     if (!pvStructInfo)
3428     {
3429         *pcbStructInfo = sizeof(int);
3430         return TRUE;
3431     }
3432     __TRY
3433     {
3434         if (pbEncoded[0] == ASN_ENUMERATED)
3435         {
3436             unsigned int val = 0, i;
3437
3438             if (cbEncoded <= 1)
3439             {
3440                 SetLastError(CRYPT_E_ASN1_EOD);
3441                 ret = FALSE;
3442             }
3443             else if (pbEncoded[1] == 0)
3444             {
3445                 SetLastError(CRYPT_E_ASN1_CORRUPT);
3446                 ret = FALSE;
3447             }
3448             else
3449             {
3450                 /* A little strange looking, but we have to accept a sign byte:
3451                  * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff.  Also,
3452                  * assuming a small length is okay here, it has to be in short
3453                  * form.
3454                  */
3455                 if (pbEncoded[1] > sizeof(unsigned int) + 1)
3456                 {
3457                     SetLastError(CRYPT_E_ASN1_LARGE);
3458                     return FALSE;
3459                 }
3460                 for (i = 0; i < pbEncoded[1]; i++)
3461                 {
3462                     val <<= 8;
3463                     val |= pbEncoded[2 + i];
3464                 }
3465                 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3466                  pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
3467                 {
3468                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3469                         pvStructInfo = *(BYTE **)pvStructInfo;
3470                     memcpy(pvStructInfo, &val, sizeof(unsigned int));
3471                 }
3472             }
3473         }
3474         else
3475         {
3476             SetLastError(CRYPT_E_ASN1_BADTAG);
3477             ret = FALSE;
3478         }
3479     }
3480     __EXCEPT_PAGE_FAULT
3481     {
3482         SetLastError(STATUS_ACCESS_VIOLATION);
3483         ret = FALSE;
3484     }
3485     __ENDTRY
3486     return ret;
3487 }
3488
3489 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3490  * if it fails.
3491  */
3492 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3493  do { \
3494     BYTE i; \
3495  \
3496     (word) = 0; \
3497     for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3498     { \
3499         if (!isdigit(*(pbEncoded))) \
3500         { \
3501             SetLastError(CRYPT_E_ASN1_CORRUPT); \
3502             ret = FALSE; \
3503         } \
3504         else \
3505         { \
3506             (word) *= 10; \
3507             (word) += *(pbEncoded)++ - '0'; \
3508         } \
3509     } \
3510  } while (0)
3511
3512 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
3513  SYSTEMTIME *sysTime)
3514 {
3515     BOOL ret = TRUE;
3516
3517     if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
3518     {
3519         WORD hours, minutes = 0;
3520         BYTE sign = *pbEncoded++;
3521
3522         len--;
3523         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
3524         if (ret && hours >= 24)
3525         {
3526             SetLastError(CRYPT_E_ASN1_CORRUPT);
3527             ret = FALSE;
3528         }
3529         else if (len >= 2)
3530         {
3531             CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
3532             if (ret && minutes >= 60)
3533             {
3534                 SetLastError(CRYPT_E_ASN1_CORRUPT);
3535                 ret = FALSE;
3536             }
3537         }
3538         if (ret)
3539         {
3540             if (sign == '+')
3541             {
3542                 sysTime->wHour += hours;
3543                 sysTime->wMinute += minutes;
3544             }
3545             else
3546             {
3547                 if (hours > sysTime->wHour)
3548                 {
3549                     sysTime->wDay--;
3550                     sysTime->wHour = 24 - (hours - sysTime->wHour);
3551                 }
3552                 else
3553                     sysTime->wHour -= hours;
3554                 if (minutes > sysTime->wMinute)
3555                 {
3556                     sysTime->wHour--;
3557                     sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
3558                 }
3559                 else
3560                     sysTime->wMinute -= minutes;
3561             }
3562         }
3563     }
3564     return ret;
3565 }
3566
3567 #define MIN_ENCODED_TIME_LENGTH 10
3568
3569 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
3570  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3571  DWORD *pcbDecoded)
3572 {
3573     BOOL ret = FALSE;
3574
3575     if (pbEncoded[0] == ASN_UTCTIME)
3576     {
3577         if (cbEncoded <= 1)
3578             SetLastError(CRYPT_E_ASN1_EOD);
3579         else if (pbEncoded[1] > 0x7f)
3580         {
3581             /* long-form date strings really can't be valid */
3582             SetLastError(CRYPT_E_ASN1_CORRUPT);
3583         }
3584         else
3585         {
3586             SYSTEMTIME sysTime = { 0 };
3587             BYTE len = pbEncoded[1];
3588
3589             if (len < MIN_ENCODED_TIME_LENGTH)
3590                 SetLastError(CRYPT_E_ASN1_CORRUPT);
3591             else
3592             {
3593                 ret = TRUE;
3594                 if (pcbDecoded)
3595                     *pcbDecoded = 2 + len;
3596                 pbEncoded += 2;
3597                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
3598                 if (sysTime.wYear >= 50)
3599                     sysTime.wYear += 1900;
3600                 else
3601                     sysTime.wYear += 2000;
3602                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
3603                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
3604                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
3605                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
3606                 if (ret && len > 0)
3607                 {
3608                     if (len >= 2 && isdigit(*pbEncoded) &&
3609                      isdigit(*(pbEncoded + 1)))
3610                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3611                          sysTime.wSecond);
3612                     else if (isdigit(*pbEncoded))
3613                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
3614                          sysTime.wSecond);
3615                     if (ret)
3616                         ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
3617                          &sysTime);
3618                 }
3619                 if (ret)
3620                 {
3621                     if (!pvStructInfo)
3622                         *pcbStructInfo = sizeof(FILETIME);
3623                     else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
3624                      sizeof(FILETIME))))
3625                         ret = SystemTimeToFileTime(&sysTime,
3626                          (FILETIME *)pvStructInfo);
3627                 }
3628             }
3629         }
3630     }
3631     else
3632         SetLastError(CRYPT_E_ASN1_BADTAG);
3633     return ret;
3634 }
3635
3636 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
3637  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3638  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3639 {
3640     BOOL ret = FALSE;
3641
3642     __TRY
3643     {
3644         DWORD bytesNeeded;
3645
3646         ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
3647          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3648         if (ret)
3649         {
3650             if (!pvStructInfo)
3651                 *pcbStructInfo = bytesNeeded;
3652             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
3653              pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
3654             {
3655                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3656                     pvStructInfo = *(BYTE **)pvStructInfo;
3657                 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
3658                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3659                  &bytesNeeded, NULL);
3660             }
3661         }
3662     }
3663     __EXCEPT_PAGE_FAULT
3664     {
3665         SetLastError(STATUS_ACCESS_VIOLATION);
3666     }
3667     __ENDTRY
3668     return ret;
3669 }
3670
3671 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
3672  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3673  DWORD *pcbDecoded)
3674 {
3675     BOOL ret = FALSE;
3676
3677     if (pbEncoded[0] == ASN_GENERALTIME)
3678     {
3679         if (cbEncoded <= 1)
3680             SetLastError(CRYPT_E_ASN1_EOD);
3681         else if (pbEncoded[1] > 0x7f)
3682         {
3683             /* long-form date strings really can't be valid */
3684             SetLastError(CRYPT_E_ASN1_CORRUPT);
3685         }
3686         else
3687         {
3688             BYTE len = pbEncoded[1];
3689
3690             if (len < MIN_ENCODED_TIME_LENGTH)
3691                 SetLastError(CRYPT_E_ASN1_CORRUPT);
3692             else
3693             {
3694                 SYSTEMTIME sysTime = { 0 };
3695
3696                 ret = TRUE;
3697                 if (pcbDecoded)
3698                     *pcbDecoded = 2 + len;
3699                 pbEncoded += 2;
3700                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
3701                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
3702                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
3703                 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
3704                 if (ret && len > 0)
3705                 {
3706                     CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3707                      sysTime.wMinute);
3708                     if (ret && len > 0)
3709                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3710                          sysTime.wSecond);
3711                     if (ret && len > 0 && (*pbEncoded == '.' ||
3712                      *pbEncoded == ','))
3713                     {
3714                         BYTE digits;
3715
3716                         pbEncoded++;
3717                         len--;
3718                         /* workaround macro weirdness */
3719                         digits = min(len, 3);
3720                         CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
3721                          sysTime.wMilliseconds);
3722                     }
3723                     if (ret)
3724                         ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
3725                          &sysTime);
3726                 }
3727                 if (ret)
3728                 {
3729                     if (!pvStructInfo)
3730                         *pcbStructInfo = sizeof(FILETIME);
3731                     else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
3732                      sizeof(FILETIME))))
3733                         ret = SystemTimeToFileTime(&sysTime,
3734                          (FILETIME *)pvStructInfo);
3735                 }
3736             }
3737         }
3738     }
3739     else
3740         SetLastError(CRYPT_E_ASN1_BADTAG);
3741     return ret;
3742 }
3743
3744 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
3745  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3746  DWORD *pcbDecoded)
3747 {
3748     BOOL ret;
3749     InternalDecodeFunc decode = NULL;
3750
3751     if (pbEncoded[0] == ASN_UTCTIME)
3752         decode = CRYPT_AsnDecodeUtcTimeInternal;
3753     else if (pbEncoded[0] == ASN_GENERALTIME)
3754         decode = CRYPT_AsnDecodeGeneralizedTime;
3755     if (decode)
3756         ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
3757          pcbStructInfo, pcbDecoded);
3758     else
3759     {
3760         SetLastError(CRYPT_E_ASN1_BADTAG);
3761         ret = FALSE;
3762     }
3763     return ret;
3764 }
3765
3766 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
3767  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3768  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3769 {
3770     BOOL ret;
3771
3772     __TRY
3773     {
3774         DWORD bytesNeeded;
3775
3776         ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
3777          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3778         if (ret)
3779         {
3780             if (!pvStructInfo)
3781                 *pcbStructInfo = bytesNeeded;
3782             else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3783              pvStructInfo, pcbStructInfo, bytesNeeded)))
3784             {
3785                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3786                     pvStructInfo = *(BYTE **)pvStructInfo;
3787                 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
3788                  dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3789                  &bytesNeeded, NULL);
3790             }
3791         }
3792     }
3793     __EXCEPT_PAGE_FAULT
3794     {
3795         SetLastError(STATUS_ACCESS_VIOLATION);
3796         ret = FALSE;
3797     }
3798     __ENDTRY
3799     return ret;
3800 }
3801
3802 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
3803  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3804  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3805 {
3806     BOOL ret = TRUE;
3807
3808     __TRY
3809     {
3810         if (pbEncoded[0] == ASN_SEQUENCEOF)
3811         {
3812             DWORD bytesNeeded, dataLen, remainingLen, cValue;
3813
3814             if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3815             {
3816                 BYTE lenBytes;
3817                 const BYTE *ptr;
3818
3819                 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3820                 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
3821                 cValue = 0;
3822                 ptr = pbEncoded + 1 + lenBytes;
3823                 remainingLen = dataLen;
3824                 while (ret && remainingLen)
3825                 {
3826                     DWORD nextLen;
3827
3828                     ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
3829                     if (ret)
3830                     {
3831                         DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
3832
3833                         remainingLen -= 1 + nextLenBytes + nextLen;
3834                         ptr += 1 + nextLenBytes + nextLen;
3835                         bytesNeeded += sizeof(CRYPT_DER_BLOB);
3836                         if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
3837                             bytesNeeded += 1 + nextLenBytes + nextLen;
3838                         cValue++;
3839                     }
3840                 }
3841                 if (ret)
3842                 {
3843                     CRYPT_SEQUENCE_OF_ANY *seq;
3844                     BYTE *nextPtr;
3845                     DWORD i;
3846
3847                     if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3848                      pvStructInfo, pcbStructInfo, bytesNeeded)))
3849                     {
3850                         if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3851                             pvStructInfo = *(BYTE **)pvStructInfo;
3852                         seq = (CRYPT_SEQUENCE_OF_ANY *)pvStructInfo;
3853                         seq->cValue = cValue;
3854                         seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
3855                          sizeof(*seq));
3856                         nextPtr = (BYTE *)seq->rgValue +
3857                          cValue * sizeof(CRYPT_DER_BLOB);
3858                         ptr = pbEncoded + 1 + lenBytes;
3859                         remainingLen = dataLen;
3860                         i = 0;
3861                         while (ret && remainingLen)
3862                         {
3863                             DWORD nextLen;
3864
3865                             ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
3866                             if (ret)
3867                             {
3868                                 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
3869
3870                                 seq->rgValue[i].cbData = 1 + nextLenBytes +
3871                                  nextLen;
3872                                 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3873                                     seq->rgValue[i].pbData = (BYTE *)ptr;
3874                                 else
3875                                 {
3876                                     seq->rgValue[i].pbData = nextPtr;
3877                                     memcpy(nextPtr, ptr, 1 + nextLenBytes +
3878                                      nextLen);
3879                                     nextPtr += 1 + nextLenBytes + nextLen;
3880                                 }
3881                                 remainingLen -= 1 + nextLenBytes + nextLen;
3882                                 ptr += 1 + nextLenBytes + nextLen;
3883                                 i++;
3884                             }
3885                         }
3886                     }
3887                 }
3888             }
3889         }
3890         else
3891         {
3892             SetLastError(CRYPT_E_ASN1_BADTAG);
3893             ret = FALSE;
3894         }
3895     }
3896     __EXCEPT_PAGE_FAULT
3897     {
3898         SetLastError(STATUS_ACCESS_VIOLATION);
3899         ret = FALSE;
3900     }
3901     __ENDTRY
3902     return ret;
3903 }
3904
3905 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
3906  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3907  DWORD *pcbDecoded)
3908 {
3909     BOOL ret;
3910
3911     if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
3912     {
3913         DWORD bytesNeeded, dataLen;
3914
3915         if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3916         {
3917             struct AsnArrayDescriptor arrayDesc = {
3918              ASN_CONTEXT | ASN_CONSTRUCTOR | 0, CRYPT_AsnDecodeAltNameEntry,
3919              sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3920              offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3921             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3922             DWORD nameLen;
3923
3924             if (dataLen)
3925             {
3926                 ret = CRYPT_AsnDecodeArray(&arrayDesc,
3927                  pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
3928                  0, NULL, NULL, &nameLen, NULL, NULL);
3929                 /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
3930                  * as the sizeof(struct GenericArray), so don't include it in the
3931                  * total bytes needed.
3932                  */
3933                 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
3934                  sizeof(CERT_ALT_NAME_INFO);
3935             }
3936             else
3937                 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
3938             if (pcbDecoded)
3939                 *pcbDecoded = 1 + lenBytes + dataLen;
3940             if (!pvStructInfo)
3941                 *pcbStructInfo = bytesNeeded;
3942             else if (*pcbStructInfo < bytesNeeded)
3943             {
3944                 *pcbStructInfo = bytesNeeded;
3945                 SetLastError(ERROR_MORE_DATA);
3946                 ret = FALSE;
3947             }
3948             else
3949             {
3950                 CRL_DIST_POINT_NAME *name = (CRL_DIST_POINT_NAME *)pvStructInfo;
3951
3952                 *pcbStructInfo = bytesNeeded;
3953                 if (dataLen)
3954                 {
3955                     name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3956                     ret = CRYPT_AsnDecodeArray(&arrayDesc,
3957                      pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
3958                      0, NULL, &name->u.FullName, &nameLen, NULL,
3959                      name->u.FullName.rgAltEntry);
3960                 }
3961                 else
3962                     name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3963             }
3964         }
3965     }
3966     else
3967     {
3968         SetLastError(CRYPT_E_ASN1_BADTAG);
3969         ret = FALSE;
3970     }
3971     return ret;
3972 }
3973
3974 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
3975  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3976 {
3977     struct AsnDecodeSequenceItem items[] = {
3978      { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
3979        DistPointName), CRYPT_AsnDecodeDistPointName,
3980        sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
3981        DistPointName.u.FullName.rgAltEntry), 0 },
3982      { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
3983        CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
3984        offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
3985      { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
3986        CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
3987        offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
3988     };
3989     BOOL ret;
3990
3991     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3992      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3993      pcbDecoded, NULL);
3994     return ret;
3995 }
3996
3997 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
3998  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3999  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4000 {
4001     BOOL ret;
4002
4003     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4004      pDecodePara, pvStructInfo, *pcbStructInfo);
4005
4006     __TRY
4007     {
4008         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4009          CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
4010          offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
4011
4012         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4013          pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4014     }
4015     __EXCEPT_PAGE_FAULT
4016     {
4017         SetLastError(STATUS_ACCESS_VIOLATION);
4018         ret = FALSE;
4019     }
4020     __ENDTRY
4021     return ret;
4022 }
4023
4024 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
4025  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4026  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4027 {
4028     BOOL ret;
4029
4030     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4031      pDecodePara, pvStructInfo, *pcbStructInfo);
4032
4033     __TRY
4034     {
4035         struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4036          CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
4037
4038         ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4039          pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4040     }
4041     __EXCEPT_PAGE_FAULT
4042     {
4043         SetLastError(STATUS_ACCESS_VIOLATION);
4044         ret = FALSE;
4045     }
4046     __ENDTRY
4047     return ret;
4048 }
4049
4050 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
4051  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4052  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4053 {
4054     BOOL ret;
4055
4056     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4057      pDecodePara, pvStructInfo, *pcbStructInfo);
4058
4059     __TRY
4060     {
4061         struct AsnDecodeSequenceItem items[] = {
4062          { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
4063            DistPointName), CRYPT_AsnDecodeDistPointName,
4064            sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
4065            offsetof(CRL_ISSUING_DIST_POINT,
4066            DistPointName.u.FullName.rgAltEntry), 0 },
4067          { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
4068            fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4069            FALSE, 0 },
4070          { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
4071            fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4072            FALSE, 0 },
4073          { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
4074            OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
4075            sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
4076            OnlySomeReasonFlags.pbData), 0 },
4077          { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
4078            fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
4079         };
4080
4081         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4082          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4083          pcbStructInfo, NULL, NULL);
4084     }
4085     __EXCEPT_PAGE_FAULT
4086     {
4087         SetLastError(STATUS_ACCESS_VIOLATION);
4088         ret = FALSE;
4089     }
4090     __ENDTRY
4091     return ret;
4092 }
4093
4094 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
4095  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4096  DWORD *pcbDecoded)
4097 {
4098     BOOL ret = FALSE;
4099
4100     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4101      pvStructInfo, *pcbStructInfo, pcbDecoded);
4102
4103     if (!cbEncoded)
4104     {
4105         SetLastError(CRYPT_E_ASN1_EOD);
4106         return FALSE;
4107     }
4108     if (pbEncoded[0] != (ASN_CONTEXT | 1))
4109     {
4110         SetLastError(CRYPT_E_ASN1_BADTAG);
4111         return FALSE;
4112     }
4113     /* The BOOL is implicit:  if the integer is present, then it's TRUE */
4114     ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
4115      pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
4116      pcbDecoded);
4117     if (ret && pvStructInfo)
4118         *(BOOL *)pvStructInfo = TRUE;
4119     TRACE("returning %d\n", ret);
4120     return ret;
4121 }
4122
4123 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
4124  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4125  DWORD *pcbDecoded)
4126 {
4127     BOOL ret;
4128     struct AsnDecodeSequenceItem items[] = {
4129      { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
4130        CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
4131        offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
4132      { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
4133        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
4134      { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
4135        CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
4136        0 },
4137     };
4138     CERT_GENERAL_SUBTREE *subtree = (CERT_GENERAL_SUBTREE *)pvStructInfo;
4139
4140     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4141      pvStructInfo, *pcbStructInfo, pcbDecoded);
4142
4143     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4144      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4145      pcbDecoded, subtree ? (BYTE *)subtree->Base.u.pwszURL : NULL);
4146     if (pcbDecoded)
4147     {
4148         TRACE("%d\n", *pcbDecoded);
4149         if (*pcbDecoded < cbEncoded)
4150             TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
4151              *(pbEncoded + *pcbDecoded + 1));
4152     }
4153     TRACE("returning %d\n", ret);
4154     return ret;
4155 }
4156
4157 static BOOL CRYPT_AsnDecodeSubtreeArray(const BYTE *pbEncoded,
4158  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4159  DWORD *pcbDecoded)
4160 {
4161     BOOL ret = TRUE;
4162     struct AsnArrayDescriptor arrayDesc = { 0,
4163      CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
4164      offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
4165     struct GenericArray *array = (struct GenericArray *)pvStructInfo;
4166
4167     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4168      pvStructInfo, *pcbStructInfo, pcbDecoded);
4169
4170     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4171      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4172      array ? array->rgItems : NULL);
4173     return ret;
4174 }
4175
4176
4177 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
4178  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4179  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4180 {
4181     BOOL ret = FALSE;
4182
4183     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4184      pDecodePara, pvStructInfo, *pcbStructInfo);
4185
4186     __TRY
4187     {
4188         struct AsnDecodeSequenceItem items[] = {
4189          { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4190            offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
4191            CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4192            offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
4193          { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
4194            offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4195            CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4196            offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
4197         };
4198
4199         ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4200          pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4201          pcbStructInfo, NULL, NULL);
4202     }
4203     __EXCEPT_PAGE_FAULT
4204     {
4205         SetLastError(STATUS_ACCESS_VIOLATION);
4206     }
4207     __ENDTRY
4208     return ret;
4209 }
4210
4211 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
4212  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4213  DWORD *pcbDecoded)
4214 {
4215     BOOL ret;
4216     struct AsnDecodeSequenceItem items[] = {
4217      { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
4218        sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
4219        Issuer.pbData) },
4220      { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
4221        CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
4222        TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
4223     };
4224     CERT_ISSUER_SERIAL_NUMBER *issuerSerial =
4225      (CERT_ISSUER_SERIAL_NUMBER *)pvStructInfo;
4226
4227     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4228      pvStructInfo, *pcbStructInfo, pcbDecoded);
4229
4230     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4231      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4232      pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
4233     if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
4234     {
4235         SetLastError(CRYPT_E_ASN1_CORRUPT);
4236         ret = FALSE;
4237     }
4238     TRACE("returning %d\n", ret);
4239     return ret;
4240 }
4241
4242 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
4243  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4244  DWORD *pcbDecoded)
4245 {
4246     CMSG_SIGNER_INFO *info = (CMSG_SIGNER_INFO *)pvStructInfo;
4247     struct AsnDecodeSequenceItem items[] = {
4248      { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
4249        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4250      { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
4251        CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
4252        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
4253      { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
4254        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4255        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
4256      { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4257        offsetof(CMSG_SIGNER_INFO, AuthAttrs),
4258        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4259        TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
4260      { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
4261        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4262        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
4263        HashEncryptionAlgorithm.pszObjId), 0 },
4264      { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
4265        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
4266        FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
4267      { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4268        offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
4269        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4270        TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
4271     };
4272     BOOL ret;
4273
4274     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4275      pvStructInfo, *pcbStructInfo);
4276
4277     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4278      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4279      pcbDecoded, info ? info->Issuer.pbData : NULL);
4280     return ret;
4281 }
4282
4283 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
4284  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4285  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4286 {
4287     BOOL ret = FALSE;
4288
4289     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4290      pDecodePara, pvStructInfo, *pcbStructInfo);
4291
4292     __TRY
4293     {
4294         ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
4295          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
4296         if (ret && pvStructInfo)
4297         {
4298             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
4299              pcbStructInfo, *pcbStructInfo);
4300             if (ret)
4301             {
4302                 CMSG_SIGNER_INFO *info;
4303
4304                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4305                     pvStructInfo = *(BYTE **)pvStructInfo;
4306                 info = (CMSG_SIGNER_INFO *)pvStructInfo;
4307                 info->Issuer.pbData = ((BYTE *)info +
4308                  sizeof(CMSG_SIGNER_INFO));
4309                 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
4310                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4311                  pcbStructInfo, NULL);
4312             }
4313         }
4314     }
4315     __EXCEPT_PAGE_FAULT
4316     {
4317         SetLastError(STATUS_ACCESS_VIOLATION);
4318     }
4319     __ENDTRY
4320     TRACE("returning %d\n", ret);
4321     return ret;
4322 }
4323
4324 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
4325  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4326  DWORD *pcbDecoded)
4327 {
4328     CERT_ID *id = (CERT_ID *)pvStructInfo;
4329     BOOL ret = FALSE;
4330
4331     if (*pbEncoded == ASN_SEQUENCEOF)
4332     {
4333         ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
4334          id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
4335         if (ret)
4336         {
4337             if (id)
4338                 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
4339             if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
4340                 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
4341                  sizeof(CERT_ISSUER_SERIAL_NUMBER);
4342             else
4343                 *pcbStructInfo = sizeof(CERT_ID);
4344         }
4345     }
4346     else if (*pbEncoded == (ASN_CONTEXT | 0))
4347     {
4348         ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
4349          id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
4350         if (ret)
4351         {
4352             if (id)
4353                 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
4354             if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
4355                 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
4356                  sizeof(CRYPT_DATA_BLOB);
4357             else
4358                 *pcbStructInfo = sizeof(CERT_ID);
4359         }
4360     }
4361     else
4362         SetLastError(CRYPT_E_ASN1_BADTAG);
4363     return ret;
4364 }
4365
4366 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
4367  DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4368  DWORD *pcbDecoded)
4369 {
4370     CMSG_CMS_SIGNER_INFO *info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
4371     struct AsnDecodeSequenceItem items[] = {
4372      { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
4373        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4374      { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
4375        CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
4376        offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
4377      { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
4378        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4379        FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
4380      { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4381        offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
4382        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4383        TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
4384      { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
4385        CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4386        FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
4387        HashEncryptionAlgorithm.pszObjId), 0 },
4388      { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
4389        CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
4390        FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
4391      { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4392        offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
4393        CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4394        TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
4395     };
4396     BOOL ret;
4397
4398     TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4399      pvStructInfo, *pcbStructInfo);
4400
4401     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4402      pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4403      pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
4404     return ret;
4405 }
4406
4407 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
4408  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4409  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4410 {
4411     BOOL ret = FALSE;
4412
4413     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4414      pDecodePara, pvStructInfo, *pcbStructInfo);
4415
4416     __TRY
4417     {
4418         ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
4419          dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
4420         if (ret && pvStructInfo)
4421         {
4422             ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
4423              pcbStructInfo, *pcbStructInfo);
4424             if (ret)
4425             {
4426                 CMSG_CMS_SIGNER_INFO *info;
4427
4428                 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4429                     pvStructInfo = *(BYTE **)pvStructInfo;
4430                 info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
4431                 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
4432                  sizeof(CMSG_CMS_SIGNER_INFO));
4433                 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
4434                  cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4435                  pcbStructInfo, NULL);
4436             }
4437         }
4438     }
4439     __EXCEPT_PAGE_FAULT
4440     {
4441         SetLastError(STATUS_ACCESS_VIOLATION);
4442     }
4443     __ENDTRY
4444     TRACE("returning %d\n", ret);
4445     return ret;
4446 }
4447
4448 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
4449  DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4450 {
4451     BOOL ret;
4452     struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
4453      CRYPT_AsnDecodePKCSSignerInfoInternal, sizeof(CMSG_SIGNER_INFO), TRUE,
4454      offsetof(CMSG_SIGNER_INFO, Issuer.pbData) };
4455     struct GenericArray *array = (struct GenericArray *)pvStructInfo;
4456
4457     TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4458      pvStructInfo, *pcbStructInfo, pcbDecoded);
4459
4460     ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4461      NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4462      array ? array->rgItems : NULL);
4463     return ret;
4464 }
4465
4466 BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
4467  DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
4468  CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
4469 {
4470     BOOL ret = FALSE;
4471     struct AsnDecodeSequenceItem items[] = {
4472      { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
4473        CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4474      /* Placeholder for the hash algorithms - redundant with those in the
4475       * signers, so just ignore them.
4476       */
4477      { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
4478      { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
4479        CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
4480        FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
4481      { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4482        offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
4483        CRYPT_DecodeDERArray, sizeof(struct GenericArray), TRUE, TRUE,
4484        offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
4485      { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4486        offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_DecodeDERArray,
4487        sizeof(struct GenericArray), TRUE, TRUE,
4488        offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
4489      { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
4490        CRYPT_DecodeSignerArray, sizeof(struct GenericArray), TRUE, TRUE,
4491        offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
4492     };
4493
4494     TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4495      pDecodePara, signedInfo, *pcbSignedInfo);
4496
4497     ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4498      pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
4499      NULL, NULL);
4500     TRACE("returning %d\n", ret);
4501     return ret;
4502 }
4503
4504 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
4505  LPCSTR lpszStructType)
4506 {
4507     CryptDecodeObjectExFunc decodeFunc = NULL;
4508
4509     if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
4510      && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
4511     {
4512         SetLastError(ERROR_FILE_NOT_FOUND);
4513         return NULL;
4514     }
4515     if (!HIWORD(lpszStructType))
4516     {
4517         switch (LOWORD(lpszStructType))
4518         {
4519         case LOWORD(X509_CERT):
4520             decodeFunc = CRYPT_AsnDecodeCertSignedContent;
4521             break;
4522         case LOWORD(X509_CERT_TO_BE_SIGNED):
4523             decodeFunc = CRYPT_AsnDecodeCert;
4524             break;
4525         case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
4526             decodeFunc = CRYPT_AsnDecodeCRL;
4527             break;
4528         case LOWORD(X509_EXTENSIONS):
4529             decodeFunc = CRYPT_AsnDecodeExtensions;
4530             break;
4531         case LOWORD(X509_NAME_VALUE):
4532             decodeFunc = CRYPT_AsnDecodeNameValue;
4533             break;
4534         case LOWORD(X509_NAME):
4535             decodeFunc = CRYPT_AsnDecodeName;
4536             break;
4537         case LOWORD(X509_PUBLIC_KEY_INFO):
4538             decodeFunc = CRYPT_AsnDecodePubKeyInfo;
4539             break;
4540         case LOWORD(X509_AUTHORITY_KEY_ID):
4541             decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
4542             break;
4543         case LOWORD(X509_ALTERNATE_NAME):
4544             decodeFunc = CRYPT_AsnDecodeAltName;
4545             break;
4546         case LOWORD(X509_BASIC_CONSTRAINTS):
4547             decodeFunc = CRYPT_AsnDecodeBasicConstraints;
4548             break;
4549         case LOWORD(X509_BASIC_CONSTRAINTS2):
4550             decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
4551             break;
4552         case LOWORD(RSA_CSP_PUBLICKEYBLOB):
4553             decodeFunc = CRYPT_AsnDecodeRsaPubKey;
4554             break;
4555         case LOWORD(X509_UNICODE_NAME):
4556             decodeFunc = CRYPT_AsnDecodeUnicodeName;
4557             break;
4558         case LOWORD(PKCS_ATTRIBUTE):
4559             decodeFunc = CRYPT_AsnDecodePKCSAttribute;
4560             break;
4561         case LOWORD(X509_UNICODE_NAME_VALUE):
4562             decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
4563             break;
4564         case LOWORD(X509_OCTET_STRING):
4565             decodeFunc = CRYPT_AsnDecodeOctets;
4566             break;
4567         case LOWORD(X509_BITS):
4568         case LOWORD(X509_KEY_USAGE):
4569             decodeFunc = CRYPT_AsnDecodeBits;
4570             break;
4571         case LOWORD(X509_INTEGER):
4572             decodeFunc = CRYPT_AsnDecodeInt;
4573             break;
4574         case LOWORD(X509_MULTI_BYTE_INTEGER):
4575             decodeFunc = CRYPT_AsnDecodeInteger;
4576             break;
4577         case LOWORD(X509_MULTI_BYTE_UINT):
4578             decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
4579             break;
4580         case LOWORD(X509_ENUMERATED):
4581             decodeFunc = CRYPT_AsnDecodeEnumerated;
4582             break;
4583         case LOWORD(X509_CHOICE_OF_TIME):
4584             decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
4585             break;
4586         case LOWORD(X509_AUTHORITY_KEY_ID2):
4587             decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
4588             break;
4589         case LOWORD(PKCS_CONTENT_INFO):
4590             decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
4591             break;
4592         case LOWORD(X509_SEQUENCE_OF_ANY):
4593             decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
4594             break;
4595         case LOWORD(PKCS_UTC_TIME):
4596             decodeFunc = CRYPT_AsnDecodeUtcTime;
4597             break;
4598         case LOWORD(X509_CRL_DIST_POINTS):
4599             decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
4600             break;
4601         case LOWORD(X509_ENHANCED_KEY_USAGE):
4602             decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
4603             break;
4604         case LOWORD(PKCS_ATTRIBUTES):
4605             decodeFunc = CRYPT_AsnDecodePKCSAttributes;
4606             break;
4607         case LOWORD(X509_ISSUING_DIST_POINT):
4608             decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
4609             break;
4610         case LOWORD(X509_NAME_CONSTRAINTS):
4611             decodeFunc = CRYPT_AsnDecodeNameConstraints;
4612             break;
4613         case LOWORD(PKCS7_SIGNER_INFO):
4614             decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
4615             break;
4616         case LOWORD(CMS_SIGNER_INFO):
4617             decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
4618             break;
4619         }
4620     }
4621     else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
4622         decodeFunc = CRYPT_AsnDecodeExtensions;
4623     else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
4624         decodeFunc = CRYPT_AsnDecodeUtcTime;
4625     else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
4626         decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
4627     else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
4628         decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
4629     else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
4630         decodeFunc = CRYPT_AsnDecodeEnumerated;
4631     else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
4632         decodeFunc = CRYPT_AsnDecodeBits;
4633     else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
4634         decodeFunc = CRYPT_AsnDecodeOctets;
4635     else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
4636         decodeFunc = CRYPT_AsnDecodeBasicConstraints;
4637     else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
4638         decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
4639     else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
4640         decodeFunc = CRYPT_AsnDecodeAltName;
4641     else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
4642         decodeFunc = CRYPT_AsnDecodeAltName;
4643     else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
4644         decodeFunc = CRYPT_AsnDecodeAltName;
4645     else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
4646         decodeFunc = CRYPT_AsnDecodeAltName;
4647     else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
4648         decodeFunc = CRYPT_AsnDecodeAltName;
4649     else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
4650         decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
4651     else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
4652         decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
4653     else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
4654         decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
4655     else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
4656         decodeFunc = CRYPT_AsnDecodeNameConstraints;
4657     return decodeFunc;
4658 }
4659
4660 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
4661  LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
4662 {
4663     static HCRYPTOIDFUNCSET set = NULL;
4664     CryptDecodeObjectFunc decodeFunc = NULL;
4665
4666     if (!set)
4667         set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
4668     CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
4669      (void **)&decodeFunc, hFunc);
4670     return decodeFunc;
4671 }
4672
4673 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
4674  LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
4675 {
4676     static HCRYPTOIDFUNCSET set = NULL;
4677     CryptDecodeObjectExFunc decodeFunc = NULL;
4678
4679     if (!set)
4680         set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
4681     CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
4682      (void **)&decodeFunc, hFunc);
4683     return decodeFunc;
4684 }
4685
4686 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
4687  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
4688  DWORD *pcbStructInfo)
4689 {
4690     BOOL ret = FALSE;
4691     CryptDecodeObjectFunc pCryptDecodeObject = NULL;
4692     CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
4693     HCRYPTOIDFUNCADDR hFunc = NULL;
4694
4695     TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
4696      debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
4697      pvStructInfo, pcbStructInfo);
4698
4699     if (!pvStructInfo && !pcbStructInfo)
4700     {
4701         SetLastError(ERROR_INVALID_PARAMETER);
4702         return FALSE;
4703     }
4704     if (!cbEncoded)
4705     {
4706         SetLastError(CRYPT_E_ASN1_EOD);
4707         return FALSE;
4708     }
4709     if (cbEncoded > MAX_ENCODED_LEN)
4710     {
4711         SetLastError(CRYPT_E_ASN1_LARGE);
4712         return FALSE;
4713     }
4714
4715     if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
4716      lpszStructType)))
4717     {
4718         TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
4719          debugstr_a(lpszStructType));
4720         pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
4721          lpszStructType, &hFunc);
4722         if (!pCryptDecodeObject)
4723             pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
4724              lpszStructType, &hFunc);
4725     }
4726     if (pCryptDecodeObject)
4727         ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4728          pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
4729     else if (pCryptDecodeObjectEx)
4730         ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
4731          pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
4732          pvStructInfo, pcbStructInfo);
4733     if (hFunc)
4734         CryptFreeOIDFunctionAddress(hFunc, 0);
4735     TRACE_(crypt)("returning %d\n", ret);
4736     return ret;
4737 }
4738
4739 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
4740  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4741  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4742 {
4743     BOOL ret = FALSE;
4744     CryptDecodeObjectExFunc decodeFunc;
4745     HCRYPTOIDFUNCADDR hFunc = NULL;
4746
4747     TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
4748      dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
4749      cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
4750
4751     if (!pvStructInfo && !pcbStructInfo)
4752     {
4753         SetLastError(ERROR_INVALID_PARAMETER);
4754         return FALSE;
4755     }
4756     if (!cbEncoded)
4757     {
4758         SetLastError(CRYPT_E_ASN1_EOD);
4759         return FALSE;
4760     }
4761     if (cbEncoded > MAX_ENCODED_LEN)
4762     {
4763         SetLastError(CRYPT_E_ASN1_LARGE);
4764         return FALSE;
4765     }
4766
4767     SetLastError(NOERROR);
4768     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
4769         *(BYTE **)pvStructInfo = NULL;
4770     decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
4771     if (!decodeFunc)
4772     {
4773         TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
4774          debugstr_a(lpszStructType));
4775         decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
4776          &hFunc);
4777     }
4778     if (decodeFunc)
4779         ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
4780          cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
4781     else
4782     {
4783         CryptDecodeObjectFunc pCryptDecodeObject =
4784          CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
4785
4786         /* Try CryptDecodeObject function.  Don't call CryptDecodeObject
4787          * directly, as that could cause an infinite loop.
4788          */
4789         if (pCryptDecodeObject)
4790         {
4791             if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4792             {
4793                 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4794                  pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
4795                 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4796                  pvStructInfo, pcbStructInfo, *pcbStructInfo)))
4797                     ret = pCryptDecodeObject(dwCertEncodingType,
4798                      lpszStructType, pbEncoded, cbEncoded, dwFlags,
4799                      *(BYTE **)pvStructInfo, pcbStructInfo);
4800             }
4801             else
4802                 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4803                  pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
4804         }
4805     }
4806     if (hFunc)
4807         CryptFreeOIDFunctionAddress(hFunc, 0);
4808     TRACE_(crypt)("returning %d\n", ret);
4809     return ret;
4810 }