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