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 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
100 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
101 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
102 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
103 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
104 * member has been initialized, doesn't do exception handling, and doesn't do
105 * memory allocation. Also doesn't check tag, assumes the caller has checked
106 * it.
107 */
108 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
109 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
110 DWORD *pcbDecoded);
111 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
112 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
113 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
114 DWORD *pcbDecoded);
115 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
116 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
117 DWORD *pcbDecoded);
118
119 /* Gets the number of length bytes from the given (leading) length byte */
120 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
121
122 /* Helper function to get the encoded length of the data starting at pbEncoded,
123 * where pbEncoded[0] is the tag. If the data are too short to contain a
124 * length or if the length is too large for cbEncoded, sets an appropriate
125 * error code and returns FALSE. If the encoded length is unknown due to
126 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
127 */
128 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
129 DWORD *len)
130 {
131 BOOL ret;
132
133 if (cbEncoded <= 1)
134 {
135 SetLastError(CRYPT_E_ASN1_CORRUPT);
136 ret = FALSE;
137 }
138 else if (pbEncoded[1] <= 0x7f)
139 {
140 if (pbEncoded[1] + 1 > cbEncoded)
141 {
142 SetLastError(CRYPT_E_ASN1_EOD);
143 ret = FALSE;
144 }
145 else
146 {
147 *len = pbEncoded[1];
148 ret = TRUE;
149 }
150 }
151 else if (pbEncoded[1] == 0x80)
152 {
153 *len = CMSG_INDEFINITE_LENGTH;
154 ret = TRUE;
155 }
156 else
157 {
158 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
159
160 if (lenLen > sizeof(DWORD) + 1)
161 {
162 SetLastError(CRYPT_E_ASN1_LARGE);
163 ret = FALSE;
164 }
165 else if (lenLen + 2 > cbEncoded)
166 {
167 SetLastError(CRYPT_E_ASN1_CORRUPT);
168 ret = FALSE;
169 }
170 else
171 {
172 DWORD out = 0;
173
174 pbEncoded += 2;
175 while (--lenLen)
176 {
177 out <<= 8;
178 out |= *pbEncoded++;
179 }
180 if (out + lenLen + 1 > cbEncoded)
181 {
182 SetLastError(CRYPT_E_ASN1_EOD);
183 ret = FALSE;
184 }
185 else
186 {
187 *len = out;
188 ret = TRUE;
189 }
190 }
191 }
192 return ret;
193 }
194
195 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
196 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
197 {
198 BOOL ret;
199
200 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
201 *len == CMSG_INDEFINITE_LENGTH)
202 {
203 SetLastError(CRYPT_E_ASN1_CORRUPT);
204 ret = FALSE;
205 }
206 return ret;
207 }
208
209 /* Helper function to check *pcbStructInfo, set it to the required size, and
210 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
211 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
212 * pointer to the newly allocated memory.
213 */
214 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
215 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
216 DWORD bytesNeeded)
217 {
218 BOOL ret = TRUE;
219
220 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
221 {
222 if (pDecodePara && pDecodePara->pfnAlloc)
223 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
224 else
225 *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
226 if (!*(BYTE **)pvStructInfo)
227 ret = FALSE;
228 else
229 *pcbStructInfo = bytesNeeded;
230 }
231 else if (*pcbStructInfo < bytesNeeded)
232 {
233 *pcbStructInfo = bytesNeeded;
234 SetLastError(ERROR_MORE_DATA);
235 ret = FALSE;
236 }
237 else
238 *pcbStructInfo = bytesNeeded;
239 return ret;
240 }
241
242 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara, LPVOID pv)
243 {
244 if (pDecodePara && pDecodePara->pfnFree)
245 pDecodePara->pfnFree(pv);
246 else
247 LocalFree(pv);
248 }
249
250 /* Helper function to check *pcbStructInfo and set it to the required size.
251 * Assumes pvStructInfo is not NULL.
252 */
253 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
254 {
255 BOOL ret;
256
257 if (*pcbStructInfo < bytesNeeded)
258 {
259 *pcbStructInfo = bytesNeeded;
260 SetLastError(ERROR_MORE_DATA);
261 ret = FALSE;
262 }
263 else
264 {
265 *pcbStructInfo = bytesNeeded;
266 ret = TRUE;
267 }
268 return ret;
269 }
270
271 /* tag:
272 * The expected tag of the item. If tag is 0, decodeFunc is called
273 * regardless of the tag value seen.
274 * offset:
275 * A sequence is decoded into a struct. The offset member is the
276 * offset of this item within that struct.
277 * decodeFunc:
278 * The decoder function to use. If this is NULL, then the member isn't
279 * decoded, but minSize space is reserved for it.
280 * minSize:
281 * The minimum amount of space occupied after decoding. You must set this.
282 * optional:
283 * If true, and the tag doesn't match the expected tag for this item,
284 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
285 * filled with 0 for this member.
286 * hasPointer, pointerOffset:
287 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
288 * the offset within the struct of the data pointer (or to the
289 * first data pointer, if more than one exist).
290 * size:
291 * Used by CRYPT_AsnDecodeSequence, not for your use.
292 */
293 struct AsnDecodeSequenceItem
294 {
295 BYTE tag;
296 DWORD offset;
297 InternalDecodeFunc decodeFunc;
298 DWORD minSize;
299 BOOL optional;
300 BOOL hasPointer;
301 DWORD pointerOffset;
302 DWORD size;
303 };
304
305 /* Decodes the items in a sequence, where the items are described in items,
306 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
307 * pvStructInfo. nextData is a pointer to the memory location at which the
308 * first decoded item with a dynamic pointer should point.
309 * Upon decoding, *cbDecoded is the total number of bytes decoded.
310 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
311 */
312 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
313 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
314 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
315 {
316 BOOL ret;
317 DWORD i, decoded = 0;
318 const BYTE *ptr = pbEncoded;
319
320 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
321 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
322
323 for (i = 0, ret = TRUE; ret && i < cItem; i++)
324 {
325 if (cbEncoded - (ptr - pbEncoded) != 0)
326 {
327 DWORD itemLen;
328
329 if ((ret = CRYPT_GetLengthIndefinite(ptr,
330 cbEncoded - (ptr - pbEncoded), &itemLen)))
331 {
332 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
333
334 if (ptr[0] == items[i].tag || !items[i].tag)
335 {
336 DWORD itemEncodedLen;
337
338 if (itemLen == CMSG_INDEFINITE_LENGTH)
339 itemEncodedLen = cbEncoded - (ptr - pbEncoded);
340 else
341 itemEncodedLen = 1 + itemLenBytes + itemLen;
342 if (nextData && pvStructInfo && items[i].hasPointer)
343 {
344 TRACE("Setting next pointer to %p\n",
345 nextData);
346 *(BYTE **)((BYTE *)pvStructInfo +
347 items[i].pointerOffset) = nextData;
348 }
349 if (items[i].decodeFunc)
350 {
351 DWORD itemDecoded;
352
353 if (pvStructInfo)
354 TRACE("decoding item %d\n", i);
355 else
356 TRACE("sizing item %d\n", i);
357 ret = items[i].decodeFunc(ptr, itemEncodedLen,
358 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
359 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
360 : NULL, &items[i].size, &itemDecoded);
361 if (ret)
362 {
363 /* Account for alignment padding */
364 if (items[i].size % sizeof(DWORD_PTR))
365 items[i].size += sizeof(DWORD_PTR) -
366 items[i].size % sizeof(DWORD_PTR);
367 TRACE("item %d size: %d\n", i, items[i].size);
368 if (nextData && items[i].hasPointer &&
369 items[i].size > items[i].minSize)
370 nextData += items[i].size - items[i].minSize;
371 if (itemDecoded > itemEncodedLen)
372 {
373 WARN("decoded length %d exceeds encoded %d\n",
374 itemDecoded, itemEncodedLen);
375 SetLastError(CRYPT_E_ASN1_CORRUPT);
376 ret = FALSE;
377 }
378 else
379 {
380 if (itemLen == CMSG_INDEFINITE_LENGTH)
381 {
382 if (itemDecoded > itemEncodedLen - 2 ||
383 *(ptr + itemDecoded) != 0 ||
384 *(ptr + itemDecoded + 1) != 0)
385 {
386 TRACE("expected 0 TLV\n");
387 SetLastError(CRYPT_E_ASN1_CORRUPT);
388 ret = FALSE;
389 }
390 else
391 itemDecoded += 2;
392 }
393 if (ret)
394 {
395 ptr += itemDecoded;
396 decoded += itemDecoded;
397 TRACE("item %d: decoded %d bytes\n", i,
398 itemDecoded);
399 }
400 }
401 }
402 else if (items[i].optional &&
403 GetLastError() == CRYPT_E_ASN1_BADTAG)
404 {
405 TRACE("skipping optional item %d\n", i);
406 items[i].size = items[i].minSize;
407 SetLastError(NOERROR);
408 ret = TRUE;
409 }
410 else
411 TRACE("item %d failed: %08x\n", i,
412 GetLastError());
413 }
414 else if (itemLen == CMSG_INDEFINITE_LENGTH)
415 {
416 ERR("can't use indefinite length encoding without a decoder\n");
417 SetLastError(CRYPT_E_ASN1_CORRUPT);
418 ret = FALSE;
419 }
420 else
421 {
422 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
423 ptr += itemEncodedLen;
424 decoded += itemEncodedLen;
425 items[i].size = items[i].minSize;
426 }
427 }
428 else if (items[i].optional)
429 {
430 TRACE("skipping optional item %d\n", i);
431 items[i].size = items[i].minSize;
432 }
433 else
434 {
435 TRACE("item %d: tag %02x doesn't match expected %02x\n",
436 i, ptr[0], items[i].tag);
437 SetLastError(CRYPT_E_ASN1_BADTAG);
438 ret = FALSE;
439 }
440 }
441 }
442 else if (items[i].optional)
443 {
444 TRACE("missing optional item %d, skipping\n", i);
445 items[i].size = items[i].minSize;
446 }
447 else
448 {
449 TRACE("not enough bytes for item %d, failing\n", i);
450 SetLastError(CRYPT_E_ASN1_CORRUPT);
451 ret = FALSE;
452 }
453 }
454 if (cbDecoded)
455 *cbDecoded = decoded;
456 TRACE("returning %d\n", ret);
457 return ret;
458 }
459
460 /* This decodes an arbitrary sequence into a contiguous block of memory
461 * (basically, a struct.) Each element being decoded is described by a struct
462 * AsnDecodeSequenceItem, see above.
463 * startingPointer is an optional pointer to the first place where dynamic
464 * data will be stored. If you know the starting offset, you may pass it
465 * here. Otherwise, pass NULL, and one will be inferred from the items.
466 */
467 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
468 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
469 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
470 DWORD *pcbDecoded, void *startingPointer)
471 {
472 BOOL ret;
473
474 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
475 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
476 startingPointer);
477
478 if (!cbEncoded)
479 {
480 SetLastError(CRYPT_E_ASN1_EOD);
481 return FALSE;
482 }
483 if (pbEncoded[0] == ASN_SEQUENCE)
484 {
485 DWORD dataLen;
486
487 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
488 {
489 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
490 const BYTE *ptr = pbEncoded + 1 + lenBytes;
491 BOOL indefinite = FALSE;
492
493 cbEncoded -= 1 + lenBytes;
494 if (dataLen == CMSG_INDEFINITE_LENGTH)
495 {
496 dataLen = cbEncoded;
497 indefinite = TRUE;
498 }
499 else if (cbEncoded < dataLen)
500 {
501 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
502 cbEncoded);
503 SetLastError(CRYPT_E_ASN1_CORRUPT);
504 ret = FALSE;
505 }
506 if (ret)
507 {
508 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
509 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
510 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
511 {
512 if (cbDecoded > cbEncoded - 2)
513 {
514 /* Not enough space for 0 TLV */
515 SetLastError(CRYPT_E_ASN1_CORRUPT);
516 ret = FALSE;
517 }
518 else if (*(ptr + cbDecoded) != 0 ||
519 *(ptr + cbDecoded + 1) != 0)
520 {
521 TRACE("expected 0 TLV\n");
522 SetLastError(CRYPT_E_ASN1_CORRUPT);
523 ret = FALSE;
524 }
525 else
526 cbDecoded += 2;
527 }
528 }
529 if (ret && !indefinite && cbDecoded != dataLen)
530 {
531 TRACE("expected %d decoded, got %d, failing\n", dataLen,
532 cbDecoded);
533 SetLastError(CRYPT_E_ASN1_CORRUPT);
534 ret = FALSE;
535 }
536 if (ret)
537 {
538 DWORD i, bytesNeeded = 0, structSize = 0;
539
540 for (i = 0; i < cItem; i++)
541 {
542 bytesNeeded += items[i].size;
543 structSize += items[i].minSize;
544 }
545 if (pcbDecoded)
546 *pcbDecoded = 1 + lenBytes + cbDecoded;
547 if (!pvStructInfo)
548 *pcbStructInfo = bytesNeeded;
549 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
550 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
551 {
552 BYTE *nextData;
553
554 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
555 pvStructInfo = *(BYTE **)pvStructInfo;
556 if (startingPointer)
557 nextData = (BYTE *)startingPointer;
558 else
559 nextData = (BYTE *)pvStructInfo + structSize;
560 memset(pvStructInfo, 0, structSize);
561 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
562 ptr, dataLen, dwFlags, pvStructInfo, nextData,
563 &cbDecoded);
564 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
565 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
566 }
567 }
568 }
569 }
570 else
571 {
572 SetLastError(CRYPT_E_ASN1_BADTAG);
573 ret = FALSE;
574 }
575 TRACE("returning %d (%08x)\n", ret, GetLastError());
576 return ret;
577 }
578
579 /* tag:
580 * The expected tag of the entire encoded array (usually a variant
581 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
582 * regardless of the tag seen.
583 * decodeFunc:
584 * used to decode each item in the array
585 * itemSize:
586 * is the minimum size of each decoded item
587 * hasPointer:
588 * indicates whether each item has a dynamic pointer
589 * pointerOffset:
590 * indicates the offset within itemSize at which the pointer exists
591 */
592 struct AsnArrayDescriptor
593 {
594 BYTE tag;
595 InternalDecodeFunc decodeFunc;
596 DWORD itemSize;
597 BOOL hasPointer;
598 DWORD pointerOffset;
599 };
600
601 struct AsnArrayItemSize
602 {
603 DWORD encodedLen;
604 DWORD size;
605 };
606
607 /* Decodes an array of like types into a struct GenericArray.
608 * The layout and decoding of the array are described by a struct
609 * AsnArrayDescriptor.
610 */
611 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
612 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
613 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
614 DWORD *pcbDecoded, void *startingPointer)
615 {
616 BOOL ret = TRUE;
617
618 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
619 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
620 startingPointer);
621
622 if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
623 {
624 DWORD dataLen;
625
626 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
627 {
628 DWORD bytesNeeded, cItems = 0, decoded;
629 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
630 /* There can be arbitrarily many items, but there is often only one.
631 */
632 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
633
634 decoded = 1 + lenBytes;
635 bytesNeeded = sizeof(struct GenericArray);
636 if (dataLen)
637 {
638 const BYTE *ptr;
639 BOOL doneDecoding = FALSE;
640
641 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
642 {
643 if (dataLen == CMSG_INDEFINITE_LENGTH)
644 {
645 if (ptr[0] == 0)
646 {
647 doneDecoding = TRUE;
648 if (ptr[1] != 0)
649 {
650 SetLastError(CRYPT_E_ASN1_CORRUPT);
651 ret = FALSE;
652 }
653 else
654 decoded += 2;
655 }
656 }
657 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
658 doneDecoding = TRUE;
659 if (!doneDecoding)
660 {
661 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
662
663 /* Each item decoded may not tolerate extraneous bytes,
664 * so get the length of the next element if known.
665 */
666 if ((ret = CRYPT_GetLengthIndefinite(ptr,
667 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
668 {
669 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
670 itemEncoded = cbEncoded - (ptr - pbEncoded);
671 else
672 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
673 itemDataLen;
674 }
675 if (ret)
676 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
677 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
678 &itemDecoded);
679 if (ret)
680 {
681 cItems++;
682 if (itemSizes != &itemSize)
683 itemSizes = CryptMemRealloc(itemSizes,
684 cItems * sizeof(struct AsnArrayItemSize));
685 else if (cItems > 1)
686 {
687 itemSizes =
688 CryptMemAlloc(
689 cItems * sizeof(struct AsnArrayItemSize));
690 if (itemSizes)
691 memcpy(itemSizes, &itemSize,
692 sizeof(itemSize));
693 }
694 if (itemSizes)
695 {
696 decoded += itemDecoded;
697 itemSizes[cItems - 1].encodedLen = itemEncoded;
698 itemSizes[cItems - 1].size = size;
699 bytesNeeded += size;
700 ptr += itemEncoded;
701 }
702 else
703 ret = FALSE;
704 }
705 }
706 }
707 }
708 if (ret)
709 {
710 if (pcbDecoded)
711 *pcbDecoded = decoded;
712 if (!pvStructInfo)
713 *pcbStructInfo = bytesNeeded;
714 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
715 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
716 {
717 DWORD i;
718 BYTE *nextData;
719 const BYTE *ptr;
720 struct GenericArray *array;
721
722 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
723 pvStructInfo = *(BYTE **)pvStructInfo;
724 array = (struct GenericArray *)pvStructInfo;
725 array->cItems = cItems;
726 if (startingPointer)
727 array->rgItems = startingPointer;
728 else
729 array->rgItems = (BYTE *)array +
730 sizeof(struct GenericArray);
731 nextData = array->rgItems +
732 array->cItems * arrayDesc->itemSize;
733 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
734 i < cItems && ptr - pbEncoded - 1 - lenBytes <
735 dataLen; i++)
736 {
737 DWORD itemDecoded;
738
739 if (arrayDesc->hasPointer)
740 *(BYTE **)(array->rgItems + i * arrayDesc->itemSize
741 + arrayDesc->pointerOffset) = nextData;
742 ret = arrayDesc->decodeFunc(ptr,
743 itemSizes[i].encodedLen,
744 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
745 array->rgItems + i * arrayDesc->itemSize,
746 &itemSizes[i].size, &itemDecoded);
747 if (ret)
748 {
749 nextData += itemSizes[i].size - arrayDesc->itemSize;
750 ptr += itemDecoded;
751 }
752 }
753 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
754 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
755 }
756 }
757 if (itemSizes != &itemSize)
758 CryptMemFree(itemSizes);
759 }
760 }
761 else
762 {
763 SetLastError(CRYPT_E_ASN1_BADTAG);
764 ret = FALSE;
765 }
766 return ret;
767 }
768
769 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
770 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
771 * to CRYPT_E_ASN1_CORRUPT.
772 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
773 * set!
774 */
775 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
776 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
777 {
778 BOOL ret;
779 DWORD dataLen;
780
781 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
782 {
783 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
784 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
785
786 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
787 bytesNeeded += 1 + lenBytes + dataLen;
788
789 if (pcbDecoded)
790 *pcbDecoded = 1 + lenBytes + dataLen;
791 if (!pvStructInfo)
792 *pcbStructInfo = bytesNeeded;
793 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
794 {
795 CRYPT_DER_BLOB *blob;
796
797 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
798 pvStructInfo = *(BYTE **)pvStructInfo;
799 blob = (CRYPT_DER_BLOB *)pvStructInfo;
800 blob->cbData = 1 + lenBytes + dataLen;
801 if (blob->cbData)
802 {
803 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
804 blob->pbData = (BYTE *)pbEncoded;
805 else
806 {
807 assert(blob->pbData);
808 memcpy(blob->pbData, pbEncoded, blob->cbData);
809 }
810 }
811 else
812 {
813 SetLastError(CRYPT_E_ASN1_CORRUPT);
814 ret = FALSE;
815 }
816 }
817 }
818 return ret;
819 }
820
821 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
822 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
823 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
824 DWORD *pcbDecoded)
825 {
826 BOOL ret;
827
828 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
829 pvStructInfo, *pcbStructInfo, pcbDecoded);
830
831 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
832 * place.
833 */
834 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
835 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
836 pcbDecoded);
837 if (ret && pvStructInfo)
838 {
839 CRYPT_BIT_BLOB *blob = (CRYPT_BIT_BLOB *)pvStructInfo;
840
841 if (blob->cbData)
842 {
843 DWORD i;
844 BYTE temp;
845
846 for (i = 0; i < blob->cbData / 2; i++)
847 {
848 temp = blob->pbData[i];
849 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
850 blob->pbData[blob->cbData - i - 1] = temp;
851 }
852 }
853 }
854 TRACE("returning %d (%08x)\n", ret, GetLastError());
855 return ret;
856 }
857
858 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
859 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
860 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
861 {
862 BOOL ret = TRUE;
863
864 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
865 pDecodePara, pvStructInfo, *pcbStructInfo);
866
867 __TRY
868 {
869 struct AsnDecodeSequenceItem items[] = {
870 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
871 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
872 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
873 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
874 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
875 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
876 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
877 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
878 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
879 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
880 };
881
882 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
883 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
884 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
885 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
886 pcbStructInfo, NULL, NULL);
887 }
888 __EXCEPT_PAGE_FAULT
889 {
890 SetLastError(STATUS_ACCESS_VIOLATION);
891 ret = FALSE;
892 }
893 __ENDTRY
894
895 TRACE("Returning %d (%08x)\n", ret, GetLastError());
896 return ret;
897 }
898
899 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
900 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
901 {
902 BOOL ret;
903 DWORD dataLen;
904
905 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
906 {
907 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
908
909 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
910 dwFlags, pvStructInfo, pcbStructInfo, NULL);
911 if (pcbDecoded)
912 *pcbDecoded = 1 + lenBytes + dataLen;
913 }
914 return ret;
915 }
916
917 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
918 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
919 {
920 BOOL ret;
921
922 struct AsnDecodeSequenceItem items[] = {
923 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
924 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
925 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
926 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
927 };
928
929 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
930 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
931 pcbDecoded, NULL);
932 return ret;
933 }
934
935 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
936 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
937 DWORD *pcbDecoded)
938 {
939 BOOL ret;
940 DWORD dataLen;
941
942 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
943 {
944 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
945
946 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded + 1 + lenBytes,
947 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
948 if (ret && pcbDecoded)
949 *pcbDecoded = 1 + lenBytes + dataLen;
950 }
951 return ret;
952 }
953
954 static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
955 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
956 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
957 {
958 BOOL ret = TRUE;
959 struct AsnDecodeSequenceItem items[] = {
960 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
961 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
962 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
963 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
964 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
965 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
966 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
967 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
968 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
969 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
970 Issuer.pbData) },
971 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
972 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
973 FALSE, 0 },
974 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
975 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
976 Subject.pbData) },
977 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
978 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
979 FALSE, TRUE, offsetof(CERT_INFO,
980 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
981 { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
982 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
983 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
984 { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
985 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
986 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
987 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
988 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
989 offsetof(CERT_INFO, rgExtension), 0 },
990 };
991
992 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
993 pDecodePara, pvStructInfo, *pcbStructInfo);
994
995 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
996 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
997 NULL, NULL);
998 if (ret && pvStructInfo)
999 {
1000 CERT_INFO *info;
1001
1002 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1003 info = *(CERT_INFO **)pvStructInfo;
1004 else
1005 info = (CERT_INFO *)pvStructInfo;
1006 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1007 !info->Subject.cbData)
1008 {
1009 SetLastError(CRYPT_E_ASN1_CORRUPT);
1010 /* Don't need to deallocate, because it should have failed on the
1011 * first pass (and no memory was allocated.)
1012 */
1013 ret = FALSE;
1014 }
1015 }
1016
1017 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1018 return ret;
1019 }
1020
1021 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1022 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1023 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1024 {
1025 BOOL ret = FALSE;
1026
1027 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1028 pDecodePara, pvStructInfo, *pcbStructInfo);
1029
1030 __TRY
1031 {
1032 DWORD size = 0;
1033
1034 /* Unless told not to, first try to decode it as a signed cert. */
1035 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1036 {
1037 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1038
1039 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1040 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1041 (BYTE *)&signedCert, &size);
1042 if (ret)
1043 {
1044 size = 0;
1045 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1046 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1047 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1048 pvStructInfo, pcbStructInfo);
1049 LocalFree(signedCert);
1050 }
1051 }
1052 /* Failing that, try it as an unsigned cert */
1053 if (!ret)
1054 {
1055 size = 0;
1056 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1057 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1058 pDecodePara, pvStructInfo, pcbStructInfo);
1059 }
1060 }
1061 __EXCEPT_PAGE_FAULT
1062 {
1063 SetLastError(STATUS_ACCESS_VIOLATION);
1064 }
1065 __ENDTRY
1066
1067 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1068 return ret;
1069 }
1070
1071 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1072 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1073 {
1074 BOOL ret;
1075 struct AsnDecodeSequenceItem items[] = {
1076 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1077 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1078 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1079 { 0, offsetof(CRL_ENTRY, RevocationDate),
1080 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1081 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1082 CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1083 offsetof(CRL_ENTRY, rgExtension), 0 },
1084 };
1085 PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo;
1086
1087 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1088 *pcbStructInfo);
1089
1090 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1091 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1092 entry ? entry->SerialNumber.pbData : NULL);
1093 if (ret && entry && !entry->SerialNumber.cbData)
1094 {
1095 WARN("empty CRL entry serial number\n");
1096 SetLastError(CRYPT_E_ASN1_CORRUPT);
1097 ret = FALSE;
1098 }
1099 return ret;
1100 }
1101
1102 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1103 * been set prior to calling.
1104 */
1105 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1106 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1107 {
1108 BOOL ret;
1109 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1110 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1111 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1112 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
1113
1114 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1115 pvStructInfo, *pcbStructInfo, pcbDecoded);
1116
1117 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1118 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1119 entries ? entries->rgItems : NULL);
1120 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1121 return ret;
1122 }
1123
1124 static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1125 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1126 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1127 {
1128 struct AsnDecodeSequenceItem items[] = {
1129 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1130 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1131 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1132 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1133 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1134 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1135 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1136 Issuer.pbData) },
1137 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1138 sizeof(FILETIME), FALSE, FALSE, 0 },
1139 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1140 sizeof(FILETIME), TRUE, FALSE, 0 },
1141 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1142 CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE,
1143 offsetof(CRL_INFO, rgCRLEntry), 0 },
1144 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1145 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1146 offsetof(CRL_INFO, rgExtension), 0 },
1147 };
1148 BOOL ret = TRUE;
1149
1150 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1151 pDecodePara, pvStructInfo, *pcbStructInfo);
1152
1153 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1154 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1155 NULL, NULL);
1156
1157 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1158 return ret;
1159 }
1160
1161 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1162 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1163 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1164 {
1165 BOOL ret = FALSE;
1166
1167 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1168 pDecodePara, pvStructInfo, *pcbStructInfo);
1169
1170 __TRY
1171 {
1172 DWORD size = 0;
1173
1174 /* Unless told not to, first try to decode it as a signed crl. */
1175 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1176 {
1177 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1178
1179 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1180 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1181 (BYTE *)&signedCrl, &size);
1182 if (ret)
1183 {
1184 size = 0;
1185 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1186 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1187 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1188 pvStructInfo, pcbStructInfo);
1189 LocalFree(signedCrl);
1190 }
1191 }
1192 /* Failing that, try it as an unsigned crl */
1193 if (!ret)
1194 {
1195 size = 0;
1196 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1197 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1198 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1199 }
1200 }
1201 __EXCEPT_PAGE_FAULT
1202 {
1203 SetLastError(STATUS_ACCESS_VIOLATION);
1204 }
1205 __ENDTRY
1206
1207 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1208 return ret;
1209 }
1210
1211 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1212 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1213 {
1214 BOOL ret = TRUE;
1215 DWORD dataLen;
1216
1217 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1218 pvStructInfo, *pcbStructInfo);
1219
1220 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1221 {
1222 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1223 DWORD bytesNeeded = sizeof(LPSTR);
1224
1225 if (dataLen)
1226 {
1227 /* The largest possible string for the first two components
1228 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1229 */
1230 char firstTwo[6];
1231 const BYTE *ptr;
1232
1233 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1234 pbEncoded[1 + lenBytes] / 40,
1235 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1236 * 40);
1237 bytesNeeded += strlen(firstTwo) + 1;
1238 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1239 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1240 {
1241 /* large enough for ".4000000" */
1242 char str[9];
1243 int val = 0;
1244
1245 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1246 (*ptr & 0x80))
1247 {
1248 val <<= 7;
1249 val |= *ptr & 0x7f;
1250 ptr++;
1251 }
1252 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1253 (*ptr & 0x80))
1254 {
1255 SetLastError(CRYPT_E_ASN1_CORRUPT);
1256 ret = FALSE;
1257 }
1258 else
1259 {
1260 val <<= 7;
1261 val |= *ptr++;
1262 snprintf(str, sizeof(str), ".%d", val);
1263 bytesNeeded += strlen(str);
1264 }
1265 }
1266 }
1267 if (pcbDecoded)
1268 *pcbDecoded = 1 + lenBytes + dataLen;
1269 if (!pvStructInfo)
1270 *pcbStructInfo = bytesNeeded;
1271 else if (*pcbStructInfo < bytesNeeded)
1272 {
1273 *pcbStructInfo = bytesNeeded;
1274 SetLastError(ERROR_MORE_DATA);
1275 ret = FALSE;
1276 }
1277 else
1278 {
1279 if (dataLen)
1280 {
1281 const BYTE *ptr;
1282 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1283
1284 *pszObjId = 0;
1285 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1286 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1287 40) * 40);
1288 pszObjId += strlen(pszObjId);
1289 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1290 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1291 {
1292 int val = 0;
1293
1294 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1295 (*ptr & 0x80))
1296 {
1297 val <<= 7;
1298 val |= *ptr & 0x7f;
1299 ptr++;
1300 }
1301 val <<= 7;
1302 val |= *ptr++;
1303 sprintf(pszObjId, ".%d", val);
1304 pszObjId += strlen(pszObjId);
1305 }
1306 }
1307 else
1308 *(LPSTR *)pvStructInfo = NULL;
1309 *pcbStructInfo = bytesNeeded;
1310 }
1311 }
1312 return ret;
1313 }
1314
1315 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1316 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1317 {
1318 BOOL ret;
1319
1320 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1321 pvStructInfo, *pcbStructInfo);
1322
1323 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1324 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1325 pvStructInfo, pcbStructInfo, pcbDecoded);
1326 else
1327 {
1328 SetLastError(CRYPT_E_ASN1_BADTAG);
1329 ret = FALSE;
1330 }
1331 return ret;
1332 }
1333
1334 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1335 * ahead of time!
1336 */
1337 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1338 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1339 {
1340 struct AsnDecodeSequenceItem items[] = {
1341 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1342 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1343 offsetof(CERT_EXTENSION, pszObjId), 0 },
1344 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1345 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1346 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1347 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1348 offsetof(CERT_EXTENSION, Value.pbData) },
1349 };
1350 BOOL ret = TRUE;
1351 PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo;
1352
1353 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1354 *pcbStructInfo);
1355
1356 if (ext)
1357 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1358 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1359 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1360 pcbDecoded, ext ? ext->pszObjId : NULL);
1361 if (ext)
1362 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1363 debugstr_a(ext->pszObjId));
1364 TRACE("returning %d (%08x)\n", ret, GetLastError());
1365 return ret;
1366 }
1367
1368 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
1369 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1370 DWORD *pcbDecoded)
1371 {
1372 BOOL ret = TRUE;
1373 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1374 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1375 offsetof(CERT_EXTENSION, pszObjId) };
1376 PCERT_EXTENSIONS exts = (PCERT_EXTENSIONS)pvStructInfo;
1377
1378 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1379 pvStructInfo, *pcbStructInfo, pcbDecoded);
1380
1381 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1382 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1383 exts ? exts->rgExtension : NULL);
1384 return ret;
1385 }
1386
1387 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1388 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1389 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1390 {
1391 BOOL ret = TRUE;
1392
1393 __TRY
1394 {
1395 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1396 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1397 if (ret && pvStructInfo)
1398 {
1399 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1400 pcbStructInfo, *pcbStructInfo);
1401 if (ret)
1402 {
1403 CERT_EXTENSIONS *exts;
1404
1405 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1406 pvStructInfo = *(BYTE **)pvStructInfo;
1407 exts = (CERT_EXTENSIONS *)pvStructInfo;
1408 exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
1409 sizeof(CERT_EXTENSIONS));
1410 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1411 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1412 pcbStructInfo, NULL);
1413 }
1414 }
1415 }
1416 __EXCEPT_PAGE_FAULT
1417 {
1418 SetLastError(STATUS_ACCESS_VIOLATION);
1419 ret = FALSE;
1420 }
1421 __ENDTRY
1422 return ret;
1423 }
1424
1425 /* Warning: this assumes the address of value->Value.pbData is already set, in
1426 * order to avoid overwriting memory. (In some cases, it may change it, if it
1427 * doesn't copy anything to memory.) Be sure to set it correctly!
1428 */
1429 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1430 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1431 DWORD *pcbDecoded)
1432 {
1433 BOOL ret = TRUE;
1434 DWORD dataLen;
1435 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1436
1437 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1438 {
1439 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1440 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1441
1442 switch (pbEncoded[0])
1443 {
1444 case ASN_OCTETSTRING:
1445 valueType = CERT_RDN_OCTET_STRING;
1446 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1447 bytesNeeded += dataLen;
1448 break;
1449 case ASN_NUMERICSTRING:
1450 valueType = CERT_RDN_NUMERIC_STRING;
1451 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1452 bytesNeeded += dataLen;
1453 break;
1454 case ASN_PRINTABLESTRING:
1455 valueType = CERT_RDN_PRINTABLE_STRING;
1456 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1457 bytesNeeded += dataLen;
1458 break;
1459 case ASN_IA5STRING:
1460 valueType = CERT_RDN_IA5_STRING;
1461 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1462 bytesNeeded += dataLen;
1463 break;
1464 case ASN_T61STRING:
1465 valueType = CERT_RDN_T61_STRING;
1466 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1467 bytesNeeded += dataLen;
1468 break;
1469 case ASN_VIDEOTEXSTRING:
1470 valueType = CERT_RDN_VIDEOTEX_STRING;
1471 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1472 bytesNeeded += dataLen;
1473 break;
1474 case ASN_GRAPHICSTRING:
1475 valueType = CERT_RDN_GRAPHIC_STRING;
1476 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1477 bytesNeeded += dataLen;
1478 break;
1479 case ASN_VISIBLESTRING:
1480 valueType = CERT_RDN_VISIBLE_STRING;
1481 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1482 bytesNeeded += dataLen;
1483 break;
1484 case ASN_GENERALSTRING:
1485 valueType = CERT_RDN_GENERAL_STRING;
1486 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1487 bytesNeeded += dataLen;
1488 break;
1489 case ASN_UNIVERSALSTRING:
1490 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1491 SetLastError(CRYPT_E_ASN1_BADTAG);
1492 return FALSE;
1493 case ASN_BMPSTRING:
1494 valueType = CERT_RDN_BMP_STRING;
1495 bytesNeeded += dataLen;
1496 break;
1497 case ASN_UTF8STRING:
1498 valueType = CERT_RDN_UTF8_STRING;
1499 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1500 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1501 break;
1502 default:
1503 SetLastError(CRYPT_E_ASN1_BADTAG);
1504 return FALSE;
1505 }
1506
1507 if (pcbDecoded)
1508 *pcbDecoded = 1 + lenBytes + dataLen;
1509 if (!value)
1510 *pcbStructInfo = bytesNeeded;
1511 else if (*pcbStructInfo < bytesNeeded)
1512 {
1513 *pcbStructInfo = bytesNeeded;
1514 SetLastError(ERROR_MORE_DATA);
1515 ret = FALSE;
1516 }
1517 else
1518 {
1519 *pcbStructInfo = bytesNeeded;
1520 value->dwValueType = valueType;
1521 if (dataLen)
1522 {
1523 DWORD i;
1524
1525 assert(value->Value.pbData);
1526 switch (pbEncoded[0])
1527 {
1528 case ASN_OCTETSTRING:
1529 case ASN_NUMERICSTRING:
1530 case ASN_PRINTABLESTRING:
1531 case ASN_IA5STRING:
1532 case ASN_T61STRING:
1533 case ASN_VIDEOTEXSTRING:
1534 case ASN_GRAPHICSTRING:
1535 case ASN_VISIBLESTRING:
1536 case ASN_GENERALSTRING:
1537 value->Value.cbData = dataLen;
1538 if (dataLen)
1539 {
1540 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1541 memcpy(value->Value.pbData,
1542 pbEncoded + 1 + lenBytes, dataLen);
1543 else
1544 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1545 lenBytes;
1546 }
1547 break;
1548 case ASN_BMPSTRING:
1549 {
1550 LPWSTR str = (LPWSTR)value->Value.pbData;
1551
1552 value->Value.cbData = dataLen;
1553 for (i = 0; i < dataLen / 2; i++)
1554 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1555 pbEncoded[1 + lenBytes + 2 * i + 1];
1556 break;
1557 }
1558 case ASN_UTF8STRING:
1559 {
1560 LPWSTR str = (LPWSTR)value->Value.pbData;
1561
1562 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1563 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1564 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1565 break;
1566 }
1567 }
1568 }
1569 else
1570 {
1571 value->Value.cbData = 0;
1572 value->Value.pbData = NULL;
1573 }
1574 }
1575 }
1576 return ret;
1577 }
1578
1579 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1580 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1581 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1582 {
1583 BOOL ret = TRUE;
1584
1585 __TRY
1586 {
1587 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1588 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1589 if (ret && pvStructInfo)
1590 {
1591 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1592 pcbStructInfo, *pcbStructInfo);
1593 if (ret)
1594 {
1595 CERT_NAME_VALUE *value;
1596
1597 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1598 pvStructInfo = *(BYTE **)pvStructInfo;
1599 value = (CERT_NAME_VALUE *)pvStructInfo;
1600 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1601 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1602 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1603 pcbStructInfo, NULL);
1604 }
1605 }
1606 }
1607 __EXCEPT_PAGE_FAULT
1608 {
1609 SetLastError(STATUS_ACCESS_VIOLATION);
1610 ret = FALSE;
1611 }
1612 __ENDTRY
1613 return ret;
1614 }
1615
1616 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1617 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1618 DWORD *pcbDecoded)
1619 {
1620 BOOL ret = TRUE;
1621 DWORD dataLen;
1622 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1623
1624 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1625 {
1626 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1627 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1628
1629 switch (pbEncoded[0])
1630 {
1631 case ASN_NUMERICSTRING:
1632 valueType = CERT_RDN_NUMERIC_STRING;
1633 bytesNeeded += dataLen * 2;
1634 break;
1635 case ASN_PRINTABLESTRING:
1636 valueType = CERT_RDN_PRINTABLE_STRING;
1637 bytesNeeded += dataLen * 2;
1638 break;
1639 case ASN_IA5STRING:
1640 valueType = CERT_RDN_IA5_STRING;
1641 bytesNeeded += dataLen * 2;
1642 break;
1643 case ASN_T61STRING:
1644 valueType = CERT_RDN_T61_STRING;
1645 bytesNeeded += dataLen * 2;
1646 break;
1647 case ASN_VIDEOTEXSTRING:
1648 valueType = CERT_RDN_VIDEOTEX_STRING;
1649 bytesNeeded += dataLen * 2;
1650 break;
1651 case ASN_GRAPHICSTRING:
1652 valueType = CERT_RDN_GRAPHIC_STRING;
1653 bytesNeeded += dataLen * 2;
1654 break;
1655 case ASN_VISIBLESTRING:
1656 valueType = CERT_RDN_VISIBLE_STRING;
1657 bytesNeeded += dataLen * 2;
1658 break;
1659 case ASN_GENERALSTRING:
1660 valueType = CERT_RDN_GENERAL_STRING;
1661 bytesNeeded += dataLen * 2;
1662 break;
1663 case ASN_UNIVERSALSTRING:
1664 valueType = CERT_RDN_UNIVERSAL_STRING;
1665 bytesNeeded += dataLen / 2;
1666 break;
1667 case ASN_BMPSTRING:
1668 valueType = CERT_RDN_BMP_STRING;
1669 bytesNeeded += dataLen;
1670 break;
1671 case ASN_UTF8STRING:
1672 valueType = CERT_RDN_UTF8_STRING;
1673 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1674 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1675 break;
1676 default:
1677 SetLastError(CRYPT_E_ASN1_BADTAG);
1678 return FALSE;
1679 }
1680
1681 if (pcbDecoded)
1682 *pcbDecoded = 1 + lenBytes + dataLen;
1683 if (!value)
1684 *pcbStructInfo = bytesNeeded;
1685 else if (*pcbStructInfo < bytesNeeded)
1686 {
1687 *pcbStructInfo = bytesNeeded;
1688 SetLastError(ERROR_MORE_DATA);
1689 ret = FALSE;
1690 }
1691 else
1692 {
1693 *pcbStructInfo = bytesNeeded;
1694 value->dwValueType = valueType;
1695 if (dataLen)
1696 {
1697 DWORD i;
1698 LPWSTR str = (LPWSTR)value->Value.pbData;
1699
1700 assert(value->Value.pbData);
1701 switch (pbEncoded[0])
1702 {
1703 case ASN_NUMERICSTRING:
1704 case ASN_PRINTABLESTRING:
1705 case ASN_IA5STRING:
1706 case ASN_T61STRING:
1707 case ASN_VIDEOTEXSTRING:
1708 case ASN_GRAPHICSTRING:
1709 case ASN_VISIBLESTRING:
1710 case ASN_GENERALSTRING:
1711 value->Value.cbData = dataLen * 2;
1712 for (i = 0; i < dataLen; i++)
1713 str[i] = pbEncoded[1 + lenBytes + i];
1714 break;
1715 case ASN_UNIVERSALSTRING:
1716 value->Value.cbData = dataLen / 2;
1717 for (i = 0; i < dataLen / 4; i++)
1718 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1719 | pbEncoded[1 + lenBytes + 2 * i + 3];
1720 break;
1721 case ASN_BMPSTRING:
1722 value->Value.cbData = dataLen;
1723 for (i = 0; i < dataLen / 2; i++)
1724 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1725 pbEncoded[1 + lenBytes + 2 * i + 1];
1726 break;
1727 case ASN_UTF8STRING:
1728 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1729 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1730 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1731 break;
1732 }
1733 }
1734 else
1735 {
1736 value->Value.cbData = 0;
1737 value->Value.pbData = NULL;
1738 }
1739 }
1740 }
1741 return ret;
1742 }
1743
1744 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1745 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1746 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1747 {
1748 BOOL ret = TRUE;
1749
1750 __TRY
1751 {
1752 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1753 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1754 if (ret && pvStructInfo)
1755 {
1756 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1757 pcbStructInfo, *pcbStructInfo);
1758 if (ret)
1759 {
1760 CERT_NAME_VALUE *value;
1761
1762 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1763 pvStructInfo = *(BYTE **)pvStructInfo;
1764 value = (CERT_NAME_VALUE *)pvStructInfo;
1765 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1766 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1767 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1768 pcbStructInfo, NULL);
1769 }
1770 }
1771 }
1772 __EXCEPT_PAGE_FAULT
1773 {
1774 SetLastError(STATUS_ACCESS_VIOLATION);
1775 ret = FALSE;
1776 }
1777 __ENDTRY
1778 return ret;
1779 }
1780
1781 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1782 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1783 {
1784 BOOL ret;
1785 struct AsnDecodeSequenceItem items[] = {
1786 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1787 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1788 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1789 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1790 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1791 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1792 };
1793 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1794
1795 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1796 pvStructInfo, *pcbStructInfo);
1797
1798 if (attr)
1799 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1800 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1801 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1802 attr ? attr->pszObjId : NULL);
1803 if (attr)
1804 {
1805 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1806 debugstr_a(attr->pszObjId));
1807 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1808 }
1809 TRACE("returning %d (%08x)\n", ret, GetLastError());
1810 return ret;
1811 }
1812
1813 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1814 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1815 {
1816 BOOL ret = TRUE;
1817 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1818 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1819 offsetof(CERT_RDN_ATTR, pszObjId) };
1820 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1821
1822 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1823 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1824 rdn ? rdn->rgRDNAttr : NULL);
1825 return ret;
1826 }
1827
1828 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1829 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1830 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1831 {
1832 BOOL ret = TRUE;
1833
1834 __TRY
1835 {
1836 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1837 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1838 offsetof(CERT_RDN, rgRDNAttr) };
1839
1840 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1841 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1842 }
1843 __EXCEPT_PAGE_FAULT
1844 {
1845 SetLastError(STATUS_ACCESS_VIOLATION);
1846 ret = FALSE;
1847 }
1848 __ENDTRY
1849 return ret;
1850 }
1851
1852 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1853 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1854 DWORD *pcbDecoded)
1855 {
1856 BOOL ret;
1857 struct AsnDecodeSequenceItem items[] = {
1858 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1859 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1860 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1861 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1862 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1863 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1864 };
1865 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1866
1867 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1868 pvStructInfo, *pcbStructInfo);
1869
1870 if (attr)
1871 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1872 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1873 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1874 attr ? attr->pszObjId : NULL);
1875 if (attr)
1876 {
1877 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1878 debugstr_a(attr->pszObjId));
1879 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1880 }
1881 TRACE("returning %d (%08x)\n", ret, GetLastError());
1882 return ret;
1883 }
1884
1885 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1886 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1887 {
1888 BOOL ret = TRUE;
1889 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1890 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1891 offsetof(CERT_RDN_ATTR, pszObjId) };
1892 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1893
1894 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1895 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1896 rdn ? rdn->rgRDNAttr : NULL);
1897 return ret;
1898 }
1899
1900 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1901 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1902 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1903 {
1904 BOOL ret = TRUE;
1905
1906 __TRY
1907 {
1908 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1909 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
1910 offsetof(CERT_RDN, rgRDNAttr) };
1911
1912 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1913 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1914 }
1915 __EXCEPT_PAGE_FAULT
1916 {
1917 SetLastError(STATUS_ACCESS_VIOLATION);
1918 ret = FALSE;
1919 }
1920 __ENDTRY
1921 return ret;
1922 }
1923
1924 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
1925 DWORD *pcbDecoded)
1926 {
1927 BOOL ret = TRUE, done = FALSE;
1928 DWORD indefiniteNestingLevels = 0, decoded = 0;
1929
1930 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
1931
1932 do {
1933 DWORD dataLen;
1934
1935 if (!cbEncoded)
1936 done = TRUE;
1937 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
1938 &dataLen)))
1939 {
1940 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1941
1942 if (dataLen == CMSG_INDEFINITE_LENGTH)
1943 {
1944 indefiniteNestingLevels++;
1945 pbEncoded += 1 + lenBytes;
1946 cbEncoded -= 1 + lenBytes;
1947 decoded += 1 + lenBytes;
1948 TRACE("indefiniteNestingLevels = %d\n",
1949 indefiniteNestingLevels);
1950 }
1951 else
1952 {
1953 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
1954 indefiniteNestingLevels)
1955 {
1956 indefiniteNestingLevels--;
1957 TRACE("indefiniteNestingLevels = %d\n",
1958 indefiniteNestingLevels);
1959 }
1960 pbEncoded += 1 + lenBytes + dataLen;
1961 cbEncoded -= 1 + lenBytes + dataLen;
1962 decoded += 1 + lenBytes + dataLen;
1963 if (!indefiniteNestingLevels)
1964 done = TRUE;
1965 }
1966 }
1967 } while (ret && !done);
1968 /* If we haven't found all 0 TLVs, we haven't found the end */
1969 if (ret && indefiniteNestingLevels)
1970 {
1971 SetLastError(CRYPT_E_ASN1_EOD);
1972 ret = FALSE;
1973 }
1974 if (ret)
1975 *pcbDecoded = decoded;
1976 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
1977 return ret;
1978 }
1979
1980 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
1981 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1982 DWORD *pcbDecoded)
1983 {
1984 BOOL ret = TRUE;
1985 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
1986
1987 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1988 pvStructInfo, *pcbStructInfo);
1989
1990 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
1991 {
1992 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1993 bytesNeeded += encodedLen;
1994 if (!pvStructInfo)
1995 *pcbStructInfo = bytesNeeded;
1996 else if (*pcbStructInfo < bytesNeeded)
1997 {
1998 SetLastError(ERROR_MORE_DATA);
1999 *pcbStructInfo = bytesNeeded;
2000 ret = FALSE;
2001 }
2002 else
2003 {
2004 PCRYPT_OBJID_BLOB blob = (PCRYPT_OBJID_BLOB)pvStructInfo;
2005
2006 *pcbStructInfo = bytesNeeded;
2007 blob->cbData = encodedLen;
2008 if (encodedLen)
2009 {
2010 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2011 blob->pbData = (LPBYTE)pbEncoded;
2012 else
2013 {
2014 assert(blob->pbData);
2015 memcpy(blob->pbData, pbEncoded, blob->cbData);
2016 }
2017 }
2018 else
2019 blob->pbData = NULL;
2020 }
2021 if (pcbDecoded)
2022 *pcbDecoded = encodedLen;
2023 }
2024 return ret;
2025 }
2026
2027 static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded,
2028 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2029 {
2030 BOOL ret;
2031 struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
2032 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2033 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
2034
2035 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2036 pvStructInfo, *pcbStructInfo, pcbDecoded);
2037
2038 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2039 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2040 array ? array->rgItems : NULL);
2041 return ret;
2042 }
2043
2044 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2045 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2046 {
2047 BOOL ret;
2048 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2049 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2050 CTL_USAGE *usage = (CTL_USAGE *)pvStructInfo;
2051
2052 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2053 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2054 usage ? usage->rgpszUsageIdentifier : NULL);
2055 return ret;
2056 }
2057
2058 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2059 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2060 {
2061 struct AsnDecodeSequenceItem items[] = {
2062 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2063 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2064 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2065 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2066 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), FALSE,
2067 TRUE, offsetof(CTL_ENTRY, rgAttribute), 0 },
2068 };
2069 BOOL ret = TRUE;
2070 CTL_ENTRY *entry = (CTL_ENTRY *)pvStructInfo;
2071
2072 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2073 *pcbStructInfo);
2074
2075 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2076 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2077 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2078 return ret;
2079 }
2080
2081 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2082 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2083 {
2084 BOOL ret;
2085 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2086 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2087 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2088 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
2089
2090 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2091 pvStructInfo, *pcbStructInfo, pcbDecoded);
2092
2093 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2094 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2095 entries ? entries->rgItems : NULL);
2096 return ret;
2097 }
2098
2099 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2100 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2101 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2102 {
2103 BOOL ret = FALSE;
2104
2105 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2106 pDecodePara, pvStructInfo, *pcbStructInfo);
2107
2108 __TRY
2109 {
2110 struct AsnDecodeSequenceItem items[] = {
2111 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2112 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2113 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2114 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2115 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2116 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2117 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2118 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2119 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2120 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2121 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2122 { 0, offsetof(CTL_INFO, ThisUpdate),
2123 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2124 0 },
2125 { 0, offsetof(CTL_INFO, NextUpdate),
2126 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2127 0 },
2128 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2129 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2130 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2131 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2132 CRYPT_AsnDecodeCTLEntries, sizeof(struct GenericArray),
2133 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2134 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2135 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
2136 offsetof(CTL_INFO, rgExtension), 0 },
2137 };
2138
2139 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2140 pDecodePara, pvStructInfo, *pcbStructInfo);
2141
2142 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2143 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2144 pcbStructInfo, NULL, NULL);
2145 }
2146 __EXCEPT_PAGE_FAULT
2147 {
2148 SetLastError(STATUS_ACCESS_VIOLATION);
2149 }
2150 __ENDTRY
2151 return ret;
2152 }
2153
2154 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2155 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2156 DWORD *pcbDecoded)
2157 {
2158 BOOL ret;
2159 struct AsnDecodeSequenceItem items[] = {
2160 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2161 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2162 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2163 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2164 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2165 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2166 };
2167 PCRYPT_SMIME_CAPABILITY capability = (PCRYPT_SMIME_CAPABILITY)pvStructInfo;
2168
2169 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2170 pvStructInfo, *pcbStructInfo);
2171
2172 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2173 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2174 pcbDecoded, capability ? capability->pszObjId : NULL);
2175 TRACE("returning %d\n", ret);
2176 return ret;
2177 }
2178
2179 static BOOL CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE *pbEncoded,
2180 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2181 DWORD *pcbDecoded)
2182 {
2183 struct AsnArrayDescriptor arrayDesc = { 0,
2184 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2185 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2186 PCRYPT_SMIME_CAPABILITIES capabilities =
2187 (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
2188 BOOL ret;
2189
2190 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2191 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2192 capabilities ? capabilities->rgCapability : NULL);
2193 return ret;
2194 }
2195
2196 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2197 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2198 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2199 {
2200 BOOL ret = FALSE;
2201
2202 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2203 pDecodePara, pvStructInfo, *pcbStructInfo);
2204
2205 __TRY
2206 {
2207 DWORD bytesNeeded;
2208
2209 if (!cbEncoded)
2210 SetLastError(CRYPT_E_ASN1_EOD);
2211 else if (pbEncoded[0] != ASN_SEQUENCEOF)
2212 SetLastError(CRYPT_E_ASN1_CORRUPT);
2213 else if ((ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2214 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2215 NULL)))
2216 {
2217 if (!pvStructInfo)
2218 *pcbStructInfo = bytesNeeded;
2219 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2220 pvStructInfo, pcbStructInfo, bytesNeeded)))
2221 {
2222 PCRYPT_SMIME_CAPABILITIES capabilities;
2223
2224 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2225 pvStructInfo = *(BYTE **)pvStructInfo;
2226 capabilities = (PCRYPT_SMIME_CAPABILITIES)pvStructInfo;
2227 capabilities->rgCapability =
2228 (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
2229 sizeof(CRYPT_SMIME_CAPABILITIES));
2230 ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded,
2231 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2232 &bytesNeeded, NULL);
2233 }
2234 }
2235 }
2236 __EXCEPT_PAGE_FAULT
2237 {
2238 SetLastError(STATUS_ACCESS_VIOLATION);
2239 }
2240 __ENDTRY
2241 TRACE("returning %d\n", ret);
2242 return ret;
2243 }
2244
2245 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2246 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2247 DWORD *pcbDecoded)
2248 {
2249 BOOL ret;
2250 struct AsnDecodeSequenceItem items[] = {
2251 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2252 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2253 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2254 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2255 CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE,
2256 offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2257 };
2258 PCRYPT_ATTRIBUTE attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2259
2260 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2261 pvStructInfo, *pcbStructInfo);
2262
2263 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2264 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2265 pcbDecoded, attr ? attr->pszObjId : NULL);
2266 TRACE("returning %d\n", ret);
2267 return ret;
2268 }
2269
2270 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2271 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2272 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2273 {
2274 BOOL ret = FALSE;
2275
2276 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2277 pDecodePara, pvStructInfo, *pcbStructInfo);
2278
2279 __TRY
2280 {
2281 DWORD bytesNeeded;
2282
2283 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2284 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2285 if (ret)
2286 {
2287 if (!pvStructInfo)
2288 *pcbStructInfo = bytesNeeded;
2289 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2290 pvStructInfo, pcbStructInfo, bytesNeeded)))
2291 {
2292 PCRYPT_ATTRIBUTE attr;
2293
2294 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2295 pvStructInfo = *(BYTE **)pvStructInfo;
2296 attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2297 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2298 sizeof(CRYPT_ATTRIBUTE));
2299 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2300 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2301 NULL);
2302 }
2303 }
2304 }
2305 __EXCEPT_PAGE_FAULT
2306 {
2307 SetLastError(STATUS_ACCESS_VIOLATION);
2308 }
2309 __ENDTRY
2310 TRACE("returning %d\n", ret);
2311 return ret;
2312 }
2313
2314 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2315 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2316 DWORD *pcbDecoded)
2317 {
2318 struct AsnArrayDescriptor arrayDesc = { 0,
2319 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2320 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2321 PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2322 BOOL ret;
2323
2324 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2325 NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
2326 NULL);
2327 return ret;
2328 }
2329
2330 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2331 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2332 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2333 {
2334 BOOL ret = FALSE;
2335
2336 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2337 pDecodePara, pvStructInfo, *pcbStructInfo);
2338
2339 __TRY
2340 {
2341 DWORD bytesNeeded;
2342
2343 if (!cbEncoded)
2344 SetLastError(CRYPT_E_ASN1_EOD);
2345 else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
2346 SetLastError(CRYPT_E_ASN1_CORRUPT);
2347 else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2348 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2349 NULL)))
2350 {
2351 if (!pvStructInfo)
2352 *pcbStructInfo = bytesNeeded;
2353 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2354 pvStructInfo, pcbStructInfo, bytesNeeded)))
2355 {
2356 PCRYPT_ATTRIBUTES attrs;
2357
2358 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2359 pvStructInfo = *(BYTE **)pvStructInfo;
2360 attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2361 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
2362 sizeof(CRYPT_ATTRIBUTES));
2363 ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2364 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2365 &bytesNeeded, NULL);
2366 }
2367 }
2368 }
2369 __EXCEPT_PAGE_FAULT
2370 {
2371 SetLastError(STATUS_ACCESS_VIOLATION);
2372 }
2373 __ENDTRY
2374 TRACE("returning %d\n", ret);
2375 return ret;
2376 }
2377
2378 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2379 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2380 {
2381 CRYPT_ALGORITHM_IDENTIFIER *algo =
2382 (CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
2383 BOOL ret = TRUE;
2384 struct AsnDecodeSequenceItem items[] = {
2385 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2386 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2387 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2388 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2389 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2390 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2391 };
2392
2393 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2394 pvStructInfo, *pcbStructInfo, pcbDecoded);
2395
2396 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2397 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2398 pcbDecoded, algo ? algo->pszObjId : NULL);
2399 if (ret && pvStructInfo)
2400 {
2401 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2402 debugstr_a(algo->pszObjId));
2403 }
2404 return ret;
2405 }
2406
2407 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2408 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2409 DWORD *pcbDecoded)
2410 {
2411 BOOL ret = TRUE;
2412 struct AsnDecodeSequenceItem items[] = {
2413 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2414 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2415 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2416 Algorithm.pszObjId) },
2417 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2418 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2419 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2420 };
2421 PCERT_PUBLIC_KEY_INFO info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2422
2423 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2424 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2425 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2426 return ret;
2427 }
2428
2429 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2430 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2431 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2432 {
2433 BOOL ret = TRUE;
2434
2435 __TRY
2436 {
2437 DWORD bytesNeeded;
2438
2439 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2440 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2441 {
2442 if (!pvStructInfo)
2443 *pcbStructInfo = bytesNeeded;
2444 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2445 pvStructInfo, pcbStructInfo, bytesNeeded)))
2446 {
2447 PCERT_PUBLIC_KEY_INFO info;
2448
2449 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2450 pvStructInfo = *(BYTE **)pvStructInfo;
2451 info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2452 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2453 sizeof(CERT_PUBLIC_KEY_INFO);
2454 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2455 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2456 &bytesNeeded, NULL);
2457 }
2458 }
2459 }
2460 __EXCEPT_PAGE_FAULT
2461 {
2462 SetLastError(STATUS_ACCESS_VIOLATION);
2463 ret = FALSE;
2464 }
2465 __ENDTRY
2466 return ret;
2467 }
2468
2469 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2470 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2471 {
2472 BOOL ret;
2473
2474 if (cbEncoded < 3)
2475 {
2476 SetLastError(CRYPT_E_ASN1_CORRUPT);
2477 return FALSE;
2478 }
2479 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2480 {
2481 SetLastError(CRYPT_E_ASN1_CORRUPT);
2482 return FALSE;
2483 }
2484 if (pbEncoded[1] > 1)
2485 {
2486 SetLastError(CRYPT_E_ASN1_CORRUPT);
2487 return FALSE;
2488 }
2489 if (pcbDecoded)
2490 *pcbDecoded = 3;
2491 if (!pvStructInfo)
2492 {
2493 *pcbStructInfo = sizeof(BOOL);
2494 ret = TRUE;
2495 }
2496 else if (*pcbStructInfo < sizeof(BOOL))
2497 {
2498 *pcbStructInfo = sizeof(BOOL);
2499 SetLastError(ERROR_MORE_DATA);
2500 ret = FALSE;
2501 }
2502 else
2503 {
2504 *pcbStructInfo = sizeof(BOOL);
2505 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2506 ret = TRUE;
2507 }
2508 TRACE("returning %d (%08x)\n", ret, GetLastError());
2509 return ret;
2510 }
2511
2512 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2513 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2514 {
2515 PCERT_ALT_NAME_ENTRY entry = (PCERT_ALT_NAME_ENTRY)pvStructInfo;
2516 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2517 BOOL ret;
2518
2519 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2520 pvStructInfo, *pcbStructInfo);
2521
2522 if (cbEncoded < 2)
2523 {
2524 SetLastError(CRYPT_E_ASN1_CORRUPT);
2525 return FALSE;
2526 }
2527 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2528 if (1 + lenBytes > cbEncoded)
2529 {
2530 SetLastError(CRYPT_E_ASN1_CORRUPT);
2531 return FALSE;
2532 }
2533 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2534 {
2535 switch (pbEncoded[0] & ASN_TYPE_MASK)
2536 {
2537 case 1: /* rfc822Name */
2538 case 2: /* dNSName */
2539 case 6: /* uniformResourceIdentifier */
2540 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2541 break;
2542 case 4: /* directoryName */
2543 case 7: /* iPAddress */
2544 bytesNeeded += dataLen;
2545 break;
2546 case 8: /* registeredID */
2547 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2548 &dataLen, NULL);
2549 if (ret)
2550 {
2551 /* FIXME: ugly, shouldn't need to know internals of OID decode
2552 * function to use it.
2553 */
2554 bytesNeeded += dataLen - sizeof(LPSTR);
2555 }
2556 break;
2557 case 0: /* otherName */
2558 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2559 SetLastError(CRYPT_E_ASN1_BADTAG);
2560 ret = FALSE;
2561 break;
2562 case 3: /* x400Address, unimplemented */
2563 case 5: /* ediPartyName, unimplemented */
2564 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2565 SetLastError(CRYPT_E_ASN1_BADTAG);
2566 ret = FALSE;
2567 break;
2568 default:
2569 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2570 SetLastError(CRYPT_E_ASN1_CORRUPT);
2571 ret = FALSE;
2572 }
2573 if (ret)
2574 {
2575 if (pcbDecoded)
2576 *pcbDecoded = 1 + lenBytes + dataLen;
2577 if (!entry)
2578 *pcbStructInfo = bytesNeeded;
2579 else if (*pcbStructInfo < bytesNeeded)
2580 {
2581 *pcbStructInfo = bytesNeeded;
2582 SetLastError(ERROR_MORE_DATA);
2583 ret = FALSE;
2584 }
2585 else
2586 {
2587 *pcbStructInfo = bytesNeeded;
2588 /* MS used values one greater than the asn1 ones.. sigh */
2589 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
2590 switch (pbEncoded[0] & ASN_TYPE_MASK)
2591 {
2592 case 1: /* rfc822Name */
2593 case 2: /* dNSName */
2594 case 6: /* uniformResourceIdentifier */
2595 {
2596 DWORD i;
2597
2598 for (i = 0; i < dataLen; i++)
2599 entry->u.pwszURL[i] =
2600 (WCHAR)pbEncoded[1 + lenBytes + i];
2601 entry->u.pwszURL[i] = 0;
2602 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
2603 debugstr_w(entry->u.pwszURL));
2604 break;
2605 }
2606 case 4: /* directoryName */
2607 /* The data are memory-equivalent with the IPAddress case,
2608 * fall-through
2609 */
2610 case 7: /* iPAddress */
2611 /* The next data pointer is in the pwszURL spot, that is,
2612 * the first 4 bytes. Need to move it to the next spot.
2613 */
2614 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
2615 entry->u.IPAddress.cbData = dataLen;
2616 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
2617 dataLen);
2618 break;
2619 case 8: /* registeredID */
2620 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
2621 &entry->u.pszRegisteredID, &dataLen, NULL);
2622 break;
2623 }
2624 }
2625 }
2626 }
2627 return ret;
2628 }
2629
2630 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
2631 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2632 DWORD *pcbDecoded)
2633 {
2634 BOOL ret = TRUE;
2635 struct AsnArrayDescriptor arrayDesc = { 0,
2636 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
2637 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
2638 PCERT_ALT_NAME_INFO info = (PCERT_ALT_NAME_INFO)pvStructInfo;
2639
2640 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2641 pvStructInfo, *pcbStructInfo, pcbDecoded);
2642
2643 if (info)
2644 TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
2645 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2646 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2647 info ? info->rgAltEntry : NULL);
2648 return ret;
2649 }
2650
2651 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2652 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
2653 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2654 DWORD *pcbDecoded)
2655 {
2656 BOOL ret;
2657
2658 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
2659 pvStructInfo, *pcbStructInfo, pcbDecoded);
2660
2661 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2662 * place.
2663 */
2664 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
2665 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
2666 pcbDecoded);
2667 if (ret && pvStructInfo)
2668 {
2669 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2670
2671 if (blob->cbData)
2672 {
2673 DWORD i;
2674 BYTE temp;
2675
2676 for (i = 0; i < blob->cbData / 2; i++)
2677 {
2678 temp = blob->pbData[i];
2679 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
2680 blob->pbData[blob->cbData - i - 1] = temp;
2681 }
2682 }
2683 }
2684 TRACE("returning %d (%08x)\n", ret, GetLastError());
2685 return ret;
2686 }
2687
2688 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
2689 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2690 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2691 {
2692 BOOL ret;
2693
2694 __TRY
2695 {
2696 struct AsnDecodeSequenceItem items[] = {
2697 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
2698 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2699 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
2700 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2701 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
2702 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
2703 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
2704 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
2705 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2706 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2707 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
2708 };
2709
2710 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2711 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2712 pcbStructInfo, NULL, NULL);
2713 }
2714 __EXCEPT_PAGE_FAULT
2715 {
2716 SetLastError(STATUS_ACCESS_VIOLATION);
2717 ret = FALSE;
2718 }
2719 __ENDTRY
2720 return ret;
2721 }
2722
2723 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
2724 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2725 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2726 {
2727 BOOL ret;
2728
2729 __TRY
2730 {
2731 struct AsnDecodeSequenceItem items[] = {
2732 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
2733 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2734 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
2735 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2736 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
2737 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
2738 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2739 AuthorityCertIssuer.rgAltEntry), 0 },
2740 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2741 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2742 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2743 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2744 AuthorityCertSerialNumber.pbData), 0 },
2745 };
2746
2747 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2748 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2749 pcbStructInfo, NULL, NULL);
2750 }
2751 __EXCEPT_PAGE_FAULT
2752 {
2753 SetLastError(STATUS_ACCESS_VIOLATION);
2754 ret = FALSE;
2755 }
2756 __ENDTRY
2757 return ret;
2758 }
2759
2760 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
2761 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2762 DWORD *pcbDecoded)
2763 {
2764 struct AsnDecodeSequenceItem items[] = {
2765 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
2766 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
2767 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
2768 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
2769 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
2770 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
2771 };
2772 CERT_ACCESS_DESCRIPTION *descr = (CERT_ACCESS_DESCRIPTION *)pvStructInfo;
2773
2774 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2775 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2776 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
2777 }
2778
2779 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
2780 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2781 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2782 {
2783 BOOL ret;
2784
2785 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2786 pDecodePara, pvStructInfo, *pcbStructInfo);
2787
2788 __TRY
2789 {
2790 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2791 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
2792 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
2793
2794 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2795 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
2796 }
2797 __EXCEPT_PAGE_FAULT
2798 {
2799 SetLastError(STATUS_ACCESS_VIOLATION);
2800 ret = FALSE;
2801 }
2802 __ENDTRY
2803 return ret;
2804 }
2805
2806 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
2807 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2808 {
2809 BOOL ret;
2810 DWORD dataLen;
2811
2812 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2813 pvStructInfo, *pcbStructInfo, pcbDecoded);
2814
2815 /* The caller has already checked the tag, no need to check it again.
2816 * Check the outer length is valid:
2817 */
2818 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
2819 {
2820 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2821 DWORD innerLen;
2822
2823 pbEncoded += 1 + lenBytes;
2824 cbEncoded -= 1 + lenBytes;
2825 if (dataLen == CMSG_INDEFINITE_LENGTH)
2826 cbEncoded -= 2; /* space for 0 TLV */
2827 /* Check the inner length is valid: */
2828 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
2829 {
2830 DWORD decodedLen;
2831
2832 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
2833 pvStructInfo, pcbStructInfo, &decodedLen);
2834 if (dataLen == CMSG_INDEFINITE_LENGTH)
2835 {
2836 if (*(pbEncoded + decodedLen) != 0 ||
2837 *(pbEncoded + decodedLen + 1) != 0)
2838 {
2839 TRACE("expected 0 TLV, got {%02x,%02x}\n",
2840 *(pbEncoded + decodedLen),
2841 *(pbEncoded + decodedLen + 1));
2842 SetLastError(CRYPT_E_ASN1_CORRUPT);
2843 ret = FALSE;
2844 }
2845 else
2846 decodedLen += 2;
2847 }
2848 if (ret && pcbDecoded)
2849 {
2850 *pcbDecoded = 1 + lenBytes + decodedLen;
2851 TRACE("decoded %d bytes\n", *pcbDecoded);
2852 }
2853 }
2854 }
2855 return ret;
2856 }
2857
2858 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
2859 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2860 DWORD *pcbDecoded)
2861 {
2862 CRYPT_CONTENT_INFO *info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2863 struct AsnDecodeSequenceItem items[] = {
2864 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
2865 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2866 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
2867 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
2868 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
2869 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
2870 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
2871 };
2872 BOOL ret;
2873
2874 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2875 pvStructInfo, *pcbStructInfo, pcbDecoded);
2876
2877 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2878 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2879 pcbDecoded, info ? info->pszObjId : NULL);
2880 return ret;
2881 }
2882
2883 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
2884 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2885 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2886 {
2887 BOOL ret = FALSE;
2888
2889 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2890 pDecodePara, pvStructInfo, *pcbStructInfo);
2891
2892 __TRY
2893 {
2894 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
2895 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
2896 if (ret && pvStructInfo)
2897 {
2898 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
2899 pcbStructInfo, *pcbStructInfo);
2900 if (ret)
2901 {
2902 CRYPT_CONTENT_INFO *info;
2903
2904 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2905 pvStructInfo = *(BYTE **)pvStructInfo;
2906 info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2907 info->pszObjId = (LPSTR)((BYTE *)info +
2908 sizeof(CRYPT_CONTENT_INFO));
2909 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
2910 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2911 pcbStructInfo, NULL);
2912 }
2913 }
2914 }
2915 __EXCEPT_PAGE_FAULT
2916 {
2917 SetLastError(STATUS_ACCESS_VIOLATION);
2918 }
2919 __ENDTRY
2920 return ret;
2921 }
2922
2923 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
2924 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2925 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
2926 {
2927 BOOL ret;
2928 struct AsnDecodeSequenceItem items[] = {
2929 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
2930 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2931 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
2932 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2933 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
2934 0 },
2935 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
2936 CRYPT_AsnDecodePKCSContentInfoInternal,
2937 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
2938 ContentInfo.pszObjId), 0 },
2939 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
2940 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
2941 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
2942 };
2943
2944 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2945 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
2946 NULL, NULL);
2947 return ret;
2948 }
2949
2950 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
2951 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2952 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2953 {
2954 BOOL ret = TRUE;
2955
2956 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2957 pDecodePara, pvStructInfo, *pcbStructInfo);
2958
2959 __TRY
2960 {
2961 DWORD bytesNeeded;
2962
2963 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2964 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2965 {
2966 if (!pvStructInfo)
2967 *pcbStructInfo = bytesNeeded;
2968 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2969 pvStructInfo, pcbStructInfo, bytesNeeded)))
2970 {
2971 CERT_ALT_NAME_INFO *name;
2972
2973 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2974 pvStructInfo = *(BYTE **)pvStructInfo;
2975 name = (CERT_ALT_NAME_INFO *)pvStructInfo;
2976 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
2977 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
2978 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2979 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2980 &bytesNeeded, NULL);
2981 }
2982 }
2983 }
2984 __EXCEPT_PAGE_FAULT
2985 {
2986 SetLastError(STATUS_ACCESS_VIOLATION);
2987 ret = FALSE;
2988 }
2989 __ENDTRY
2990 return ret;
2991 }
2992
2993 struct PATH_LEN_CONSTRAINT
2994 {
2995 BOOL fPathLenConstraint;
2996 DWORD dwPathLenConstraint;
2997 };
2998
2999 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3000 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3001 DWORD *pcbDecoded)
3002 {
3003 BOOL ret = TRUE;
3004 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3005
3006 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3007 pvStructInfo, *pcbStructInfo, pcbDecoded);
3008
3009 if (!pvStructInfo)
3010 {
3011 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3012 &size, pcbDecoded);
3013 *pcbStructInfo = bytesNeeded;
3014 }
3015 else if (*pcbStructInfo < bytesNeeded)
3016 {
3017 SetLastError(ERROR_MORE_DATA);
3018 *pcbStructInfo = bytesNeeded;
3019 ret = FALSE;
3020 }
3021 else
3022 {
3023 struct PATH_LEN_CONSTRAINT *constraint =
3024 (struct PATH_LEN_CONSTRAINT *)pvStructInfo;
3025
3026 *pcbStructInfo = bytesNeeded;
3027 size = sizeof(constraint->dwPathLenConstraint);
3028 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3029 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3030 if (ret)
3031 constraint->fPathLenConstraint = TRUE;
3032 TRACE("got an int, dwPathLenConstraint is %d\n",
3033 constraint->dwPathLenConstraint);
3034 }
3035 TRACE("returning %d (%08x)\n", ret, GetLastError());
3036 return ret;
3037 }
3038
3039 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3040 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3041 DWORD *pcbDecoded)
3042 {
3043 BOOL ret;
3044 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3045 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3046 offsetof(CERT_NAME_BLOB, pbData) };
3047 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
3048
3049 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3050 pvStructInfo, *pcbStructInfo, pcbDecoded);
3051
3052 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3053 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
3054 entries ? entries->rgItems : NULL);
3055 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3056 return ret;
3057 }
3058
3059 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3060 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3061 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3062 {
3063 BOOL ret;
3064
3065 __TRY
3066 {
3067 struct AsnDecodeSequenceItem items[] = {
3068 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3069 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3070 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3071 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3072 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3073 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3074 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3075 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3076 sizeof(struct GenericArray), TRUE, TRUE,
3077 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3078 };
3079
3080 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3081 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3082 pcbStructInfo, NULL, NULL);
3083 }
3084 __EXCEPT_PAGE_FAULT
3085 {
3086 SetLastError(STATUS_ACCESS_VIOLATION);
3087 ret = FALSE;
3088 }
3089 __ENDTRY
3090 return ret;
3091 }
3092
3093 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3094 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3095 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3096 {
3097 BOOL ret;
3098
3099 __TRY
3100 {
3101 struct AsnDecodeSequenceItem items[] = {
3102 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3103 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3104 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3105 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3106 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3107 };
3108
3109 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3110 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3111 pcbStructInfo, NULL, NULL);
3112 }
3113 __EXCEPT_PAGE_FAULT
3114 {
3115 SetLastError(STATUS_ACCESS_VIOLATION);
3116 ret = FALSE;
3117 }
3118 __ENDTRY
3119 return ret;
3120 }
3121
3122 #define RSA1_MAGIC 0x31415352
3123
3124 struct DECODED_RSA_PUB_KEY
3125 {
3126 DWORD pubexp;
3127 CRYPT_INTEGER_BLOB modulus;
3128 };
3129
3130 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3131 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3132 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3133 {
3134 BOOL ret;
3135
3136 __TRY
3137 {
3138 struct AsnDecodeSequenceItem items[] = {
3139 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3140 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3141 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3142 0 },
3143 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3144 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3145 };
3146 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3147 DWORD size = 0;
3148
3149 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3150 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3151 &size, NULL, NULL);
3152 if (ret)
3153 {
3154 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3155 decodedKey->modulus.cbData;
3156
3157 if (!pvStructInfo)
3158 {
3159 *pcbStructInfo = bytesNeeded;
3160 ret = TRUE;
3161 }
3162 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3163 pvStructInfo, pcbStructInfo, bytesNeeded)))
3164 {
3165 BLOBHEADER *hdr;
3166 RSAPUBKEY *rsaPubKey;
3167
3168 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3169 pvStructInfo = *(BYTE **)pvStructInfo;
3170 hdr = (BLOBHEADER *)pvStructInfo;
3171 hdr->bType = PUBLICKEYBLOB;
3172 hdr->bVersion = CUR_BLOB_VERSION;
3173 hdr->reserved = 0;
3174 hdr->aiKeyAlg = CALG_RSA_KEYX;
3175 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3176 sizeof(BLOBHEADER));
3177 rsaPubKey->magic = RSA1_MAGIC;
3178 rsaPubKey->pubexp = decodedKey->pubexp;
3179 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3180 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3181 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3182 decodedKey->modulus.cbData);
3183 }
3184 LocalFree(decodedKey);
3185 }
3186 }
3187 __EXCEPT_PAGE_FAULT
3188 {
3189 SetLastError(STATUS_ACCESS_VIOLATION);
3190 ret = FALSE;
3191 }
3192 __ENDTRY
3193 return ret;
3194 }
3195
3196 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3197 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3198 DWORD *pcbDecoded)
3199 {
3200 BOOL ret;
3201 DWORD bytesNeeded, dataLen;
3202
3203 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3204 pvStructInfo, *pcbStructInfo, pcbDecoded);
3205
3206 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3207 {
3208 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3209
3210 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3211 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3212 else
3213 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3214 if (pcbDecoded)
3215 *pcbDecoded = 1 + lenBytes + dataLen;
3216 if (!pvStructInfo)
3217 *pcbStructInfo = bytesNeeded;
3218 else if (*pcbStructInfo < bytesNeeded)
3219 {
3220 SetLastError(ERROR_MORE_DATA);
3221 *pcbStructInfo = bytesNeeded;
3222 ret = FALSE;
3223 }
3224 else
3225 {
3226 CRYPT_DATA_BLOB *blob;
3227
3228 *pcbStructInfo = bytesNeeded;
3229 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3230 blob->cbData = dataLen;
3231 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3232 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
3233 else
3234 {
3235 assert(blob->pbData);
3236 if (blob->cbData)
3237 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
3238 blob->cbData);
3239 }
3240 }
3241 }
3242 return ret;
3243 }
3244
3245 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
3246 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3247 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3248 {
3249 BOOL ret;
3250
3251 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3252 pDecodePara, pvStructInfo, *pcbStructInfo);
3253
3254 __TRY
3255 {
3256 DWORD bytesNeeded;
3257
3258 if (!cbEncoded)
3259 {
3260 SetLastError(CRYPT_E_ASN1_CORRUPT);
3261 ret = FALSE;
3262 }
3263 else if (pbEncoded[0] != ASN_OCTETSTRING)
3264 {
3265 SetLastError(CRYPT_E_ASN1_BADTAG);
3266 ret = FALSE;
3267 }
3268 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3269 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3270 {
3271 if (!pvStructInfo)
3272 *pcbStructInfo = bytesNeeded;
3273 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3274 pvStructInfo, pcbStructInfo, bytesNeeded)))
3275 {
3276 CRYPT_DATA_BLOB *blob;
3277
3278 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3279 pvStructInfo = *(BYTE **)pvStructInfo;
3280 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3281 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3282 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3283 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3284 &bytesNeeded, NULL);
3285 }
3286 }
3287 }
3288 __EXCEPT_PAGE_FAULT
3289 {
3290 SetLastError(STATUS_ACCESS_VIOLATION);
3291 ret = FALSE;
3292 }
3293 __ENDTRY
3294 return ret;
3295 }
3296
3297 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3298 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3299 {
3300 BOOL ret;
3301
3302 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3303 pvStructInfo, *pcbStructInfo, pcbDecoded);
3304
3305 if (pbEncoded[0] == ASN_BITSTRING)