ReactOS 0.4.16-dev-92-g0c2cdca
decode.c
Go to the documentation of this file.
1/*
2 * Copyright 2005-2009 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
60
62 DWORD, DWORD, void *, DWORD *);
64 DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *);
65
66/* Internal decoders don't do memory allocation or exception handling, and
67 * they report how many bytes they decoded.
68 */
69typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded,
70 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
71
73 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
74 DWORD *pcbDecoded);
76 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
77 DWORD *pcbDecoded);
78/* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
79 */
80static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
81 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
82/* Assumes algo->Parameters.pbData is set ahead of time. */
83static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
84 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
85static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
86 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
87/* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
89 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
90 DWORD *pcbDecoded);
91/* Doesn't check the tag, assumes the caller does so */
92static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
93 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
94static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
95 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
96/* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
97 * member has been initialized, doesn't do exception handling, and doesn't do
98 * memory allocation. Also doesn't check tag, assumes the caller has checked
99 * it.
100 */
102 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
103 DWORD *pcbDecoded);
104/* Like CRYPT_AsnDecodeInteger, but unsigned. */
106 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
107 DWORD *pcbDecoded);
109 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
110 DWORD *pcbDecoded);
111
112/* Gets the number of length bytes from the given (leading) length byte */
113#define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
114
115/* Helper function to get the encoded length of the data starting at pbEncoded,
116 * where pbEncoded[0] is the tag. If the data are too short to contain a
117 * length or if the length is too large for cbEncoded, sets an appropriate
118 * error code and returns FALSE. If the encoded length is unknown due to
119 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
120 */
122 DWORD *len)
123{
124 BOOL ret;
125
126 if (cbEncoded <= 1)
127 {
129 ret = FALSE;
130 }
131 else if (pbEncoded[1] <= 0x7f)
132 {
133 if (pbEncoded[1] + 1 > cbEncoded)
134 {
136 ret = FALSE;
137 }
138 else
139 {
140 *len = pbEncoded[1];
141 ret = TRUE;
142 }
143 }
144 else if (pbEncoded[1] == 0x80)
145 {
147 ret = TRUE;
148 }
149 else
150 {
151 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
152
153 if (lenLen > sizeof(DWORD) + 1)
154 {
156 ret = FALSE;
157 }
158 else if (lenLen + 2 > cbEncoded)
159 {
161 ret = FALSE;
162 }
163 else
164 {
165 DWORD out = 0;
166
167 pbEncoded += 2;
168 while (--lenLen)
169 {
170 out <<= 8;
171 out |= *pbEncoded++;
172 }
173 if (out + lenLen + 1 > cbEncoded)
174 {
176 ret = FALSE;
177 }
178 else
179 {
180 *len = out;
181 ret = TRUE;
182 }
183 }
184 }
185 return ret;
186}
187
188/* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
189static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
190{
191 BOOL ret;
192
193 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
195 {
197 ret = FALSE;
198 }
199 return ret;
200}
201
202/* Helper function to check *pcbStructInfo, set it to the required size, and
203 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
204 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
205 * pointer to the newly allocated memory.
206 */
208 const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
209 DWORD bytesNeeded)
210{
211 BOOL ret = TRUE;
212
214 {
215 if (pDecodePara && pDecodePara->pfnAlloc)
216 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
217 else
218 *(BYTE **)pvStructInfo = LocalAlloc(LPTR, bytesNeeded);
219 if (!*(BYTE **)pvStructInfo)
220 ret = FALSE;
221 else
222 *pcbStructInfo = bytesNeeded;
223 }
224 else if (*pcbStructInfo < bytesNeeded)
225 {
226 *pcbStructInfo = bytesNeeded;
228 ret = FALSE;
229 }
230 else
231 *pcbStructInfo = bytesNeeded;
232 return ret;
233}
234
235static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA *pDecodePara, LPVOID pv)
236{
237 if (pDecodePara && pDecodePara->pfnFree)
238 pDecodePara->pfnFree(pv);
239 else
240 LocalFree(pv);
241}
242
243/* Helper function to check *pcbStructInfo and set it to the required size.
244 * Assumes pvStructInfo is not NULL.
245 */
246static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
247{
248 BOOL ret;
249
250 if (*pcbStructInfo < bytesNeeded)
251 {
252 *pcbStructInfo = bytesNeeded;
254 ret = FALSE;
255 }
256 else
257 {
258 *pcbStructInfo = bytesNeeded;
259 ret = TRUE;
260 }
261 return ret;
262}
263
264/* tag:
265 * The expected tag of the item. If tag is 0, decodeFunc is called
266 * regardless of the tag value seen.
267 * offset:
268 * A sequence is decoded into a struct. The offset member is the
269 * offset of this item within that struct.
270 * decodeFunc:
271 * The decoder function to use. If this is NULL, then the member isn't
272 * decoded, but minSize space is reserved for it.
273 * minSize:
274 * The minimum amount of space occupied after decoding. You must set this.
275 * optional:
276 * If true, and the tag doesn't match the expected tag for this item,
277 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
278 * filled with 0 for this member.
279 * hasPointer, pointerOffset:
280 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
281 * the offset within the struct of the data pointer (or to the
282 * first data pointer, if more than one exist).
283 * size:
284 * Used by CRYPT_AsnDecodeSequence, not for your use.
285 */
287{
296};
297
298#define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
299#define MEMBERSIZE(s, member, nextmember) \
300 (offsetof(s, nextmember) - offsetof(s, member))
301
302/* Decodes the items in a sequence, where the items are described in items,
303 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
304 * pvStructInfo. nextData is a pointer to the memory location at which the
305 * first decoded item with a dynamic pointer should point.
306 * Upon decoding, *cbDecoded is the total number of bytes decoded.
307 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
308 */
310 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
311 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
312{
313 BOOL ret;
314 DWORD i, decoded = 0;
315 const BYTE *ptr = pbEncoded;
316
317 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
318 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
319
320 for (i = 0, ret = TRUE; ret && i < cItem; i++)
321 {
322 if (cbEncoded - (ptr - pbEncoded) != 0)
323 {
324 DWORD itemLen;
325
327 cbEncoded - (ptr - pbEncoded), &itemLen)))
328 {
329 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
330
331 if (ptr[0] == items[i].tag || !items[i].tag)
332 {
333 DWORD itemEncodedLen;
334
335 if (itemLen == CMSG_INDEFINITE_LENGTH)
336 itemEncodedLen = cbEncoded - (ptr - pbEncoded);
337 else
338 itemEncodedLen = 1 + itemLenBytes + itemLen;
339 if (nextData && pvStructInfo && items[i].hasPointer)
340 {
341 TRACE("Setting next pointer to %p\n",
342 nextData);
343 *(BYTE **)((BYTE *)pvStructInfo +
344 items[i].pointerOffset) = nextData;
345 }
346 if (items[i].decodeFunc)
347 {
348 DWORD itemDecoded;
349
350 if (pvStructInfo)
351 TRACE("decoding item %d\n", i);
352 else
353 TRACE("sizing item %d\n", i);
354 ret = items[i].decodeFunc(ptr, itemEncodedLen,
356 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
357 : NULL, &items[i].size, &itemDecoded);
358 if (ret)
359 {
360 if (items[i].size < items[i].minSize)
361 items[i].size = items[i].minSize;
362 else if (items[i].size > items[i].minSize)
363 {
364 /* Account for alignment padding */
365 items[i].size = ALIGN_DWORD_PTR(items[i].size);
366 }
367 TRACE("item %d size: %d\n", i, items[i].size);
368 if (nextData && items[i].hasPointer &&
369 items[i].size > items[i].minSize)
370 nextData += items[i].size - items[i].minSize;
371 if (itemDecoded > itemEncodedLen)
372 {
373 WARN("decoded length %d exceeds encoded %d\n",
374 itemDecoded, itemEncodedLen);
376 ret = FALSE;
377 }
378 else
379 {
380 ptr += itemDecoded;
381 decoded += itemDecoded;
382 TRACE("item %d: decoded %d bytes\n", i,
383 itemDecoded);
384 }
385 }
386 else if (items[i].optional &&
388 {
389 TRACE("skipping optional item %d\n", i);
390 items[i].size = items[i].minSize;
392 ret = TRUE;
393 }
394 else
395 TRACE("item %d failed: %08x\n", i,
396 GetLastError());
397 }
398 else if (itemLen == CMSG_INDEFINITE_LENGTH)
399 {
400 ERR("can't use indefinite length encoding without a decoder\n");
402 ret = FALSE;
403 }
404 else
405 {
406 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
407 ptr += itemEncodedLen;
408 decoded += itemEncodedLen;
409 items[i].size = items[i].minSize;
410 }
411 }
412 else if (items[i].optional)
413 {
414 TRACE("skipping optional item %d\n", i);
415 items[i].size = items[i].minSize;
416 }
417 else
418 {
419 TRACE("item %d: tag %02x doesn't match expected %02x\n",
420 i, ptr[0], items[i].tag);
422 ret = FALSE;
423 }
424 }
425 }
426 else if (items[i].optional)
427 {
428 TRACE("missing optional item %d, skipping\n", i);
429 items[i].size = items[i].minSize;
430 }
431 else
432 {
433 TRACE("not enough bytes for item %d, failing\n", i);
435 ret = FALSE;
436 }
437 }
438 if (cbDecoded)
439 *cbDecoded = decoded;
440 TRACE("returning %d\n", ret);
441 return ret;
442}
443
444/* This decodes an arbitrary sequence into a contiguous block of memory
445 * (basically, a struct.) Each element being decoded is described by a struct
446 * AsnDecodeSequenceItem, see above.
447 * startingPointer is an optional pointer to the first place where dynamic
448 * data will be stored. If you know the starting offset, you may pass it
449 * here. Otherwise, pass NULL, and one will be inferred from the items.
450 */
452 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
453 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
454 DWORD *pcbDecoded, void *startingPointer)
455{
456 BOOL ret;
457
458 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
459 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
460 startingPointer);
461
462 if (!cbEncoded)
463 {
465 return FALSE;
466 }
467 if (pbEncoded[0] == ASN_SEQUENCE)
468 {
469 DWORD dataLen;
470
471 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
472 {
473 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
474 const BYTE *ptr = pbEncoded + 1 + lenBytes;
475 BOOL indefinite = FALSE;
476
477 cbEncoded -= 1 + lenBytes;
478 if (dataLen == CMSG_INDEFINITE_LENGTH)
479 {
480 dataLen = cbEncoded;
481 indefinite = TRUE;
482 lenBytes += 2;
483 }
484 else if (cbEncoded < dataLen)
485 {
486 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
487 cbEncoded);
489 ret = FALSE;
490 }
491 if (ret)
492 {
494 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
495 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
496 {
497 if (cbDecoded > cbEncoded - 2)
498 {
499 /* Not enough space for 0 TLV */
501 ret = FALSE;
502 }
503 else if (*(ptr + cbDecoded) != 0 ||
504 *(ptr + cbDecoded + 1) != 0)
505 {
506 TRACE("expected 0 TLV\n");
508 ret = FALSE;
509 }
510 else
511 cbDecoded += 2;
512 }
513 }
514 if (ret && !indefinite && cbDecoded != dataLen)
515 {
516 TRACE("expected %d decoded, got %d, failing\n", dataLen,
517 cbDecoded);
519 ret = FALSE;
520 }
521 if (ret)
522 {
523 DWORD i, bytesNeeded = 0, structSize = 0;
524
525 for (i = 0; i < cItem; i++)
526 {
527 if (items[i].size > items[i].minSize)
528 bytesNeeded += items[i].size - items[i].minSize;
529 structSize = max( structSize, items[i].offset + items[i].minSize );
530 }
531 bytesNeeded += structSize;
532 if (pcbDecoded)
533 *pcbDecoded = 1 + lenBytes + cbDecoded;
534 if (!pvStructInfo)
535 *pcbStructInfo = bytesNeeded;
537 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
538 {
539 BYTE *nextData;
540
542 pvStructInfo = *(BYTE **)pvStructInfo;
543 if (startingPointer)
544 nextData = startingPointer;
545 else
546 nextData = (BYTE *)pvStructInfo + structSize;
547 memset(pvStructInfo, 0, structSize);
549 ptr, dataLen, dwFlags, pvStructInfo, nextData,
550 &cbDecoded);
552 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
553 }
554 }
555 }
556 }
557 else
558 {
560 ret = FALSE;
561 }
562 TRACE("returning %d (%08x)\n", ret, GetLastError());
563 return ret;
564}
565
566/* tag:
567 * The expected tag of the entire encoded array (usually a variant
568 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
569 * regardless of the tag seen.
570 * countOffset:
571 * The offset within the outer structure at which the count exists.
572 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
573 * while CRYPT_ATTRIBUTE has countOffset ==
574 * offsetof(CRYPT_ATTRIBUTE, cValue).
575 * arrayOffset:
576 * The offset within the outer structure at which the array pointer exists.
577 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
578 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
579 * minArraySize:
580 * The minimum size of the decoded array. On WIN32, this is always 8:
581 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
582 * alignment.
583 * decodeFunc:
584 * used to decode each item in the array
585 * itemSize:
586 * is the minimum size of each decoded item
587 * hasPointer:
588 * indicates whether each item has a dynamic pointer
589 * pointerOffset:
590 * indicates the offset within itemSize at which the pointer exists
591 */
593{
602};
603
605{
608};
609
610/* Decodes an array of like types into a structure described by a struct
611 * AsnArrayDescriptor.
612 */
613static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
614 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
615 const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
616 DWORD *pcbDecoded)
617{
618 BOOL ret = TRUE;
619
620 TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded,
621 cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
622
623 if (!cbEncoded)
624 {
626 ret = FALSE;
627 }
628 else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
629 {
630 DWORD dataLen;
631
632 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
633 {
634 DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded;
635 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
636 /* There can be arbitrarily many items, but there is often only one.
637 */
638 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
639
640 decoded = 1 + lenBytes;
641 if (dataLen)
642 {
643 const BYTE *ptr;
644 BOOL doneDecoding = FALSE;
645
646 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
647 {
648 if (dataLen == CMSG_INDEFINITE_LENGTH)
649 {
650 if (ptr[0] == 0)
651 {
652 doneDecoding = TRUE;
653 if (ptr[1] != 0)
654 {
656 ret = FALSE;
657 }
658 else
659 decoded += 2;
660 }
661 }
662 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
663 doneDecoding = TRUE;
664 if (!doneDecoding)
665 {
666 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
667
668 /* Each item decoded may not tolerate extraneous bytes,
669 * so get the length of the next element if known.
670 */
672 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
673 {
674 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
675 itemEncoded = cbEncoded - (ptr - pbEncoded);
676 else
677 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
678 itemDataLen;
679 }
680 if (ret)
681 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
683 &itemDecoded);
684 if (ret)
685 {
686 cItems++;
687 if (itemSizes != &itemSize)
688 itemSizes = CryptMemRealloc(itemSizes,
689 cItems * sizeof(struct AsnArrayItemSize));
690 else if (cItems > 1)
691 {
692 itemSizes =
694 cItems * sizeof(struct AsnArrayItemSize));
695 if (itemSizes)
696 *itemSizes = itemSize;
697 }
698 if (itemSizes)
699 {
700 decoded += itemDecoded;
701 itemSizes[cItems - 1].encodedLen = itemEncoded;
702 itemSizes[cItems - 1].size = size;
703 bytesNeeded += size;
704 ptr += itemEncoded;
705 }
706 else
707 ret = FALSE;
708 }
709 }
710 }
711 }
712 if (ret)
713 {
714 if (pcbDecoded)
715 *pcbDecoded = decoded;
716 if (!pvStructInfo)
717 *pcbStructInfo = bytesNeeded;
718 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
719 pvStructInfo, pcbStructInfo, bytesNeeded)))
720 {
721 DWORD i, *pcItems;
722 BYTE *nextData;
723 const BYTE *ptr;
724 void *rgItems;
725
727 pvStructInfo = *(void **)pvStructInfo;
728 pcItems = pvStructInfo;
729 *pcItems = cItems;
731 {
732 rgItems = (BYTE *)pvStructInfo +
733 arrayDesc->minArraySize;
734 *(void **)((BYTE *)pcItems -
735 arrayDesc->countOffset + arrayDesc->arrayOffset) =
736 rgItems;
737 }
738 else
739 rgItems = *(void **)((BYTE *)pcItems -
740 arrayDesc->countOffset + arrayDesc->arrayOffset);
741 nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize;
742 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
743 i < cItems && ptr - pbEncoded - 1 - lenBytes <
744 dataLen; i++)
745 {
746 DWORD itemDecoded;
747
748 if (arrayDesc->hasPointer)
749 *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize
750 + arrayDesc->pointerOffset) = nextData;
751 ret = arrayDesc->decodeFunc(ptr,
752 itemSizes[i].encodedLen,
754 (BYTE *)rgItems + i * arrayDesc->itemSize,
755 &itemSizes[i].size, &itemDecoded);
756 if (ret)
757 {
758 nextData += itemSizes[i].size - arrayDesc->itemSize;
759 ptr += itemDecoded;
760 }
761 }
763 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
764 }
765 }
766 if (itemSizes != &itemSize)
767 CryptMemFree(itemSizes);
768 }
769 }
770 else
771 {
773 ret = FALSE;
774 }
775 return ret;
776}
777
778/* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
779 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
780 * to CRYPT_E_ASN1_CORRUPT.
781 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
782 * set!
783 */
785 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
786{
787 BOOL ret;
788 DWORD dataLen;
789
790 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
791 {
792 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
793 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
794
796 bytesNeeded += 1 + lenBytes + dataLen;
797
798 if (pcbDecoded)
799 *pcbDecoded = 1 + lenBytes + dataLen;
800 if (!pvStructInfo)
801 *pcbStructInfo = bytesNeeded;
802 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
803 {
805
807 pvStructInfo = *(BYTE **)pvStructInfo;
808 blob = pvStructInfo;
809 blob->cbData = 1 + lenBytes + dataLen;
810 if (blob->cbData)
811 {
813 blob->pbData = (BYTE *)pbEncoded;
814 else
815 {
816 assert(blob->pbData);
817 memcpy(blob->pbData, pbEncoded, blob->cbData);
818 }
819 }
820 else
821 {
823 ret = FALSE;
824 }
825 }
826 }
827 return ret;
828}
829
830/* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
832 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
833 DWORD *pcbDecoded)
834{
835 BOOL ret;
836
837 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
838 pvStructInfo, *pcbStructInfo, pcbDecoded);
839
840 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
841 * place.
842 */
844 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
845 pcbDecoded);
846 if (ret && pvStructInfo)
847 {
848 CRYPT_BIT_BLOB *blob = pvStructInfo;
849
850 if (blob->cbData)
851 {
852 DWORD i;
853 BYTE temp;
854
855 for (i = 0; i < blob->cbData / 2; i++)
856 {
857 temp = blob->pbData[i];
858 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
859 blob->pbData[blob->cbData - i - 1] = temp;
860 }
861 }
862 }
863 TRACE("returning %d (%08x)\n", ret, GetLastError());
864 return ret;
865}
866
868 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
869 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
870{
871 BOOL ret = TRUE;
872
873 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
874 pDecodePara, pvStructInfo, *pcbStructInfo);
875
876 __TRY
877 {
878 struct AsnDecodeSequenceItem items[] = {
879 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
881 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
883 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
885 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
889 };
890
892 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
894 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
895 pcbStructInfo, NULL, NULL);
896 }
898 {
900 ret = FALSE;
901 }
903
904 TRACE("Returning %d (%08x)\n", ret, GetLastError());
905 return ret;
906}
907
909 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
910{
911 BOOL ret;
912 DWORD dataLen;
913
914 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
915 {
916 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
917
918 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
919 dwFlags, pvStructInfo, pcbStructInfo, NULL);
920 if (pcbDecoded)
921 *pcbDecoded = 1 + lenBytes + dataLen;
922 }
923 return ret;
924}
925
927 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
928{
929 BOOL ret;
930
931 struct AsnDecodeSequenceItem items[] = {
932 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
934 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
936 };
937
939 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
940 pcbDecoded, NULL);
941 return ret;
942}
943
945 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
946 DWORD *pcbDecoded)
947{
948 BOOL ret = TRUE;
949 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
950 offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
951 FINALMEMBERSIZE(CERT_INFO, cExtension),
953 offsetof(CERT_EXTENSION, pszObjId) };
954
955 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
956 pvStructInfo, *pcbStructInfo, pcbDecoded);
957
958 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
959 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
960 return ret;
961}
962
964 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
965 DWORD *pcbDecoded)
966{
967 BOOL ret;
968 DWORD dataLen;
969
970 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
971 {
972 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
973
975 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
976 if (ret && pcbDecoded)
977 *pcbDecoded = 1 + lenBytes + dataLen;
978 }
979 return ret;
980}
981
983 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
984 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
985{
986 BOOL ret = TRUE;
987 struct AsnDecodeSequenceItem items[] = {
989 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
992 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
993 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
995 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
998 Issuer.pbData) },
999 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
1001 FALSE, 0 },
1004 Subject.pbData) },
1005 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
1008 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
1009 { ASN_CONTEXT | 1, offsetof(CERT_INFO, IssuerUniqueId),
1011 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
1012 { ASN_CONTEXT | 2, offsetof(CERT_INFO, SubjectUniqueId),
1014 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
1015 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
1017 TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
1018 };
1019
1020 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1021 pDecodePara, pvStructInfo, *pcbStructInfo);
1022
1024 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1025 NULL, NULL);
1026 if (ret && pvStructInfo)
1027 {
1028 CERT_INFO *info;
1029
1031 info = *(CERT_INFO **)pvStructInfo;
1032 else
1033 info = pvStructInfo;
1034 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1035 !info->Subject.cbData)
1036 {
1038 /* Don't need to deallocate, because it should have failed on the
1039 * first pass (and no memory was allocated.)
1040 */
1041 ret = FALSE;
1042 }
1043 }
1044
1045 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1046 return ret;
1047}
1048
1050 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1051 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1052{
1053 BOOL ret = FALSE;
1054
1055 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1056 pDecodePara, pvStructInfo, *pcbStructInfo);
1057
1058 __TRY
1059 {
1060 DWORD size = 0;
1061
1062 /* Unless told not to, first try to decode it as a signed cert. */
1064 {
1065 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1066
1069 &signedCert, &size);
1070 if (ret)
1071 {
1072 size = 0;
1075 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1076 pvStructInfo, pcbStructInfo);
1077 LocalFree(signedCert);
1078 }
1079 }
1080 /* Failing that, try it as an unsigned cert */
1081 if (!ret)
1082 {
1083 size = 0;
1086 pDecodePara, pvStructInfo, pcbStructInfo);
1087 }
1088 }
1090 {
1092 }
1093 __ENDTRY
1094
1095 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1096 return ret;
1097}
1098
1100 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1101 DWORD *pcbDecoded)
1102{
1103 BOOL ret = TRUE;
1104 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1105 offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
1106 FINALMEMBERSIZE(CRL_ENTRY, cExtension),
1108 offsetof(CERT_EXTENSION, pszObjId) };
1109
1110 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1111 pvStructInfo, *pcbStructInfo, pcbDecoded);
1112
1113 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1114 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1115 return ret;
1116}
1117
1119 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1120{
1121 BOOL ret;
1122 struct AsnDecodeSequenceItem items[] = {
1125 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1126 { 0, offsetof(CRL_ENTRY, RevocationDate),
1128 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1130 FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
1131 offsetof(CRL_ENTRY, rgExtension), 0 },
1132 };
1133 PCRL_ENTRY entry = pvStructInfo;
1134
1135 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1136 *pcbStructInfo);
1137
1139 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1140 entry ? entry->SerialNumber.pbData : NULL);
1141 if (ret && entry && !entry->SerialNumber.cbData)
1142 {
1143 WARN("empty CRL entry serial number\n");
1145 ret = FALSE;
1146 }
1147 return ret;
1148}
1149
1150/* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1151 * whose rgCRLEntry member has been set prior to calling.
1152 */
1154 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1155{
1156 BOOL ret;
1157 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1158 offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
1159 MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1161 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1162
1163 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1164 pvStructInfo, *pcbStructInfo, pcbDecoded);
1165
1166 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1167 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1168 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1169 return ret;
1170}
1171
1173 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1174 DWORD *pcbDecoded)
1175{
1176 BOOL ret = TRUE;
1177 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1178 offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
1179 FINALMEMBERSIZE(CRL_INFO, cExtension),
1181 offsetof(CERT_EXTENSION, pszObjId) };
1182
1183 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1184 pvStructInfo, *pcbStructInfo, pcbDecoded);
1185
1186 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1187 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1188 return ret;
1189}
1190
1192 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1193 DWORD *pcbDecoded)
1194{
1195 BOOL ret;
1196 DWORD dataLen;
1197
1198 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1199 {
1200 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1201
1203 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1204 if (ret && pcbDecoded)
1205 *pcbDecoded = 1 + lenBytes + dataLen;
1206 }
1207 return ret;
1208}
1209
1211 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1212 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1213{
1214 struct AsnDecodeSequenceItem items[] = {
1216 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1217 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1219 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1222 Issuer.pbData) },
1224 sizeof(FILETIME), FALSE, FALSE, 0 },
1226 sizeof(FILETIME), TRUE, FALSE, 0 },
1227 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1228 CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1229 TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
1230 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1232 TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
1233 };
1234 BOOL ret = TRUE;
1235
1236 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1237 pDecodePara, pvStructInfo, *pcbStructInfo);
1238
1240 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1241
1242 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1243 return ret;
1244}
1245
1247 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1248 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1249{
1250 BOOL ret = FALSE;
1251
1252 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1253 pDecodePara, pvStructInfo, *pcbStructInfo);
1254
1255 __TRY
1256 {
1257 DWORD size = 0;
1258
1259 /* Unless told not to, first try to decode it as a signed crl. */
1261 {
1262 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1263
1266 &signedCrl, &size);
1267 if (ret)
1268 {
1269 size = 0;
1272 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1273 pvStructInfo, pcbStructInfo);
1274 LocalFree(signedCrl);
1275 }
1276 }
1277 /* Failing that, try it as an unsigned crl */
1278 if (!ret)
1279 {
1280 size = 0;
1283 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1284 }
1285 }
1287 {
1289 }
1290 __ENDTRY
1291
1292 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1293 return ret;
1294}
1295
1297 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1298{
1299 BOOL ret = TRUE;
1300 DWORD dataLen;
1301
1302 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1303 pvStructInfo, *pcbStructInfo);
1304
1305 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1306 {
1307 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1308 DWORD bytesNeeded = sizeof(LPSTR);
1309
1310 if (dataLen)
1311 {
1312 const BYTE *ptr;
1313 char str[32];
1314
1315 snprintf(str, sizeof(str), "%d.%d",
1316 pbEncoded[1 + lenBytes] / 40,
1317 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1318 * 40);
1319 bytesNeeded += strlen(str) + 1;
1320 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1321 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1322 {
1323 int val = 0;
1324
1325 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1326 (*ptr & 0x80))
1327 {
1328 val <<= 7;
1329 val |= *ptr & 0x7f;
1330 ptr++;
1331 }
1332 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1333 (*ptr & 0x80))
1334 {
1336 ret = FALSE;
1337 }
1338 else
1339 {
1340 val <<= 7;
1341 val |= *ptr++;
1342 snprintf(str, sizeof(str), ".%d", val);
1343 bytesNeeded += strlen(str);
1344 }
1345 }
1346 }
1347 if (pcbDecoded)
1348 *pcbDecoded = 1 + lenBytes + dataLen;
1349 if (!pvStructInfo)
1350 *pcbStructInfo = bytesNeeded;
1351 else if (*pcbStructInfo < bytesNeeded)
1352 {
1353 *pcbStructInfo = bytesNeeded;
1355 ret = FALSE;
1356 }
1357 else
1358 {
1359 if (dataLen)
1360 {
1361 const BYTE *ptr;
1362 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1363
1364 *pszObjId = 0;
1365 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1366 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1367 40) * 40);
1368 pszObjId += strlen(pszObjId);
1369 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1370 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1371 {
1372 int val = 0;
1373
1374 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1375 (*ptr & 0x80))
1376 {
1377 val <<= 7;
1378 val |= *ptr & 0x7f;
1379 ptr++;
1380 }
1381 val <<= 7;
1382 val |= *ptr++;
1383 sprintf(pszObjId, ".%d", val);
1384 pszObjId += strlen(pszObjId);
1385 }
1386 }
1387 else
1388 *(LPSTR *)pvStructInfo = NULL;
1389 *pcbStructInfo = bytesNeeded;
1390 }
1391 }
1392 return ret;
1393}
1394
1396 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1397{
1398 BOOL ret;
1399
1400 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1401 pvStructInfo, *pcbStructInfo);
1402
1405 pvStructInfo, pcbStructInfo, pcbDecoded);
1406 else
1407 {
1409 ret = FALSE;
1410 }
1411 return ret;
1412}
1413
1415 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1416{
1417 struct AsnDecodeSequenceItem items[] = {
1420 offsetof(CERT_EXTENSION, pszObjId), 0 },
1422 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1425 offsetof(CERT_EXTENSION, Value.pbData) },
1426 };
1427 BOOL ret = TRUE;
1428 PCERT_EXTENSION ext = pvStructInfo;
1429
1430 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1431 *pcbStructInfo);
1432
1433 if (ext)
1434 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1436 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1437 pcbDecoded, ext ? ext->pszObjId : NULL);
1438 if (ext)
1439 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1440 debugstr_a(ext->pszObjId));
1441 TRACE("returning %d (%08x)\n", ret, GetLastError());
1442 return ret;
1443}
1444
1446 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1447 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1448{
1449 BOOL ret = TRUE;
1450
1451 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1452 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1453
1454 __TRY
1455 {
1456 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1457 offsetof(CERT_EXTENSIONS, cExtension),
1458 offsetof(CERT_EXTENSIONS, rgExtension),
1459 sizeof(CERT_EXTENSIONS),
1461 offsetof(CERT_EXTENSION, pszObjId) };
1462 CERT_EXTENSIONS *exts = pvStructInfo;
1463
1464 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1465 exts->rgExtension = (CERT_EXTENSION *)(exts + 1);
1466 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1467 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1468 }
1470 {
1472 ret = FALSE;
1473 }
1474 __ENDTRY
1475 return ret;
1476}
1477
1478/* Warning: this assumes the address of value->Value.pbData is already set, in
1479 * order to avoid overwriting memory. (In some cases, it may change it, if it
1480 * doesn't copy anything to memory.) Be sure to set it correctly!
1481 */
1483 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1484 DWORD *pcbDecoded)
1485{
1486 BOOL ret = TRUE;
1487 DWORD dataLen;
1488 CERT_NAME_VALUE *value = pvStructInfo;
1489
1490 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1491 {
1492 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1493 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1494
1495 switch (pbEncoded[0])
1496 {
1497 case ASN_OCTETSTRING:
1498 valueType = CERT_RDN_OCTET_STRING;
1500 bytesNeeded += dataLen;
1501 break;
1502 case ASN_NUMERICSTRING:
1503 valueType = CERT_RDN_NUMERIC_STRING;
1505 bytesNeeded += dataLen;
1506 break;
1508 valueType = CERT_RDN_PRINTABLE_STRING;
1510 bytesNeeded += dataLen;
1511 break;
1512 case ASN_IA5STRING:
1513 valueType = CERT_RDN_IA5_STRING;
1515 bytesNeeded += dataLen;
1516 break;
1517 case ASN_T61STRING:
1518 valueType = CERT_RDN_T61_STRING;
1520 bytesNeeded += dataLen;
1521 break;
1522 case ASN_VIDEOTEXSTRING:
1523 valueType = CERT_RDN_VIDEOTEX_STRING;
1525 bytesNeeded += dataLen;
1526 break;
1527 case ASN_GRAPHICSTRING:
1528 valueType = CERT_RDN_GRAPHIC_STRING;
1530 bytesNeeded += dataLen;
1531 break;
1532 case ASN_VISIBLESTRING:
1533 valueType = CERT_RDN_VISIBLE_STRING;
1535 bytesNeeded += dataLen;
1536 break;
1537 case ASN_GENERALSTRING:
1538 valueType = CERT_RDN_GENERAL_STRING;
1540 bytesNeeded += dataLen;
1541 break;
1543 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1545 return FALSE;
1546 case ASN_BMPSTRING:
1547 valueType = CERT_RDN_BMP_STRING;
1548 bytesNeeded += dataLen;
1549 break;
1550 case ASN_UTF8STRING:
1551 valueType = CERT_RDN_UTF8_STRING;
1552 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1553 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * sizeof(WCHAR);
1554 break;
1555 default:
1557 return FALSE;
1558 }
1559
1560 if (pcbDecoded)
1561 *pcbDecoded = 1 + lenBytes + dataLen;
1562 if (!value)
1563 *pcbStructInfo = bytesNeeded;
1564 else if (*pcbStructInfo < bytesNeeded)
1565 {
1566 *pcbStructInfo = bytesNeeded;
1568 ret = FALSE;
1569 }
1570 else
1571 {
1572 *pcbStructInfo = bytesNeeded;
1573 value->dwValueType = valueType;
1574 if (dataLen)
1575 {
1576 DWORD i;
1577
1578 assert(value->Value.pbData);
1579 switch (pbEncoded[0])
1580 {
1581 case ASN_OCTETSTRING:
1582 case ASN_NUMERICSTRING:
1584 case ASN_IA5STRING:
1585 case ASN_T61STRING:
1586 case ASN_VIDEOTEXSTRING:
1587 case ASN_GRAPHICSTRING:
1588 case ASN_VISIBLESTRING:
1589 case ASN_GENERALSTRING:
1590 value->Value.cbData = dataLen;
1591 if (dataLen)
1592 {
1594 memcpy(value->Value.pbData,
1595 pbEncoded + 1 + lenBytes, dataLen);
1596 else
1597 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1598 lenBytes;
1599 }
1600 break;
1601 case ASN_BMPSTRING:
1602 {
1603 LPWSTR str = (LPWSTR)value->Value.pbData;
1604
1605 value->Value.cbData = dataLen;
1606 for (i = 0; i < dataLen / 2; i++)
1607 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1608 pbEncoded[1 + lenBytes + 2 * i + 1];
1609 break;
1610 }
1611 case ASN_UTF8STRING:
1612 {
1613 LPWSTR str = (LPWSTR)value->Value.pbData;
1614
1615 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1616 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1617 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1618 break;
1619 }
1620 }
1621 }
1622 else
1623 {
1624 value->Value.cbData = 0;
1625 value->Value.pbData = NULL;
1626 }
1627 }
1628 }
1629 return ret;
1630}
1631
1633 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1634 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1635{
1636 BOOL ret = TRUE;
1637
1638 __TRY
1639 {
1641 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1642 if (ret && pvStructInfo)
1643 {
1644 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1645 pcbStructInfo, *pcbStructInfo);
1646 if (ret)
1647 {
1649
1651 pvStructInfo = *(BYTE **)pvStructInfo;
1652 value = pvStructInfo;
1653 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1655 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1656 pcbStructInfo, NULL);
1658 CRYPT_FreeSpace(pDecodePara, value);
1659 }
1660 }
1661 }
1663 {
1665 ret = FALSE;
1666 }
1667 __ENDTRY
1668 return ret;
1669}
1670
1672 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1673 DWORD *pcbDecoded)
1674{
1675 BOOL ret = TRUE;
1676 DWORD dataLen;
1677 CERT_NAME_VALUE *value = pvStructInfo;
1678
1679 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1680 {
1681 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1682 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1683
1684 switch (pbEncoded[0])
1685 {
1686 case ASN_NUMERICSTRING:
1687 valueType = CERT_RDN_NUMERIC_STRING;
1688 if (dataLen)
1689 bytesNeeded += (dataLen + 1) * 2;
1690 break;
1692 valueType = CERT_RDN_PRINTABLE_STRING;
1693 if (dataLen)
1694 bytesNeeded += (dataLen + 1) * 2;
1695 break;
1696 case ASN_IA5STRING:
1697 valueType = CERT_RDN_IA5_STRING;
1698 if (dataLen)
1699 bytesNeeded += (dataLen + 1) * 2;
1700 break;
1701 case ASN_T61STRING:
1702 valueType = CERT_RDN_T61_STRING;
1703 if (dataLen)
1704 bytesNeeded += (dataLen + 1) * 2;
1705 break;
1706 case ASN_VIDEOTEXSTRING:
1707 valueType = CERT_RDN_VIDEOTEX_STRING;
1708 if (dataLen)
1709 bytesNeeded += (dataLen + 1) * 2;
1710 break;
1711 case ASN_GRAPHICSTRING:
1712 valueType = CERT_RDN_GRAPHIC_STRING;
1713 if (dataLen)
1714 bytesNeeded += (dataLen + 1) * 2;
1715 break;
1716 case ASN_VISIBLESTRING:
1717 valueType = CERT_RDN_VISIBLE_STRING;
1718 if (dataLen)
1719 bytesNeeded += (dataLen + 1) * 2;
1720 break;
1721 case ASN_GENERALSTRING:
1722 valueType = CERT_RDN_GENERAL_STRING;
1723 if (dataLen)
1724 bytesNeeded += (dataLen + 1) * 2;
1725 break;
1727 valueType = CERT_RDN_UNIVERSAL_STRING;
1728 if (dataLen)
1729 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1730 break;
1731 case ASN_BMPSTRING:
1732 valueType = CERT_RDN_BMP_STRING;
1733 if (dataLen)
1734 bytesNeeded += dataLen + sizeof(WCHAR);
1735 break;
1736 case ASN_UTF8STRING:
1737 valueType = CERT_RDN_UTF8_STRING;
1738 if (dataLen)
1739 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1740 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1741 break;
1742 default:
1744 return FALSE;
1745 }
1746
1747 if (pcbDecoded)
1748 *pcbDecoded = 1 + lenBytes + dataLen;
1749 if (!value)
1750 *pcbStructInfo = bytesNeeded;
1751 else if (*pcbStructInfo < bytesNeeded)
1752 {
1753 *pcbStructInfo = bytesNeeded;
1755 ret = FALSE;
1756 }
1757 else
1758 {
1759 *pcbStructInfo = bytesNeeded;
1760 value->dwValueType = valueType;
1761 if (dataLen)
1762 {
1763 DWORD i;
1764 LPWSTR str = (LPWSTR)value->Value.pbData;
1765
1766 assert(value->Value.pbData);
1767 switch (pbEncoded[0])
1768 {
1769 case ASN_NUMERICSTRING:
1771 case ASN_IA5STRING:
1772 case ASN_T61STRING:
1773 case ASN_VIDEOTEXSTRING:
1774 case ASN_GRAPHICSTRING:
1775 case ASN_VISIBLESTRING:
1776 case ASN_GENERALSTRING:
1777 value->Value.cbData = dataLen * 2;
1778 for (i = 0; i < dataLen; i++)
1779 str[i] = pbEncoded[1 + lenBytes + i];
1780 str[i] = 0;
1781 break;
1783 value->Value.cbData = dataLen / 2;
1784 for (i = 0; i < dataLen / 4; i++)
1785 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1786 | pbEncoded[1 + lenBytes + 2 * i + 3];
1787 str[i] = 0;
1788 break;
1789 case ASN_BMPSTRING:
1790 value->Value.cbData = dataLen;
1791 for (i = 0; i < dataLen / 2; i++)
1792 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1793 pbEncoded[1 + lenBytes + 2 * i + 1];
1794 str[i] = 0;
1795 break;
1796 case ASN_UTF8STRING:
1797 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1798 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1799 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
1800 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
1801 value->Value.cbData += sizeof(WCHAR);
1802 break;
1803 }
1804 }
1805 else
1806 {
1807 value->Value.cbData = 0;
1808 value->Value.pbData = NULL;
1809 }
1810 }
1811 }
1812 return ret;
1813}
1814
1816 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1817 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1818{
1819 BOOL ret = TRUE;
1820
1821 __TRY
1822 {
1824 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1825 if (ret && pvStructInfo)
1826 {
1827 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1828 pcbStructInfo, *pcbStructInfo);
1829 if (ret)
1830 {
1832
1834 pvStructInfo = *(BYTE **)pvStructInfo;
1835 value = pvStructInfo;
1836 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1838 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1839 pcbStructInfo, NULL);
1841 CRYPT_FreeSpace(pDecodePara, value);
1842 }
1843 }
1844 }
1846 {
1848 ret = FALSE;
1849 }
1850 __ENDTRY
1851 return ret;
1852}
1853
1855 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1856{
1857 BOOL ret;
1858 struct AsnDecodeSequenceItem items[] = {
1861 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1862 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1864 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1865 };
1866 CERT_RDN_ATTR *attr = pvStructInfo;
1867
1868 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1869 pvStructInfo, *pcbStructInfo);
1870
1871 if (attr)
1872 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1874 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1875 attr ? attr->pszObjId : NULL);
1876 if (attr)
1877 {
1878 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1879 debugstr_a(attr->pszObjId));
1880 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1881 }
1882 TRACE("returning %d (%08x)\n", ret, GetLastError());
1883 return ret;
1884}
1885
1886static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1887 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1888{
1889 BOOL ret = TRUE;
1890 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1891 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1892 sizeof(CERT_RDN),
1894 offsetof(CERT_RDN_ATTR, pszObjId) };
1895
1896 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1897 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1898 return ret;
1899}
1900
1902 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1903 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1904{
1905 BOOL ret = TRUE;
1906
1907 __TRY
1908 {
1909 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1911 sizeof(CERT_NAME_INFO),
1913 offsetof(CERT_RDN, rgRDNAttr) };
1914 DWORD bytesNeeded = 0;
1915
1916 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1917 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
1918 NULL);
1919 if (ret)
1920 {
1921 if (!pvStructInfo)
1922 *pcbStructInfo = bytesNeeded;
1923 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
1924 pvStructInfo, pcbStructInfo, bytesNeeded)))
1925 {
1927
1929 pvStructInfo = *(BYTE **)pvStructInfo;
1930 info = pvStructInfo;
1931 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
1932 sizeof(CERT_NAME_INFO));
1933 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1934 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
1935 &bytesNeeded, NULL);
1937 CRYPT_FreeSpace(pDecodePara, info);
1938 }
1939 }
1940 }
1942 {
1944 ret = FALSE;
1945 }
1946 __ENDTRY
1947 return ret;
1948}
1949
1951 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1952 DWORD *pcbDecoded)
1953{
1954 BOOL ret;
1955 struct AsnDecodeSequenceItem items[] = {
1958 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1959 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1961 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1962 };
1963 CERT_RDN_ATTR *attr = pvStructInfo;
1964
1965 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1966 pvStructInfo, *pcbStructInfo);
1967
1968 if (attr)
1969 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1971 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1972 attr ? attr->pszObjId : NULL);
1973 if (attr)
1974 {
1975 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1976 debugstr_a(attr->pszObjId));
1977 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1978 }
1979 TRACE("returning %d (%08x)\n", ret, GetLastError());
1980 return ret;
1981}
1982
1984 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1985{
1986 BOOL ret = TRUE;
1987 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1988 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1989 sizeof(CERT_RDN),
1991 offsetof(CERT_RDN_ATTR, pszObjId) };
1992
1993 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1994 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1995 return ret;
1996}
1997
1999 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2000 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2001{
2002 BOOL ret = TRUE;
2003
2004 __TRY
2005 {
2006 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2008 sizeof(CERT_NAME_INFO),
2010 offsetof(CERT_RDN, rgRDNAttr) };
2011 DWORD bytesNeeded = 0;
2012
2013 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2014 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
2015 NULL);
2016 if (ret)
2017 {
2018 if (!pvStructInfo)
2019 *pcbStructInfo = bytesNeeded;
2020 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2021 pvStructInfo, pcbStructInfo, bytesNeeded)))
2022 {
2024
2026 pvStructInfo = *(BYTE **)pvStructInfo;
2027 info = pvStructInfo;
2028 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
2029 sizeof(CERT_NAME_INFO));
2030 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2031 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
2032 &bytesNeeded, NULL);
2034 CRYPT_FreeSpace(pDecodePara, info);
2035 }
2036 }
2037 }
2039 {
2041 ret = FALSE;
2042 }
2043 __ENDTRY
2044 return ret;
2045}
2046
2048 DWORD *pcbDecoded)
2049{
2050 BOOL ret = TRUE, done = FALSE;
2051 DWORD indefiniteNestingLevels = 0, decoded = 0;
2052
2053 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2054
2055 do {
2056 DWORD dataLen;
2057
2058 if (!cbEncoded)
2059 done = TRUE;
2060 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2061 &dataLen)))
2062 {
2063 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2064
2065 if (dataLen == CMSG_INDEFINITE_LENGTH)
2066 {
2067 indefiniteNestingLevels++;
2068 pbEncoded += 1 + lenBytes;
2069 cbEncoded -= 1 + lenBytes;
2070 decoded += 1 + lenBytes;
2071 TRACE("indefiniteNestingLevels = %d\n",
2072 indefiniteNestingLevels);
2073 }
2074 else
2075 {
2076 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2077 indefiniteNestingLevels)
2078 {
2079 indefiniteNestingLevels--;
2080 TRACE("indefiniteNestingLevels = %d\n",
2081 indefiniteNestingLevels);
2082 }
2083 pbEncoded += 1 + lenBytes + dataLen;
2084 cbEncoded -= 1 + lenBytes + dataLen;
2085 decoded += 1 + lenBytes + dataLen;
2086 if (!indefiniteNestingLevels)
2087 done = TRUE;
2088 }
2089 }
2090 } while (ret && !done);
2091 /* If we haven't found all 0 TLVs, we haven't found the end */
2092 if (ret && indefiniteNestingLevels)
2093 {
2095 ret = FALSE;
2096 }
2097 if (ret)
2098 *pcbDecoded = decoded;
2099 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2100 return ret;
2101}
2102
2104 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2105 DWORD *pcbDecoded)
2106{
2107 BOOL ret = TRUE;
2108 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2109
2110 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2111 pvStructInfo, *pcbStructInfo);
2112
2113 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2114 {
2116 bytesNeeded += encodedLen;
2117 if (!pvStructInfo)
2118 *pcbStructInfo = bytesNeeded;
2119 else if (*pcbStructInfo < bytesNeeded)
2120 {
2122 *pcbStructInfo = bytesNeeded;
2123 ret = FALSE;
2124 }
2125 else
2126 {
2127 PCRYPT_OBJID_BLOB blob = pvStructInfo;
2128
2129 *pcbStructInfo = bytesNeeded;
2130 blob->cbData = encodedLen;
2131 if (encodedLen)
2132 {
2134 blob->pbData = (LPBYTE)pbEncoded;
2135 else
2136 {
2137 assert(blob->pbData);
2138 memcpy(blob->pbData, pbEncoded, blob->cbData);
2139 }
2140 }
2141 else
2142 blob->pbData = NULL;
2143 }
2144 if (pcbDecoded)
2145 *pcbDecoded = encodedLen;
2146 }
2147 return ret;
2148}
2149
2151 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2152{
2153 BOOL ret;
2154 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2155 offsetof(CTL_USAGE, cUsageIdentifier),
2156 offsetof(CTL_USAGE, rgpszUsageIdentifier),
2157 sizeof(CTL_USAGE),
2158 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2159
2160 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2161 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2162 return ret;
2163}
2164
2166 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2167 DWORD *pcbDecoded)
2168{
2169 struct AsnArrayDescriptor arrayDesc = { 0,
2170 offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
2171 FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
2173 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2174 BOOL ret;
2175
2176 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2177 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2178 return ret;
2179}
2180
2182 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2183{
2184 struct AsnDecodeSequenceItem items[] = {
2185 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2187 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2188 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2190 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
2191 offsetof(CTL_ENTRY, rgAttribute), 0 },
2192 };
2193 BOOL ret = TRUE;
2194 CTL_ENTRY *entry = pvStructInfo;
2195
2196 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2197 *pcbStructInfo);
2198
2200 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2201 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2202 return ret;
2203}
2204
2206 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2207{
2208 BOOL ret;
2209 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2210 offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
2211 FINALMEMBERSIZE(CTL_INFO, cExtension),
2213 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2214
2215 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2216 pvStructInfo, *pcbStructInfo, pcbDecoded);
2217
2218 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2219 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2220 return ret;
2221}
2222
2224 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2225 DWORD *pcbDecoded)
2226{
2227 BOOL ret = TRUE;
2228 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2229 offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
2230 FINALMEMBERSIZE(CTL_INFO, cExtension),
2232 offsetof(CERT_EXTENSION, pszObjId) };
2233
2234 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2235 pvStructInfo, *pcbStructInfo, pcbDecoded);
2236
2237 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2238 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2239 return ret;
2240}
2241
2243 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2244 DWORD *pcbDecoded)
2245{
2246 BOOL ret;
2247 DWORD dataLen;
2248
2249 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2250 {
2251 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2252
2254 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
2255 if (ret && pcbDecoded)
2256 *pcbDecoded = 1 + lenBytes + dataLen;
2257 }
2258 return ret;
2259}
2260
2262 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2263 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2264{
2265 BOOL ret = FALSE;
2266
2267 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2268 pDecodePara, pvStructInfo, *pcbStructInfo);
2269
2270 __TRY
2271 {
2272 struct AsnDecodeSequenceItem items[] = {
2274 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2275 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2277 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2280 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2281 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2283 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2284 { 0, offsetof(CTL_INFO, ThisUpdate),
2286 0 },
2287 { 0, offsetof(CTL_INFO, NextUpdate),
2289 0 },
2290 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2292 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2293 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2295 MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2296 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2297 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2299 TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
2300 };
2301
2303 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2304 pcbStructInfo, NULL, NULL);
2305 }
2307 {
2309 }
2310 __ENDTRY
2311 return ret;
2312}
2313
2315 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2316 DWORD *pcbDecoded)
2317{
2318 BOOL ret;
2319 struct AsnDecodeSequenceItem items[] = {
2322 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2326 };
2327 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2328
2329 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2330 pvStructInfo, *pcbStructInfo);
2331
2333 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2334 pcbDecoded, capability ? capability->pszObjId : NULL);
2335 TRACE("returning %d\n", ret);
2336 return ret;
2337}
2338
2340 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2341 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2342{
2343 BOOL ret = FALSE;
2344
2345 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2346 pDecodePara, pvStructInfo, *pcbStructInfo);
2347
2348 __TRY
2349 {
2350 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2351 offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
2352 offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
2355 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2356 CRYPT_SMIME_CAPABILITIES *capabilities = pvStructInfo;
2357
2358 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2359 capabilities->rgCapability = (CRYPT_SMIME_CAPABILITY *)(capabilities + 1);
2360 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2361 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2362 }
2364 {
2366 }
2367 __ENDTRY
2368 TRACE("returning %d\n", ret);
2369 return ret;
2370}
2371
2373 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2374 DWORD *pcbDecoded)
2375{
2376 BOOL ret = TRUE;
2377 DWORD dataLen;
2378 LPSTR *pStr = pvStructInfo;
2379
2380 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2381 {
2382 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2383 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2384
2385 if (pbEncoded[0] != ASN_IA5STRING)
2386 {
2388 ret = FALSE;
2389 }
2390 else
2391 {
2392 bytesNeeded += dataLen;
2393 if (pcbDecoded)
2394 *pcbDecoded = 1 + lenBytes + dataLen;
2395 if (!pvStructInfo)
2396 *pcbStructInfo = bytesNeeded;
2397 else if (*pcbStructInfo < bytesNeeded)
2398 {
2399 *pcbStructInfo = bytesNeeded;
2401 ret = FALSE;
2402 }
2403 else
2404 {
2405 *pcbStructInfo = bytesNeeded;
2406 if (dataLen)
2407 {
2408 LPSTR str = *pStr;
2409
2410 assert(str);
2411 memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2412 str[dataLen] = 0;
2413 }
2414 else
2415 *pStr = NULL;
2416 }
2417 }
2418 }
2419 return ret;
2420}
2421
2423 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2424 DWORD *pcbDecoded)
2425{
2426 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2430 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2431 BOOL ret;
2432
2433 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2434 pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2435
2436 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2437 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2438 TRACE("returning %d\n", ret);
2439 return ret;
2440}
2441
2443 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2444 DWORD *pcbDecoded)
2445{
2446 BOOL ret;
2447 struct AsnDecodeSequenceItem items[] = {
2449 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2450 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2452 cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
2455 rgNoticeNumbers), 0 },
2456 };
2457 DWORD bytesNeeded = 0;
2458
2459 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2460 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2461
2463 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2464 NULL);
2465 if (ret)
2466 {
2467 /* The caller is expecting a pointer to a
2468 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2469 * CRYPT_AsnDecodeSequence is decoding a
2470 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2471 * needed, and decode again if the requisite space is available.
2472 */
2473 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2474 if (!pvStructInfo)
2475 *pcbStructInfo = bytesNeeded;
2476 else if (*pcbStructInfo < bytesNeeded)
2477 {
2478 *pcbStructInfo = bytesNeeded;
2480 ret = FALSE;
2481 }
2482 else
2483 {
2485
2486 *pcbStructInfo = bytesNeeded;
2487 /* The pointer (pvStructInfo) passed in points to the first dynamic
2488 * pointer, so use it as the pointer to the
2489 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2490 * appropriate offset for the first dynamic pointer within the
2491 * notice reference by pointing to the first memory location past
2492 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2493 */
2494 noticeRef =
2496 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2499 NULL, noticeRef, &bytesNeeded, pcbDecoded, noticeRef->pszOrganization);
2500 }
2501 }
2502 TRACE("returning %d\n", ret);
2503 return ret;
2504}
2505
2507 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2508 DWORD *pcbDecoded)
2509{
2510 BOOL ret = TRUE;
2511 DWORD dataLen;
2512
2513 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2514 {
2515 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2516 DWORD bytesNeeded = sizeof(LPWSTR);
2517
2518 switch (pbEncoded[0])
2519 {
2520 case ASN_NUMERICSTRING:
2521 if (dataLen)
2522 bytesNeeded += (dataLen + 1) * 2;
2523 break;
2525 if (dataLen)
2526 bytesNeeded += (dataLen + 1) * 2;
2527 break;
2528 case ASN_IA5STRING:
2529 if (dataLen)
2530 bytesNeeded += (dataLen + 1) * 2;
2531 break;
2532 case ASN_T61STRING:
2533 if (dataLen)
2534 bytesNeeded += (dataLen + 1) * 2;
2535 break;
2536 case ASN_VIDEOTEXSTRING:
2537 if (dataLen)
2538 bytesNeeded += (dataLen + 1) * 2;
2539 break;
2540 case ASN_GRAPHICSTRING:
2541 if (dataLen)
2542 bytesNeeded += (dataLen + 1) * 2;
2543 break;
2544 case ASN_VISIBLESTRING:
2545 if (dataLen)
2546 bytesNeeded += (dataLen + 1) * 2;
2547 break;
2548 case ASN_GENERALSTRING:
2549 if (dataLen)
2550 bytesNeeded += (dataLen + 1) * 2;
2551 break;
2553 if (dataLen)
2554 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2555 break;
2556 case ASN_BMPSTRING:
2557 if (dataLen)
2558 bytesNeeded += dataLen + sizeof(WCHAR);
2559 break;
2560 case ASN_UTF8STRING:
2561 if (dataLen)
2562 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2563 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2564 break;
2565 default:
2567 return FALSE;
2568 }
2569
2570 if (pcbDecoded)
2571 *pcbDecoded = 1 + lenBytes + dataLen;
2572 if (!pvStructInfo)
2573 *pcbStructInfo = bytesNeeded;
2574 else if (*pcbStructInfo < bytesNeeded)
2575 {
2576 *pcbStructInfo = bytesNeeded;
2578 ret = FALSE;
2579 }
2580 else
2581 {
2582 LPWSTR *pStr = pvStructInfo;
2583
2584 *pcbStructInfo = bytesNeeded;
2585 if (dataLen)
2586 {
2587 DWORD i;
2588 LPWSTR str = *(LPWSTR *)pStr;
2589
2590 assert(str);
2591 switch (pbEncoded[0])
2592 {
2593 case ASN_NUMERICSTRING:
2595 case ASN_IA5STRING:
2596 case ASN_T61STRING:
2597 case ASN_VIDEOTEXSTRING:
2598 case ASN_GRAPHICSTRING:
2599 case ASN_VISIBLESTRING:
2600 case ASN_GENERALSTRING:
2601 for (i = 0; i < dataLen; i++)
2602 str[i] = pbEncoded[1 + lenBytes + i];
2603 str[i] = 0;
2604 break;
2606 for (i = 0; i < dataLen / 4; i++)
2607 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2608 | pbEncoded[1 + lenBytes + 2 * i + 3];
2609 str[i] = 0;
2610 break;
2611 case ASN_BMPSTRING:
2612 for (i = 0; i < dataLen / 2; i++)
2613 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2614 pbEncoded[1 + lenBytes + 2 * i + 1];
2615 str[i] = 0;
2616 break;
2617 case ASN_UTF8STRING:
2618 {
2620 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2621 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2622 str[len] = 0;
2623 break;
2624 }
2625 }
2626 }
2627 else
2628 *pStr = NULL;
2629 }
2630 }
2631 return ret;
2632}
2633
2635 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2636 DWORD *pcbStructInfo, DWORD *pcbDecoded)
2637{
2638 BOOL ret;
2639 struct AsnDecodeSequenceItem items[] = {
2641 pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2643 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2644 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2646 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2647 };
2649
2650 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2651 pvStructInfo, *pcbStructInfo);
2652
2654 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2655 pcbDecoded, notice ? notice->pNoticeReference : NULL);
2656 TRACE("returning %d\n", ret);
2657 return ret;
2658}
2659
2661 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2662 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2663 void *pvStructInfo, DWORD *pcbStructInfo)
2664{
2665 BOOL ret = FALSE;
2666
2667 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2668 pDecodePara, pvStructInfo, *pcbStructInfo);
2669
2670 __TRY
2671 {
2672 DWORD bytesNeeded = 0;
2673
2675 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2676 NULL);
2677 if (ret)
2678 {
2679 if (!pvStructInfo)
2680 *pcbStructInfo = bytesNeeded;
2681 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2682 pvStructInfo, pcbStructInfo, bytesNeeded)))
2683 {
2685
2687 pvStructInfo = *(BYTE **)pvStructInfo;
2688 notice = pvStructInfo;
2689 notice->pNoticeReference =
2691 ((BYTE *)pvStructInfo +
2695 pvStructInfo, &bytesNeeded, NULL);
2697 CRYPT_FreeSpace(pDecodePara, notice);
2698 }
2699 }
2700 }
2702 {
2704 }
2705 __ENDTRY
2706 TRACE("returning %d\n", ret);
2707 return ret;
2708}
2709
2711 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2712 DWORD *pcbDecoded)
2713{
2714 BOOL ret;
2715 struct AsnArrayDescriptor arrayDesc = { 0,
2720
2721 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2722 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
2723
2724 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2725 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2726 return ret;
2727}
2728
2730 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2731 DWORD *pcbDecoded)
2732{
2733 BOOL ret;
2734 struct AsnDecodeSequenceItem items[] = {
2737 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2741 TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2742 };
2743 PCRYPT_ATTRIBUTE attr = pvStructInfo;
2744
2745 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2746 pvStructInfo, *pcbStructInfo);
2747
2749 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2750 pcbDecoded, attr ? attr->pszObjId : NULL);
2751 TRACE("returning %d\n", ret);
2752 return ret;
2753}
2754
2756 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2757 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2758{
2759 BOOL ret = FALSE;
2760
2761 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2762 pDecodePara, pvStructInfo, *pcbStructInfo);
2763
2764 __TRY
2765 {
2766 DWORD bytesNeeded = 0;
2767
2769 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2770 if (ret)
2771 {
2772 if (!pvStructInfo)
2773 *pcbStructInfo = bytesNeeded;
2774 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2775 pvStructInfo, pcbStructInfo, bytesNeeded)))
2776 {
2778
2780 pvStructInfo = *(BYTE **)pvStructInfo;
2781 attr = pvStructInfo;
2782 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2783 sizeof(CRYPT_ATTRIBUTE));
2785 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2786 NULL);
2788 CRYPT_FreeSpace(pDecodePara, attr);
2789 }
2790 }
2791 }
2793 {
2795 }
2796 __ENDTRY
2797 TRACE("returning %d\n", ret);
2798 return ret;
2799}
2800
2802 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2803 DWORD *pcbDecoded)
2804{
2805 struct AsnArrayDescriptor arrayDesc = { 0,
2807 sizeof(CRYPT_ATTRIBUTES),
2809 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2810 BOOL ret;
2811
2812 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2813 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2814 return ret;
2815}
2816
2818 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2819 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2820{
2821 BOOL ret = FALSE;
2822
2823 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2824 pDecodePara, pvStructInfo, *pcbStructInfo);
2825
2826 __TRY
2827 {
2828 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2830 sizeof(CRYPT_ATTRIBUTES),
2832 TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2833 CRYPT_ATTRIBUTES *attrs = pvStructInfo;
2834
2835 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2836 attrs->rgAttr = (CRYPT_ATTRIBUTE *)(attrs + 1);
2837 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2838 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2839 }
2841 {
2843 }
2844 __ENDTRY
2845 TRACE("returning %d\n", ret);
2846 return ret;
2847}
2848
2850 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2851{
2852 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2853 BOOL ret = TRUE;
2854 struct AsnDecodeSequenceItem items[] = {
2857 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2861 };
2862
2863 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2864 pvStructInfo, *pcbStructInfo, pcbDecoded);
2865
2867 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2868 pcbDecoded, algo ? algo->pszObjId : NULL);
2869 if (ret && pvStructInfo)
2870 {
2871 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2872 debugstr_a(algo->pszObjId));
2873 }
2874 return ret;
2875}
2876
2878 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2879 DWORD *pcbDecoded)
2880{
2881 BOOL ret = TRUE;
2882 struct AsnDecodeSequenceItem items[] = {
2886 Algorithm.pszObjId) },
2889 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2890 };
2891 PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2892
2894 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2895 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2896 return ret;
2897}
2898
2900 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2901 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2902{
2903 BOOL ret = TRUE;
2904
2905 __TRY
2906 {
2907 DWORD bytesNeeded = 0;
2908
2910 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2911 {
2912 if (!pvStructInfo)
2913 *pcbStructInfo = bytesNeeded;
2914 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2915 pvStructInfo, pcbStructInfo, bytesNeeded)))
2916 {
2918
2920 pvStructInfo = *(BYTE **)pvStructInfo;
2921 info = pvStructInfo;
2922 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2923 sizeof(CERT_PUBLIC_KEY_INFO);
2925 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2926 &bytesNeeded, NULL);
2928 CRYPT_FreeSpace(pDecodePara, info);
2929 }
2930 }
2931 }
2933 {
2935 ret = FALSE;
2936 }
2937 __ENDTRY
2938 return ret;
2939}
2940
2942 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2943{
2944 BOOL ret;
2945
2946 if (cbEncoded < 3)
2947 {
2949 return FALSE;
2950 }
2951 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2952 {
2954 return FALSE;
2955 }
2956 if (pbEncoded[1] > 1)
2957 {
2959 return FALSE;
2960 }
2961 if (pcbDecoded)
2962 *pcbDecoded = 3;
2963 if (!pvStructInfo)
2964 {
2965 *pcbStructInfo = sizeof(BOOL);
2966 ret = TRUE;
2967 }
2968 else if (*pcbStructInfo < sizeof(BOOL))
2969 {
2970 *pcbStructInfo = sizeof(BOOL);
2972 ret = FALSE;
2973 }
2974 else
2975 {
2976 *pcbStructInfo = sizeof(BOOL);
2977 *(BOOL *)pvStructInfo = pbEncoded[2] != 0;
2978 ret = TRUE;
2979 }
2980 TRACE("returning %d (%08x)\n", ret, GetLastError());
2981 return ret;
2982}
2983
2985 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2986{
2987 PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2988 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2989 BOOL ret;
2990
2991 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2992 pvStructInfo, *pcbStructInfo);
2993
2994 if (cbEncoded < 2)
2995 {
2997 return FALSE;
2998 }
2999 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3000 if (1 + lenBytes > cbEncoded)
3001 {
3003 return FALSE;
3004 }
3005 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3006 {
3007 switch (pbEncoded[0] & ASN_TYPE_MASK)
3008 {
3009 case 1: /* rfc822Name */
3010 case 2: /* dNSName */
3011 case 6: /* uniformResourceIdentifier */
3012 if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen))
3013 {
3015 ret = FALSE;
3016 }
3017 else
3018 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
3019 break;
3020 case 4: /* directoryName */
3021 case 7: /* iPAddress */
3022 bytesNeeded += dataLen;
3023 break;
3024 case 8: /* registeredID */
3026 &dataLen, NULL);
3027 if (ret)
3028 {
3029 /* FIXME: ugly, shouldn't need to know internals of OID decode
3030 * function to use it.
3031 */
3032 bytesNeeded += dataLen - sizeof(LPSTR);
3033 }
3034 break;
3035 case 0: /* otherName */
3036 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
3038 ret = FALSE;
3039 break;
3040 case 3: /* x400Address, unimplemented */
3041 case 5: /* ediPartyName, unimplemented */
3042 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
3044 ret = FALSE;
3045 break;
3046 default:
3047 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
3049 ret = FALSE;
3050 }
3051 if (ret)
3052 {
3053 if (pcbDecoded)
3054 *pcbDecoded = 1 + lenBytes + dataLen;
3055 if (!entry)
3056 *pcbStructInfo = bytesNeeded;
3057 else if (*pcbStructInfo < bytesNeeded)
3058 {
3059 *pcbStructInfo = bytesNeeded;
3061 ret = FALSE;
3062 }
3063 else
3064 {
3065 *pcbStructInfo = bytesNeeded;
3066 /* MS used values one greater than the asn1 ones.. sigh */
3067 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
3068 switch (pbEncoded[0] & ASN_TYPE_MASK)
3069 {
3070 case 1: /* rfc822Name */
3071 case 2: /* dNSName */
3072 case 6: /* uniformResourceIdentifier */
3073 {
3074 DWORD i;
3075
3076 for (i = 0; i < dataLen; i++)
3077 entry->u.pwszURL[i] =
3078 (WCHAR)pbEncoded[1 + lenBytes + i];
3079 entry->u.pwszURL[i] = 0;
3080 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3081 debugstr_w(entry->u.pwszURL));
3082 break;
3083 }
3084 case 4: /* directoryName */
3085 /* The data are memory-equivalent with the IPAddress case,
3086 * fall-through
3087 */
3088 case 7: /* iPAddress */
3089 /* The next data pointer is in the pwszURL spot, that is,
3090 * the first 4 bytes. Need to move it to the next spot.
3091 */
3092 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3093 entry->u.IPAddress.cbData = dataLen;
3094 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3095 dataLen);
3096 break;
3097 case 8: /* registeredID */
3099 &entry->u.pszRegisteredID, &dataLen, NULL);
3100 break;
3101 }
3102 }
3103 }
3104 }
3105 return ret;
3106}
3107
3109 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3110 DWORD *pcbDecoded)
3111{
3112 BOOL ret;
3113 struct AsnArrayDescriptor arrayDesc = { 0,
3114 offsetof(CERT_ALT_NAME_INFO, cAltEntry),
3115 offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
3116 sizeof(CERT_ALT_NAME_INFO),
3118 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3119
3120 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3121 pvStructInfo, *pcbStructInfo, pcbDecoded);
3122
3123 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3124 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3125 return ret;
3126}
3127
3129 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3130 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3131{
3132 BOOL ret;
3133
3134 __TRY
3135 {
3136 struct AsnDecodeSequenceItem items[] = {
3139 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3143 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3145 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3146 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3147 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3148 };
3149
3151 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3152 pcbStructInfo, NULL, NULL);
3153 }
3155 {
3157 ret = FALSE;
3158 }
3159 __ENDTRY
3160 return ret;
3161}
3162
3164 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3165 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3166{
3167 BOOL ret;
3168
3169 __TRY
3170 {
3171 struct AsnDecodeSequenceItem items[] = {
3174 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3176 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3179 AuthorityCertIssuer.rgAltEntry), 0 },
3181 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3182 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3184 AuthorityCertSerialNumber.pbData), 0 },
3185 };
3186
3188 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3189 pcbStructInfo, NULL, NULL);
3190 }
3192 {
3194 ret = FALSE;
3195 }
3196 __ENDTRY
3197 return ret;
3198}
3199
3201 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3202 DWORD *pcbDecoded)
3203{
3204 struct AsnDecodeSequenceItem items[] = {
3205 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3207 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3208 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3210 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3211 };
3212 CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3213
3215 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3216 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3217}
3218
3220 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3221 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3222{
3223 BOOL ret;
3224
3225 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3226 pDecodePara, pvStructInfo, *pcbStructInfo);
3227
3228 __TRY
3229 {
3230 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3235 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3236 CERT_AUTHORITY_INFO_ACCESS *info = pvStructInfo;
3237
3238 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3239 info->rgAccDescr = (CERT_ACCESS_DESCRIPTION *)(info + 1);
3240 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3241 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3242 }
3244 {
3246 ret = FALSE;
3247 }
3248 __ENDTRY
3249 return ret;
3250}
3251
3253 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3254{
3255 BOOL ret;
3256 DWORD dataLen;
3257
3258 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3259 pvStructInfo, *pcbStructInfo, pcbDecoded);
3260
3261 /* The caller has already checked the tag, no need to check it again.
3262 * Check the outer length is valid:
3263 */
3264 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3265 {
3266 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3267 DWORD innerLen;
3268
3269 pbEncoded += 1 + lenBytes;
3270 cbEncoded -= 1 + lenBytes;
3271 if (dataLen == CMSG_INDEFINITE_LENGTH)
3272 cbEncoded -= 2; /* space for 0 TLV */
3273 /* Check the inner length is valid: */
3274 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3275 {
3276 DWORD decodedLen;
3277
3279 pvStructInfo, pcbStructInfo, &decodedLen);
3280 if (dataLen == CMSG_INDEFINITE_LENGTH)
3281 {
3282 if (*(pbEncoded + decodedLen) != 0 ||
3283 *(pbEncoded + decodedLen + 1) != 0)
3284 {
3285 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3286 *(pbEncoded + decodedLen),
3287 *(pbEncoded + decodedLen + 1));
3289 ret = FALSE;
3290 }
3291 else
3292 decodedLen += 2;
3293 }
3294 if (ret && pcbDecoded)
3295 {
3296 *pcbDecoded = 1 + lenBytes + decodedLen;
3297 TRACE("decoded %d bytes\n", *pcbDecoded);
3298 }
3299 }
3300 }
3301 return ret;
3302}
3303
3305 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3306 DWORD *pcbDecoded)
3307{
3308 CRYPT_CONTENT_INFO *info = pvStructInfo;
3309 struct AsnDecodeSequenceItem items[] = {
3312 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3315 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3316 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3317 };
3318 BOOL ret;
3319
3320 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3321 pvStructInfo, *pcbStructInfo, pcbDecoded);
3322
3324 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3325 pcbDecoded, info ? info->pszObjId : NULL);
3326 return ret;
3327}
3328
3330 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3331 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3332{
3333 BOOL ret = FALSE;
3334
3335 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3336 pDecodePara, pvStructInfo, *pcbStructInfo);
3337
3338 __TRY
3339 {
3341 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3342 if (ret && pvStructInfo)
3343 {
3344 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3345 pcbStructInfo, *pcbStructInfo);
3346 if (ret)
3347 {
3349
3351 pvStructInfo = *(BYTE **)pvStructInfo;
3352 info = pvStructInfo;
3353 info->pszObjId = (LPSTR)((BYTE *)info +
3354 sizeof(CRYPT_CONTENT_INFO));
3356 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3357 pcbStructInfo, NULL);
3359 CRYPT_FreeSpace(pDecodePara, info);
3360 }
3361 }
3362 }
3364 {
3366 }
3367 __ENDTRY
3368 return ret;
3369}
3370
3372 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3373 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3374{
3375 BOOL ret;
3376 struct AsnDecodeSequenceItem items[] = {
3378 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3379 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3381 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3382 0 },
3386 ContentInfo.pszObjId), 0 },
3389 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3390 };
3391
3393 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3394 NULL, NULL);
3395 return ret;
3396}
3397
3399 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3400 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3401{
3402 BOOL ret = TRUE;
3403
3404 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3405 pDecodePara, pvStructInfo, *pcbStructInfo);
3406
3407 __TRY
3408 {
3409 DWORD bytesNeeded = 0;
3410
3412 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3413 {
3414 if (!pvStructInfo)
3415 *pcbStructInfo = bytesNeeded;
3416 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3417 pvStructInfo, pcbStructInfo, bytesNeeded)))
3418 {
3420
3422 pvStructInfo = *(BYTE **)pvStructInfo;
3423 name = pvStructInfo;
3424 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3425 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3427 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3428 &bytesNeeded, NULL);
3430 CRYPT_FreeSpace(pDecodePara, name);
3431 }
3432 }
3433 }
3435 {
3437 ret = FALSE;
3438 }
3439 __ENDTRY
3440 return ret;
3441}
3442
3444{
3447};
3448
3450 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3451 DWORD *pcbDecoded)
3452{
3453 BOOL ret = TRUE;
3454 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3455
3456 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3457 pvStructInfo, *pcbStructInfo, pcbDecoded);
3458
3459 if (!pvStructInfo)
3460 {
3462 &size, pcbDecoded);
3463 *pcbStructInfo = bytesNeeded;
3464 }
3465 else if (*pcbStructInfo < bytesNeeded)
3466 {
3468 *pcbStructInfo = bytesNeeded;
3469 ret = FALSE;
3470 }
3471 else
3472 {
3473 struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3474
3475 *pcbStructInfo = bytesNeeded;
3476 size = sizeof(constraint->dwPathLenConstraint);
3478 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3479 if (ret)
3480 constraint->fPathLenConstraint = TRUE;
3481 TRACE("got an int, dwPathLenConstraint is %d\n",
3482 constraint->dwPathLenConstraint);
3483 }
3484 TRACE("returning %d (%08x)\n", ret, GetLastError());
3485 return ret;
3486}
3487
3489 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3490 DWORD *pcbDecoded)
3491{
3492 BOOL ret;
3493 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3494 offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3495 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
3496 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3499
3500 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3501 pvStructInfo, *pcbStructInfo, pcbDecoded);
3502
3503 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3504 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3505 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3506 return ret;
3507}
3508
3510 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3511 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3512{
3513 BOOL ret;
3514
3515 __TRY
3516 {
3517 struct AsnDecodeSequenceItem items[] = {
3520 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3522 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3523 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3525 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3526 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3527 TRUE, TRUE,
3528 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3529 };
3530
3532 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3533 pcbStructInfo, NULL, NULL);
3534 }
3536 {
3538 ret = FALSE;
3539 }
3540 __ENDTRY
3541 return ret;
3542}
3543
3545 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3546 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3547{
3548 BOOL ret;
3549
3550 __TRY
3551 {
3552 struct AsnDecodeSequenceItem items[] = {
3554 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3556 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3557 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3558 };
3559
3561 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3562 pcbStructInfo, NULL, NULL);
3563 }
3565 {
3567 ret = FALSE;
3568 }
3569 __ENDTRY
3570 return ret;
3571}
3572
3574 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3575 DWORD *pcbDecoded)
3576{
3577 struct AsnDecodeSequenceItem items[] = {
3579 pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3580 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3581 0 },
3582 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3584 offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3585 };
3586 BOOL ret;
3587 CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3588
3589 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3590 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3591
3593 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3594 pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3595 return ret;
3596}
3597
3599 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3600 DWORD *pcbDecoded)
3601{
3602 BOOL ret;
3603 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3604 offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3605 offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
3606 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
3608 offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3609
3610 TRACE("%p, %d, %08x, %p, %d\n&quo