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