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 if (itemLen == CMSG_INDEFINITE_LENGTH)
380 {
381 if (itemDecoded > itemEncodedLen - 2 ||
382 *(ptr + itemDecoded) != 0 ||
383 *(ptr + itemDecoded + 1) != 0)
384 {
385 TRACE("expected 0 TLV\n");
386 SetLastError(CRYPT_E_ASN1_CORRUPT);
387 ret = FALSE;
388 }
389 else
390 itemDecoded += 2;
391 }
392 if (ret)
393 {
394 ptr += itemDecoded;
395 decoded += itemDecoded;
396 TRACE("item %d: decoded %d bytes\n", i,
397 itemDecoded);
398 }
399 }
400 }
401 else if (items[i].optional &&
402 GetLastError() == CRYPT_E_ASN1_BADTAG)
403 {
404 TRACE("skipping optional item %d\n", i);
405 items[i].size = items[i].minSize;
406 SetLastError(NOERROR);
407 ret = TRUE;
408 }
409 else
410 TRACE("item %d failed: %08x\n", i,
411 GetLastError());
412 }
413 else if (itemLen == CMSG_INDEFINITE_LENGTH)
414 {
415 ERR("can't use indefinite length encoding without a decoder\n");
416 SetLastError(CRYPT_E_ASN1_CORRUPT);
417 ret = FALSE;
418 }
419 else
420 {
421 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
422 ptr += itemEncodedLen;
423 decoded += itemEncodedLen;
424 items[i].size = items[i].minSize;
425 }
426 }
427 else if (items[i].optional)
428 {
429 TRACE("skipping optional item %d\n", i);
430 items[i].size = items[i].minSize;
431 }
432 else
433 {
434 TRACE("item %d: tag %02x doesn't match expected %02x\n",
435 i, ptr[0], items[i].tag);
436 SetLastError(CRYPT_E_ASN1_BADTAG);
437 ret = FALSE;
438 }
439 }
440 }
441 else if (items[i].optional)
442 {
443 TRACE("missing optional item %d, skipping\n", i);
444 items[i].size = items[i].minSize;
445 }
446 else
447 {
448 TRACE("not enough bytes for item %d, failing\n", i);
449 SetLastError(CRYPT_E_ASN1_CORRUPT);
450 ret = FALSE;
451 }
452 }
453 if (cbDecoded)
454 *cbDecoded = decoded;
455 TRACE("returning %d\n", ret);
456 return ret;
457 }
458
459 /* This decodes an arbitrary sequence into a contiguous block of memory
460 * (basically, a struct.) Each element being decoded is described by a struct
461 * AsnDecodeSequenceItem, see above.
462 * startingPointer is an optional pointer to the first place where dynamic
463 * data will be stored. If you know the starting offset, you may pass it
464 * here. Otherwise, pass NULL, and one will be inferred from the items.
465 */
466 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
467 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
468 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
469 DWORD *pcbDecoded, void *startingPointer)
470 {
471 BOOL ret;
472
473 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
474 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
475 startingPointer);
476
477 if (!cbEncoded)
478 {
479 SetLastError(CRYPT_E_ASN1_EOD);
480 return FALSE;
481 }
482 if (pbEncoded[0] == ASN_SEQUENCE)
483 {
484 DWORD dataLen;
485
486 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
487 {
488 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
489 const BYTE *ptr = pbEncoded + 1 + lenBytes;
490 BOOL indefinite = FALSE;
491
492 cbEncoded -= 1 + lenBytes;
493 if (dataLen == CMSG_INDEFINITE_LENGTH)
494 {
495 dataLen = cbEncoded;
496 indefinite = TRUE;
497 }
498 else if (cbEncoded < dataLen)
499 {
500 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
501 cbEncoded);
502 SetLastError(CRYPT_E_ASN1_CORRUPT);
503 ret = FALSE;
504 }
505 if (ret)
506 {
507 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
508 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
509 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
510 {
511 if (cbDecoded > cbEncoded - 2)
512 {
513 /* Not enough space for 0 TLV */
514 SetLastError(CRYPT_E_ASN1_CORRUPT);
515 ret = FALSE;
516 }
517 else if (*(ptr + cbDecoded) != 0 ||
518 *(ptr + cbDecoded + 1) != 0)
519 {
520 TRACE("expected 0 TLV\n");
521 SetLastError(CRYPT_E_ASN1_CORRUPT);
522 ret = FALSE;
523 }
524 else
525 cbDecoded += 2;
526 }
527 }
528 if (ret && !indefinite && cbDecoded != dataLen)
529 {
530 TRACE("expected %d decoded, got %d, failing\n", dataLen,
531 cbDecoded);
532 SetLastError(CRYPT_E_ASN1_CORRUPT);
533 ret = FALSE;
534 }
535 if (ret)
536 {
537 DWORD i, bytesNeeded = 0, structSize = 0;
538
539 for (i = 0; i < cItem; i++)
540 {
541 bytesNeeded += items[i].size;
542 structSize += items[i].minSize;
543 }
544 if (pcbDecoded)
545 *pcbDecoded = 1 + lenBytes + cbDecoded;
546 if (!pvStructInfo)
547 *pcbStructInfo = bytesNeeded;
548 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
549 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
550 {
551 BYTE *nextData;
552
553 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
554 pvStructInfo = *(BYTE **)pvStructInfo;
555 if (startingPointer)
556 nextData = (BYTE *)startingPointer;
557 else
558 nextData = (BYTE *)pvStructInfo + structSize;
559 memset(pvStructInfo, 0, structSize);
560 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
561 ptr, dataLen, dwFlags, pvStructInfo, nextData,
562 &cbDecoded);
563 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
564 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
565 }
566 }
567 }
568 }
569 else
570 {
571 SetLastError(CRYPT_E_ASN1_BADTAG);
572 ret = FALSE;
573 }
574 TRACE("returning %d (%08x)\n", ret, GetLastError());
575 return ret;
576 }
577
578 /* tag:
579 * The expected tag of the entire encoded array (usually a variant
580 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
581 * regardless of the tag seen.
582 * decodeFunc:
583 * used to decode each item in the array
584 * itemSize:
585 * is the minimum size of each decoded item
586 * hasPointer:
587 * indicates whether each item has a dynamic pointer
588 * pointerOffset:
589 * indicates the offset within itemSize at which the pointer exists
590 */
591 struct AsnArrayDescriptor
592 {
593 BYTE tag;
594 InternalDecodeFunc decodeFunc;
595 DWORD itemSize;
596 BOOL hasPointer;
597 DWORD pointerOffset;
598 };
599
600 struct AsnArrayItemSize
601 {
602 DWORD encodedLen;
603 DWORD size;
604 };
605
606 /* Decodes an array of like types into a struct GenericArray.
607 * The layout and decoding of the array are described by a struct
608 * AsnArrayDescriptor.
609 */
610 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
611 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
612 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
613 DWORD *pcbDecoded, void *startingPointer)
614 {
615 BOOL ret = TRUE;
616
617 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
618 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
619 startingPointer);
620
621 if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
622 {
623 DWORD dataLen;
624
625 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
626 {
627 DWORD bytesNeeded, cItems = 0, decoded;
628 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
629 /* There can be arbitrarily many items, but there is often only one.
630 */
631 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
632
633 decoded = 1 + lenBytes;
634 bytesNeeded = sizeof(struct GenericArray);
635 if (dataLen)
636 {
637 const BYTE *ptr;
638 BOOL doneDecoding = FALSE;
639
640 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
641 {
642 if (dataLen == CMSG_INDEFINITE_LENGTH)
643 {
644 if (ptr[0] == 0)
645 {
646 doneDecoding = TRUE;
647 if (ptr[1] != 0)
648 {
649 SetLastError(CRYPT_E_ASN1_CORRUPT);
650 ret = FALSE;
651 }
652 else
653 decoded += 2;
654 }
655 }
656 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
657 doneDecoding = TRUE;
658 if (!doneDecoding)
659 {
660 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
661
662 /* Each item decoded may not tolerate extraneous bytes,
663 * so get the length of the next element if known.
664 */
665 if ((ret = CRYPT_GetLengthIndefinite(ptr,
666 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
667 {
668 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
669 itemEncoded = cbEncoded - (ptr - pbEncoded);
670 else
671 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
672 itemDataLen;
673 }
674 if (ret)
675 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
676 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
677 &itemDecoded);
678 if (ret)
679 {
680 cItems++;
681 if (itemSizes != &itemSize)
682 itemSizes = CryptMemRealloc(itemSizes,
683 cItems * sizeof(struct AsnArrayItemSize));
684 else if (cItems > 1)
685 {
686 itemSizes =
687 CryptMemAlloc(
688 cItems * sizeof(struct AsnArrayItemSize));
689 if (itemSizes)
690 memcpy(itemSizes, &itemSize,
691 sizeof(itemSize));
692 }
693 if (itemSizes)
694 {
695 decoded += itemDecoded;
696 itemSizes[cItems - 1].encodedLen = itemEncoded;
697 itemSizes[cItems - 1].size = size;
698 bytesNeeded += size;
699 ptr += itemEncoded;
700 }
701 else
702 ret = FALSE;
703 }
704 }
705 }
706 }
707 if (ret)
708 {
709 if (pcbDecoded)
710 *pcbDecoded = decoded;
711 if (!pvStructInfo)
712 *pcbStructInfo = bytesNeeded;
713 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
714 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
715 {
716 DWORD i;
717 BYTE *nextData;
718 const BYTE *ptr;
719 struct GenericArray *array;
720
721 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
722 pvStructInfo = *(BYTE **)pvStructInfo;
723 array = (struct GenericArray *)pvStructInfo;
724 array->cItems = cItems;
725 if (startingPointer)
726 array->rgItems = startingPointer;
727 else
728 array->rgItems = (BYTE *)array +
729 sizeof(struct GenericArray);
730 nextData = array->rgItems +
731 array->cItems * arrayDesc->itemSize;
732 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
733 i < cItems && ptr - pbEncoded - 1 - lenBytes <
734 dataLen; i++)
735 {
736 DWORD itemDecoded;
737
738 if (arrayDesc->hasPointer)
739 *(BYTE **)(array->rgItems + i * arrayDesc->itemSize
740 + arrayDesc->pointerOffset) = nextData;
741 ret = arrayDesc->decodeFunc(ptr,
742 itemSizes[i].encodedLen,
743 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
744 array->rgItems + i * arrayDesc->itemSize,
745 &itemSizes[i].size, &itemDecoded);
746 if (ret)
747 {
748 nextData += itemSizes[i].size - arrayDesc->itemSize;
749 ptr += itemDecoded;
750 }
751 }
752 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
753 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
754 }
755 }
756 if (itemSizes != &itemSize)
757 CryptMemFree(itemSizes);
758 }
759 }
760 else
761 {
762 SetLastError(CRYPT_E_ASN1_BADTAG);
763 ret = FALSE;
764 }
765 return ret;
766 }
767
768 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
769 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
770 * to CRYPT_E_ASN1_CORRUPT.
771 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
772 * set!
773 */
774 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
775 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
776 {
777 BOOL ret;
778 DWORD dataLen;
779
780 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
781 {
782 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
783 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
784
785 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
786 bytesNeeded += 1 + lenBytes + dataLen;
787
788 if (pcbDecoded)
789 *pcbDecoded = 1 + lenBytes + dataLen;
790 if (!pvStructInfo)
791 *pcbStructInfo = bytesNeeded;
792 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
793 {
794 CRYPT_DER_BLOB *blob;
795
796 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
797 pvStructInfo = *(BYTE **)pvStructInfo;
798 blob = (CRYPT_DER_BLOB *)pvStructInfo;
799 blob->cbData = 1 + lenBytes + dataLen;
800 if (blob->cbData)
801 {
802 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
803 blob->pbData = (BYTE *)pbEncoded;
804 else
805 {
806 assert(blob->pbData);
807 memcpy(blob->pbData, pbEncoded, blob->cbData);
808 }
809 }
810 else
811 {
812 SetLastError(CRYPT_E_ASN1_CORRUPT);
813 ret = FALSE;
814 }
815 }
816 }
817 return ret;
818 }
819
820 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
821 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
822 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
823 DWORD *pcbDecoded)
824 {
825 BOOL ret;
826
827 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
828 pvStructInfo, *pcbStructInfo, pcbDecoded);
829
830 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
831 * place.
832 */
833 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
834 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
835 pcbDecoded);
836 if (ret && pvStructInfo)
837 {
838 CRYPT_BIT_BLOB *blob = (CRYPT_BIT_BLOB *)pvStructInfo;
839
840 if (blob->cbData)
841 {
842 DWORD i;
843 BYTE temp;
844
845 for (i = 0; i < blob->cbData / 2; i++)
846 {
847 temp = blob->pbData[i];
848 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
849 blob->pbData[blob->cbData - i - 1] = temp;
850 }
851 }
852 }
853 TRACE("returning %d (%08x)\n", ret, GetLastError());
854 return ret;
855 }
856
857 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
858 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
859 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
860 {
861 BOOL ret = TRUE;
862
863 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
864 pDecodePara, pvStructInfo, *pcbStructInfo);
865
866 __TRY
867 {
868 struct AsnDecodeSequenceItem items[] = {
869 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
870 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
871 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
872 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
873 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
874 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
875 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
876 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
877 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
878 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
879 };
880
881 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
882 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
883 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
884 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
885 pcbStructInfo, NULL, NULL);
886 }
887 __EXCEPT_PAGE_FAULT
888 {
889 SetLastError(STATUS_ACCESS_VIOLATION);
890 ret = FALSE;
891 }
892 __ENDTRY
893
894 TRACE("Returning %d (%08x)\n", ret, GetLastError());
895 return ret;
896 }
897
898 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
899 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
900 {
901 BOOL ret;
902 DWORD dataLen;
903
904 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
905 {
906 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
907
908 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
909 dwFlags, pvStructInfo, pcbStructInfo, NULL);
910 if (pcbDecoded)
911 *pcbDecoded = 1 + lenBytes + dataLen;
912 }
913 return ret;
914 }
915
916 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
917 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
918 {
919 BOOL ret;
920
921 struct AsnDecodeSequenceItem items[] = {
922 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
923 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
924 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
925 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
926 };
927
928 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
929 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
930 pcbDecoded, NULL);
931 return ret;
932 }
933
934 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
935 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
936 DWORD *pcbDecoded)
937 {
938 BOOL ret;
939 DWORD dataLen;
940
941 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
942 {
943 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
944
945 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded + 1 + lenBytes,
946 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
947 if (ret && pcbDecoded)
948 *pcbDecoded = 1 + lenBytes + dataLen;
949 }
950 return ret;
951 }
952
953 static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
954 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
955 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
956 {
957 BOOL ret = TRUE;
958 struct AsnDecodeSequenceItem items[] = {
959 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
960 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
961 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
962 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
963 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
964 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
965 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
966 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
967 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
968 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
969 Issuer.pbData) },
970 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
971 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
972 FALSE, 0 },
973 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
974 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
975 Subject.pbData) },
976 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
977 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
978 FALSE, TRUE, offsetof(CERT_INFO,
979 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
980 { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
981 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
982 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
983 { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
984 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
985 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
986 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
987 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
988 offsetof(CERT_INFO, rgExtension), 0 },
989 };
990
991 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
992 pDecodePara, pvStructInfo, *pcbStructInfo);
993
994 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
995 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
996 NULL, NULL);
997 if (ret && pvStructInfo)
998 {
999 CERT_INFO *info;
1000
1001 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1002 info = *(CERT_INFO **)pvStructInfo;
1003 else
1004 info = (CERT_INFO *)pvStructInfo;
1005 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1006 !info->Subject.cbData)
1007 {
1008 SetLastError(CRYPT_E_ASN1_CORRUPT);
1009 /* Don't need to deallocate, because it should have failed on the
1010 * first pass (and no memory was allocated.)
1011 */
1012 ret = FALSE;
1013 }
1014 }
1015
1016 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1017 return ret;
1018 }
1019
1020 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1021 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1022 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1023 {
1024 BOOL ret = FALSE;
1025
1026 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1027 pDecodePara, pvStructInfo, *pcbStructInfo);
1028
1029 __TRY
1030 {
1031 DWORD size = 0;
1032
1033 /* Unless told not to, first try to decode it as a signed cert. */
1034 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1035 {
1036 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1037
1038 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1039 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1040 (BYTE *)&signedCert, &size);
1041 if (ret)
1042 {
1043 size = 0;
1044 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1045 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1046 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1047 pvStructInfo, pcbStructInfo);
1048 LocalFree(signedCert);
1049 }
1050 }
1051 /* Failing that, try it as an unsigned cert */
1052 if (!ret)
1053 {
1054 size = 0;
1055 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1056 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1057 pDecodePara, pvStructInfo, pcbStructInfo);
1058 }
1059 }
1060 __EXCEPT_PAGE_FAULT
1061 {
1062 SetLastError(STATUS_ACCESS_VIOLATION);
1063 }
1064 __ENDTRY
1065
1066 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1067 return ret;
1068 }
1069
1070 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1071 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1072 {
1073 BOOL ret;
1074 struct AsnDecodeSequenceItem items[] = {
1075 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1076 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1077 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1078 { 0, offsetof(CRL_ENTRY, RevocationDate),
1079 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1080 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1081 CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1082 offsetof(CRL_ENTRY, rgExtension), 0 },
1083 };
1084 PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo;
1085
1086 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1087 *pcbStructInfo);
1088
1089 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1090 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1091 entry ? entry->SerialNumber.pbData : NULL);
1092 if (ret && entry && !entry->SerialNumber.cbData)
1093 {
1094 WARN("empty CRL entry serial number\n");
1095 SetLastError(CRYPT_E_ASN1_CORRUPT);
1096 ret = FALSE;
1097 }
1098 return ret;
1099 }
1100
1101 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1102 * been set prior to calling.
1103 */
1104 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1105 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1106 {
1107 BOOL ret;
1108 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1109 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1110 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1111 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
1112
1113 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1114 pvStructInfo, *pcbStructInfo, pcbDecoded);
1115
1116 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1117 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1118 entries ? entries->rgItems : NULL);
1119 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1120 return ret;
1121 }
1122
1123 static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1124 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1125 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1126 {
1127 struct AsnDecodeSequenceItem items[] = {
1128 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1129 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1130 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1131 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1132 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1133 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1134 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1135 Issuer.pbData) },
1136 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1137 sizeof(FILETIME), FALSE, FALSE, 0 },
1138 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1139 sizeof(FILETIME), TRUE, FALSE, 0 },
1140 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1141 CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE,
1142 offsetof(CRL_INFO, rgCRLEntry), 0 },
1143 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1144 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1145 offsetof(CRL_INFO, rgExtension), 0 },
1146 };
1147 BOOL ret = TRUE;
1148
1149 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1150 pDecodePara, pvStructInfo, *pcbStructInfo);
1151
1152 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1153 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1154 NULL, NULL);
1155
1156 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1157 return ret;
1158 }
1159
1160 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1161 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1162 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1163 {
1164 BOOL ret = FALSE;
1165
1166 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1167 pDecodePara, pvStructInfo, *pcbStructInfo);
1168
1169 __TRY
1170 {
1171 DWORD size = 0;
1172
1173 /* Unless told not to, first try to decode it as a signed crl. */
1174 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1175 {
1176 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1177
1178 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1179 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1180 (BYTE *)&signedCrl, &size);
1181 if (ret)
1182 {
1183 size = 0;
1184 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1185 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1186 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1187 pvStructInfo, pcbStructInfo);
1188 LocalFree(signedCrl);
1189 }
1190 }
1191 /* Failing that, try it as an unsigned crl */
1192 if (!ret)
1193 {
1194 size = 0;
1195 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1196 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1197 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1198 }
1199 }
1200 __EXCEPT_PAGE_FAULT
1201 {
1202 SetLastError(STATUS_ACCESS_VIOLATION);
1203 }
1204 __ENDTRY
1205
1206 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1207 return ret;
1208 }
1209
1210 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1211 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1212 {
1213 BOOL ret = TRUE;
1214 DWORD dataLen;
1215
1216 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1217 pvStructInfo, *pcbStructInfo);
1218
1219 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1220 {
1221 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1222 DWORD bytesNeeded = sizeof(LPSTR);
1223
1224 if (dataLen)
1225 {
1226 /* The largest possible string for the first two components
1227 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1228 */
1229 char firstTwo[6];
1230 const BYTE *ptr;
1231
1232 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1233 pbEncoded[1 + lenBytes] / 40,
1234 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1235 * 40);
1236 bytesNeeded += strlen(firstTwo) + 1;
1237 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1238 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1239 {
1240 /* large enough for ".4000000" */
1241 char str[9];
1242 int val = 0;
1243
1244 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1245 (*ptr & 0x80))
1246 {
1247 val <<= 7;
1248 val |= *ptr & 0x7f;
1249 ptr++;
1250 }
1251 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1252 (*ptr & 0x80))
1253 {
1254 SetLastError(CRYPT_E_ASN1_CORRUPT);
1255 ret = FALSE;
1256 }
1257 else
1258 {
1259 val <<= 7;
1260 val |= *ptr++;
1261 snprintf(str, sizeof(str), ".%d", val);
1262 bytesNeeded += strlen(str);
1263 }
1264 }
1265 }
1266 if (pcbDecoded)
1267 *pcbDecoded = 1 + lenBytes + dataLen;
1268 if (!pvStructInfo)
1269 *pcbStructInfo = bytesNeeded;
1270 else if (*pcbStructInfo < bytesNeeded)
1271 {
1272 *pcbStructInfo = bytesNeeded;
1273 SetLastError(ERROR_MORE_DATA);
1274 ret = FALSE;
1275 }
1276 else
1277 {
1278 if (dataLen)
1279 {
1280 const BYTE *ptr;
1281 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1282
1283 *pszObjId = 0;
1284 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1285 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1286 40) * 40);
1287 pszObjId += strlen(pszObjId);
1288 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1289 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1290 {
1291 int val = 0;
1292
1293 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1294 (*ptr & 0x80))
1295 {
1296 val <<= 7;
1297 val |= *ptr & 0x7f;
1298 ptr++;
1299 }
1300 val <<= 7;
1301 val |= *ptr++;
1302 sprintf(pszObjId, ".%d", val);
1303 pszObjId += strlen(pszObjId);
1304 }
1305 }
1306 else
1307 *(LPSTR *)pvStructInfo = NULL;
1308 *pcbStructInfo = bytesNeeded;
1309 }
1310 }
1311 return ret;
1312 }
1313
1314 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1315 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1316 {
1317 BOOL ret;
1318
1319 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1320 pvStructInfo, *pcbStructInfo);
1321
1322 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1323 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1324 pvStructInfo, pcbStructInfo, pcbDecoded);
1325 else
1326 {
1327 SetLastError(CRYPT_E_ASN1_BADTAG);
1328 ret = FALSE;
1329 }
1330 return ret;
1331 }
1332
1333 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1334 * ahead of time!
1335 */
1336 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1337 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1338 {
1339 struct AsnDecodeSequenceItem items[] = {
1340 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1341 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1342 offsetof(CERT_EXTENSION, pszObjId), 0 },
1343 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1344 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1345 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1346 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1347 offsetof(CERT_EXTENSION, Value.pbData) },
1348 };
1349 BOOL ret = TRUE;
1350 PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo;
1351
1352 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1353 *pcbStructInfo);
1354
1355 if (ext)
1356 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1357 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1358 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1359 pcbDecoded, ext ? ext->pszObjId : NULL);
1360 if (ext)
1361 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1362 debugstr_a(ext->pszObjId));
1363 TRACE("returning %d (%08x)\n", ret, GetLastError());
1364 return ret;
1365 }
1366
1367 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
1368 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1369 DWORD *pcbDecoded)
1370 {
1371 BOOL ret = TRUE;
1372 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1373 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1374 offsetof(CERT_EXTENSION, pszObjId) };
1375 PCERT_EXTENSIONS exts = (PCERT_EXTENSIONS)pvStructInfo;
1376
1377 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1378 pvStructInfo, *pcbStructInfo, pcbDecoded);
1379
1380 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1381 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1382 exts ? exts->rgExtension : NULL);
1383 return ret;
1384 }
1385
1386 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1387 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1388 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1389 {
1390 BOOL ret = TRUE;
1391
1392 __TRY
1393 {
1394 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1395 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1396 if (ret && pvStructInfo)
1397 {
1398 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1399 pcbStructInfo, *pcbStructInfo);
1400 if (ret)
1401 {
1402 CERT_EXTENSIONS *exts;
1403
1404 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1405 pvStructInfo = *(BYTE **)pvStructInfo;
1406 exts = (CERT_EXTENSIONS *)pvStructInfo;
1407 exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
1408 sizeof(CERT_EXTENSIONS));
1409 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1410 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1411 pcbStructInfo, NULL);
1412 }
1413 }
1414 }
1415 __EXCEPT_PAGE_FAULT
1416 {
1417 SetLastError(STATUS_ACCESS_VIOLATION);
1418 ret = FALSE;
1419 }
1420 __ENDTRY
1421 return ret;
1422 }
1423
1424 /* Warning: this assumes the address of value->Value.pbData is already set, in
1425 * order to avoid overwriting memory. (In some cases, it may change it, if it
1426 * doesn't copy anything to memory.) Be sure to set it correctly!
1427 */
1428 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1429 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1430 DWORD *pcbDecoded)
1431 {
1432 BOOL ret = TRUE;
1433 DWORD dataLen;
1434 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1435
1436 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1437 {
1438 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1439 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1440
1441 switch (pbEncoded[0])
1442 {
1443 case ASN_OCTETSTRING:
1444 valueType = CERT_RDN_OCTET_STRING;
1445 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1446 bytesNeeded += dataLen;
1447 break;
1448 case ASN_NUMERICSTRING:
1449 valueType = CERT_RDN_NUMERIC_STRING;
1450 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1451 bytesNeeded += dataLen;
1452 break;
1453 case ASN_PRINTABLESTRING:
1454 valueType = CERT_RDN_PRINTABLE_STRING;
1455 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1456 bytesNeeded += dataLen;
1457 break;
1458 case ASN_IA5STRING:
1459 valueType = CERT_RDN_IA5_STRING;
1460 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1461 bytesNeeded += dataLen;
1462 break;
1463 case ASN_T61STRING:
1464 valueType = CERT_RDN_T61_STRING;
1465 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1466 bytesNeeded += dataLen;
1467 break;
1468 case ASN_VIDEOTEXSTRING:
1469 valueType = CERT_RDN_VIDEOTEX_STRING;
1470 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1471 bytesNeeded += dataLen;
1472 break;
1473 case ASN_GRAPHICSTRING:
1474 valueType = CERT_RDN_GRAPHIC_STRING;
1475 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1476 bytesNeeded += dataLen;
1477 break;
1478 case ASN_VISIBLESTRING:
1479 valueType = CERT_RDN_VISIBLE_STRING;
1480 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1481 bytesNeeded += dataLen;
1482 break;
1483 case ASN_GENERALSTRING:
1484 valueType = CERT_RDN_GENERAL_STRING;
1485 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1486 bytesNeeded += dataLen;
1487 break;
1488 case ASN_UNIVERSALSTRING:
1489 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1490 SetLastError(CRYPT_E_ASN1_BADTAG);
1491 return FALSE;
1492 case ASN_BMPSTRING:
1493 valueType = CERT_RDN_BMP_STRING;
1494 bytesNeeded += dataLen;
1495 break;
1496 case ASN_UTF8STRING:
1497 valueType = CERT_RDN_UTF8_STRING;
1498 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1499 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1500 break;
1501 default:
1502 SetLastError(CRYPT_E_ASN1_BADTAG);
1503 return FALSE;
1504 }
1505
1506 if (pcbDecoded)
1507 *pcbDecoded = 1 + lenBytes + dataLen;
1508 if (!value)
1509 *pcbStructInfo = bytesNeeded;
1510 else if (*pcbStructInfo < bytesNeeded)
1511 {
1512 *pcbStructInfo = bytesNeeded;
1513 SetLastError(ERROR_MORE_DATA);
1514 ret = FALSE;
1515 }
1516 else
1517 {
1518 *pcbStructInfo = bytesNeeded;
1519 value->dwValueType = valueType;
1520 if (dataLen)
1521 {
1522 DWORD i;
1523
1524 assert(value->Value.pbData);
1525 switch (pbEncoded[0])
1526 {
1527 case ASN_OCTETSTRING:
1528 case ASN_NUMERICSTRING:
1529 case ASN_PRINTABLESTRING:
1530 case ASN_IA5STRING:
1531 case ASN_T61STRING:
1532 case ASN_VIDEOTEXSTRING:
1533 case ASN_GRAPHICSTRING:
1534 case ASN_VISIBLESTRING:
1535 case ASN_GENERALSTRING:
1536 value->Value.cbData = dataLen;
1537 if (dataLen)
1538 {
1539 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1540 memcpy(value->Value.pbData,
1541 pbEncoded + 1 + lenBytes, dataLen);
1542 else
1543 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1544 lenBytes;
1545 }
1546 break;
1547 case ASN_BMPSTRING:
1548 {
1549 LPWSTR str = (LPWSTR)value->Value.pbData;
1550
1551 value->Value.cbData = dataLen;
1552 for (i = 0; i < dataLen / 2; i++)
1553 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1554 pbEncoded[1 + lenBytes + 2 * i + 1];
1555 break;
1556 }
1557 case ASN_UTF8STRING:
1558 {
1559 LPWSTR str = (LPWSTR)value->Value.pbData;
1560
1561 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1562 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1563 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1564 break;
1565 }
1566 }
1567 }
1568 else
1569 {
1570 value->Value.cbData = 0;
1571 value->Value.pbData = NULL;
1572 }
1573 }
1574 }
1575 return ret;
1576 }
1577
1578 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1579 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1580 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1581 {
1582 BOOL ret = TRUE;
1583
1584 __TRY
1585 {
1586 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1587 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1588 if (ret && pvStructInfo)
1589 {
1590 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1591 pcbStructInfo, *pcbStructInfo);
1592 if (ret)
1593 {
1594 CERT_NAME_VALUE *value;
1595
1596 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1597 pvStructInfo = *(BYTE **)pvStructInfo;
1598 value = (CERT_NAME_VALUE *)pvStructInfo;
1599 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1600 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1601 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1602 pcbStructInfo, NULL);
1603 }
1604 }
1605 }
1606 __EXCEPT_PAGE_FAULT
1607 {
1608 SetLastError(STATUS_ACCESS_VIOLATION);
1609 ret = FALSE;
1610 }
1611 __ENDTRY
1612 return ret;
1613 }
1614
1615 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1616 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1617 DWORD *pcbDecoded)
1618 {
1619 BOOL ret = TRUE;
1620 DWORD dataLen;
1621 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1622
1623 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1624 {
1625 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1626 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1627
1628 switch (pbEncoded[0])
1629 {
1630 case ASN_NUMERICSTRING:
1631 valueType = CERT_RDN_NUMERIC_STRING;
1632 bytesNeeded += dataLen * 2;
1633 break;
1634 case ASN_PRINTABLESTRING:
1635 valueType = CERT_RDN_PRINTABLE_STRING;
1636 bytesNeeded += dataLen * 2;
1637 break;
1638 case ASN_IA5STRING:
1639 valueType = CERT_RDN_IA5_STRING;
1640 bytesNeeded += dataLen * 2;
1641 break;
1642 case ASN_T61STRING:
1643 valueType = CERT_RDN_T61_STRING;
1644 bytesNeeded += dataLen * 2;
1645 break;
1646 case ASN_VIDEOTEXSTRING:
1647 valueType = CERT_RDN_VIDEOTEX_STRING;
1648 bytesNeeded += dataLen * 2;
1649 break;
1650 case ASN_GRAPHICSTRING:
1651 valueType = CERT_RDN_GRAPHIC_STRING;
1652 bytesNeeded += dataLen * 2;
1653 break;
1654 case ASN_VISIBLESTRING:
1655 valueType = CERT_RDN_VISIBLE_STRING;
1656 bytesNeeded += dataLen * 2;
1657 break;
1658 case ASN_GENERALSTRING:
1659 valueType = CERT_RDN_GENERAL_STRING;
1660 bytesNeeded += dataLen * 2;
1661 break;
1662 case ASN_UNIVERSALSTRING:
1663 valueType = CERT_RDN_UNIVERSAL_STRING;
1664 bytesNeeded += dataLen / 2;
1665 break;
1666 case ASN_BMPSTRING:
1667 valueType = CERT_RDN_BMP_STRING;
1668 bytesNeeded += dataLen;
1669 break;
1670 case ASN_UTF8STRING:
1671 valueType = CERT_RDN_UTF8_STRING;
1672 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1673 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1674 break;
1675 default:
1676 SetLastError(CRYPT_E_ASN1_BADTAG);
1677 return FALSE;
1678 }
1679
1680 if (pcbDecoded)
1681 *pcbDecoded = 1 + lenBytes + dataLen;
1682 if (!value)
1683 *pcbStructInfo = bytesNeeded;
1684 else if (*pcbStructInfo < bytesNeeded)
1685 {
1686 *pcbStructInfo = bytesNeeded;
1687 SetLastError(ERROR_MORE_DATA);
1688 ret = FALSE;
1689 }
1690 else
1691 {
1692 *pcbStructInfo = bytesNeeded;
1693 value->dwValueType = valueType;
1694 if (dataLen)
1695 {
1696 DWORD i;
1697 LPWSTR str = (LPWSTR)value->Value.pbData;
1698
1699 assert(value->Value.pbData);
1700 switch (pbEncoded[0])
1701 {
1702 case ASN_NUMERICSTRING:
1703 case ASN_PRINTABLESTRING:
1704 case ASN_IA5STRING:
1705 case ASN_T61STRING:
1706 case ASN_VIDEOTEXSTRING:
1707 case ASN_GRAPHICSTRING:
1708 case ASN_VISIBLESTRING:
1709 case ASN_GENERALSTRING:
1710 value->Value.cbData = dataLen * 2;
1711 for (i = 0; i < dataLen; i++)
1712 str[i] = pbEncoded[1 + lenBytes + i];
1713 break;
1714 case ASN_UNIVERSALSTRING:
1715 value->Value.cbData = dataLen / 2;
1716 for (i = 0; i < dataLen / 4; i++)
1717 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1718 | pbEncoded[1 + lenBytes + 2 * i + 3];
1719 break;
1720 case ASN_BMPSTRING:
1721 value->Value.cbData = dataLen;
1722 for (i = 0; i < dataLen / 2; i++)
1723 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1724 pbEncoded[1 + lenBytes + 2 * i + 1];
1725 break;
1726 case ASN_UTF8STRING:
1727 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1728 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1729 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
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 = (CERT_NAME_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 = (CERT_RDN_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 = (PCERT_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 = (CERT_RDN_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 = (PCERT_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 = (PCRYPT_OBJID_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 = (struct GenericArray *)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 = (CTL_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 = (CTL_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 = (struct GenericArray *)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 = (PCRYPT_SMIME_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 =
2186 (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
2187 BOOL ret;
2188
2189 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2190 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2191 capabilities ? capabilities->rgCapability : NULL);
2192 return ret;
2193 }
2194
2195 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2196 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2197 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2198 {
2199 BOOL ret = FALSE;
2200
2201 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2202 pDecodePara, pvStructInfo, *pcbStructInfo);
2203
2204 __TRY
2205 {
2206 DWORD bytesNeeded;
2207
2208 if (!cbEncoded)
2209 SetLastError(CRYPT_E_ASN1_EOD);
2210 else if (pbEncoded[0] != ASN_SEQUENCEOF)
2211 SetLastError(CRYPT_E_ASN1_CORRUPT);
2212 else if ((ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2213 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2214 NULL)))
2215 {
2216 if (!pvStructInfo)
2217 *pcbStructInfo = bytesNeeded;
2218 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2219 pvStructInfo, pcbStructInfo, bytesNeeded)))
2220 {
2221 PCRYPT_SMIME_CAPABILITIES capabilities;
2222
2223 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2224 pvStructInfo = *(BYTE **)pvStructInfo;
2225 capabilities = (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
2226 capabilities->rgCapability =
2227 (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
2228 sizeof(CRYPT_SMIME_CAPABILITIES));
2229 ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2230 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2231 &bytesNeeded, NULL);
2232 }
2233 }
2234 }
2235 __EXCEPT_PAGE_FAULT
2236 {
2237 SetLastError(STATUS_ACCESS_VIOLATION);
2238 }
2239 __ENDTRY
2240 TRACE("returning %d\n", ret);
2241 return ret;
2242 }
2243
2244 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2245 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2246 DWORD *pcbDecoded)
2247 {
2248 BOOL ret;
2249 struct AsnDecodeSequenceItem items[] = {
2250 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2251 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2252 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2253 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2254 CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE,
2255 offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2256 };
2257 PCRYPT_ATTRIBUTE attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2258
2259 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2260 pvStructInfo, *pcbStructInfo);
2261
2262 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2263 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2264 pcbDecoded, attr ? attr->pszObjId : NULL);
2265 TRACE("returning %d\n", ret);
2266 return ret;
2267 }
2268
2269 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2270 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2271 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2272 {
2273 BOOL ret = FALSE;
2274
2275 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2276 pDecodePara, pvStructInfo, *pcbStructInfo);
2277
2278 __TRY
2279 {
2280 DWORD bytesNeeded;
2281
2282 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2283 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2284 if (ret)
2285 {
2286 if (!pvStructInfo)
2287 *pcbStructInfo = bytesNeeded;
2288 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2289 pvStructInfo, pcbStructInfo, bytesNeeded)))
2290 {
2291 PCRYPT_ATTRIBUTE attr;
2292
2293 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2294 pvStructInfo = *(BYTE **)pvStructInfo;
2295 attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2296 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2297 sizeof(CRYPT_ATTRIBUTE));
2298 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2299 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2300 NULL);
2301 }
2302 }
2303 }
2304 __EXCEPT_PAGE_FAULT
2305 {
2306 SetLastError(STATUS_ACCESS_VIOLATION);
2307 }
2308 __ENDTRY
2309 TRACE("returning %d\n", ret);
2310 return ret;
2311 }
2312
2313 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2314 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2315 DWORD *pcbDecoded)
2316 {
2317 struct AsnArrayDescriptor arrayDesc = { 0,
2318 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2319 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2320 PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2321 BOOL ret;
2322
2323 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2324 NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
2325 NULL);
2326 return ret;
2327 }
2328
2329 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2330 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2331 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2332 {
2333 BOOL ret = FALSE;
2334
2335 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2336 pDecodePara, pvStructInfo, *pcbStructInfo);
2337
2338 __TRY
2339 {
2340 DWORD bytesNeeded;
2341
2342 if (!cbEncoded)
2343 SetLastError(CRYPT_E_ASN1_EOD);
2344 else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
2345 SetLastError(CRYPT_E_ASN1_CORRUPT);
2346 else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2347 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2348 NULL)))
2349 {
2350 if (!pvStructInfo)
2351 *pcbStructInfo = bytesNeeded;
2352 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2353 pvStructInfo, pcbStructInfo, bytesNeeded)))
2354 {
2355 PCRYPT_ATTRIBUTES attrs;
2356
2357 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2358 pvStructInfo = *(BYTE **)pvStructInfo;
2359 attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2360 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
2361 sizeof(CRYPT_ATTRIBUTES));
2362 ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2363 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2364 &bytesNeeded, NULL);
2365 }
2366 }
2367 }
2368 __EXCEPT_PAGE_FAULT
2369 {
2370 SetLastError(STATUS_ACCESS_VIOLATION);
2371 }
2372 __ENDTRY
2373 TRACE("returning %d\n", ret);
2374 return ret;
2375 }
2376
2377 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2378 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2379 {
2380 CRYPT_ALGORITHM_IDENTIFIER *algo =
2381 (CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
2382 BOOL ret = TRUE;
2383 struct AsnDecodeSequenceItem items[] = {
2384 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2385 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2386 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2387 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2388 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2389 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2390 };
2391
2392 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2393 pvStructInfo, *pcbStructInfo, pcbDecoded);
2394
2395 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2396 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2397 pcbDecoded, algo ? algo->pszObjId : NULL);
2398 if (ret && pvStructInfo)
2399 {
2400 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2401 debugstr_a(algo->pszObjId));
2402 }
2403 return ret;
2404 }
2405
2406 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2407 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2408 DWORD *pcbDecoded)
2409 {
2410 BOOL ret = TRUE;
2411 struct AsnDecodeSequenceItem items[] = {
2412 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2413 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2414 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2415 Algorithm.pszObjId) },
2416 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2417 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2418 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2419 };
2420 PCERT_PUBLIC_KEY_INFO info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2421
2422 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2423 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2424 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2425 return ret;
2426 }
2427
2428 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2429 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2430 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2431 {
2432 BOOL ret = TRUE;
2433
2434 __TRY
2435 {
2436 DWORD bytesNeeded;
2437
2438 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2439 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2440 {
2441 if (!pvStructInfo)
2442 *pcbStructInfo = bytesNeeded;
2443 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2444 pvStructInfo, pcbStructInfo, bytesNeeded)))
2445 {
2446 PCERT_PUBLIC_KEY_INFO info;
2447
2448 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2449 pvStructInfo = *(BYTE **)pvStructInfo;
2450 info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2451 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2452 sizeof(CERT_PUBLIC_KEY_INFO);
2453 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2454 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2455 &bytesNeeded, NULL);
2456 }
2457 }
2458 }
2459 __EXCEPT_PAGE_FAULT
2460 {
2461 SetLastError(STATUS_ACCESS_VIOLATION);
2462 ret = FALSE;
2463 }
2464 __ENDTRY
2465 return ret;
2466 }
2467
2468 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2469 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2470 {
2471 BOOL ret;
2472
2473 if (cbEncoded < 3)
2474 {
2475 SetLastError(CRYPT_E_ASN1_CORRUPT);
2476 return FALSE;
2477 }
2478 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2479 {
2480 SetLastError(CRYPT_E_ASN1_CORRUPT);
2481 return FALSE;
2482 }
2483 if (pbEncoded[1] > 1)
2484 {
2485 SetLastError(CRYPT_E_ASN1_CORRUPT);
2486 return FALSE;
2487 }
2488 if (pcbDecoded)
2489 *pcbDecoded = 3;
2490 if (!pvStructInfo)
2491 {
2492 *pcbStructInfo = sizeof(BOOL);
2493 ret = TRUE;
2494 }
2495 else if (*pcbStructInfo < sizeof(BOOL))
2496 {
2497 *pcbStructInfo = sizeof(BOOL);
2498 SetLastError(ERROR_MORE_DATA);
2499 ret = FALSE;
2500 }
2501 else
2502 {
2503 *pcbStructInfo = sizeof(BOOL);
2504 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2505 ret = TRUE;
2506 }
2507 TRACE("returning %d (%08x)\n", ret, GetLastError());
2508 return ret;
2509 }
2510
2511 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2512 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2513 {
2514 PCERT_ALT_NAME_ENTRY entry = (PCERT_ALT_NAME_ENTRY)pvStructInfo;
2515 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2516 BOOL ret;
2517
2518 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2519 pvStructInfo, *pcbStructInfo);
2520
2521 if (cbEncoded < 2)
2522 {
2523 SetLastError(CRYPT_E_ASN1_CORRUPT);
2524 return FALSE;
2525 }
2526 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2527 if (1 + lenBytes > cbEncoded)
2528 {
2529 SetLastError(CRYPT_E_ASN1_CORRUPT);
2530 return FALSE;
2531 }
2532 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2533 {
2534 switch (pbEncoded[0] & ASN_TYPE_MASK)
2535 {
2536 case 1: /* rfc822Name */
2537 case 2: /* dNSName */
2538 case 6: /* uniformResourceIdentifier */
2539 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2540 break;
2541 case 4: /* directoryName */
2542 case 7: /* iPAddress */
2543 bytesNeeded += dataLen;
2544 break;
2545 case 8: /* registeredID */
2546 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2547 &dataLen, NULL);
2548 if (ret)
2549 {
2550 /* FIXME: ugly, shouldn't need to know internals of OID decode
2551 * function to use it.
2552 */
2553 bytesNeeded += dataLen - sizeof(LPSTR);
2554 }
2555 break;
2556 case 0: /* otherName */
2557 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2558 SetLastError(CRYPT_E_ASN1_BADTAG);
2559 ret = FALSE;
2560 break;
2561 case 3: /* x400Address, unimplemented */
2562 case 5: /* ediPartyName, unimplemented */
2563 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2564 SetLastError(CRYPT_E_ASN1_BADTAG);
2565 ret = FALSE;
2566 break;
2567 default:
2568 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2569 SetLastError(CRYPT_E_ASN1_CORRUPT);
2570 ret = FALSE;
2571 }
2572 if (ret)
2573 {
2574 if (pcbDecoded)
2575 *pcbDecoded = 1 + lenBytes + dataLen;
2576 if (!entry)
2577 *pcbStructInfo = bytesNeeded;
2578 else if (*pcbStructInfo < bytesNeeded)
2579 {
2580 *pcbStructInfo = bytesNeeded;
2581 SetLastError(ERROR_MORE_DATA);
2582 ret = FALSE;
2583 }
2584 else
2585 {
2586 *pcbStructInfo = bytesNeeded;
2587 /* MS used values one greater than the asn1 ones.. sigh */
2588 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
2589 switch (pbEncoded[0] & ASN_TYPE_MASK)
2590 {
2591 case 1: /* rfc822Name */
2592 case 2: /* dNSName */
2593 case 6: /* uniformResourceIdentifier */
2594 {
2595 DWORD i;
2596
2597 for (i = 0; i < dataLen; i++)
2598 entry->u.pwszURL[i] =
2599 (WCHAR)pbEncoded[1 + lenBytes + i];
2600 entry->u.pwszURL[i] = 0;
2601 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
2602 debugstr_w(entry->u.pwszURL));
2603 break;
2604 }
2605 case 4: /* directoryName */
2606 /* The data are memory-equivalent with the IPAddress case,
2607 * fall-through
2608 */
2609 case 7: /* iPAddress */
2610 /* The next data pointer is in the pwszURL spot, that is,
2611 * the first 4 bytes. Need to move it to the next spot.
2612 */
2613 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
2614 entry->u.IPAddress.cbData = dataLen;
2615 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
2616 dataLen);
2617 break;
2618 case 8: /* registeredID */
2619 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
2620 &entry->u.pszRegisteredID, &dataLen, NULL);
2621 break;
2622 }
2623 }
2624 }
2625 }
2626 return ret;
2627 }
2628
2629 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
2630 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2631 DWORD *pcbDecoded)
2632 {
2633 BOOL ret = TRUE;
2634 struct AsnArrayDescriptor arrayDesc = { 0,
2635 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
2636 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
2637 PCERT_ALT_NAME_INFO info = (PCERT_ALT_NAME_INFO)pvStructInfo;
2638
2639 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2640 pvStructInfo, *pcbStructInfo, pcbDecoded);
2641
2642 if (info)
2643 TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
2644 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2645 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2646 info ? info->rgAltEntry : NULL);
2647 return ret;
2648 }
2649
2650 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2651 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
2652 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2653 DWORD *pcbDecoded)
2654 {
2655 BOOL ret;
2656
2657 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
2658 pvStructInfo, *pcbStructInfo, pcbDecoded);
2659
2660 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2661 * place.
2662 */
2663 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
2664 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
2665 pcbDecoded);
2666 if (ret && pvStructInfo)
2667 {
2668 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2669
2670 if (blob->cbData)
2671 {
2672 DWORD i;
2673 BYTE temp;
2674
2675 for (i = 0; i < blob->cbData / 2; i++)
2676 {
2677 temp = blob->pbData[i];
2678 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
2679 blob->pbData[blob->cbData - i - 1] = temp;
2680 }
2681 }
2682 }
2683 TRACE("returning %d (%08x)\n", ret, GetLastError());
2684 return ret;
2685 }
2686
2687 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
2688 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2689 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2690 {
2691 BOOL ret;
2692
2693 __TRY
2694 {
2695 struct AsnDecodeSequenceItem items[] = {
2696 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
2697 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2698 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
2699 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2700 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
2701 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
2702 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
2703 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
2704 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2705 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2706 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
2707 };
2708
2709 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2710 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2711 pcbStructInfo, NULL, NULL);
2712 }
2713 __EXCEPT_PAGE_FAULT
2714 {
2715 SetLastError(STATUS_ACCESS_VIOLATION);
2716 ret = FALSE;
2717 }
2718 __ENDTRY
2719 return ret;
2720 }
2721
2722 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
2723 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2724 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2725 {
2726 BOOL ret;
2727
2728 __TRY
2729 {
2730 struct AsnDecodeSequenceItem items[] = {
2731 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
2732 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2733 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
2734 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2735 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
2736 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
2737 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2738 AuthorityCertIssuer.rgAltEntry), 0 },
2739 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2740 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2741 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2742 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2743 AuthorityCertSerialNumber.pbData), 0 },
2744 };
2745
2746 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2747 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2748 pcbStructInfo, NULL, NULL);
2749 }
2750 __EXCEPT_PAGE_FAULT
2751 {
2752 SetLastError(STATUS_ACCESS_VIOLATION);
2753 ret = FALSE;
2754 }
2755 __ENDTRY
2756 return ret;
2757 }
2758
2759 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
2760 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2761 DWORD *pcbDecoded)
2762 {
2763 struct AsnDecodeSequenceItem items[] = {
2764 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
2765 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
2766 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
2767 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
2768 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
2769 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
2770 };
2771 CERT_ACCESS_DESCRIPTION *descr = (CERT_ACCESS_DESCRIPTION *)pvStructInfo;
2772
2773 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2774 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2775 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
2776 }
2777
2778 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
2779 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2780 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2781 {
2782 BOOL ret;
2783
2784 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2785 pDecodePara, pvStructInfo, *pcbStructInfo);
2786
2787 __TRY
2788 {
2789 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2790 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
2791 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
2792
2793 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2794 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
2795 }
2796 __EXCEPT_PAGE_FAULT
2797 {
2798 SetLastError(STATUS_ACCESS_VIOLATION);
2799 ret = FALSE;
2800 }
2801 __ENDTRY
2802 return ret;
2803 }
2804
2805 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
2806 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2807 {
2808 BOOL ret;
2809 DWORD dataLen;
2810
2811 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2812 pvStructInfo, *pcbStructInfo, pcbDecoded);
2813
2814 /* The caller has already checked the tag, no need to check it again.
2815 * Check the outer length is valid:
2816 */
2817 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
2818 {
2819 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2820 DWORD innerLen;
2821
2822 pbEncoded += 1 + lenBytes;
2823 cbEncoded -= 1 + lenBytes;
2824 if (dataLen == CMSG_INDEFINITE_LENGTH)
2825 cbEncoded -= 2; /* space for 0 TLV */
2826 /* Check the inner length is valid: */
2827 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
2828 {
2829 DWORD decodedLen;
2830
2831 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
2832 pvStructInfo, pcbStructInfo, &decodedLen);
2833 if (dataLen == CMSG_INDEFINITE_LENGTH)
2834 {
2835 if (*(pbEncoded + decodedLen) != 0 ||
2836 *(pbEncoded + decodedLen + 1) != 0)
2837 {
2838 TRACE("expected 0 TLV, got {%02x,%02x}\n",
2839 *(pbEncoded + decodedLen),
2840 *(pbEncoded + decodedLen + 1));
2841 SetLastError(CRYPT_E_ASN1_CORRUPT);
2842 ret = FALSE;
2843 }
2844 else
2845 decodedLen += 2;
2846 }
2847 if (ret && pcbDecoded)
2848 {
2849 *pcbDecoded = 1 + lenBytes + decodedLen;
2850 TRACE("decoded %d bytes\n", *pcbDecoded);
2851 }
2852 }
2853 }
2854 return ret;
2855 }
2856
2857 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
2858 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2859 DWORD *pcbDecoded)
2860 {
2861 CRYPT_CONTENT_INFO *info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2862 struct AsnDecodeSequenceItem items[] = {
2863 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
2864 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2865 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
2866 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
2867 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
2868 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
2869 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
2870 };
2871 BOOL ret;
2872
2873 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2874 pvStructInfo, *pcbStructInfo, pcbDecoded);
2875
2876 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2877 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2878 pcbDecoded, info ? info->pszObjId : NULL);
2879 return ret;
2880 }
2881
2882 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
2883 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2884 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2885 {
2886 BOOL ret = FALSE;
2887
2888 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2889 pDecodePara, pvStructInfo, *pcbStructInfo);
2890
2891 __TRY
2892 {
2893 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
2894 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
2895 if (ret && pvStructInfo)
2896 {
2897 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
2898 pcbStructInfo, *pcbStructInfo);
2899 if (ret)
2900 {
2901 CRYPT_CONTENT_INFO *info;
2902
2903 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2904 pvStructInfo = *(BYTE **)pvStructInfo;
2905 info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2906 info->pszObjId = (LPSTR)((BYTE *)info +
2907 sizeof(CRYPT_CONTENT_INFO));
2908 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
2909 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2910 pcbStructInfo, NULL);
2911 }
2912 }
2913 }
2914 __EXCEPT_PAGE_FAULT
2915 {
2916 SetLastError(STATUS_ACCESS_VIOLATION);
2917 }
2918 __ENDTRY
2919 return ret;
2920 }
2921
2922 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
2923 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2924 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
2925 {
2926 BOOL ret;
2927 struct AsnDecodeSequenceItem items[] = {
2928 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
2929 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2930 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
2931 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2932 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
2933 0 },
2934 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
2935 CRYPT_AsnDecodePKCSContentInfoInternal,
2936 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
2937 ContentInfo.pszObjId), 0 },
2938 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
2939 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
2940 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
2941 };
2942
2943 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2944 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
2945 NULL, NULL);
2946 return ret;
2947 }
2948
2949 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
2950 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2951 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2952 {
2953 BOOL ret = TRUE;
2954
2955 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2956 pDecodePara, pvStructInfo, *pcbStructInfo);
2957
2958 __TRY
2959 {
2960 DWORD bytesNeeded;
2961
2962 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2963 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2964 {
2965 if (!pvStructInfo)
2966 *pcbStructInfo = bytesNeeded;
2967 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2968 pvStructInfo, pcbStructInfo, bytesNeeded)))
2969 {
2970 CERT_ALT_NAME_INFO *name;
2971
2972 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2973 pvStructInfo = *(BYTE **)pvStructInfo;
2974 name = (CERT_ALT_NAME_INFO *)pvStructInfo;
2975 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
2976 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
2977 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2978 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2979 &bytesNeeded, NULL);
2980 }
2981 }
2982 }
2983 __EXCEPT_PAGE_FAULT
2984 {
2985 SetLastError(STATUS_ACCESS_VIOLATION);
2986 ret = FALSE;
2987 }
2988 __ENDTRY
2989 return ret;
2990 }
2991
2992 struct PATH_LEN_CONSTRAINT
2993 {
2994 BOOL fPathLenConstraint;
2995 DWORD dwPathLenConstraint;
2996 };
2997
2998 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
2999 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3000 DWORD *pcbDecoded)
3001 {
3002 BOOL ret = TRUE;
3003 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3004
3005 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3006 pvStructInfo, *pcbStructInfo, pcbDecoded);
3007
3008 if (!pvStructInfo)
3009 {
3010 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3011 &size, pcbDecoded);
3012 *pcbStructInfo = bytesNeeded;
3013 }
3014 else if (*pcbStructInfo < bytesNeeded)
3015 {
3016 SetLastError(ERROR_MORE_DATA);
3017 *pcbStructInfo = bytesNeeded;
3018 ret = FALSE;
3019 }
3020 else
3021 {
3022 struct PATH_LEN_CONSTRAINT *constraint =
3023 (struct PATH_LEN_CONSTRAINT *)pvStructInfo;
3024
3025 *pcbStructInfo = bytesNeeded;
3026 size = sizeof(constraint->dwPathLenConstraint);
3027 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3028 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3029 if (ret)
3030 constraint->fPathLenConstraint = TRUE;
3031 TRACE("got an int, dwPathLenConstraint is %d\n",
3032 constraint->dwPathLenConstraint);
3033 }
3034 TRACE("returning %d (%08x)\n", ret, GetLastError());
3035 return ret;
3036 }
3037
3038 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3039 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3040 DWORD *pcbDecoded)
3041 {
3042 BOOL ret;
3043 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3044 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3045 offsetof(CERT_NAME_BLOB, pbData) };
3046 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
3047
3048 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3049 pvStructInfo, *pcbStructInfo, pcbDecoded);
3050
3051 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3052 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
3053 entries ? entries->rgItems : NULL);
3054 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3055 return ret;
3056 }
3057
3058 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3059 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3060 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3061 {
3062 BOOL ret;
3063
3064 __TRY
3065 {
3066 struct AsnDecodeSequenceItem items[] = {
3067 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3068 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3069 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3070 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3071 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3072 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3073 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3074 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3075 sizeof(struct GenericArray), TRUE, TRUE,
3076 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3077 };
3078
3079 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3080 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3081 pcbStructInfo, NULL, NULL);
3082 }
3083 __EXCEPT_PAGE_FAULT
3084 {
3085 SetLastError(STATUS_ACCESS_VIOLATION);
3086 ret = FALSE;
3087 }
3088 __ENDTRY
3089 return ret;
3090 }
3091
3092 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3093 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3094 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3095 {
3096 BOOL ret;
3097
3098 __TRY
3099 {
3100 struct AsnDecodeSequenceItem items[] = {
3101 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3102 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3103 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3104 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3105 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3106 };
3107
3108 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3109 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3110 pcbStructInfo, NULL, NULL);
3111 }
3112 __EXCEPT_PAGE_FAULT
3113 {
3114 SetLastError(STATUS_ACCESS_VIOLATION);
3115 ret = FALSE;
3116 }
3117 __ENDTRY
3118 return ret;
3119 }
3120
3121 #define RSA1_MAGIC 0x31415352
3122
3123 struct DECODED_RSA_PUB_KEY
3124 {
3125 DWORD pubexp;
3126 CRYPT_INTEGER_BLOB modulus;
3127 };
3128
3129 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3130 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3131 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3132 {
3133 BOOL ret;
3134
3135 __TRY
3136 {
3137 struct AsnDecodeSequenceItem items[] = {
3138 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3139 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3140 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3141 0 },
3142 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3143 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3144 };
3145 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3146 DWORD size = 0;
3147
3148 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3149 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3150 &size, NULL, NULL);
3151 if (ret)
3152 {
3153 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3154 decodedKey->modulus.cbData;
3155
3156 if (!pvStructInfo)
3157 {
3158 *pcbStructInfo = bytesNeeded;
3159 ret = TRUE;
3160 }
3161 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3162 pvStructInfo, pcbStructInfo, bytesNeeded)))
3163 {
3164 BLOBHEADER *hdr;
3165 RSAPUBKEY *rsaPubKey;
3166
3167 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3168 pvStructInfo = *(BYTE **)pvStructInfo;
3169 hdr = (BLOBHEADER *)pvStructInfo;
3170 hdr->bType = PUBLICKEYBLOB;
3171 hdr->bVersion = CUR_BLOB_VERSION;
3172 hdr->reserved = 0;
3173 hdr->aiKeyAlg = CALG_RSA_KEYX;
3174 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3175 sizeof(BLOBHEADER));
3176 rsaPubKey->magic = RSA1_MAGIC;
3177 rsaPubKey->pubexp = decodedKey->pubexp;
3178 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3179 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3180 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3181 decodedKey->modulus.cbData);
3182 }
3183 LocalFree(decodedKey);
3184 }
3185 }
3186 __EXCEPT_PAGE_FAULT
3187 {
3188 SetLastError(STATUS_ACCESS_VIOLATION);
3189 ret = FALSE;
3190 }
3191 __ENDTRY
3192 return ret;
3193 }
3194
3195 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3196 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3197 DWORD *pcbDecoded)
3198 {
3199 BOOL ret;
3200 DWORD bytesNeeded, dataLen;
3201
3202 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3203 pvStructInfo, *pcbStructInfo, pcbDecoded);
3204
3205 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3206 {
3207 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3208
3209 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3210 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3211 else
3212 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3213 if (pcbDecoded)
3214 *pcbDecoded = 1 + lenBytes + dataLen;
3215 if (!pvStructInfo)
3216 *pcbStructInfo = bytesNeeded;
3217 else if (*pcbStructInfo < bytesNeeded)
3218 {
3219 SetLastError(ERROR_MORE_DATA);
3220 *pcbStructInfo = bytesNeeded;
3221 ret = FALSE;
3222 }
3223 else
3224 {
3225 CRYPT_DATA_BLOB *blob;
3226
3227 *pcbStructInfo = bytesNeeded;
3228 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3229 blob->cbData = dataLen;
3230 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3231 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
3232 else
3233 {
3234 assert(blob->pbData);
3235 if (blob->cbData)
3236 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
3237 blob->cbData);
3238 }
3239 }
3240 }
3241 return ret;
3242 }
3243
3244 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
3245 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3246 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3247 {
3248 BOOL ret;
3249
3250 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3251 pDecodePara, pvStructInfo, *pcbStructInfo);
3252
3253 __TRY
3254 {
3255 DWORD bytesNeeded;
3256
3257 if (!cbEncoded)
3258 {
3259 SetLastError(CRYPT_E_ASN1_CORRUPT);
3260 ret = FALSE;
3261 }
3262 else if (pbEncoded[0] != ASN_OCTETSTRING)
3263 {
3264 SetLastError(CRYPT_E_ASN1_BADTAG);
3265 ret = FALSE;
3266 }
3267 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3268 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3269 {
3270 if (!pvStructInfo)
3271 *pcbStructInfo = bytesNeeded;
3272 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3273 pvStructInfo, pcbStructInfo, bytesNeeded)))
3274 {
3275 CRYPT_DATA_BLOB *blob;
3276
3277 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3278 pvStructInfo = *(BYTE **)pvStructInfo;
3279 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3280 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3281 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3282 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3283 &bytesNeeded, NULL);
3284 }
3285 }
3286 }
3287 __EXCEPT_PAGE_FAULT
3288 {
3289 SetLastError(STATUS_ACCESS_VIOLATION);
3290 ret = FALSE;
3291 }
3292 __ENDTRY
3293 return ret;
3294 }
3295
3296 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3297 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3298 {
3299 BOOL ret;
3300 DWORD bytesNeeded, dataLen;
3301 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3302
3303 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3304 pvStructInfo, *pcbStructInfo, pcbDecoded);
3305
3306 if ((