Merge amd64 NDK from amd64 branch:
[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 = max( structSize, items[i].offset + 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 = 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 = 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 = 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 = 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 = 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 &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 = 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 = 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 &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 = 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 = 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 = 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 = 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 = 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 = 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)) * sizeof(WCHAR);
1728 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
1729 value->Value.cbData += sizeof(WCHAR);
1730 break;
1731 }
1732 }
1733 else
1734 {
1735 value->Value.cbData = 0;
1736 value->Value.pbData = NULL;
1737 }
1738 }
1739 }
1740 return ret;
1741 }
1742
1743 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1744 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1745 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1746 {
1747 BOOL ret = TRUE;
1748
1749 __TRY
1750 {
1751 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1752 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1753 if (ret && pvStructInfo)
1754 {
1755 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1756 pcbStructInfo, *pcbStructInfo);
1757 if (ret)
1758 {
1759 CERT_NAME_VALUE *value;
1760
1761 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1762 pvStructInfo = *(BYTE **)pvStructInfo;
1763 value = pvStructInfo;
1764 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1765 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1766 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1767 pcbStructInfo, NULL);
1768 }
1769 }
1770 }
1771 __EXCEPT_PAGE_FAULT
1772 {
1773 SetLastError(STATUS_ACCESS_VIOLATION);
1774 ret = FALSE;
1775 }
1776 __ENDTRY
1777 return ret;
1778 }
1779
1780 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1781 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1782 {
1783 BOOL ret;
1784 struct AsnDecodeSequenceItem items[] = {
1785 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1786 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1787 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1788 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1789 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1790 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1791 };
1792 CERT_RDN_ATTR *attr = pvStructInfo;
1793
1794 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1795 pvStructInfo, *pcbStructInfo);
1796
1797 if (attr)
1798 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1799 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1800 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1801 attr ? attr->pszObjId : NULL);
1802 if (attr)
1803 {
1804 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1805 debugstr_a(attr->pszObjId));
1806 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1807 }
1808 TRACE("returning %d (%08x)\n", ret, GetLastError());
1809 return ret;
1810 }
1811
1812 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1813 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1814 {
1815 BOOL ret = TRUE;
1816 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1817 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1818 offsetof(CERT_RDN_ATTR, pszObjId) };
1819 PCERT_RDN rdn = pvStructInfo;
1820
1821 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1822 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1823 rdn ? rdn->rgRDNAttr : NULL);
1824 return ret;
1825 }
1826
1827 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1828 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1829 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1830 {
1831 BOOL ret = TRUE;
1832
1833 __TRY
1834 {
1835 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1836 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1837 offsetof(CERT_RDN, rgRDNAttr) };
1838
1839 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1840 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1841 }
1842 __EXCEPT_PAGE_FAULT
1843 {
1844 SetLastError(STATUS_ACCESS_VIOLATION);
1845 ret = FALSE;
1846 }
1847 __ENDTRY
1848 return ret;
1849 }
1850
1851 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1852 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1853 DWORD *pcbDecoded)
1854 {
1855 BOOL ret;
1856 struct AsnDecodeSequenceItem items[] = {
1857 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1858 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1859 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1860 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1861 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1862 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1863 };
1864 CERT_RDN_ATTR *attr = pvStructInfo;
1865
1866 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1867 pvStructInfo, *pcbStructInfo);
1868
1869 if (attr)
1870 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1871 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1872 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1873 attr ? attr->pszObjId : NULL);
1874 if (attr)
1875 {
1876 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1877 debugstr_a(attr->pszObjId));
1878 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1879 }
1880 TRACE("returning %d (%08x)\n", ret, GetLastError());
1881 return ret;
1882 }
1883
1884 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1885 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1886 {
1887 BOOL ret = TRUE;
1888 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1889 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1890 offsetof(CERT_RDN_ATTR, pszObjId) };
1891 PCERT_RDN rdn = pvStructInfo;
1892
1893 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1894 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1895 rdn ? rdn->rgRDNAttr : NULL);
1896 return ret;
1897 }
1898
1899 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1900 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1901 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1902 {
1903 BOOL ret = TRUE;
1904
1905 __TRY
1906 {
1907 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1908 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
1909 offsetof(CERT_RDN, rgRDNAttr) };
1910
1911 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1912 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1913 }
1914 __EXCEPT_PAGE_FAULT
1915 {
1916 SetLastError(STATUS_ACCESS_VIOLATION);
1917 ret = FALSE;
1918 }
1919 __ENDTRY
1920 return ret;
1921 }
1922
1923 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
1924 DWORD *pcbDecoded)
1925 {
1926 BOOL ret = TRUE, done = FALSE;
1927 DWORD indefiniteNestingLevels = 0, decoded = 0;
1928
1929 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
1930
1931 do {
1932 DWORD dataLen;
1933
1934 if (!cbEncoded)
1935 done = TRUE;
1936 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
1937 &dataLen)))
1938 {
1939 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1940
1941 if (dataLen == CMSG_INDEFINITE_LENGTH)
1942 {
1943 indefiniteNestingLevels++;
1944 pbEncoded += 1 + lenBytes;
1945 cbEncoded -= 1 + lenBytes;
1946 decoded += 1 + lenBytes;
1947 TRACE("indefiniteNestingLevels = %d\n",
1948 indefiniteNestingLevels);
1949 }
1950 else
1951 {
1952 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
1953 indefiniteNestingLevels)
1954 {
1955 indefiniteNestingLevels--;
1956 TRACE("indefiniteNestingLevels = %d\n",
1957 indefiniteNestingLevels);
1958 }
1959 pbEncoded += 1 + lenBytes + dataLen;
1960 cbEncoded -= 1 + lenBytes + dataLen;
1961 decoded += 1 + lenBytes + dataLen;
1962 if (!indefiniteNestingLevels)
1963 done = TRUE;
1964 }
1965 }
1966 } while (ret && !done);
1967 /* If we haven't found all 0 TLVs, we haven't found the end */
1968 if (ret && indefiniteNestingLevels)
1969 {
1970 SetLastError(CRYPT_E_ASN1_EOD);
1971 ret = FALSE;
1972 }
1973 if (ret)
1974 *pcbDecoded = decoded;
1975 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
1976 return ret;
1977 }
1978
1979 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
1980 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1981 DWORD *pcbDecoded)
1982 {
1983 BOOL ret = TRUE;
1984 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
1985
1986 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1987 pvStructInfo, *pcbStructInfo);
1988
1989 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
1990 {
1991 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1992 bytesNeeded += encodedLen;
1993 if (!pvStructInfo)
1994 *pcbStructInfo = bytesNeeded;
1995 else if (*pcbStructInfo < bytesNeeded)
1996 {
1997 SetLastError(ERROR_MORE_DATA);
1998 *pcbStructInfo = bytesNeeded;
1999 ret = FALSE;
2000 }
2001 else
2002 {
2003 PCRYPT_OBJID_BLOB blob = pvStructInfo;
2004
2005 *pcbStructInfo = bytesNeeded;
2006 blob->cbData = encodedLen;
2007 if (encodedLen)
2008 {
2009 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2010 blob->pbData = (LPBYTE)pbEncoded;
2011 else
2012 {
2013 assert(blob->pbData);
2014 memcpy(blob->pbData, pbEncoded, blob->cbData);
2015 }
2016 }
2017 else
2018 blob->pbData = NULL;
2019 }
2020 if (pcbDecoded)
2021 *pcbDecoded = encodedLen;
2022 }
2023 return ret;
2024 }
2025
2026 static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded,
2027 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2028 {
2029 BOOL ret;
2030 struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
2031 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2032 struct GenericArray *array = pvStructInfo;
2033
2034 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2035 pvStructInfo, *pcbStructInfo, pcbDecoded);
2036
2037 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2038 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2039 array ? array->rgItems : NULL);
2040 return ret;
2041 }
2042
2043 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2044 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2045 {
2046 BOOL ret;
2047 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2048 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2049 CTL_USAGE *usage = pvStructInfo;
2050
2051 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2052 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2053 usage ? usage->rgpszUsageIdentifier : NULL);
2054 return ret;
2055 }
2056
2057 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2058 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2059 {
2060 struct AsnDecodeSequenceItem items[] = {
2061 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2062 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2063 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2064 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2065 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), FALSE,
2066 TRUE, offsetof(CTL_ENTRY, rgAttribute), 0 },
2067 };
2068 BOOL ret = TRUE;
2069 CTL_ENTRY *entry = pvStructInfo;
2070
2071 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2072 *pcbStructInfo);
2073
2074 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2075 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2076 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2077 return ret;
2078 }
2079
2080 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2081 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2082 {
2083 BOOL ret;
2084 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2085 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2086 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2087 struct GenericArray *entries = pvStructInfo;
2088
2089 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2090 pvStructInfo, *pcbStructInfo, pcbDecoded);
2091
2092 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2093 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2094 entries ? entries->rgItems : NULL);
2095 return ret;
2096 }
2097
2098 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2099 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2100 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2101 {
2102 BOOL ret = FALSE;
2103
2104 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2105 pDecodePara, pvStructInfo, *pcbStructInfo);
2106
2107 __TRY
2108 {
2109 struct AsnDecodeSequenceItem items[] = {
2110 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2111 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2112 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2113 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2114 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2115 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2116 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2117 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2118 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2119 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2120 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2121 { 0, offsetof(CTL_INFO, ThisUpdate),
2122 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2123 0 },
2124 { 0, offsetof(CTL_INFO, NextUpdate),
2125 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2126 0 },
2127 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2128 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2129 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2130 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2131 CRYPT_AsnDecodeCTLEntries, sizeof(struct GenericArray),
2132 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2133 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2134 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
2135 offsetof(CTL_INFO, rgExtension), 0 },
2136 };
2137
2138 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2139 pDecodePara, pvStructInfo, *pcbStructInfo);
2140
2141 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2142 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2143 pcbStructInfo, NULL, NULL);
2144 }
2145 __EXCEPT_PAGE_FAULT
2146 {
2147 SetLastError(STATUS_ACCESS_VIOLATION);
2148 }
2149 __ENDTRY
2150 return ret;
2151 }
2152
2153 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2154 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2155 DWORD *pcbDecoded)
2156 {
2157 BOOL ret;
2158 struct AsnDecodeSequenceItem items[] = {
2159 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2160 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2161 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2162 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2163 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2164 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2165 };
2166 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2167
2168 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2169 pvStructInfo, *pcbStructInfo);
2170
2171 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2172 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2173 pcbDecoded, capability ? capability->pszObjId : NULL);
2174 TRACE("returning %d\n", ret);
2175 return ret;
2176 }
2177
2178 static BOOL CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE *pbEncoded,
2179 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2180 DWORD *pcbDecoded)
2181 {
2182 struct AsnArrayDescriptor arrayDesc = { 0,
2183 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2184 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2185 PCRYPT_SMIME_CAPABILITIES capabilities = pvStructInfo;
2186 BOOL ret;
2187
2188 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2189 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2190 capabilities ? capabilities->rgCapability : NULL);
2191 return ret;
2192 }
2193
2194 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2195 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2196 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2197 {
2198 BOOL ret = FALSE;
2199
2200 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2201 pDecodePara, pvStructInfo, *pcbStructInfo);
2202
2203 __TRY
2204 {
2205 DWORD bytesNeeded;
2206
2207 if (!cbEncoded)
2208 SetLastError(CRYPT_E_ASN1_EOD);
2209 else if (pbEncoded[0] != ASN_SEQUENCEOF)
2210 SetLastError(CRYPT_E_ASN1_CORRUPT);
2211 else if ((ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2212 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2213 NULL)))
2214 {
2215 if (!pvStructInfo)
2216 *pcbStructInfo = bytesNeeded;
2217 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2218 pvStructInfo, pcbStructInfo, bytesNeeded)))
2219 {
2220 PCRYPT_SMIME_CAPABILITIES capabilities;
2221
2222 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2223 pvStructInfo = *(BYTE **)pvStructInfo;
2224 capabilities = pvStructInfo;
2225 capabilities->rgCapability =
2226 (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
2227 sizeof(CRYPT_SMIME_CAPABILITIES));
2228 ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2229 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2230 &bytesNeeded, NULL);
2231 }
2232 }
2233 }
2234 __EXCEPT_PAGE_FAULT
2235 {
2236 SetLastError(STATUS_ACCESS_VIOLATION);
2237 }
2238 __ENDTRY
2239 TRACE("returning %d\n", ret);
2240 return ret;
2241 }
2242
2243 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2244 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2245 DWORD *pcbDecoded)
2246 {
2247 BOOL ret = TRUE;
2248 DWORD dataLen;
2249 LPSTR *pStr = pvStructInfo;
2250
2251 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2252 {
2253 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2254 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2255
2256 if (pbEncoded[0] != ASN_IA5STRING)
2257 {
2258 SetLastError(CRYPT_E_ASN1_CORRUPT);
2259 ret = FALSE;
2260 }
2261 else
2262 {
2263 bytesNeeded += dataLen;
2264 if (pcbDecoded)
2265 *pcbDecoded = 1 + lenBytes + dataLen;
2266 if (!pvStructInfo)
2267 *pcbStructInfo = bytesNeeded;
2268 else if (*pcbStructInfo < bytesNeeded)
2269 {
2270 *pcbStructInfo = bytesNeeded;
2271 SetLastError(ERROR_MORE_DATA);
2272 ret = FALSE;
2273 }
2274 else
2275 {
2276 *pcbStructInfo = bytesNeeded;
2277 if (dataLen)
2278 {
2279 LPSTR str = *pStr;
2280
2281 assert(str);
2282 memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2283 str[dataLen] = 0;
2284 }
2285 else
2286 *pStr = NULL;
2287 }
2288 }
2289 }
2290 return ret;
2291 }
2292
2293 static BOOL CRYPT_AsnDecodeIntArray(const BYTE *pbEncoded,
2294 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2295 DWORD *pcbDecoded)
2296 {
2297 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2298 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2299 struct GenericArray *array = pvStructInfo;
2300 BOOL ret;
2301
2302 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2303 pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2304
2305 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2306 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2307 array ? array->rgItems : NULL);
2308 TRACE("returning %d\n", ret);
2309 return ret;
2310 }
2311
2312 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2313 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2314 DWORD *pcbDecoded)
2315 {
2316 BOOL ret;
2317 struct AsnDecodeSequenceItem items[] = {
2318 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2319 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2320 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2321 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2322 cNoticeNumbers), CRYPT_AsnDecodeIntArray, sizeof(struct GenericArray),
2323 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2324 rgNoticeNumbers), 0 },
2325 };
2326 DWORD bytesNeeded;
2327
2328 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2329 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2330
2331 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2332 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2333 NULL);
2334 if (ret)
2335 {
2336 /* The caller is expecting a pointer to a
2337 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2338 * CRYPT_AsnDecodeSequence is decoding a
2339 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2340 * needed, and decode again if the requisite space is available.
2341 */
2342 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2343 if (!pvStructInfo)
2344 *pcbStructInfo = bytesNeeded;
2345 else if (*pcbStructInfo < bytesNeeded)
2346 {
2347 *pcbStructInfo = bytesNeeded;
2348 SetLastError(ERROR_MORE_DATA);
2349 ret = FALSE;
2350 }
2351 else
2352 {
2353 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2354
2355 *pcbStructInfo = bytesNeeded;
2356 /* The pointer (pvStructInfo) passed in points to the first dynamic
2357 * pointer, so use it as the pointer to the
2358 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2359 * appropriate offset for the first dynamic pointer within the
2360 * notice reference by pointing to the first memory location past
2361 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2362 */
2363 noticeRef =
2364 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2365 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2366 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2367 ret = CRYPT_AsnDecodeSequence(items,
2368 sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2369 NULL, noticeRef, &bytesNeeded, pcbDecoded,
2370 noticeRef->pszOrganization);
2371 }
2372 }
2373 TRACE("returning %d\n", ret);
2374 return ret;
2375 }
2376
2377 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2378 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2379 DWORD *pcbDecoded)
2380 {
2381 BOOL ret = TRUE;
2382 DWORD dataLen;
2383
2384 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2385 {
2386 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2387 DWORD bytesNeeded = sizeof(LPWSTR);
2388
2389 switch (pbEncoded[0])
2390 {
2391 case ASN_NUMERICSTRING:
2392 if (dataLen)
2393 bytesNeeded += (dataLen + 1) * 2;
2394 break;
2395 case ASN_PRINTABLESTRING:
2396 if (dataLen)
2397 bytesNeeded += (dataLen + 1) * 2;
2398 break;
2399 case ASN_IA5STRING:
2400 if (dataLen)
2401 bytesNeeded += (dataLen + 1) * 2;
2402 break;
2403 case ASN_T61STRING:
2404 if (dataLen)
2405 bytesNeeded += (dataLen + 1) * 2;
2406 break;
2407 case ASN_VIDEOTEXSTRING:
2408 if (dataLen)
2409 bytesNeeded += (dataLen + 1) * 2;
2410 break;
2411 case ASN_GRAPHICSTRING:
2412 if (dataLen)
2413 bytesNeeded += (dataLen + 1) * 2;
2414 break;
2415 case ASN_VISIBLESTRING:
2416 if (dataLen)
2417 bytesNeeded += (dataLen + 1) * 2;
2418 break;
2419 case ASN_GENERALSTRING:
2420 if (dataLen)
2421 bytesNeeded += (dataLen + 1) * 2;
2422 break;
2423 case ASN_UNIVERSALSTRING:
2424 if (dataLen)
2425 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2426 break;
2427 case ASN_BMPSTRING:
2428 if (dataLen)
2429 bytesNeeded += dataLen + sizeof(WCHAR);
2430 break;
2431 case ASN_UTF8STRING:
2432 if (dataLen)
2433 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2434 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2435 break;
2436 default:
2437 SetLastError(CRYPT_E_ASN1_BADTAG);
2438 return FALSE;
2439 }
2440
2441 if (pcbDecoded)
2442 *pcbDecoded = 1 + lenBytes + dataLen;
2443 if (!pvStructInfo)
2444 *pcbStructInfo = bytesNeeded;
2445 else if (*pcbStructInfo < bytesNeeded)
2446 {
2447 *pcbStructInfo = bytesNeeded;
2448 SetLastError(ERROR_MORE_DATA);
2449 ret = FALSE;
2450 }
2451 else
2452 {
2453 LPWSTR *pStr = pvStructInfo;
2454
2455 *pcbStructInfo = bytesNeeded;
2456 if (dataLen)
2457 {
2458 DWORD i;
2459 LPWSTR str = *(LPWSTR *)pStr;
2460
2461 assert(str);
2462 switch (pbEncoded[0])
2463 {
2464 case ASN_NUMERICSTRING:
2465 case ASN_PRINTABLESTRING:
2466 case ASN_IA5STRING:
2467 case ASN_T61STRING:
2468 case ASN_VIDEOTEXSTRING:
2469 case ASN_GRAPHICSTRING:
2470 case ASN_VISIBLESTRING:
2471 case ASN_GENERALSTRING:
2472 for (i = 0; i < dataLen; i++)
2473 str[i] = pbEncoded[1 + lenBytes + i];
2474 str[i] = 0;
2475 break;
2476 case ASN_UNIVERSALSTRING:
2477 for (i = 0; i < dataLen / 4; i++)
2478 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2479 | pbEncoded[1 + lenBytes + 2 * i + 3];
2480 str[i] = 0;
2481 break;
2482 case ASN_BMPSTRING:
2483 for (i = 0; i < dataLen / 2; i++)
2484 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2485 pbEncoded[1 + lenBytes + 2 * i + 1];
2486 str[i] = 0;
2487 break;
2488 case ASN_UTF8STRING:
2489 {
2490 int len = MultiByteToWideChar(CP_UTF8, 0,
2491 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2492 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2493 str[len] = 0;
2494 break;
2495 }
2496 }
2497 }
2498 else
2499 *pStr = NULL;
2500 }
2501 }
2502 return ret;
2503 }
2504
2505 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2506 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2507 DWORD *pcbStructInfo, DWORD *pcbDecoded)
2508 {
2509 BOOL ret;
2510 struct AsnDecodeSequenceItem items[] = {
2511 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2512 pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2513 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2514 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2515 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2516 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2517 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2518 };
2519 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2520
2521 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2522 pvStructInfo, *pcbStructInfo);
2523
2524 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2525 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2526 pcbDecoded, notice ? notice->pNoticeReference : NULL);
2527 TRACE("returning %d\n", ret);
2528 return ret;
2529 }
2530
2531 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2532 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2533 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2534 void *pvStructInfo, DWORD *pcbStructInfo)
2535 {
2536 BOOL ret = FALSE;
2537
2538 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2539 pDecodePara, pvStructInfo, *pcbStructInfo);
2540
2541 __TRY
2542 {
2543 DWORD bytesNeeded;
2544
2545 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2546 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2547 NULL);
2548 if (ret)
2549 {
2550 if (!pvStructInfo)
2551 *pcbStructInfo = bytesNeeded;
2552 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2553 pvStructInfo, pcbStructInfo, bytesNeeded)))
2554 {
2555 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2556
2557 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2558 pvStructInfo = *(BYTE **)pvStructInfo;
2559 notice = pvStructInfo;
2560 notice->pNoticeReference =
2561 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2562 ((BYTE *)pvStructInfo +
2563 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2564 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2565 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2566 pvStructInfo, &bytesNeeded, NULL);
2567 }
2568 }
2569 }
2570 __EXCEPT_PAGE_FAULT
2571 {
2572 SetLastError(STATUS_ACCESS_VIOLATION);
2573 }
2574 __ENDTRY
2575 TRACE("returning %d\n", ret);
2576 return ret;
2577 }
2578
2579 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2580 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2581 DWORD *pcbDecoded)
2582 {
2583 BOOL ret;
2584 struct AsnDecodeSequenceItem items[] = {
2585 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2586 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2587 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2588 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2589 CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE,
2590 offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2591 };
2592 PCRYPT_ATTRIBUTE attr = pvStructInfo;
2593
2594 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2595 pvStructInfo, *pcbStructInfo);
2596
2597 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2598 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2599 pcbDecoded, attr ? attr->pszObjId : NULL);
2600 TRACE("returning %d\n", ret);
2601 return ret;
2602 }
2603
2604 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2605 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2606 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2607 {
2608 BOOL ret = FALSE;
2609
2610 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2611 pDecodePara, pvStructInfo, *pcbStructInfo);
2612
2613 __TRY
2614 {
2615 DWORD bytesNeeded;
2616
2617 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2618 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2619 if (ret)
2620 {
2621 if (!pvStructInfo)
2622 *pcbStructInfo = bytesNeeded;
2623 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2624 pvStructInfo, pcbStructInfo, bytesNeeded)))
2625 {
2626 PCRYPT_ATTRIBUTE attr;
2627
2628 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2629 pvStructInfo = *(BYTE **)pvStructInfo;
2630 attr = pvStructInfo;
2631 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2632 sizeof(CRYPT_ATTRIBUTE));
2633 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2634 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2635 NULL);
2636 }
2637 }
2638 }
2639 __EXCEPT_PAGE_FAULT
2640 {
2641 SetLastError(STATUS_ACCESS_VIOLATION);
2642 }
2643 __ENDTRY
2644 TRACE("returning %d\n", ret);
2645 return ret;
2646 }
2647
2648 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2649 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2650 DWORD *pcbDecoded)
2651 {
2652 struct AsnArrayDescriptor arrayDesc = { 0,
2653 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2654 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2655 PCRYPT_ATTRIBUTES attrs = pvStructInfo;
2656 BOOL ret;
2657
2658 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2659 NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
2660 NULL);
2661 return ret;
2662 }
2663
2664 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2665 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2666 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2667 {
2668 BOOL ret = FALSE;
2669
2670 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2671 pDecodePara, pvStructInfo, *pcbStructInfo);
2672
2673 __TRY
2674 {
2675 DWORD bytesNeeded;
2676
2677 if (!cbEncoded)
2678 SetLastError(CRYPT_E_ASN1_EOD);
2679 else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
2680 SetLastError(CRYPT_E_ASN1_CORRUPT);
2681 else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2682 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2683 NULL)))
2684 {
2685 if (!pvStructInfo)
2686 *pcbStructInfo = bytesNeeded;
2687 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2688 pvStructInfo, pcbStructInfo, bytesNeeded)))
2689 {
2690 PCRYPT_ATTRIBUTES attrs;
2691
2692 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2693 pvStructInfo = *(BYTE **)pvStructInfo;
2694 attrs = pvStructInfo;
2695 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
2696 sizeof(CRYPT_ATTRIBUTES));
2697 ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2698 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2699 &bytesNeeded, NULL);
2700 }
2701 }
2702 }
2703 __EXCEPT_PAGE_FAULT
2704 {
2705 SetLastError(STATUS_ACCESS_VIOLATION);
2706 }
2707 __ENDTRY
2708 TRACE("returning %d\n", ret);
2709 return ret;
2710 }
2711
2712 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2713 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2714 {
2715 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2716 BOOL ret = TRUE;
2717 struct AsnDecodeSequenceItem items[] = {
2718 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2719 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2720 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2721 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2722 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2723 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2724 };
2725
2726 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2727 pvStructInfo, *pcbStructInfo, pcbDecoded);
2728
2729 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2730 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2731 pcbDecoded, algo ? algo->pszObjId : NULL);
2732 if (ret && pvStructInfo)
2733 {
2734 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2735 debugstr_a(algo->pszObjId));
2736 }
2737 return ret;
2738 }
2739
2740 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2741 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2742 DWORD *pcbDecoded)
2743 {
2744 BOOL ret = TRUE;
2745 struct AsnDecodeSequenceItem items[] = {
2746 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2747 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2748 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2749 Algorithm.pszObjId) },
2750 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2751 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2752 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2753 };
2754 PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2755
2756 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2757 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2758 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2759 return ret;
2760 }
2761
2762 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2763 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2764 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2765 {
2766 BOOL ret = TRUE;
2767
2768 __TRY
2769 {
2770 DWORD bytesNeeded;
2771
2772 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2773 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2774 {
2775 if (!pvStructInfo)
2776 *pcbStructInfo = bytesNeeded;
2777 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2778 pvStructInfo, pcbStructInfo, bytesNeeded)))
2779 {
2780 PCERT_PUBLIC_KEY_INFO info;
2781
2782 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2783 pvStructInfo = *(BYTE **)pvStructInfo;
2784 info = pvStructInfo;
2785 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2786 sizeof(CERT_PUBLIC_KEY_INFO);
2787 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2788 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2789 &bytesNeeded, NULL);
2790 }
2791 }
2792 }
2793 __EXCEPT_PAGE_FAULT
2794 {
2795 SetLastError(STATUS_ACCESS_VIOLATION);
2796 ret = FALSE;
2797 }
2798 __ENDTRY
2799 return ret;
2800 }
2801
2802 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2803 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2804 {
2805 BOOL ret;
2806
2807 if (cbEncoded < 3)
2808 {
2809 SetLastError(CRYPT_E_ASN1_CORRUPT);
2810 return FALSE;
2811 }
2812 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2813 {
2814 SetLastError(CRYPT_E_ASN1_CORRUPT);
2815 return FALSE;
2816 }
2817 if (pbEncoded[1] > 1)
2818 {
2819 SetLastError(CRYPT_E_ASN1_CORRUPT);
2820 return FALSE;
2821 }
2822 if (pcbDecoded)
2823 *pcbDecoded = 3;
2824 if (!pvStructInfo)
2825 {
2826 *pcbStructInfo = sizeof(BOOL);
2827 ret = TRUE;
2828 }
2829 else if (*pcbStructInfo < sizeof(BOOL))
2830 {
2831 *pcbStructInfo = sizeof(BOOL);
2832 SetLastError(ERROR_MORE_DATA);
2833 ret = FALSE;
2834 }
2835 else
2836 {
2837 *pcbStructInfo = sizeof(BOOL);
2838 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2839 ret = TRUE;
2840 }
2841 TRACE("returning %d (%08x)\n", ret, GetLastError());
2842 return ret;
2843 }
2844
2845 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2846 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2847 {
2848 PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2849 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2850 BOOL ret;
2851
2852 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2853 pvStructInfo, *pcbStructInfo);
2854
2855 if (cbEncoded < 2)
2856 {
2857 SetLastError(CRYPT_E_ASN1_CORRUPT);
2858 return FALSE;
2859 }
2860 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2861 if (1 + lenBytes > cbEncoded)
2862 {
2863 SetLastError(CRYPT_E_ASN1_CORRUPT);
2864 return FALSE;
2865 }
2866 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2867 {
2868 switch (pbEncoded[0] & ASN_TYPE_MASK)
2869 {
2870 case 1: /* rfc822Name */
2871 case 2: /* dNSName */
2872 case 6: /* uniformResourceIdentifier */
2873 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2874 break;
2875 case 4: /* directoryName */
2876 case 7: /* iPAddress */
2877 bytesNeeded += dataLen;
2878 break;
2879 case 8: /* registeredID */
2880 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2881 &dataLen, NULL);
2882 if (ret)
2883 {
2884 /* FIXME: ugly, shouldn't need to know internals of OID decode
2885 * function to use it.
2886 */
2887 bytesNeeded += dataLen - sizeof(LPSTR);
2888 }
2889 break;
2890 case 0: /* otherName */
2891 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2892 SetLastError(CRYPT_E_ASN1_BADTAG);
2893 ret = FALSE;
2894 break;
2895 case 3: /* x400Address, unimplemented */
2896 case 5: /* ediPartyName, unimplemented */
2897 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2898 SetLastError(CRYPT_E_ASN1_BADTAG);
2899 ret = FALSE;
2900 break;
2901 default:
2902 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2903 SetLastError(CRYPT_E_ASN1_CORRUPT);
2904 ret = FALSE;
2905 }
2906 if (ret)
2907 {
2908 if (pcbDecoded)
2909 *pcbDecoded = 1 + lenBytes + dataLen;
2910 if (!entry)
2911 *pcbStructInfo = bytesNeeded;
2912 else if (*pcbStructInfo < bytesNeeded)
2913 {
2914 *pcbStructInfo = bytesNeeded;
2915 SetLastError(ERROR_MORE_DATA);
2916 ret = FALSE;
2917 }
2918 else
2919 {
2920 *pcbStructInfo = bytesNeeded;
2921 /* MS used values one greater than the asn1 ones.. sigh */
2922 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
2923 switch (pbEncoded[0] & ASN_TYPE_MASK)
2924 {
2925 case 1: /* rfc822Name */
2926 case 2: /* dNSName */
2927 case 6: /* uniformResourceIdentifier */
2928 {
2929 DWORD i;
2930
2931 for (i = 0; i < dataLen; i++)
2932 entry->u.pwszURL[i] =
2933 (WCHAR)pbEncoded[1 + lenBytes + i];
2934 entry->u.pwszURL[i] = 0;
2935 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
2936 debugstr_w(entry->u.pwszURL));
2937 break;
2938 }
2939 case 4: /* directoryName */
2940 /* The data are memory-equivalent with the IPAddress case,
2941 * fall-through
2942 */
2943 case 7: /* iPAddress */
2944 /* The next data pointer is in the pwszURL spot, that is,
2945 * the first 4 bytes. Need to move it to the next spot.
2946 */
2947 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
2948 entry->u.IPAddress.cbData = dataLen;
2949 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
2950 dataLen);
2951 break;
2952 case 8: /* registeredID */
2953 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
2954 &entry->u.pszRegisteredID, &dataLen, NULL);
2955 break;
2956 }
2957 }
2958 }
2959 }
2960 return ret;
2961 }
2962
2963 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
2964 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2965 DWORD *pcbDecoded)
2966 {
2967 BOOL ret = TRUE;
2968 struct AsnArrayDescriptor arrayDesc = { 0,
2969 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
2970 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
2971 PCERT_ALT_NAME_INFO info = pvStructInfo;
2972
2973 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2974 pvStructInfo, *pcbStructInfo, pcbDecoded);
2975
2976 if (info)
2977 TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
2978 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2979 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2980 info ? info->rgAltEntry : NULL);
2981 return ret;
2982 }
2983
2984 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2985 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
2986 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2987 DWORD *pcbDecoded)
2988 {
2989 BOOL ret;
2990
2991 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
2992 pvStructInfo, *pcbStructInfo, pcbDecoded);
2993
2994 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2995 * place.
2996 */
2997 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
2998 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
2999 pcbDecoded);
3000 if (ret && pvStructInfo)
3001 {
3002 CRYPT_DATA_BLOB *blob = pvStructInfo;
3003
3004 if (blob->cbData)
3005 {
3006 DWORD i;
3007 BYTE temp;
3008
3009 for (i = 0; i < blob->cbData / 2; i++)
3010 {
3011 temp = blob->pbData[i];
3012 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
3013 blob->pbData[blob->cbData - i - 1] = temp;
3014 }
3015 }
3016 }
3017 TRACE("returning %d (%08x)\n", ret, GetLastError());
3018 return ret;
3019 }
3020
3021 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3022 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3023 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3024 {
3025 BOOL ret;
3026
3027 __TRY
3028 {
3029 struct AsnDecodeSequenceItem items[] = {
3030 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3031 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3032 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3033 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3034 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3035 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3036 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3037 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3038 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3039 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3040 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3041 };
3042
3043 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3044 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3045 pcbStructInfo, NULL, NULL);
3046 }
3047 __EXCEPT_PAGE_FAULT
3048 {
3049 SetLastError(STATUS_ACCESS_VIOLATION);
3050 ret = FALSE;
3051 }
3052 __ENDTRY
3053 return ret;
3054 }
3055
3056 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3057 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3058 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3059 {
3060 BOOL ret;
3061
3062 __TRY
3063 {
3064 struct AsnDecodeSequenceItem items[] = {
3065 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3066 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3067 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3068 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3069 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3070 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3071 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3072 AuthorityCertIssuer.rgAltEntry), 0 },
3073 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3074 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3075 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3076 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3077 AuthorityCertSerialNumber.pbData), 0 },
3078 };
3079
3080 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3081 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3082 pcbStructInfo, NULL, NULL);
3083 }
3084 __EXCEPT_PAGE_FAULT
3085 {
3086 SetLastError(STATUS_ACCESS_VIOLATION);
3087 ret = FALSE;
3088 }
3089 __ENDTRY
3090 return ret;
3091 }
3092
3093 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3094 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3095 DWORD *pcbDecoded)
3096 {
3097 struct AsnDecodeSequenceItem items[] = {
3098 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3099 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3100 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3101 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3102 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3103 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3104 };
3105 CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3106
3107 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3108 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3109 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3110 }
3111
3112 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3113 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3114 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3115 {
3116 BOOL ret;
3117
3118 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3119 pDecodePara, pvStructInfo, *pcbStructInfo);
3120
3121 __TRY
3122 {
3123 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3124 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3125 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3126
3127 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3128 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
3129 }
3130 __EXCEPT_PAGE_FAULT
3131 {
3132 SetLastError(STATUS_ACCESS_VIOLATION);
3133 ret = FALSE;
3134 }
3135 __ENDTRY
3136 return ret;
3137 }
3138
3139 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3140 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3141 {
3142 BOOL ret;
3143 DWORD dataLen;
3144
3145 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3146 pvStructInfo, *pcbStructInfo, pcbDecoded);
3147
3148 /* The caller has already checked the tag, no need to check it again.
3149 * Check the outer length is valid:
3150 */
3151 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3152 {
3153 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3154 DWORD innerLen;
3155
3156 pbEncoded += 1 + lenBytes;
3157 cbEncoded -= 1 + lenBytes;
3158 if (dataLen == CMSG_INDEFINITE_LENGTH)
3159 cbEncoded -= 2; /* space for 0 TLV */
3160 /* Check the inner length is valid: */
3161 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3162 {
3163 DWORD decodedLen;
3164
3165 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3166 pvStructInfo, pcbStructInfo, &decodedLen);
3167 if (dataLen == CMSG_INDEFINITE_LENGTH)
3168 {
3169 if (*(pbEncoded + decodedLen) != 0 ||
3170 *(pbEncoded + decodedLen + 1) != 0)
3171 {
3172 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3173 *(pbEncoded + decodedLen),
3174 *(pbEncoded + decodedLen + 1));
3175 SetLastError(CRYPT_E_ASN1_CORRUPT);
3176 ret = FALSE;
3177 }
3178 else
3179 decodedLen += 2;
3180 }
3181 if (ret && pcbDecoded)
3182 {
3183 *pcbDecoded = 1 + lenBytes + decodedLen;
3184 TRACE("decoded %d bytes\n", *pcbDecoded);
3185 }
3186 }
3187 }
3188 return ret;
3189 }
3190
3191 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3192 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3193 DWORD *pcbDecoded)
3194 {
3195 CRYPT_CONTENT_INFO *info = pvStructInfo;
3196 struct AsnDecodeSequenceItem items[] = {
3197 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3198 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3199 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3200 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3201 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3202 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3203 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3204 };
3205 BOOL ret;
3206
3207 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3208 pvStructInfo, *pcbStructInfo, pcbDecoded);
3209
3210 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3211 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3212 pcbDecoded, info ? info->pszObjId : NULL);
3213 return ret;
3214 }
3215
3216 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3217 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3218 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3219 {
3220 BOOL ret = FALSE;
3221
3222 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3223 pDecodePara, pvStructInfo, *pcbStructInfo);
3224
3225 __TRY
3226 {
3227 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3228 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3229 if (ret && pvStructInfo)
3230 {
3231 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3232 pcbStructInfo, *pcbStructInfo);
3233 if (ret)
3234 {
3235 CRYPT_CONTENT_INFO *info;
3236
3237 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3238 pvStructInfo = *(BYTE **)pvStructInfo;
3239 info = pvStructInfo;
3240 info->pszObjId = (LPSTR)((BYTE *)info +
3241 sizeof(CRYPT_CONTENT_INFO));
3242 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3243 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3244 pcbStructInfo, NULL);
3245 }
3246 }
3247 }
3248 __EXCEPT_PAGE_FAULT
3249 {
3250 SetLastError(STATUS_ACCESS_VIOLATION);
3251 }
3252 __ENDTRY
3253 return ret;
3254 }
3255
3256 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3257 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3258 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3259 {
3260 BOOL ret;
3261 struct AsnDecodeSequenceItem items[] = {
3262 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3263 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3264 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3265 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3266 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3267 0 },
3268 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3269 CRYPT_AsnDecodePKCSContentInfoInternal,
3270 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3271 ContentInfo.pszObjId), 0 },
3272 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3273 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3274 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3275 };
3276
3277 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3278 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3279 NULL, NULL);
3280 return ret;
3281 }
3282
3283 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3284 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3285 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3286 {
3287 BOOL ret = TRUE;
3288
3289 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3290 pDecodePara, pvStructInfo, *pcbStructInfo);
3291
3292 __TRY
3293 {
3294 DWORD bytesNeeded;
3295
3296 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3297 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3298 {
3299 if (!pvStructInfo)
3300 *pcbStructInfo = bytesNeeded;
3301 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3302 pvStructInfo, pcbStructInfo, bytesNeeded)))
3303 {
3304 CERT_ALT_NAME_INFO *name;
3305
3306 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3307 pvStructInfo = *(BYTE **)pvStructInfo;
3308 name = pvStructInfo;
3309 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3310 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3311 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3312 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3313 &bytesNeeded, NULL);
3314 }
3315 }
3316 }
3317 __EXCEPT_PAGE_FAULT
3318 {
3319 SetLastError(STATUS_ACCESS_VIOLATION);
3320 ret = FALSE;
3321 }
3322 __ENDTRY
3323 return ret;
3324 }
3325
3326 struct PATH_LEN_CONSTRAINT
3327 {
3328 BOOL fPathLenConstraint;
3329 DWORD dwPathLenConstraint;
3330 };
3331
3332 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3333 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3334 DWORD *pcbDecoded)
3335 {
3336 BOOL ret = TRUE;
3337 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3338
3339 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3340 pvStructInfo, *pcbStructInfo, pcbDecoded);
3341
3342 if (!pvStructInfo)
3343 {
3344 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3345 &size, pcbDecoded);
3346 *pcbStructInfo = bytesNeeded;
3347 }
3348 else if (*pcbStructInfo < bytesNeeded)
3349 {
3350 SetLastError(ERROR_MORE_DATA);
3351 *pcbStructInfo = bytesNeeded;
3352 ret = FALSE;
3353 }
3354 else
3355 {
3356 struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3357
3358 *pcbStructInfo = bytesNeeded;
3359 size = sizeof(constraint->dwPathLenConstraint);
3360 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3361 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3362 if (ret)
3363 constraint->fPathLenConstraint = TRUE;
3364 TRACE("got an int, dwPathLenConstraint is %d\n",
3365 constraint->dwPathLenConstraint);
3366 }
3367 TRACE("returning %d (%08x)\n", ret, GetLastError());
3368 return ret;
3369 }
3370
3371 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3372 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3373 DWORD *pcbDecoded)
3374 {
3375 BOOL ret;
3376 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3377 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3378 offsetof(CERT_NAME_BLOB, pbData) };
3379 struct GenericArray *entries = pvStructInfo;
3380
3381 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3382 pvStructInfo, *pcbStructInfo, pcbDecoded);
3383
3384 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3385 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
3386 entries ? entries->rgItems : NULL);
3387 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3388 return ret;
3389 }
3390
3391 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3392 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3393 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3394 {
3395 BOOL ret;
3396
3397 __TRY
3398 {
3399 struct AsnDecodeSequenceItem items[] = {
3400 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3401 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3402 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3403 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3404 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3405 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3406 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3407 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3408 sizeof(struct GenericArray), TRUE, TRUE,
3409 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3410 };
3411
3412 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3413 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3414 pcbStructInfo, NULL, NULL);
3415 }
3416 __EXCEPT_PAGE_FAULT
3417 {
3418 SetLastError(STATUS_ACCESS_VIOLATION);
3419 ret = FALSE;
3420 }
3421 __ENDTRY
3422 return ret;
3423 }
3424
3425 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3426 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3427 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3428 {
3429 BOOL ret;
3430
3431 __TRY
3432 {
3433 struct AsnDecodeSequenceItem items[] = {
3434 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3435 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3436 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3437 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3438 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3439 };
3440
3441 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3442 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3443 pcbStructInfo, NULL, NULL);
3444 }
3445 __EXCEPT_PAGE_FAULT
3446 {
3447 SetLastError(STATUS_ACCESS_VIOLATION);
3448 ret = FALSE;
3449 }
3450 __ENDTRY
3451 return ret;
3452 }
3453
3454 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
3455 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3456 DWORD *pcbDecoded)
3457 {
3458 struct AsnDecodeSequenceItem items[] = {
3459 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
3460 pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3461 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3462 0 },
3463 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3464 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3465 offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3466 };
3467 BOOL ret;
3468 CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3469
3470 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3471 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3472
3473 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3474 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3475 pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3476 return ret;
3477 }
3478
3479 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
3480 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3481 DWORD *pcbDecoded)
3482 {
3483 BOOL ret;
3484 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3485 CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
3486 offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3487 struct GenericArray *entries = pvStructInfo;
3488
3489 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3490 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3491
3492 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3493 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
3494 entries ? entries->rgItems : NULL);
3495 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3496 return ret;
3497 }
3498
3499 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
3500 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3501 {
3502 struct AsnDecodeSequenceItem items[] = {
3503 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3504 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3505 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3506 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3507 CRYPT_AsnDecodePolicyQualifiers, sizeof(struct GenericArray), TRUE,
3508 TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3509 };
3510 CERT_POLICY_INFO *info = pvStructInfo;
3511 BOOL ret;
3512
3513 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3514 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3515
3516 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3517 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3518 pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
3519 return ret;
3520 }
3521
3522 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
3523 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3524 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3525 {
3526 BOOL ret = FALSE;
3527
3528 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3529 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3530
3531 __TRY
3532 {
3533 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3534 CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
3535 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
3536
3537 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3538 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
3539 }
3540 __EXCEPT_PAGE_FAULT
3541 {
3542 SetLastError(STATUS_ACCESS_VIOLATION);
3543 }
3544 __ENDTRY
3545 return ret;
3546 }
3547
3548 #define RSA1_MAGIC 0x31415352
3549
3550 struct DECODED_RSA_PUB_KEY
3551 {
3552 DWORD pubexp;
3553 CRYPT_INTEGER_BLOB modulus;
3554 };
3555
3556 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3557 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3558 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3559 {
3560 BOOL ret;
3561
3562 __TRY
3563 {
3564 struct AsnDecodeSequenceItem items[] = {
3565 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3566 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3567 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3568 0 },
3569 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3570 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3571 };
3572 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3573 DWORD size = 0;
3574
3575 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3576 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3577 &size, NULL, NULL);
3578 if (ret)
3579 {
3580 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3581 decodedKey->modulus.cbData;
3582
3583 if (!pvStructInfo)
3584 {
3585 *pcbStructInfo = bytesNeeded;
3586 ret = TRUE;
3587 }
3588 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3589 pvStructInfo, pcbStructInfo, bytesNeeded)))
3590 {
3591 BLOBHEADER *hdr;
3592 RSAPUBKEY *rsaPubKey;
3593
3594 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3595 pvStructInfo = *(BYTE **)pvStructInfo;
3596 hdr = pvStructInfo;
3597 hdr->bType = PUBLICKEYBLOB;
3598 hdr->bVersion = CUR_BLOB_VERSION;
3599 hdr->reserved = 0;
3600 hdr->aiKeyAlg = CALG_RSA_KEYX;
3601 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3602 sizeof(BLOBHEADER));
3603 rsaPubKey->magic = RSA1_MAGIC;
3604 rsaPubKey->pubexp = decodedKey->pubexp;
3605 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3606 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3607 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3608 decodedKey->modulus.cbData);
3609 }
3610 LocalFree(decodedKey);
3611 }
3612 }
3613 __EXCEPT_PAGE_FAULT
3614 {
3615 SetLastError(STATUS_ACCESS_VIOLATION);
3616 ret = FALSE;
3617 }
3618 __ENDTRY
3619 return ret;
3620 }
3621
3622 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3623 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3624 DWORD *pcbDecoded)
3625 {
3626 BOOL ret;
3627 DWORD bytesNeeded, dataLen;
3628
3629 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3630 pvStructInfo, *pcbStructInfo, pcbDecoded);
3631
3632 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3633 {
3634 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3635
3636 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3637 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3638 else
3639 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3640 if (pcbDecoded)
3641 *pcbDecoded = 1 + lenBytes + dataLen;
3642 if (!pvStructInfo)
3643 *pcbStructInfo = bytesNeeded;
3644 else if (*pcbStructInfo < bytesNeeded)
3645 {
3646 SetLastError(ERROR_MORE_DATA);
3647 *pcbStructInfo = bytesNeeded;
3648 ret = FALSE;
3649 }
3650 else
3651 {
3652 CRYPT_DATA_BLOB *blob;
3653
3654 *pcbStructInfo = bytesNeeded;
3655 blob = pvStructInfo;
3656 blob->cbData = dataLen;
3657 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3658 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
3659 else
3660 {
3661 assert(blob->pbData);
3662 if (blob->cbData)
3663 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
3664 blob->cbData);
3665 }
3666 }
3667 }
3668 return ret;
3669 }
3670
3671 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
3672 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3673 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3674 {
3675 BOOL ret;
3676
3677 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3678 pDecodePara, pvStructInfo, *pcbStructInfo);
3679
3680 __TRY
3681 {
3682 DWORD bytesNeeded;
3683
3684 if (!cbEncoded)
3685 {
3686 SetLastError(CRYPT_E_ASN1_CORRUPT);
3687 ret = FALSE;
3688 }
3689 else if (pbEncoded[0] != ASN_OCTETSTRING)
3690 {
3691 SetLastError(CRYPT_E_ASN1_BADTAG);
3692 ret = FALSE;
3693 }
3694 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3695 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3696 {
3697 if (!pvStructInfo)
3698 *pcbStructInfo = bytesNeeded;
3699 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3700 pvStructInfo, pcbStructInfo, bytesNeeded)))
3701 {
3702 CRYPT_DATA_BLOB *blob;
3703
3704 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3705 pvStructInfo = *(BYTE **)pvStructInfo;
3706 blob = pvStructInfo;
3707 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3708 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3709 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3710 &bytesNeeded, NULL);
3711 }
3712 }
3713 }
3714 __EXCEPT_PAGE_FAULT
3715 {
3716 SetLastError(STATUS_ACCESS_VIOLATION);
3717 ret = FALSE;
3718 }
3719 __ENDTRY
3720 return ret;
3721 }
3722
3723 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3724 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3725 {
3726 BOOL ret;
3727 DWORD bytesNeeded, dataLen;
3728 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3729
3730 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3731 pvStructInfo, *pcbStructInfo, pcbDecoded);
3732
3733 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3734 {
3735 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3736 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
3737 else
3738 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
3739 if (pcbDecoded)
3740 *pcbDecoded = 1 + lenBytes + dataLen;
3741 if (!pvStructInfo)
3742 *pcbStructInfo = bytesNeeded;
3743 else if (*pcbStructInfo < bytesNeeded)
3744 {
3745 *pcbStructInfo = bytesNeeded;
3746 SetLastError(ERROR_MORE_DATA);
3747 ret = FALSE;
3748 }
3749 else
3750 {
3751 CRYPT_BIT_BLOB *blob;
3752
3753 *pcbStructInfo = bytesNeeded;
3754 blob = pvStructInfo;
3755 blob->cbData = dataLen - 1;
3756 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
3757 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3758 {
3759 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
3760 }
3761 else
3762 {
3763 assert(blob->pbData);
3764 if (blob->cbData)
3765 {
3766 BYTE mask = 0xff << blob->cUnusedBits;
3767
3768 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
3769 blob->cbData);
3770 blob->pbData[blob->cbData - 1] &= mask;
3771 }
3772 }
3773 }
3774 }
3775 return ret;
3776 }
3777
3778 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
3779 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3780 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3781 {
3782 BOOL ret;
3783
3784 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
3785 pDecodePara, pvStructInfo, pcbStructInfo);
3786
3787 __TRY
3788 {
3789 DWORD bytesNeeded;
3790
3791 if (!cbEncoded)
3792 {
3793 SetLastError(CRYPT_E_ASN1_CORRUPT);
3794 ret = FALSE;
3795 }
3796 else if (pbEncoded[0] != ASN_BITSTRING)
3797 {
3798 SetLastError(CRYPT_E_ASN1_BADTAG);
3799 ret = FALSE;
3800 }
3801 else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3802 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3803 {
3804 if (!pvStructInfo)
3805 *pcbStructInfo = bytesNeeded;
3806 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3807 pvStructInfo, pcbStructInfo, bytesNeeded)))
3808 {
3809 CRYPT_BIT_BLOB *blob;
3810
3811 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3812 pvStructInfo = *(BYTE **)pvStructInfo;
3813 blob = pvStructInfo;
3814 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
3815 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3816 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3817 &bytesNeeded, NULL);
3818 }
3819 }
3820 }
3821 __EXCEPT_PAGE_FAULT
3822 {
3823 SetLastError(STATUS_ACCESS_VIOLATION);
3824 ret = FALSE;
3825 }
3826 __ENDTRY
3827 TRACE("returning %d (%08x)\n", ret, GetLastError());
3828 return ret;
3829 }
3830
3831 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3832 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3833 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3834 {
3835 BOOL ret;
3836 BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
3837 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
3838 DWORD size = sizeof(buf);
3839
3840 blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
3841 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, buf,
3842 &size, pcbDecoded);
3843 if (ret)
3844 {
3845 if (!pvStructInfo)
3846 *pcbStructInfo = sizeof(int);
3847 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
3848 {
3849 int val, i;
3850
3851 if (blob->pbData[blob->cbData - 1] & 0x80)
3852 {
3853 /* initialize to a negative value to sign-extend */
3854 val = -1;
3855 }
3856 else
3857 val = 0;
3858 for (i = 0; i < blob->cbData; i++)
3859 {
3860 val <<= 8;
3861 val |= blob->pbData[blob->cbData - i - 1];
3862 }
3863 memcpy(pvStructInfo, &val, sizeof(int));
3864 }
3865 }
3866 else if (GetLastError() == ERROR_MORE_DATA)
3867 SetLastError(CRYPT_E_ASN1_LARGE);
3868 return ret;
3869 }
3870
3871 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
3872 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3873 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3874 {
3875 BOOL ret;
3876
3877 __TRY
3878 {
3879 DWORD bytesNeeded;
3880
3881 if (!cbEncoded)
3882 {
3883 SetLastError(CRYPT_E_ASN1_EOD);
3884 ret = FALSE;
3885 }
3886 else if (pbEncoded[0] != ASN_INTEGER)
3887 {
3888 SetLastError(CRYPT_E_ASN1_BADTAG);
3889 ret = FALSE;
3890 }
3891 else
3892 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3893 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3894 if (ret)
3895 {
3896 if (!pvStructInfo)
3897 *pcbStructInfo = bytesNeeded;
3898 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3899 pvStructInfo, pcbStructInfo, bytesNeeded)))
3900 {
3901 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3902 pvStructInfo = *(BYTE **)pvStructInfo;
3903 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3904 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3905 &bytesNeeded, NULL);
3906 }
3907 }
3908 }
3909 __EXCEPT_PAGE_FAULT
3910 {
3911 SetLastError(STATUS_ACCESS_VIOLATION);
3912 ret = FALSE;
3913 }
3914 __ENDTRY
3915 return ret;
3916 }
3917
3918 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
3919 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3920 DWORD *pcbDecoded)
3921 {
3922 BOOL ret;
3923 DWORD bytesNeeded, dataLen;
3924
3925 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3926 {
3927 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3928
3929 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3930 if (pcbDecoded)
3931 *pcbDecoded = 1 + lenBytes + dataLen;
3932 if (!pvStructInfo)
3933 *pcbStructInfo = bytesNeeded;
3934 else if (*pcbStructInfo < bytesNeeded)
3935 {
3936 *pcbStructInfo = bytesNeeded;
3937 SetLastError(ERROR_MORE_DATA);
3938 ret = FALSE;
3939 }
3940 else
3941 {
3942 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
3943
3944 *pcbStructInfo = bytesNeeded;
3945 blob->cbData = dataLen;
3946 assert(blob->pbData);
3947 if (blob->cbData)
3948 {
3949 DWORD i;
3950
3951 for (i = 0; i < blob->cbData; i++)
3952 {
3953 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3954 dataLen - i - 1);
3955 }
3956 }
3957 }
3958 }
3959 return ret;
3960 }
3961
3962 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
3963 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3964 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3965 {
3966 BOOL ret;
3967
3968 __TRY
3969 {
3970 DWORD bytesNeeded;
3971
3972 if (pbEncoded[0] != ASN_INTEGER)
3973 {
3974 SetLastError(CRYPT_E_ASN1_BADTAG);
3975 ret = FALSE;
3976 }
3977 else
3978 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3979 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3980 if (ret)
3981 {
3982 if (!pvStructInfo)
3983 *pcbStructInfo = bytesNeeded;
3984 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3985 pvStructInfo, pcbStructInfo, bytesNeeded)))
3986 {
3987 CRYPT_INTEGER_BLOB *blob;
3988
3989 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3990 pvStructInfo = *(BYTE **)pvStructInfo;
3991 blob = pvStructInfo;
3992 blob->pbData = (BYTE *)pvStructInfo +
3993 sizeof(CRYPT_INTEGER_BLOB);
3994 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3995 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
3996 &bytesNeeded, NULL);
3997 }
3998 }
3999 }
4000 __EXCEPT_PAGE_FAULT
4001 {
4002 SetLastError(STATUS_ACCESS_VIOLATION);
4003 ret = FALSE;
4004 }
4005 __ENDTRY
4006 return ret;
4007 }
4008
4009 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
4010 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4011 DWORD *pcbDecoded)
4012 {
4013 BOOL ret;
4014
4015 if (pbEncoded[0] == ASN_INTEGER)
4016 {
4017 DWORD bytesNeeded, dataLen;
4018
4019 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4020 {
4021 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4022
4023 if (pcbDecoded)
4024 *pcbDecoded = 1 + lenBytes + dataLen;
4025 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4026 if (!pvStructInfo)
4027 *pcbStructInfo = bytesNeeded;
4028 else if (*pcbStructInfo < bytesNeeded)
4029 {
4030 *pcbStructInfo = bytesNeeded;
4031 SetLastError(ERROR_MORE_DATA);
4032 ret = FALSE;
4033 }
4034 else
4035 {
4036 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4037
4038 *pcbStructInfo = bytesNeeded;
4039 blob->cbData = dataLen;
4040 assert(blob->pbData);
4041 /* remove leading zero byte if it exists */
4042 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
4043 {
4044 blob->cbData--;
4045 blob->pbData++;
4046 }
4047 if (blob->cbData)
4048 {
4049 DWORD i;
4050
4051 for (i = 0; i < blob->cbData; i++)
4052 {
4053 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4054 dataLen - i - 1);
4055 }
4056 }
4057 }
4058 }
4059 }
4060 else
4061 {
4062 SetLastError(CRYPT_E_ASN1_BADTAG);
4063 ret = FALSE;
4064 }
4065 return ret;
4066 }
4067
4068 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
4069 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4070 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4071 {
4072 BOOL ret;
4073
4074 __TRY
4075 {
4076 DWORD bytesNeeded;
4077
4078 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
4079 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4080 {
4081 if (!pvStructInfo)
4082 *pcbStructInfo = bytesNeeded;
4083 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4084 pvStructInfo, pcbStructInfo, bytesNeeded)))
4085 {
4086 CRYPT_INTEGER_BLOB *blob;
4087
4088 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4089 pvStructInfo = *(BYTE **)pvStructInfo;
4090 blob = pvStructInfo;
4091 blob->pbData = (BYTE *)pvStructInfo +
4092 sizeof(CRYPT_INTEGER_BLOB);
4093 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
4094 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4095 &bytesNeeded, NULL);
4096 }
4097 }
4098 }
4099 __EXCEPT_PAGE_FAULT
4100 {
4101 SetLastError(STATUS_ACCESS_VIOLATION);
4102 ret = FALSE;
4103 }
4104 __ENDTRY
4105 return ret;
4106 }
4107
4108 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
4109 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4110 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4111 {
4112 BOOL ret;
4113
4114 if (!pvStructInfo)
4115 {
4116 *pcbStructInfo = sizeof(int);
4117 return TRUE;
4118 }
4119 __TRY
4120 {
4121 if (pbEncoded[0] == ASN_ENUMERATED)
4122 {
4123 unsigned int val = 0, i;
4124
4125 if (cbEncoded <= 1)
4126 {
4127 SetLastError(CRYPT_E_ASN1_EOD);
4128 ret = FALSE;
4129 }
4130 else if (pbEncoded[1] == 0)
4131 {
4132 SetLastError(CRYPT_E_ASN1_CORRUPT);
4133 ret = FALSE;
4134 }
4135 else
4136 {
4137 /* A little strange looking, but we have to accept a sign byte:
4138 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4139 * assuming a small length is okay here, it has to be in short
4140 * form.
4141 */
4142 if (pbEncoded[1] > sizeof(unsigned int) + 1)
4143 {
4144 SetLastError(CRYPT_E_ASN1_LARGE);
4145 return FALSE;
4146 }
4147 for (i = 0; i < pbEncoded[1]; i++)
4148 {
4149 val <<= 8;
4150 val |= pbEncoded[2 + i];
4151 }
4152 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4153 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
4154 {
4155 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4156 pvStructInfo = *(BYTE **)pvStructInfo;
4157 memcpy(pvStructInfo, &val, sizeof(unsigned int));
4158 }
4159 }
4160 }
4161 else
4162 {
4163 SetLastError(CRYPT_E_ASN1_BADTAG);
4164 ret = FALSE;
4165 }
4166 }
4167 __EXCEPT_PAGE_FAULT
4168 {
4169 SetLastError(STATUS_ACCESS_VIOLATION);
4170 ret = FALSE;
4171 }
4172 __ENDTRY
4173 return ret;
4174 }
4175
4176 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4177 * if it fails.
4178 */
4179 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4180 do { \
4181 BYTE i; \
4182 \
4183 (word) = 0; \
4184 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4185 { \
4186 if (!isdigit(*(pbEncoded))) \
4187 { \
4188 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4189 ret = FALSE; \
4190 } \
4191 else \
4192 { \
4193 (word) *= 10; \
4194 (word) += *(pbEncoded)++ - '0'; \
4195 } \
4196 } \
4197 } while (0)
4198
4199 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
4200 SYSTEMTIME *sysTime)
4201 {
4202 BOOL ret = TRUE;
4203
4204 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
4205 {
4206 WORD hours, minutes = 0;
4207 BYTE sign = *pbEncoded++;
4208
4209 len--;
4210 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
4211 if (ret && hours >= 24)
4212 {
4213 SetLastError(CRYPT_E_ASN1_CORRUPT);
4214 ret = FALSE;
4215 }
4216 else if (len >= 2)
4217 {
4218 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
4219 if (ret && minutes >= 60)
4220 {
4221 SetLastError(CRYPT_E_ASN1_CORRUPT);
4222 ret = FALSE;
4223 }
4224 }
4225 if (ret)
4226 {
4227 if (sign == '+')
4228 {
4229 sysTime->wHour += hours;
4230 sysTime->wMinute += minutes;
4231 }
4232 else
4233 {
4234 if (hours > sysTime->wHour)
4235 {
4236 sysTime->wDay--;
4237 sysTime->wHour = 24 - (hours - sysTime->wHour);
4238 }
4239 else
4240 sysTime->wHour -= hours;
4241 if (minutes > sysTime->wMinute)
4242 {
4243 sysTime->wHour--;
4244 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
4245 }
4246 else
4247 sysTime->wMinute -= minutes;
4248 }
4249 }
4250 }
4251 return ret;
4252 }
4253
4254 #define MIN_ENCODED_TIME_LENGTH 10
4255
4256 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
4257 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4258 DWORD *pcbDecoded)
4259 {
4260 BOOL ret = FALSE;
4261
4262 if (pbEncoded[0] == ASN_UTCTIME)
4263 {
4264 if (cbEncoded <= 1)
4265 SetLastError(CRYPT_E_ASN1_EOD);
4266 else if (pbEncoded[1] > 0x7f)
4267 {
4268 /* long-form date strings really can't be valid */
4269 SetLastError(CRYPT_E_ASN1_CORRUPT);
4270 }
4271 else
4272 {
4273 SYSTEMTIME sysTime = { 0 };
4274 BYTE len = pbEncoded[1];
4275
4276 if (len < MIN_ENCODED_TIME_LENGTH)
4277 SetLastError(CRYPT_E_ASN1_CORRUPT);
4278 else
4279 {
4280 ret = TRUE;
4281 if (pcbDecoded)
4282 *pcbDecoded = 2 + len;
4283 pbEncoded += 2;
4284 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
4285 if (sysTime.wYear >= 50)
4286 sysTime.wYear += 1900;
4287 else
4288 sysTime.wYear += 2000;
4289 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4290 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4291 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4292 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
4293 if (ret && len > 0)
4294 {
4295 if (len >= 2 && isdigit(*pbEncoded) &&
4296 isdigit(*(pbEncoded + 1)))
4297 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4298 sysTime.wSecond);
4299 else if (isdigit(*pbEncoded))
4300 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
4301 sysTime.wSecond);
4302 if (ret)
4303 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4304 &sysTime);
4305 }
4306 if (ret)
4307 {
4308 if (!pvStructInfo)
4309 *pcbStructInfo = sizeof(FILETIME);
4310 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4311 sizeof(FILETIME))))
4312 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4313 }
4314 }
4315 }
4316 }
4317 else
4318 SetLastError(CRYPT_E_ASN1_BADTAG);
4319 return ret;
4320 }
4321
4322 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
4323 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4324 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4325 {
4326 BOOL ret = FALSE;
4327
4328 __TRY
4329 {
4330 DWORD bytesNeeded;
4331
4332 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4333 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4334 if (ret)
4335 {
4336 if (!pvStructInfo)
4337 *pcbStructInfo = bytesNeeded;
4338 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
4339 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
4340 {
4341 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4342 pvStructInfo = *(BYTE **)pvStructInfo;
4343 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4344 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4345 &bytesNeeded, NULL);
4346 }
4347 }
4348 }
4349 __EXCEPT_PAGE_FAULT
4350 {
4351 SetLastError(STATUS_ACCESS_VIOLATION);
4352 }
4353 __ENDTRY
4354 return ret;
4355 }
4356
4357 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
4358 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4359 DWORD *pcbDecoded)
4360 {
4361 BOOL ret = FALSE;
4362
4363 if (pbEncoded[0] == ASN_GENERALTIME)
4364 {
4365 if (cbEncoded <= 1)
4366 SetLastError(CRYPT_E_ASN1_EOD);
4367 else if (pbEncoded[1] > 0x7f)
4368 {
4369 /* long-form date strings really can't be valid */
4370 SetLastError(CRYPT_E_ASN1_CORRUPT);
4371 }
4372 else
4373 {
4374 BYTE len = pbEncoded[1];
4375
4376 if (len < MIN_ENCODED_TIME_LENGTH)
4377 SetLastError(CRYPT_E_ASN1_CORRUPT);
4378 else
4379 {
4380 SYSTEMTIME sysTime = { 0 };
4381
4382 ret = TRUE;
4383 if (pcbDecoded)
4384 *pcbDecoded = 2 + len;
4385 pbEncoded += 2;
4386 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
4387 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4388 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4389 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4390 if (ret && len > 0)
4391 {
4392 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4393 sysTime.wMinute);
4394 if (ret && len > 0)
4395 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4396 sysTime.wSecond);
4397 if (ret && len > 0 && (*pbEncoded == '.' ||
4398 *pbEncoded == ','))
4399 {
4400 BYTE digits;
4401
4402 pbEncoded++;
4403 len--;
4404 /* workaround macro weirdness */
4405 digits = min(len, 3);
4406 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
4407 sysTime.wMilliseconds);
4408 }
4409 if (ret)
4410 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4411 &sysTime);
4412 }
4413 if (ret)
4414 {
4415 if (!pvStructInfo)
4416 *pcbStructInfo = sizeof(FILETIME);
4417 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4418 sizeof(FILETIME))))
4419 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4420 }
4421 }
4422 }
4423 }
4424 else
4425 SetLastError(CRYPT_E_ASN1_BADTAG);
4426 return ret;
4427 }
4428
4429 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
4430 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4431 DWORD *pcbDecoded)
4432 {
4433 BOOL ret;
4434 InternalDecodeFunc decode = NULL;
4435
4436 if (pbEncoded[0] == ASN_UTCTIME)
4437 decode = CRYPT_AsnDecodeUtcTimeInternal;
4438 else if (pbEncoded[0] == ASN_GENERALTIME)
4439 decode = CRYPT_AsnDecodeGeneralizedTime;
4440 if (decode)
4441 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
4442 pcbStructInfo, pcbDecoded);
4443 else
4444 {
4445 SetLastError(CRYPT_E_ASN1_BADTAG);
4446 ret = FALSE;
4447 }
4448 return ret;
4449 }
4450
4451 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
4452 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4453 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4454 {
4455 BOOL ret;
4456
4457 __TRY
4458 {
4459 DWORD bytesNeeded;
4460
4461 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4462 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4463 if (ret)
4464 {
4465 if (!pvStructInfo)
4466 *pcbStructInfo = bytesNeeded;
4467 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4468 pvStructInfo, pcbStructInfo, bytesNeeded)))
4469 {
4470 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4471 pvStructInfo = *(BYTE **)pvStructInfo;
4472 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4473 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4474 &bytesNeeded, NULL);
4475 }
4476 }
4477 }
4478 __EXCEPT_PAGE_FAULT
4479 {
4480 SetLastError(STATUS_ACCESS_VIOLATION);
4481 ret = FALSE;
4482 }
4483 __ENDTRY
4484 return ret;
4485 }
4486
4487 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
4488 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4489 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4490 {
4491 BOOL ret = TRUE;
4492
4493 __TRY
4494 {
4495 if (pbEncoded[0] == ASN_SEQUENCEOF)
4496 {
4497 DWORD bytesNeeded, dataLen, remainingLen, cValue;
4498
4499 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4500 {
4501 BYTE lenBytes;
4502 const BYTE *ptr;
4503
4504 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4505 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
4506 cValue = 0;
4507 ptr = pbEncoded + 1 + lenBytes;
4508 remainingLen = dataLen;
4509 while (ret && remainingLen)
4510 {
4511 DWORD nextLen;
4512
4513 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4514 if (ret)
4515 {
4516 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4517
4518 remainingLen -= 1 + nextLenBytes + nextLen;
4519 ptr += 1 + nextLenBytes + nextLen;
4520 bytesNeeded += sizeof(CRYPT_DER_BLOB);
4521 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
4522 bytesNeeded += 1 + nextLenBytes + nextLen;
4523 cValue++;
4524 }
4525 }
4526 if (ret)
4527 {
4528 CRYPT_SEQUENCE_OF_ANY *seq;
4529 BYTE *nextPtr;
4530 DWORD i;
4531
4532 if (!pvStructInfo)
4533 *pcbStructInfo = bytesNeeded;
4534 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4535 pvStructInfo, pcbStructInfo, bytesNeeded)))
4536 {
4537 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4538 pvStructInfo = *(BYTE **)pvStructInfo;
4539 seq = pvStructInfo;
4540 seq->cValue = cValue;
4541 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
4542 sizeof(*seq));
4543 nextPtr = (BYTE *)seq->rgValue +
4544 cValue * sizeof(CRYPT_DER_BLOB);
4545 ptr = pbEncoded + 1 + lenBytes;
4546 remainingLen = dataLen;
4547 i = 0;
4548 while (ret && remainingLen)
4549 {
4550 DWORD nextLen;
4551
4552 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4553 if (ret)
4554 {
4555 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4556
4557 seq->rgValue[i].cbData = 1 + nextLenBytes +
4558 nextLen;
4559 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4560 seq->rgValue[i].pbData = (BYTE *)ptr;
4561 else
4562 {
4563 seq->rgValue[i].pbData = nextPtr;
4564 memcpy(nextPtr, ptr, 1 + nextLenBytes +
4565 nextLen);
4566 nextPtr += 1 + nextLenBytes + nextLen;
4567 }
4568 remainingLen -= 1 + nextLenBytes + nextLen;
4569 ptr += 1 + nextLenBytes + nextLen;
4570 i++;
4571 }
4572 }
4573 }
4574 }
4575 }
4576 }
4577 else
4578 {
4579 SetLastError(CRYPT_E_ASN1_BADTAG);
4580 ret = FALSE;
4581 }
4582 }
4583 __EXCEPT_PAGE_FAULT
4584 {
4585 SetLastError(STATUS_ACCESS_VIOLATION);
4586 ret = FALSE;
4587 }
4588 __ENDTRY
4589 return ret;
4590 }
4591
4592 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
4593 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4594 DWORD *pcbDecoded)
4595 {
4596 BOOL ret;
4597
4598 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
4599 {
4600 DWORD bytesNeeded, dataLen;
4601
4602 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4603 {
4604 struct AsnArrayDescriptor arrayDesc = {
4605 ASN_CONTEXT | ASN_CONSTRUCTOR | 0, CRYPT_AsnDecodeAltNameEntry,
4606 sizeof(CERT_ALT_NAME_ENTRY), TRUE,
4607 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
4608 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4609 DWORD nameLen;
4610
4611 if (dataLen)
4612 {
4613 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4614 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4615 0, NULL, NULL, &nameLen, NULL, NULL);
4616 /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
4617 * as the sizeof(struct GenericArray), so don't include it in the
4618 * total bytes needed.
4619 */
4620 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
4621 sizeof(CERT_ALT_NAME_INFO);
4622 }
4623 else
4624 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
4625 if (pcbDecoded)
4626 *pcbDecoded = 1 + lenBytes + dataLen;
4627 if (!pvStructInfo)
4628 *pcbStructInfo = bytesNeeded;
4629 else if (*pcbStructInfo < bytesNeeded)
4630 {
4631 *pcbStructInfo = bytesNeeded;
4632 SetLastError(ERROR_MORE_DATA);
4633 ret = FALSE;
4634 }
4635 else
4636 {
4637 CRL_DIST_POINT_NAME *name = pvStructInfo;
4638
4639 *pcbStructInfo = bytesNeeded;
4640 if (dataLen)
4641 {
4642 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
4643 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4644 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4645 0, NULL, &name->u.FullName, &nameLen, NULL,
4646 name->u.FullName.rgAltEntry);
4647 }
4648 else
4649 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
4650 }
4651 }
4652 }
4653 else
4654 {
4655 SetLastError(CRYPT_E_ASN1_BADTAG);
4656 ret = FALSE;
4657 }
4658 return ret;
4659 }
4660
4661 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
4662 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4663 {
4664 struct AsnDecodeSequenceItem items[] = {
4665 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
4666 DistPointName), CRYPT_AsnDecodeDistPointName,
4667 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
4668 DistPointName.u.FullName.rgAltEntry), 0 },
4669 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
4670 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
4671 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
4672 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
4673 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
4674 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
4675 };
4676 CRL_DIST_POINT *point = pvStructInfo;
4677 BOOL ret;
4678
4679 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4680 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4681 pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
4682 return ret;
4683 }
4684
4685 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
4686 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4687 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4688 {
4689 BOOL ret;
4690
4691 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4692 pDecodePara, pvStructInfo, *pcbStructInfo);
4693
4694 __TRY
4695 {
4696 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4697 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
4698 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
4699
4700 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4701 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4702 }
4703 __EXCEPT_PAGE_FAULT
4704 {
4705 SetLastError(STATUS_ACCESS_VIOLATION);
4706 ret = FALSE;
4707 }
4708 __ENDTRY
4709 return ret;
4710 }
4711
4712 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
4713 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4714 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4715 {
4716 BOOL ret;
4717
4718 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4719 pDecodePara, pvStructInfo, *pcbStructInfo);
4720
4721 __TRY
4722 {
4723 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4724 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
4725
4726 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4727 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4728 }
4729 __EXCEPT_PAGE_FAULT
4730 {
4731 SetLastError(STATUS_ACCESS_VIOLATION);
4732 ret = FALSE;
4733 }
4734 __ENDTRY
4735 return ret;
4736 }
4737
4738 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
4739 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4740 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4741 {
4742 BOOL ret;
4743
4744 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4745 pDecodePara, pvStructInfo, *pcbStructInfo);
4746
4747 __TRY
4748 {
4749 struct AsnDecodeSequenceItem items[] = {
4750 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
4751 DistPointName), CRYPT_AsnDecodeDistPointName,
4752 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
4753 offsetof(CRL_ISSUING_DIST_POINT,
4754 DistPointName.u.FullName.rgAltEntry), 0 },
4755 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
4756 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4757 FALSE, 0 },
4758 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
4759 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4760 FALSE, 0 },
4761 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
4762 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
4763 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
4764 OnlySomeReasonFlags.pbData), 0 },
4765 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
4766 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
4767 };
4768
4769 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4770 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4771 pcbStructInfo, NULL, NULL);
4772 }
4773 __EXCEPT_PAGE_FAULT
4774 {
4775 SetLastError(STATUS_ACCESS_VIOLATION);
4776 ret = FALSE;
4777 }
4778 __ENDTRY
4779 return ret;
4780 }
4781
4782 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
4783 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4784 DWORD *pcbDecoded)
4785 {
4786 BOOL ret = FALSE;
4787
4788 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4789 pvStructInfo, *pcbStructInfo, pcbDecoded);
4790
4791 if (!cbEncoded)
4792 {
4793 SetLastError(CRYPT_E_ASN1_EOD);
4794 return FALSE;
4795 }
4796 if (pbEncoded[0] != (ASN_CONTEXT | 1))
4797 {
4798 SetLastError(CRYPT_E_ASN1_BADTAG);
4799 return FALSE;
4800 }
4801 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4802 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
4803 pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
4804 pcbDecoded);
4805 if (ret && pvStructInfo)
4806 *(BOOL *)pvStructInfo = TRUE;
4807 TRACE("returning %d\n", ret);
4808 return ret;
4809 }
4810
4811 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
4812 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4813 DWORD *pcbDecoded)
4814 {
4815 BOOL ret;
4816 struct AsnDecodeSequenceItem items[] = {
4817 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
4818 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
4819 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
4820 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
4821 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
4822 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
4823 CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
4824 0 },
4825 };
4826 CERT_GENERAL_SUBTREE *subtree = pvStructInfo;
4827
4828 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4829 pvStructInfo, *pcbStructInfo, pcbDecoded);
4830
4831 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4832 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4833 pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
4834 if (pcbDecoded)
4835 {
4836 TRACE("%d\n", *pcbDecoded);
4837 if (*pcbDecoded < cbEncoded)
4838 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
4839 *(pbEncoded + *pcbDecoded + 1));
4840 }
4841 TRACE("returning %d\n", ret);
4842 return ret;
4843 }
4844
4845 static BOOL CRYPT_AsnDecodeSubtreeArray(const BYTE *pbEncoded,
4846 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4847 DWORD *pcbDecoded)
4848 {
4849 BOOL ret = TRUE;
4850 struct AsnArrayDescriptor arrayDesc = { 0,
4851 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
4852 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
4853 struct GenericArray *array = pvStructInfo;
4854
4855 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4856 pvStructInfo, *pcbStructInfo, pcbDecoded);
4857
4858 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4859 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4860 array ? array->rgItems : NULL);
4861 return ret;
4862 }
4863
4864
4865 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
4866 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4867 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4868 {
4869 BOOL ret = FALSE;
4870
4871 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4872 pDecodePara, pvStructInfo, *pcbStructInfo);
4873
4874 __TRY
4875 {
4876 struct AsnDecodeSequenceItem items[] = {
4877 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4878 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
4879 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4880 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
4881 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
4882 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4883 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4884 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
4885 };
4886
4887 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4888 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4889 pcbStructInfo, NULL, NULL);
4890 }
4891 __EXCEPT_PAGE_FAULT
4892 {
4893 SetLastError(STATUS_ACCESS_VIOLATION);
4894 }
4895 __ENDTRY
4896 return ret;
4897 }
4898
4899 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
4900 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4901 DWORD *pcbDecoded)
4902 {
4903 BOOL ret;
4904 struct AsnDecodeSequenceItem items[] = {
4905 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
4906 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
4907 Issuer.pbData) },
4908 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
4909 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
4910 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
4911 };
4912 CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;
4913
4914 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4915 pvStructInfo, *pcbStructInfo, pcbDecoded);
4916
4917 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4918 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4919 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
4920 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
4921 {
4922 SetLastError(CRYPT_E_ASN1_CORRUPT);
4923 ret = FALSE;
4924 }
4925 TRACE("returning %d\n", ret);
4926 return ret;
4927 }
4928
4929 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
4930 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4931 DWORD *pcbDecoded)
4932 {
4933 CMSG_SIGNER_INFO *info = pvStructInfo;
4934 struct AsnDecodeSequenceItem items[] = {
4935 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
4936 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4937 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
4938 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
4939 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
4940 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
4941 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4942 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
4943 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4944 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
4945 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4946 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
4947 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
4948 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4949 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
4950 HashEncryptionAlgorithm.pszObjId), 0 },
4951 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
4952 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
4953 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
4954 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4955 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
4956 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4957 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
4958 };
4959 BOOL ret;
4960
4961 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4962 pvStructInfo, *pcbStructInfo);
4963
4964 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4965 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4966 pcbDecoded, info ? info->Issuer.pbData : NULL);
4967 return ret;
4968 }
4969
4970 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
4971 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4972 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4973 {
4974 BOOL ret = FALSE;
4975
4976 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4977 pDecodePara, pvStructInfo, *pcbStructInfo);
4978
4979 __TRY
4980 {
4981 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
4982 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
4983 if (ret && pvStructInfo)
4984 {
4985 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
4986 pcbStructInfo, *pcbStructInfo);
4987 if (ret)
4988 {
4989 CMSG_SIGNER_INFO *info;
4990
4991 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4992 pvStructInfo = *(BYTE **)pvStructInfo;
4993 info = pvStructInfo;
4994 info->Issuer.pbData = ((BYTE *)info +
4995 sizeof(CMSG_SIGNER_INFO));
4996 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
4997 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4998 pcbStructInfo, NULL);
4999 }
5000 }
5001 }
5002 __EXCEPT_PAGE_FAULT
5003 {
5004 SetLastError(STATUS_ACCESS_VIOLATION);
5005 }
5006 __ENDTRY
5007 TRACE("returning %d\n", ret);
5008 return ret;
5009 }
5010
5011 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
5012 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5013 DWORD *pcbDecoded)
5014 {
5015 CERT_ID *id = pvStructInfo;
5016 BOOL ret = FALSE;
5017
5018 if (*pbEncoded == ASN_SEQUENCEOF)
5019 {
5020 ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
5021 id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
5022 if (ret)
5023 {
5024 if (id)
5025 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5026 if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
5027 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5028 sizeof(CERT_ISSUER_SERIAL_NUMBER);
5029 else
5030 *pcbStructInfo = sizeof(CERT_ID);
5031 }
5032 }
5033 else if (*pbEncoded == (ASN_CONTEXT | 0))
5034 {
5035 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
5036 id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
5037 if (ret)
5038 {
5039 if (id)
5040 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5041 if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
5042 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5043 sizeof(CRYPT_DATA_BLOB);
5044 else
5045 *pcbStructInfo = sizeof(CERT_ID);
5046 }
5047 }
5048 else
5049 SetLastError(CRYPT_E_ASN1_BADTAG);
5050 return ret;
5051 }
5052
5053 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
5054 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5055 DWORD *pcbDecoded)
5056 {
5057 CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
5058 struct AsnDecodeSequenceItem items[] = {
5059 { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
5060 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5061 { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
5062 CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
5063 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
5064 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
5065 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5066 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5067 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5068 offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
5069 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5070 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5071 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
5072 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5073 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
5074 HashEncryptionAlgorithm.pszObjId), 0 },
5075 { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
5076 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5077 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
5078 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5079 offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
5080 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5081 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5082 };
5083 BOOL ret;
5084
5085 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5086 pvStructInfo, *pcbStructInfo);
5087
5088 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5089 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5090 pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
5091 return ret;
5092 }
5093
5094 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
5095 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5096 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5097 {
5098 BOOL ret = FALSE;
5099
5100 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5101 pDecodePara, pvStructInfo, *pcbStructInfo);
5102
5103 __TRY
5104 {
5105 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
5106 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5107 if (ret && pvStructInfo)
5108 {
5109 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5110 pcbStructInfo, *pcbStructInfo);
5111 if (ret)
5112 {
5113 CMSG_CMS_SIGNER_INFO *info;
5114
5115 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5116 pvStructInfo = *(BYTE **)pvStructInfo;
5117 info = pvStructInfo;
5118 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
5119 sizeof(CMSG_CMS_SIGNER_INFO));
5120 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
5121 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5122 pcbStructInfo, NULL);
5123 }
5124 }
5125 }
5126 __EXCEPT_PAGE_FAULT
5127 {
5128 SetLastError(STATUS_ACCESS_VIOLATION);
5129 }
5130 __ENDTRY
5131 TRACE("returning %d\n", ret);
5132 return ret;
5133 }
5134
5135 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
5136 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5137 {
5138 BOOL ret;
5139 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5140 CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
5141 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
5142 struct GenericArray *array = pvStructInfo;
5143
5144 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5145 pvStructInfo, *pcbStructInfo, pcbDecoded);
5146
5147 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
5148 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
5149 array ? array->rgItems : NULL);
5150 return ret;
5151 }
5152
5153 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5154 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5155 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
5156 {
5157 BOOL ret = FALSE;
5158 struct AsnDecodeSequenceItem items[] = {
5159 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
5160 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5161 /* Placeholder for the hash algorithms - redundant with those in the
5162 * signers, so just ignore them.
5163 */
5164 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5165 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
5166 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
5167 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
5168 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5169 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
5170 CRYPT_DecodeDERArray, sizeof(struct GenericArray), TRUE, TRUE,
5171 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
5172 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5173 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_DecodeDERArray,
5174 sizeof(struct GenericArray), TRUE, TRUE,
5175 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
5176 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5177 CRYPT_DecodeSignerArray, sizeof(struct GenericArray), TRUE, TRUE,
5178 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
5179 };
5180
5181 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5182 pDecodePara, signedInfo, *pcbSignedInfo);
5183
5184 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5185 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
5186 NULL, NULL);
5187 TRACE("returning %d\n", ret);
5188 return ret;
5189 }
5190
5191 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
5192 LPCSTR lpszStructType)
5193 {
5194 CryptDecodeObjectExFunc decodeFunc = NULL;
5195
5196 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
5197 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
5198 {
5199 SetLastError(ERROR_FILE_NOT_FOUND);
5200 return NULL;
5201 }
5202 if (!HIWORD(lpszStructType))
5203 {
5204 switch (LOWORD(lpszStructType))
5205 {
5206 case LOWORD(X509_CERT):
5207 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
5208 break;
5209 case LOWORD(X509_CERT_TO_BE_SIGNED):
5210 decodeFunc = CRYPT_AsnDecodeCert;
5211 break;
5212 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
5213 decodeFunc = CRYPT_AsnDecodeCRL;
5214 break;
5215 case LOWORD(X509_EXTENSIONS):
5216 decodeFunc = CRYPT_AsnDecodeExtensions;
5217 break;
5218 case LOWORD(X509_NAME_VALUE):
5219 decodeFunc = CRYPT_AsnDecodeNameValue;
5220 break;
5221 case LOWORD(X509_NAME):
5222 decodeFunc = CRYPT_AsnDecodeName;
5223 break;
5224 case LOWORD(X509_PUBLIC_KEY_INFO):
5225 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
5226 break;
5227 case LOWORD(X509_AUTHORITY_KEY_ID):
5228 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5229 break;
5230 case LOWORD(X509_ALTERNATE_NAME):
5231 decodeFunc = CRYPT_AsnDecodeAltName;
5232 break;
5233 case LOWORD(X509_BASIC_CONSTRAINTS):
5234 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5235 break;
5236 case LOWORD(X509_BASIC_CONSTRAINTS2):
5237 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5238 break;
5239 case LOWORD(X509_CERT_POLICIES):
5240 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5241 break;
5242 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
5243 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
5244 break;
5245 case LOWORD(X509_UNICODE_NAME):
5246 decodeFunc = CRYPT_AsnDecodeUnicodeName;
5247 break;
5248 case LOWORD(PKCS_ATTRIBUTE):
5249 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
5250 break;
5251 case LOWORD(X509_UNICODE_NAME_VALUE):
5252 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
5253 break;
5254 case LOWORD(X509_OCTET_STRING):
5255 decodeFunc = CRYPT_AsnDecodeOctets;
5256 break;
5257 case LOWORD(X509_BITS):
5258 case LOWORD(X509_KEY_USAGE):
5259 decodeFunc = CRYPT_AsnDecodeBits;
5260 break;
5261 case LOWORD(X509_INTEGER):
5262 decodeFunc = CRYPT_AsnDecodeInt;
5263 break;
5264 case LOWORD(X509_MULTI_BYTE_INTEGER):
5265 decodeFunc = CRYPT_AsnDecodeInteger;
5266 break;
5267 case LOWORD(X509_MULTI_BYTE_UINT):
5268 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
5269 break;
5270 case LOWORD(X509_ENUMERATED):
5271 decodeFunc = CRYPT_AsnDecodeEnumerated;
5272 break;
5273 case LOWORD(X509_CHOICE_OF_TIME):
5274 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
5275 break;
5276 case LOWORD(X509_AUTHORITY_KEY_ID2):
5277 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5278 break;
5279 case LOWORD(X509_AUTHORITY_INFO_ACCESS):
5280 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5281 break;
5282 case LOWORD(PKCS_CONTENT_INFO):
5283 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
5284 break;
5285 case LOWORD(X509_SEQUENCE_OF_ANY):
5286 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
5287 break;
5288 case LOWORD(PKCS_UTC_TIME):
5289 decodeFunc = CRYPT_AsnDecodeUtcTime;
5290 break;
5291 case LOWORD(X509_CRL_DIST_POINTS):
5292 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5293 break;
5294 case LOWORD(X509_ENHANCED_KEY_USAGE):
5295 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5296 break;
5297 case LOWORD(PKCS_CTL):
5298 decodeFunc = CRYPT_AsnDecodeCTL;
5299 break;
5300 case LOWORD(PKCS_SMIME_CAPABILITIES):
5301 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5302 break;
5303 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
5304 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5305 break;
5306 case LOWORD(PKCS_ATTRIBUTES):
5307 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
5308 break;
5309 case LOWORD(X509_ISSUING_DIST_POINT):
5310 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5311 break;
5312 case LOWORD(X509_NAME_CONSTRAINTS):
5313 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5314 break;
5315 case LOWORD(PKCS7_SIGNER_INFO):
5316 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
5317 break;
5318 case LOWORD(CMS_SIGNER_INFO):
5319 decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
5320 break;
5321 }
5322 }
5323 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
5324 decodeFunc = CRYPT_AsnDecodeExtensions;
5325 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
5326 decodeFunc = CRYPT_AsnDecodeUtcTime;
5327 else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
5328 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5329 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
5330 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5331 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
5332 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5333 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
5334 decodeFunc = CRYPT_AsnDecodeEnumerated;
5335 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
5336 decodeFunc = CRYPT_AsnDecodeBits;
5337 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
5338 decodeFunc = CRYPT_AsnDecodeOctets;
5339 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
5340 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5341 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
5342 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5343 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
5344 decodeFunc = CRYPT_AsnDecodeAltName;
5345 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
5346 decodeFunc = CRYPT_AsnDecodeAltName;
5347 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
5348 decodeFunc = CRYPT_AsnDecodeAltName;
5349 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
5350 decodeFunc = CRYPT_AsnDecodeAltName;
5351 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
5352 decodeFunc = CRYPT_AsnDecodeAltName;
5353 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
5354 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5355 else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
5356 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5357 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
5358 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5359 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
5360 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5361 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
5362 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5363 else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
5364 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5365 else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
5366 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5367 else if (!strcmp(lpszStructType, szOID_CTL))
5368 decodeFunc = CRYPT_AsnDecodeCTL;
5369 return decodeFunc;
5370 }
5371
5372 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
5373 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5374 {
5375 static HCRYPTOIDFUNCSET set = NULL;
5376 CryptDecodeObjectFunc decodeFunc = NULL;
5377
5378 if (!set)
5379 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
5380 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5381 (void **)&decodeFunc, hFunc);
5382 return decodeFunc;
5383 }
5384
5385 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
5386 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5387 {
5388 static HCRYPTOIDFUNCSET set = NULL;
5389 CryptDecodeObjectExFunc decodeFunc = NULL;
5390
5391 if (!set)
5392 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
5393 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5394 (void **)&decodeFunc, hFunc);
5395 return decodeFunc;
5396 }
5397
5398 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5399 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
5400 DWORD *pcbStructInfo)
5401 {
5402 BOOL ret = FALSE;
5403 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
5404 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
5405 HCRYPTOIDFUNCADDR hFunc = NULL;
5406
5407 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
5408 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
5409 pvStructInfo, pcbStructInfo);
5410
5411 if (!pvStructInfo && !pcbStructInfo)
5412 {
5413 SetLastError(ERROR_INVALID_PARAMETER);
5414 return FALSE;
5415 }
5416 if (cbEncoded > MAX_ENCODED_LEN)
5417 {
5418 SetLastError(CRYPT_E_ASN1_LARGE);
5419 return FALSE;
5420 }
5421
5422 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
5423 lpszStructType)))
5424 {
5425 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5426 debugstr_a(lpszStructType));
5427 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
5428 lpszStructType, &hFunc);
5429 if (!pCryptDecodeObject)
5430 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
5431 lpszStructType, &hFunc);
5432 }
5433 if (pCryptDecodeObject)
5434 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5435 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5436 else if (pCryptDecodeObjectEx)
5437 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
5438 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
5439 pvStructInfo, pcbStructInfo);
5440 if (hFunc)
5441 CryptFreeOIDFunctionAddress(hFunc, 0);
5442 TRACE_(crypt)("returning %d\n", ret);
5443 return ret;
5444 }
5445
5446 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5447 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5448 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5449 {
5450 BOOL ret = FALSE;
5451 CryptDecodeObjectExFunc decodeFunc;
5452 HCRYPTOIDFUNCADDR hFunc = NULL;
5453
5454 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5455 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
5456 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5457
5458 if (!pvStructInfo && !pcbStructInfo)
5459 {
5460 SetLastError(ERROR_INVALID_PARAMETER);
5461 return FALSE;
5462 }
5463 if (cbEncoded > MAX_ENCODED_LEN)
5464 {
5465 SetLastError(CRYPT_E_ASN1_LARGE);
5466 return FALSE;
5467 }
5468
5469 SetLastError(NOERROR);
5470 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
5471 *(BYTE **)pvStructInfo = NULL;
5472 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
5473 if (!decodeFunc)
5474 {
5475 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5476 debugstr_a(lpszStructType));
5477 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
5478 &hFunc);
5479 }
5480 if (decodeFunc)
5481 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
5482 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5483 else
5484 {
5485 CryptDecodeObjectFunc pCryptDecodeObject =
5486 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
5487
5488 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5489 * directly, as that could cause an infinite loop.
5490 */
5491 if (pCryptDecodeObject)
5492 {
5493 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5494 {
5495 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5496 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
5497 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
5498 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
5499 ret = pCryptDecodeObject(dwCertEncodingType,
5500 lpszStructType, pbEncoded, cbEncoded, dwFlags,
5501 *(BYTE **)pvStructInfo, pcbStructInfo);
5502 }
5503 else
5504 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5505 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5506 }
5507 }
5508 if (hFunc)
5509 CryptFreeOIDFunctionAddress(hFunc, 0);
5510 TRACE_(crypt)("returning %d\n", ret);
5511 return ret;
5512 }
5513
5514 BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
5515 {
5516 BOOL ret;
5517
5518 TRACE_(crypt)("(%p)\n", pPFX);
5519
5520 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
5521 * version integer of length 1 (3 encoded byes) and at least one other
5522 * datum (two encoded bytes), plus at least two bytes for the outer
5523 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
5524 */
5525 if (pPFX->cbData < 7)
5526 ret = FALSE;
5527 else if (pPFX->pbData[0] == ASN_SEQUENCE)
5528 {
5529 DWORD len;
5530
5531 if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
5532 {
5533 BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);
5534
5535 /* Need at least three bytes for the integer version */
5536 if (pPFX->cbData < 1 + lenLen + 3)
5537 ret = FALSE;
5538 else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
5539 pPFX->pbData[1 + lenLen + 1] != 1 || /* Definite length */
5540 pPFX->pbData[1 + lenLen + 2] != 3) /* PFX version */
5541 ret = FALSE;
5542 }
5543 }
5544 else
5545 ret = FALSE;
5546 return ret;
5547 }
5548
5549 HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
5550 DWORD dwFlags)
5551 {
5552 FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);
5553 return NULL;
5554 }