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