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