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