source: trunk/src/crypt32/decode.c@ 21916

Last change on this file since 21916 was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

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