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