2 * Copyright 2005-2008 Juan Lang
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.
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.
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
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.
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.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt);
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 *);
72 /* Internal decoders don't do memory allocation or exception handling, and
73 * they report how many bytes they decoded.
75 typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded,
76 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
78 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
79 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
81 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
82 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
84 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
86 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
87 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
88 /* Assumes algo->Parameters.pbData is set ahead of time. */
89 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
90 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
91 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
92 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
93 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
94 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
95 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
97 /* Doesn't check the tag, assumes the caller does so */
98 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
99 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
100 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
101 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
102 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
103 * member has been initialized, doesn't do exception handling, and doesn't do
104 * memory allocation. Also doesn't check tag, assumes the caller has checked
107 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
108 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
110 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
111 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
112 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
114 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
115 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
118 /* Gets the number of length bytes from the given (leading) length byte */
119 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
121 /* Helper function to get the encoded length of the data starting at pbEncoded,
122 * where pbEncoded[0] is the tag. If the data are too short to contain a
123 * length or if the length is too large for cbEncoded, sets an appropriate
124 * error code and returns FALSE. If the encoded length is unknown due to
125 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
127 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
134 SetLastError(CRYPT_E_ASN1_CORRUPT);
137 else if (pbEncoded[1] <= 0x7f)
139 if (pbEncoded[1] + 1 > cbEncoded)
141 SetLastError(CRYPT_E_ASN1_EOD);
150 else if (pbEncoded[1] == 0x80)
152 *len = CMSG_INDEFINITE_LENGTH;
157 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
159 if (lenLen > sizeof(DWORD) + 1)
161 SetLastError(CRYPT_E_ASN1_LARGE);
164 else if (lenLen + 2 > cbEncoded)
166 SetLastError(CRYPT_E_ASN1_CORRUPT);
179 if (out + lenLen + 1 > cbEncoded)
181 SetLastError(CRYPT_E_ASN1_EOD);
194 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
195 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
199 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
200 *len == CMSG_INDEFINITE_LENGTH)
202 SetLastError(CRYPT_E_ASN1_CORRUPT);
208 /* Helper function to check *pcbStructInfo, set it to the required size, and
209 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
210 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
211 * pointer to the newly allocated memory.
213 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
214 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
219 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
221 if (pDecodePara && pDecodePara->pfnAlloc)
222 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
224 *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
225 if (!*(BYTE **)pvStructInfo)
228 *pcbStructInfo = bytesNeeded;
230 else if (*pcbStructInfo < bytesNeeded)
232 *pcbStructInfo = bytesNeeded;
233 SetLastError(ERROR_MORE_DATA);
237 *pcbStructInfo = bytesNeeded;
241 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara, LPVOID pv)
243 if (pDecodePara && pDecodePara->pfnFree)
244 pDecodePara->pfnFree(pv);
249 /* Helper function to check *pcbStructInfo and set it to the required size.
250 * Assumes pvStructInfo is not NULL.
252 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
256 if (*pcbStructInfo < bytesNeeded)
258 *pcbStructInfo = bytesNeeded;
259 SetLastError(ERROR_MORE_DATA);
264 *pcbStructInfo = bytesNeeded;
271 * The expected tag of the item. If tag is 0, decodeFunc is called
272 * regardless of the tag value seen.
274 * A sequence is decoded into a struct. The offset member is the
275 * offset of this item within that struct.
277 * The decoder function to use. If this is NULL, then the member isn't
278 * decoded, but minSize space is reserved for it.
280 * The minimum amount of space occupied after decoding. You must set this.
282 * If true, and the tag doesn't match the expected tag for this item,
283 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
284 * filled with 0 for this member.
285 * hasPointer, pointerOffset:
286 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
287 * the offset within the struct of the data pointer (or to the
288 * first data pointer, if more than one exist).
290 * Used by CRYPT_AsnDecodeSequence, not for your use.
292 struct AsnDecodeSequenceItem
296 InternalDecodeFunc decodeFunc;
304 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
305 #define MEMBERSIZE(s, member, nextmember) \
306 (offsetof(s, nextmember) - offsetof(s, member))
308 /* Decodes the items in a sequence, where the items are described in items,
309 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
310 * pvStructInfo. nextData is a pointer to the memory location at which the
311 * first decoded item with a dynamic pointer should point.
312 * Upon decoding, *cbDecoded is the total number of bytes decoded.
313 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
315 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
316 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
317 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
320 DWORD i, decoded = 0;
321 const BYTE *ptr = pbEncoded;
323 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
324 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
326 for (i = 0, ret = TRUE; ret && i < cItem; i++)
328 if (cbEncoded - (ptr - pbEncoded) != 0)
332 if ((ret = CRYPT_GetLengthIndefinite(ptr,
333 cbEncoded - (ptr - pbEncoded), &itemLen)))
335 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
337 if (ptr[0] == items[i].tag || !items[i].tag)
339 DWORD itemEncodedLen;
341 if (itemLen == CMSG_INDEFINITE_LENGTH)
342 itemEncodedLen = cbEncoded - (ptr - pbEncoded);
344 itemEncodedLen = 1 + itemLenBytes + itemLen;
345 if (nextData && pvStructInfo && items[i].hasPointer)
347 TRACE("Setting next pointer to %p\n",
349 *(BYTE **)((BYTE *)pvStructInfo +
350 items[i].pointerOffset) = nextData;
352 if (items[i].decodeFunc)
357 TRACE("decoding item %d\n", i);
359 TRACE("sizing item %d\n", i);
360 ret = items[i].decodeFunc(ptr, itemEncodedLen,
361 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
362 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
363 : NULL, &items[i].size, &itemDecoded);
366 /* Account for alignment padding */
367 items[i].size = ALIGN_DWORD_PTR(items[i].size);
368 TRACE("item %d size: %d\n", i, items[i].size);
369 if (nextData && items[i].hasPointer &&
370 items[i].size > items[i].minSize)
371 nextData += items[i].size - items[i].minSize;
372 if (itemDecoded > itemEncodedLen)
374 WARN("decoded length %d exceeds encoded %d\n",
375 itemDecoded, itemEncodedLen);
376 SetLastError(CRYPT_E_ASN1_CORRUPT);
382 decoded += itemDecoded;
383 TRACE("item %d: decoded %d bytes\n", i,
387 else if (items[i].optional &&
388 GetLastError() == CRYPT_E_ASN1_BADTAG)
390 TRACE("skipping optional item %d\n", i);
391 items[i].size = items[i].minSize;
392 SetLastError(NOERROR);
396 TRACE("item %d failed: %08x\n", i,
399 else if (itemLen == CMSG_INDEFINITE_LENGTH)
401 ERR("can't use indefinite length encoding without a decoder\n");
402 SetLastError(CRYPT_E_ASN1_CORRUPT);
407 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
408 ptr += itemEncodedLen;
409 decoded += itemEncodedLen;
410 items[i].size = items[i].minSize;
413 else if (items[i].optional)
415 TRACE("skipping optional item %d\n", i);
416 items[i].size = items[i].minSize;
420 TRACE("item %d: tag %02x doesn't match expected %02x\n",
421 i, ptr[0], items[i].tag);
422 SetLastError(CRYPT_E_ASN1_BADTAG);
427 else if (items[i].optional)
429 TRACE("missing optional item %d, skipping\n", i);
430 items[i].size = items[i].minSize;
434 TRACE("not enough bytes for item %d, failing\n", i);
435 SetLastError(CRYPT_E_ASN1_CORRUPT);
440 *cbDecoded = decoded;
441 TRACE("returning %d\n", ret);
445 /* This decodes an arbitrary sequence into a contiguous block of memory
446 * (basically, a struct.) Each element being decoded is described by a struct
447 * AsnDecodeSequenceItem, see above.
448 * startingPointer is an optional pointer to the first place where dynamic
449 * data will be stored. If you know the starting offset, you may pass it
450 * here. Otherwise, pass NULL, and one will be inferred from the items.
452 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
453 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
454 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
455 DWORD *pcbDecoded, void *startingPointer)
459 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
460 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
465 SetLastError(CRYPT_E_ASN1_EOD);
468 if (pbEncoded[0] == ASN_SEQUENCE)
472 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
474 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
475 const BYTE *ptr = pbEncoded + 1 + lenBytes;
476 BOOL indefinite = FALSE;
478 cbEncoded -= 1 + lenBytes;
479 if (dataLen == CMSG_INDEFINITE_LENGTH)
484 else if (cbEncoded < dataLen)
486 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
488 SetLastError(CRYPT_E_ASN1_CORRUPT);
493 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
494 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
495 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
497 if (cbDecoded > cbEncoded - 2)
499 /* Not enough space for 0 TLV */
500 SetLastError(CRYPT_E_ASN1_CORRUPT);
503 else if (*(ptr + cbDecoded) != 0 ||
504 *(ptr + cbDecoded + 1) != 0)
506 TRACE("expected 0 TLV\n");
507 SetLastError(CRYPT_E_ASN1_CORRUPT);
514 if (ret && !indefinite && cbDecoded != dataLen)
516 TRACE("expected %d decoded, got %d, failing\n", dataLen,
518 SetLastError(CRYPT_E_ASN1_CORRUPT);
523 DWORD i, bytesNeeded = 0, structSize = 0;
525 for (i = 0; i < cItem; i++)
527 bytesNeeded += items[i].size;
528 structSize = max( structSize, items[i].offset + items[i].minSize );
531 *pcbDecoded = 1 + lenBytes + cbDecoded;
533 *pcbStructInfo = bytesNeeded;
534 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
535 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
539 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
540 pvStructInfo = *(BYTE **)pvStructInfo;
542 nextData = startingPointer;
544 nextData = (BYTE *)pvStructInfo + structSize;
545 memset(pvStructInfo, 0, structSize);
546 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
547 ptr, dataLen, dwFlags, pvStructInfo, nextData,
549 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
550 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
557 SetLastError(CRYPT_E_ASN1_BADTAG);
560 TRACE("returning %d (%08x)\n", ret, GetLastError());
565 * The expected tag of the entire encoded array (usually a variant
566 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
567 * regardless of the tag seen.
569 * used to decode each item in the array
571 * is the minimum size of each decoded item
573 * indicates whether each item has a dynamic pointer
575 * indicates the offset within itemSize at which the pointer exists
577 struct AsnArrayDescriptor
580 InternalDecodeFunc decodeFunc;
586 struct AsnArrayItemSize
592 /* Decodes an array of like types into a struct GenericArray.
593 * The layout and decoding of the array are described by a struct
594 * AsnArrayDescriptor.
596 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
597 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
598 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
599 DWORD *pcbDecoded, void *startingPointer)
603 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
604 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
609 SetLastError(CRYPT_E_ASN1_EOD);
612 else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
616 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
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.
622 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
624 decoded = 1 + lenBytes;
625 bytesNeeded = sizeof(struct GenericArray);
629 BOOL doneDecoding = FALSE;
631 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
633 if (dataLen == CMSG_INDEFINITE_LENGTH)
640 SetLastError(CRYPT_E_ASN1_CORRUPT);
647 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
651 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
653 /* Each item decoded may not tolerate extraneous bytes,
654 * so get the length of the next element if known.
656 if ((ret = CRYPT_GetLengthIndefinite(ptr,
657 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
659 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
660 itemEncoded = cbEncoded - (ptr - pbEncoded);
662 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
666 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
667 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
672 if (itemSizes != &itemSize)
673 itemSizes = CryptMemRealloc(itemSizes,
674 cItems * sizeof(struct AsnArrayItemSize));
679 cItems * sizeof(struct AsnArrayItemSize));
681 memcpy(itemSizes, &itemSize,
686 decoded += itemDecoded;
687 itemSizes[cItems - 1].encodedLen = itemEncoded;
688 itemSizes[cItems - 1].size = size;
701 *pcbDecoded = decoded;
703 *pcbStructInfo = bytesNeeded;
704 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
705 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
710 struct GenericArray *array;
712 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
713 pvStructInfo = *(BYTE **)pvStructInfo;
714 array = pvStructInfo;
715 array->cItems = cItems;
717 array->rgItems = startingPointer;
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 <
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);
739 nextData += itemSizes[i].size - arrayDesc->itemSize;
743 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
744 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
747 if (itemSizes != &itemSize)
748 CryptMemFree(itemSizes);
753 SetLastError(CRYPT_E_ASN1_BADTAG);
759 /* Decodes an array of like types into a struct GenericArray.
760 * The layout and decoding of the array are described by a struct
761 * AsnArrayDescriptor. Doesn't allocate memory for the decoded items,
762 * leaves that up to the caller.
764 static BOOL CRYPT_AsnDecodeArrayNoAlloc(const struct AsnArrayDescriptor *arrayDesc,
765 const BYTE *pbEncoded, DWORD cbEncoded, DWORD *pcItems, void *rgItems,
766 DWORD *pcbItems, DWORD *pcbDecoded)
770 TRACE("%p, %p, %d, %p, %p, %d\n", arrayDesc, pbEncoded,
771 cbEncoded, pcItems, rgItems, pcItems ? *pcbItems : 0);
775 SetLastError(CRYPT_E_ASN1_EOD);
778 else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
782 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
784 DWORD bytesNeeded = 0, cItems = 0, decoded;
785 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
786 /* There can be arbitrarily many items, but there is often only one.
788 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
790 decoded = 1 + lenBytes;
794 BOOL doneDecoding = FALSE;
796 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
798 if (dataLen == CMSG_INDEFINITE_LENGTH)
805 SetLastError(CRYPT_E_ASN1_CORRUPT);
812 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
816 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
818 /* Each item decoded may not tolerate extraneous bytes,
819 * so get the length of the next element if known.
821 if ((ret = CRYPT_GetLengthIndefinite(ptr,
822 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
824 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
825 itemEncoded = cbEncoded - (ptr - pbEncoded);
827 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
831 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
832 0, NULL, &size, &itemDecoded);
836 if (itemSizes != &itemSize)
837 itemSizes = CryptMemRealloc(itemSizes,
838 cItems * sizeof(struct AsnArrayItemSize));
843 cItems * sizeof(struct AsnArrayItemSize));
845 memcpy(itemSizes, &itemSize,
850 decoded += itemDecoded;
851 itemSizes[cItems - 1].encodedLen = itemEncoded;
852 itemSizes[cItems - 1].size = size;
865 *pcbDecoded = decoded;
867 *pcbItems = bytesNeeded;
868 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, rgItems,
869 pcbItems, bytesNeeded)))
876 nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize;
877 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
878 i < cItems && ptr - pbEncoded - 1 - lenBytes <
883 if (arrayDesc->hasPointer)
884 *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize
885 + arrayDesc->pointerOffset) = nextData;
886 ret = arrayDesc->decodeFunc(ptr,
887 itemSizes[i].encodedLen, 0,
888 (BYTE *)rgItems + i * arrayDesc->itemSize,
889 &itemSizes[i].size, &itemDecoded);
892 nextData += itemSizes[i].size - arrayDesc->itemSize;
898 if (itemSizes != &itemSize)
899 CryptMemFree(itemSizes);
904 SetLastError(CRYPT_E_ASN1_BADTAG);
910 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
911 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
912 * to CRYPT_E_ASN1_CORRUPT.
913 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
916 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
917 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
922 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
924 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
925 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
927 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
928 bytesNeeded += 1 + lenBytes + dataLen;
931 *pcbDecoded = 1 + lenBytes + dataLen;
933 *pcbStructInfo = bytesNeeded;
934 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
936 CRYPT_DER_BLOB *blob;
938 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
939 pvStructInfo = *(BYTE **)pvStructInfo;
941 blob->cbData = 1 + lenBytes + dataLen;
944 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
945 blob->pbData = (BYTE *)pbEncoded;
948 assert(blob->pbData);
949 memcpy(blob->pbData, pbEncoded, blob->cbData);
954 SetLastError(CRYPT_E_ASN1_CORRUPT);
962 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
963 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
964 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
969 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
970 pvStructInfo, *pcbStructInfo, pcbDecoded);
972 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
975 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
976 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
978 if (ret && pvStructInfo)
980 CRYPT_BIT_BLOB *blob = pvStructInfo;
987 for (i = 0; i < blob->cbData / 2; i++)
989 temp = blob->pbData[i];
990 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
991 blob->pbData[blob->cbData - i - 1] = temp;
995 TRACE("returning %d (%08x)\n", ret, GetLastError());
999 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
1000 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1001 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1005 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1006 pDecodePara, pvStructInfo, *pcbStructInfo);
1010 struct AsnDecodeSequenceItem items[] = {
1011 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
1012 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
1013 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
1014 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
1015 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
1016 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
1017 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
1018 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
1019 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
1020 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
1023 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
1024 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
1025 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1026 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
1027 pcbStructInfo, NULL, NULL);
1031 SetLastError(STATUS_ACCESS_VIOLATION);
1036 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1040 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
1041 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1046 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1048 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1050 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
1051 dwFlags, pvStructInfo, pcbStructInfo, NULL);
1053 *pcbDecoded = 1 + lenBytes + dataLen;
1058 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
1059 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1063 struct AsnDecodeSequenceItem items[] = {
1064 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
1065 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1066 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
1067 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1070 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1071 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
1076 static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded,
1077 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1081 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1082 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1083 offsetof(CERT_EXTENSION, pszObjId) };
1086 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1087 pvStructInfo, *pcbStructInfo, pcbDecoded);
1089 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
1090 NULL, NULL, &itemSize, pcbDecoded);
1095 /* The size expected by the caller includes the combination of
1096 * CERT_INFO's cExtension and rgExtension, in addition to the size of
1097 * all the decoded items. CRYPT_AsnDecodeArrayNoAlloc only returns
1098 * the size of the decoded items, so add the size of cExtension and
1101 bytesNeeded = FINALMEMBERSIZE(CERT_INFO, cExtension) + itemSize;
1103 *pcbStructInfo = bytesNeeded;
1104 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
1105 pcbStructInfo, bytesNeeded)))
1109 info = (CERT_INFO *)((BYTE *)pvStructInfo -
1110 offsetof(CERT_INFO, cExtension));
1111 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
1112 cbEncoded, &info->cExtension, info->rgExtension, &itemSize,
1119 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
1120 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1126 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1128 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1130 ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes,
1131 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1132 if (ret && pcbDecoded)
1133 *pcbDecoded = 1 + lenBytes + dataLen;
1138 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
1139 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1140 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1143 struct AsnDecodeSequenceItem items[] = {
1144 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
1145 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1146 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
1147 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
1148 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
1149 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
1150 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1151 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
1152 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1153 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
1155 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
1156 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
1158 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
1159 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
1161 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
1162 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
1163 FALSE, TRUE, offsetof(CERT_INFO,
1164 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
1165 { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
1166 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1167 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
1168 { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
1169 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1170 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
1171 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
1172 CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension),
1173 TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
1176 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1177 pDecodePara, pvStructInfo, *pcbStructInfo);
1179 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1180 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1182 if (ret && pvStructInfo)
1186 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1187 info = *(CERT_INFO **)pvStructInfo;
1189 info = pvStructInfo;
1190 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1191 !info->Subject.cbData)
1193 SetLastError(CRYPT_E_ASN1_CORRUPT);
1194 /* Don't need to deallocate, because it should have failed on the
1195 * first pass (and no memory was allocated.)
1201 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1205 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1206 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1207 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1211 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1212 pDecodePara, pvStructInfo, *pcbStructInfo);
1218 /* Unless told not to, first try to decode it as a signed cert. */
1219 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1221 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1223 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1224 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1225 &signedCert, &size);
1229 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1230 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1231 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1232 pvStructInfo, pcbStructInfo);
1233 LocalFree(signedCert);
1236 /* Failing that, try it as an unsigned cert */
1240 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1241 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1242 pDecodePara, pvStructInfo, pcbStructInfo);
1247 SetLastError(STATUS_ACCESS_VIOLATION);
1251 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1255 static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded,
1256 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1260 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1261 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1262 offsetof(CERT_EXTENSION, pszObjId) };
1265 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1266 pvStructInfo, *pcbStructInfo, pcbDecoded);
1268 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
1269 NULL, NULL, &itemSize, pcbDecoded);
1274 /* The size expected by the caller includes the combination of
1275 * CRL_ENTRY's cExtension and rgExtension, in addition to the size of
1276 * all the decoded items. CRYPT_AsnDecodeArrayNoAlloc only returns
1277 * the size of the decoded items, so add the size of cExtension and
1280 bytesNeeded = FINALMEMBERSIZE(CRL_ENTRY, cExtension) + itemSize;
1282 *pcbStructInfo = bytesNeeded;
1283 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
1284 pcbStructInfo, bytesNeeded)))
1288 entry = (CRL_ENTRY *)((BYTE *)pvStructInfo -
1289 offsetof(CRL_ENTRY, cExtension));
1290 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
1291 cbEncoded, &entry->cExtension, entry->rgExtension, &itemSize,
1298 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1299 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1302 struct AsnDecodeSequenceItem items[] = {
1303 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1304 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1305 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1306 { 0, offsetof(CRL_ENTRY, RevocationDate),
1307 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1308 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1309 CRYPT_AsnDecodeCRLEntryExtensions,
1310 FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
1311 offsetof(CRL_ENTRY, rgExtension), 0 },
1313 PCRL_ENTRY entry = pvStructInfo;
1315 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1318 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1319 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1320 entry ? entry->SerialNumber.pbData : NULL);
1321 if (ret && entry && !entry->SerialNumber.cbData)
1323 WARN("empty CRL entry serial number\n");
1324 SetLastError(CRYPT_E_ASN1_CORRUPT);
1330 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1331 * whose rgCRLEntry member has been set prior to calling.
1333 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1334 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1337 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1338 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1339 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1342 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1343 pvStructInfo, *pcbStructInfo, pcbDecoded);
1345 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
1346 NULL, NULL, &itemSize, pcbDecoded);
1351 /* The size expected by the caller includes the combination of
1352 * CRL_INFO's cCRLEntry and rgCRLEntry, in addition to the size of
1353 * all the decoded items. CRYPT_AsnDecodeArrayNoAlloc only returns
1354 * the size of the decoded items, so add the size of cCRLEntry and
1357 bytesNeeded = offsetof(CRL_INFO, cExtension) -
1358 offsetof(CRL_INFO, cCRLEntry) + itemSize;
1360 *pcbStructInfo = bytesNeeded;
1361 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
1362 pcbStructInfo, bytesNeeded)))
1366 info = (CRL_INFO *)((BYTE *)pvStructInfo -
1367 offsetof(CRL_INFO, cCRLEntry));
1368 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
1369 cbEncoded, &info->cCRLEntry, info->rgCRLEntry, &itemSize,
1373 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1377 static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded,
1378 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1382 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1383 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1384 offsetof(CERT_EXTENSION, pszObjId) };
1387 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1388 pvStructInfo, *pcbStructInfo, pcbDecoded);
1390 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
1391 NULL, NULL, &itemSize, pcbDecoded);
1396 /* The size expected by the caller includes the combination of
1397 * CRL_INFO's cExtension and rgExtension, in addition to the size of
1398 * all the decoded items. CRYPT_AsnDecodeArrayNoAlloc only returns
1399 * the size of the decoded items, so add the size of cExtension and
1402 bytesNeeded = FINALMEMBERSIZE(CRL_INFO, cExtension) + itemSize;
1404 *pcbStructInfo = bytesNeeded;
1405 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
1406 pcbStructInfo, bytesNeeded)))
1410 info = (CRL_INFO *)((BYTE *)pvStructInfo -
1411 offsetof(CRL_INFO, cExtension));
1412 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
1413 cbEncoded, &info->cExtension, info->rgExtension, &itemSize,
1420 static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded,
1421 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1427 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1429 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1431 ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes,
1432 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1433 if (ret && pcbDecoded)
1434 *pcbDecoded = 1 + lenBytes + dataLen;
1439 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1440 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1441 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1443 struct AsnDecodeSequenceItem items[] = {
1444 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1445 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1446 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1447 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1448 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1449 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1450 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1452 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1453 sizeof(FILETIME), FALSE, FALSE, 0 },
1454 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1455 sizeof(FILETIME), TRUE, FALSE, 0 },
1456 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1457 CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1458 TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
1459 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1460 CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension),
1461 TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
1465 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1466 pDecodePara, pvStructInfo, *pcbStructInfo);
1468 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1469 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1472 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1476 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1477 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1478 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1482 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1483 pDecodePara, pvStructInfo, *pcbStructInfo);
1489 /* Unless told not to, first try to decode it as a signed crl. */
1490 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1492 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1494 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1495 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1500 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1501 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1502 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1503 pvStructInfo, pcbStructInfo);
1504 LocalFree(signedCrl);
1507 /* Failing that, try it as an unsigned crl */
1511 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1512 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1513 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1518 SetLastError(STATUS_ACCESS_VIOLATION);
1522 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1526 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1527 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1532 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1533 pvStructInfo, *pcbStructInfo);
1535 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1537 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1538 DWORD bytesNeeded = sizeof(LPSTR);
1542 /* The largest possible string for the first two components
1543 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1548 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1549 pbEncoded[1 + lenBytes] / 40,
1550 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1552 bytesNeeded += strlen(firstTwo) + 1;
1553 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1554 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1556 /* large enough for ".4000000" */
1560 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1567 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1570 SetLastError(CRYPT_E_ASN1_CORRUPT);
1577 snprintf(str, sizeof(str), ".%d", val);
1578 bytesNeeded += strlen(str);
1583 *pcbDecoded = 1 + lenBytes + dataLen;
1585 *pcbStructInfo = bytesNeeded;
1586 else if (*pcbStructInfo < bytesNeeded)
1588 *pcbStructInfo = bytesNeeded;
1589 SetLastError(ERROR_MORE_DATA);
1597 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1600 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1601 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1603 pszObjId += strlen(pszObjId);
1604 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1605 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1609 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1618 sprintf(pszObjId, ".%d", val);
1619 pszObjId += strlen(pszObjId);
1623 *(LPSTR *)pvStructInfo = NULL;
1624 *pcbStructInfo = bytesNeeded;
1630 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1631 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1635 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1636 pvStructInfo, *pcbStructInfo);
1638 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1639 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1640 pvStructInfo, pcbStructInfo, pcbDecoded);
1643 SetLastError(CRYPT_E_ASN1_BADTAG);
1649 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1650 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1652 struct AsnDecodeSequenceItem items[] = {
1653 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1654 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1655 offsetof(CERT_EXTENSION, pszObjId), 0 },
1656 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1657 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1658 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1659 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1660 offsetof(CERT_EXTENSION, Value.pbData) },
1663 PCERT_EXTENSION ext = pvStructInfo;
1665 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1669 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1670 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1671 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1672 pcbDecoded, ext ? ext->pszObjId : NULL);
1674 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1675 debugstr_a(ext->pszObjId));
1676 TRACE("returning %d (%08x)\n", ret, GetLastError());
1680 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1681 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1682 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1686 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1687 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1691 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1692 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1693 offsetof(CERT_EXTENSION, pszObjId) };
1696 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
1697 NULL, NULL, &itemSize, NULL);
1702 /* CRYPT_AsnDecodeArrayNoAlloc only returns the size of the decoded
1703 * items, so add the size of CERT_EXTENSIONS.
1705 bytesNeeded = sizeof(CERT_EXTENSIONS) + itemSize;
1707 *pcbStructInfo = bytesNeeded;
1708 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
1709 pvStructInfo, pcbStructInfo, bytesNeeded)))
1711 CERT_EXTENSIONS *exts;
1713 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1714 pvStructInfo = *(BYTE **)pvStructInfo;
1715 exts = (CERT_EXTENSIONS *)pvStructInfo;
1716 exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
1717 sizeof(CERT_EXTENSIONS));
1718 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
1719 cbEncoded, &exts->cExtension, exts->rgExtension, &itemSize,
1726 SetLastError(STATUS_ACCESS_VIOLATION);
1733 /* Warning: this assumes the address of value->Value.pbData is already set, in
1734 * order to avoid overwriting memory. (In some cases, it may change it, if it
1735 * doesn't copy anything to memory.) Be sure to set it correctly!
1737 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1738 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1743 CERT_NAME_VALUE *value = pvStructInfo;
1745 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1747 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1748 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1750 switch (pbEncoded[0])
1752 case ASN_OCTETSTRING:
1753 valueType = CERT_RDN_OCTET_STRING;
1754 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1755 bytesNeeded += dataLen;
1757 case ASN_NUMERICSTRING:
1758 valueType = CERT_RDN_NUMERIC_STRING;
1759 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1760 bytesNeeded += dataLen;
1762 case ASN_PRINTABLESTRING:
1763 valueType = CERT_RDN_PRINTABLE_STRING;
1764 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1765 bytesNeeded += dataLen;
1768 valueType = CERT_RDN_IA5_STRING;
1769 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1770 bytesNeeded += dataLen;
1773 valueType = CERT_RDN_T61_STRING;
1774 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1775 bytesNeeded += dataLen;
1777 case ASN_VIDEOTEXSTRING:
1778 valueType = CERT_RDN_VIDEOTEX_STRING;
1779 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1780 bytesNeeded += dataLen;
1782 case ASN_GRAPHICSTRING:
1783 valueType = CERT_RDN_GRAPHIC_STRING;
1784 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1785 bytesNeeded += dataLen;
1787 case ASN_VISIBLESTRING:
1788 valueType = CERT_RDN_VISIBLE_STRING;
1789 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1790 bytesNeeded += dataLen;
1792 case ASN_GENERALSTRING:
1793 valueType = CERT_RDN_GENERAL_STRING;
1794 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1795 bytesNeeded += dataLen;
1797 case ASN_UNIVERSALSTRING:
1798 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1799 SetLastError(CRYPT_E_ASN1_BADTAG);
1802 valueType = CERT_RDN_BMP_STRING;
1803 bytesNeeded += dataLen;
1805 case ASN_UTF8STRING:
1806 valueType = CERT_RDN_UTF8_STRING;
1807 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1808 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1811 SetLastError(CRYPT_E_ASN1_BADTAG);
1816 *pcbDecoded = 1 + lenBytes + dataLen;
1818 *pcbStructInfo = bytesNeeded;
1819 else if (*pcbStructInfo < bytesNeeded)
1821 *pcbStructInfo = bytesNeeded;
1822 SetLastError(ERROR_MORE_DATA);
1827 *pcbStructInfo = bytesNeeded;
1828 value->dwValueType = valueType;
1833 assert(value->Value.pbData);
1834 switch (pbEncoded[0])
1836 case ASN_OCTETSTRING:
1837 case ASN_NUMERICSTRING:
1838 case ASN_PRINTABLESTRING:
1841 case ASN_VIDEOTEXSTRING:
1842 case ASN_GRAPHICSTRING:
1843 case ASN_VISIBLESTRING:
1844 case ASN_GENERALSTRING:
1845 value->Value.cbData = dataLen;
1848 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1849 memcpy(value->Value.pbData,
1850 pbEncoded + 1 + lenBytes, dataLen);
1852 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1858 LPWSTR str = (LPWSTR)value->Value.pbData;
1860 value->Value.cbData = dataLen;
1861 for (i = 0; i < dataLen / 2; i++)
1862 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1863 pbEncoded[1 + lenBytes + 2 * i + 1];
1866 case ASN_UTF8STRING:
1868 LPWSTR str = (LPWSTR)value->Value.pbData;
1870 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1871 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1872 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1879 value->Value.cbData = 0;
1880 value->Value.pbData = NULL;
1887 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1888 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1889 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1895 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1896 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1897 if (ret && pvStructInfo)
1899 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1900 pcbStructInfo, *pcbStructInfo);
1903 CERT_NAME_VALUE *value;
1905 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1906 pvStructInfo = *(BYTE **)pvStructInfo;
1907 value = pvStructInfo;
1908 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1909 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1910 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1911 pcbStructInfo, NULL);
1917 SetLastError(STATUS_ACCESS_VIOLATION);
1924 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1925 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1930 CERT_NAME_VALUE *value = pvStructInfo;
1932 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1934 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1935 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1937 switch (pbEncoded[0])
1939 case ASN_NUMERICSTRING:
1940 valueType = CERT_RDN_NUMERIC_STRING;
1942 bytesNeeded += (dataLen + 1) * 2;
1944 case ASN_PRINTABLESTRING:
1945 valueType = CERT_RDN_PRINTABLE_STRING;
1947 bytesNeeded += (dataLen + 1) * 2;
1950 valueType = CERT_RDN_IA5_STRING;
1952 bytesNeeded += (dataLen + 1) * 2;
1955 valueType = CERT_RDN_T61_STRING;
1957 bytesNeeded += (dataLen + 1) * 2;
1959 case ASN_VIDEOTEXSTRING:
1960 valueType = CERT_RDN_VIDEOTEX_STRING;
1962 bytesNeeded += (dataLen + 1) * 2;
1964 case ASN_GRAPHICSTRING:
1965 valueType = CERT_RDN_GRAPHIC_STRING;
1967 bytesNeeded += (dataLen + 1) * 2;
1969 case ASN_VISIBLESTRING:
1970 valueType = CERT_RDN_VISIBLE_STRING;
1972 bytesNeeded += (dataLen + 1) * 2;
1974 case ASN_GENERALSTRING:
1975 valueType = CERT_RDN_GENERAL_STRING;
1977 bytesNeeded += (dataLen + 1) * 2;
1979 case ASN_UNIVERSALSTRING:
1980 valueType = CERT_RDN_UNIVERSAL_STRING;
1982 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1985 valueType = CERT_RDN_BMP_STRING;
1987 bytesNeeded += dataLen + sizeof(WCHAR);
1989 case ASN_UTF8STRING:
1990 valueType = CERT_RDN_UTF8_STRING;
1992 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1993 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1996 SetLastError(CRYPT_E_ASN1_BADTAG);
2001 *pcbDecoded = 1 + lenBytes + dataLen;
2003 *pcbStructInfo = bytesNeeded;
2004 else if (*pcbStructInfo < bytesNeeded)
2006 *pcbStructInfo = bytesNeeded;
2007 SetLastError(ERROR_MORE_DATA);
2012 *pcbStructInfo = bytesNeeded;
2013 value->dwValueType = valueType;
2017 LPWSTR str = (LPWSTR)value->Value.pbData;
2019 assert(value->Value.pbData);
2020 switch (pbEncoded[0])
2022 case ASN_NUMERICSTRING:
2023 case ASN_PRINTABLESTRING:
2026 case ASN_VIDEOTEXSTRING:
2027 case ASN_GRAPHICSTRING:
2028 case ASN_VISIBLESTRING:
2029 case ASN_GENERALSTRING:
2030 value->Value.cbData = dataLen * 2;
2031 for (i = 0; i < dataLen; i++)
2032 str[i] = pbEncoded[1 + lenBytes + i];
2035 case ASN_UNIVERSALSTRING:
2036 value->Value.cbData = dataLen / 2;
2037 for (i = 0; i < dataLen / 4; i++)
2038 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2039 | pbEncoded[1 + lenBytes + 2 * i + 3];
2043 value->Value.cbData = dataLen;
2044 for (i = 0; i < dataLen / 2; i++)
2045 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2046 pbEncoded[1 + lenBytes + 2 * i + 1];
2049 case ASN_UTF8STRING:
2050 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
2051 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2052 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
2053 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
2054 value->Value.cbData += sizeof(WCHAR);
2060 value->Value.cbData = 0;
2061 value->Value.pbData = NULL;
2068 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
2069 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2070 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2076 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
2077 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
2078 if (ret && pvStructInfo)
2080 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
2081 pcbStructInfo, *pcbStructInfo);
2084 CERT_NAME_VALUE *value;
2086 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2087 pvStructInfo = *(BYTE **)pvStructInfo;
2088 value = pvStructInfo;
2089 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
2090 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
2091 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2092 pcbStructInfo, NULL);
2098 SetLastError(STATUS_ACCESS_VIOLATION);
2105 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
2106 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2109 struct AsnDecodeSequenceItem items[] = {
2110 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
2111 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2112 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
2113 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
2114 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
2115 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
2117 CERT_RDN_ATTR *attr = pvStructInfo;
2119 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2120 pvStructInfo, *pcbStructInfo);
2123 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
2124 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2125 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
2126 attr ? attr->pszObjId : NULL);
2129 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
2130 debugstr_a(attr->pszObjId));
2131 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
2133 TRACE("returning %d (%08x)\n", ret, GetLastError());
2137 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
2138 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2141 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2142 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
2143 offsetof(CERT_RDN_ATTR, pszObjId) };
2144 PCERT_RDN rdn = pvStructInfo;
2146 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2147 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2148 rdn ? rdn->rgRDNAttr : NULL);
2152 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
2153 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2154 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2160 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2161 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
2162 offsetof(CERT_RDN, rgRDNAttr) };
2164 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2165 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
2169 SetLastError(STATUS_ACCESS_VIOLATION);
2176 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
2177 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2181 struct AsnDecodeSequenceItem items[] = {
2182 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
2183 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2184 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
2185 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
2186 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
2187 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
2189 CERT_RDN_ATTR *attr = pvStructInfo;
2191 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2192 pvStructInfo, *pcbStructInfo);
2195 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
2196 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2197 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
2198 attr ? attr->pszObjId : NULL);
2201 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
2202 debugstr_a(attr->pszObjId));
2203 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
2205 TRACE("returning %d (%08x)\n", ret, GetLastError());
2209 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
2210 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2213 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2214 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
2215 offsetof(CERT_RDN_ATTR, pszObjId) };
2216 PCERT_RDN rdn = pvStructInfo;
2218 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2219 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2220 rdn ? rdn->rgRDNAttr : NULL);
2224 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
2225 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2226 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2232 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2233 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
2234 offsetof(CERT_RDN, rgRDNAttr) };
2236 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2237 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
2241 SetLastError(STATUS_ACCESS_VIOLATION);
2248 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
2251 BOOL ret = TRUE, done = FALSE;
2252 DWORD indefiniteNestingLevels = 0, decoded = 0;
2254 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2261 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2264 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2266 if (dataLen == CMSG_INDEFINITE_LENGTH)
2268 indefiniteNestingLevels++;
2269 pbEncoded += 1 + lenBytes;
2270 cbEncoded -= 1 + lenBytes;
2271 decoded += 1 + lenBytes;
2272 TRACE("indefiniteNestingLevels = %d\n",
2273 indefiniteNestingLevels);
2277 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2278 indefiniteNestingLevels)
2280 indefiniteNestingLevels--;
2281 TRACE("indefiniteNestingLevels = %d\n",
2282 indefiniteNestingLevels);
2284 pbEncoded += 1 + lenBytes + dataLen;
2285 cbEncoded -= 1 + lenBytes + dataLen;
2286 decoded += 1 + lenBytes + dataLen;
2287 if (!indefiniteNestingLevels)
2291 } while (ret && !done);
2292 /* If we haven't found all 0 TLVs, we haven't found the end */
2293 if (ret && indefiniteNestingLevels)
2295 SetLastError(CRYPT_E_ASN1_EOD);
2299 *pcbDecoded = decoded;
2300 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2304 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
2305 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2309 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2311 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2312 pvStructInfo, *pcbStructInfo);
2314 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2316 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
2317 bytesNeeded += encodedLen;
2319 *pcbStructInfo = bytesNeeded;
2320 else if (*pcbStructInfo < bytesNeeded)
2322 SetLastError(ERROR_MORE_DATA);
2323 *pcbStructInfo = bytesNeeded;
2328 PCRYPT_OBJID_BLOB blob = pvStructInfo;
2330 *pcbStructInfo = bytesNeeded;
2331 blob->cbData = encodedLen;
2334 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2335 blob->pbData = (LPBYTE)pbEncoded;
2338 assert(blob->pbData);
2339 memcpy(blob->pbData, pbEncoded, blob->cbData);
2343 blob->pbData = NULL;
2346 *pcbDecoded = encodedLen;
2351 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2352 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2355 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2356 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2357 CTL_USAGE *usage = pvStructInfo;
2359 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2360 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2361 usage ? usage->rgpszUsageIdentifier : NULL);
2365 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2366 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2368 struct AsnDecodeSequenceItem items[] = {
2369 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2370 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2371 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2372 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2373 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), FALSE,
2374 TRUE, offsetof(CTL_ENTRY, rgAttribute), 0 },
2377 CTL_ENTRY *entry = pvStructInfo;
2379 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2382 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2383 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2384 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2388 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2389 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2392 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2393 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2394 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2397 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2398 pvStructInfo, *pcbStructInfo, pcbDecoded);
2400 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
2401 NULL, NULL, &bytesNeeded, pcbDecoded);
2404 /* The size expected by the caller includes the combination of
2405 * CTL_INFO's cCTLEntry and rgCTLEntry, in addition to the size of
2406 * all the decoded items. CRYPT_AsnDecodeArrayNoAlloc only returns
2407 * the size of the decoded items, so add the size of cCTLEntry and
2410 bytesNeeded += MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension);
2412 *pcbStructInfo = bytesNeeded;
2413 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, NULL, pvStructInfo,
2414 pcbStructInfo, bytesNeeded)))
2418 info = (CTL_INFO *)((BYTE *)pvStructInfo -
2419 offsetof(CTL_INFO, cCTLEntry));
2420 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded,
2421 cbEncoded, &info->cCTLEntry, info->rgCTLEntry, &bytesNeeded,
2428 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2429 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2430 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2434 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2435 pDecodePara, pvStructInfo, *pcbStructInfo);
2439 struct AsnDecodeSequenceItem items[] = {
2440 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2441 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2442 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2443 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2444 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2445 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2446 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2447 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2448 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2449 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2450 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2451 { 0, offsetof(CTL_INFO, ThisUpdate),
2452 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2454 { 0, offsetof(CTL_INFO, NextUpdate),
2455 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2457 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2458 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2459 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2460 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2461 CRYPT_AsnDecodeCTLEntries,
2462 MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2463 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2464 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2465 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
2466 offsetof(CTL_INFO, rgExtension), 0 },
2469 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2470 pDecodePara, pvStructInfo, *pcbStructInfo);
2472 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2473 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2474 pcbStructInfo, NULL, NULL);
2478 SetLastError(STATUS_ACCESS_VIOLATION);
2484 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2485 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2489 struct AsnDecodeSequenceItem items[] = {
2490 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2491 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2492 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2493 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2494 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2495 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2497 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2499 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2500 pvStructInfo, *pcbStructInfo);
2502 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2503 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2504 pcbDecoded, capability ? capability->pszObjId : NULL);
2505 TRACE("returning %d\n", ret);
2509 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2510 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2511 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2515 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2516 pDecodePara, pvStructInfo, *pcbStructInfo);
2521 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2522 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2523 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2525 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
2526 NULL, NULL, &bytesNeeded, NULL)))
2528 bytesNeeded += sizeof(CRYPT_SMIME_CAPABILITIES);
2530 *pcbStructInfo = bytesNeeded;
2531 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2532 pvStructInfo, pcbStructInfo, bytesNeeded)))
2534 PCRYPT_SMIME_CAPABILITIES capabilities;
2536 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2537 pvStructInfo = *(BYTE **)pvStructInfo;
2538 capabilities = pvStructInfo;
2539 capabilities->rgCapability =
2540 (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo +
2541 sizeof(CRYPT_SMIME_CAPABILITIES));
2542 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc,
2543 pbEncoded, cbEncoded, &capabilities->cCapability,
2544 capabilities->rgCapability, pcbStructInfo, NULL);
2550 SetLastError(STATUS_ACCESS_VIOLATION);
2553 TRACE("returning %d\n", ret);
2557 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2558 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2563 LPSTR *pStr = pvStructInfo;
2565 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2567 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2568 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2570 if (pbEncoded[0] != ASN_IA5STRING)
2572 SetLastError(CRYPT_E_ASN1_CORRUPT);
2577 bytesNeeded += dataLen;
2579 *pcbDecoded = 1 + lenBytes + dataLen;
2581 *pcbStructInfo = bytesNeeded;
2582 else if (*pcbStructInfo < bytesNeeded)
2584 *pcbStructInfo = bytesNeeded;
2585 SetLastError(ERROR_MORE_DATA);
2590 *pcbStructInfo = bytesNeeded;
2596 memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2607 static BOOL CRYPT_AsnDecodeIntArray(const BYTE *pbEncoded,
2608 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2611 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2612 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2613 struct GenericArray *array = pvStructInfo;
2616 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2617 pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2619 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2620 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2621 array ? array->rgItems : NULL);
2622 TRACE("returning %d\n", ret);
2626 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2627 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2631 struct AsnDecodeSequenceItem items[] = {
2632 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2633 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2634 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2635 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2636 cNoticeNumbers), CRYPT_AsnDecodeIntArray, sizeof(struct GenericArray),
2637 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2638 rgNoticeNumbers), 0 },
2642 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2643 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2645 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2646 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2650 /* The caller is expecting a pointer to a
2651 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2652 * CRYPT_AsnDecodeSequence is decoding a
2653 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2654 * needed, and decode again if the requisite space is available.
2656 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2658 *pcbStructInfo = bytesNeeded;
2659 else if (*pcbStructInfo < bytesNeeded)
2661 *pcbStructInfo = bytesNeeded;
2662 SetLastError(ERROR_MORE_DATA);
2667 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2669 *pcbStructInfo = bytesNeeded;
2670 /* The pointer (pvStructInfo) passed in points to the first dynamic
2671 * pointer, so use it as the pointer to the
2672 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2673 * appropriate offset for the first dynamic pointer within the
2674 * notice reference by pointing to the first memory location past
2675 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2678 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2679 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2680 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2681 ret = CRYPT_AsnDecodeSequence(items,
2682 sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2683 NULL, noticeRef, &bytesNeeded, pcbDecoded,
2684 noticeRef->pszOrganization);
2687 TRACE("returning %d\n", ret);
2691 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2692 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2698 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2700 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2701 DWORD bytesNeeded = sizeof(LPWSTR);
2703 switch (pbEncoded[0])
2705 case ASN_NUMERICSTRING:
2707 bytesNeeded += (dataLen + 1) * 2;
2709 case ASN_PRINTABLESTRING:
2711 bytesNeeded += (dataLen + 1) * 2;
2715 bytesNeeded += (dataLen + 1) * 2;
2719 bytesNeeded += (dataLen + 1) * 2;
2721 case ASN_VIDEOTEXSTRING:
2723 bytesNeeded += (dataLen + 1) * 2;
2725 case ASN_GRAPHICSTRING:
2727 bytesNeeded += (dataLen + 1) * 2;
2729 case ASN_VISIBLESTRING:
2731 bytesNeeded += (dataLen + 1) * 2;
2733 case ASN_GENERALSTRING:
2735 bytesNeeded += (dataLen + 1) * 2;
2737 case ASN_UNIVERSALSTRING:
2739 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2743 bytesNeeded += dataLen + sizeof(WCHAR);
2745 case ASN_UTF8STRING:
2747 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2748 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2751 SetLastError(CRYPT_E_ASN1_BADTAG);
2756 *pcbDecoded = 1 + lenBytes + dataLen;
2758 *pcbStructInfo = bytesNeeded;
2759 else if (*pcbStructInfo < bytesNeeded)
2761 *pcbStructInfo = bytesNeeded;
2762 SetLastError(ERROR_MORE_DATA);
2767 LPWSTR *pStr = pvStructInfo;
2769 *pcbStructInfo = bytesNeeded;
2773 LPWSTR str = *(LPWSTR *)pStr;
2776 switch (pbEncoded[0])
2778 case ASN_NUMERICSTRING:
2779 case ASN_PRINTABLESTRING:
2782 case ASN_VIDEOTEXSTRING:
2783 case ASN_GRAPHICSTRING:
2784 case ASN_VISIBLESTRING:
2785 case ASN_GENERALSTRING:
2786 for (i = 0; i < dataLen; i++)
2787 str[i] = pbEncoded[1 + lenBytes + i];
2790 case ASN_UNIVERSALSTRING:
2791 for (i = 0; i < dataLen / 4; i++)
2792 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2793 | pbEncoded[1 + lenBytes + 2 * i + 3];
2797 for (i = 0; i < dataLen / 2; i++)
2798 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2799 pbEncoded[1 + lenBytes + 2 * i + 1];
2802 case ASN_UTF8STRING:
2804 int len = MultiByteToWideChar(CP_UTF8, 0,
2805 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2806 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2819 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2820 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2821 DWORD *pcbStructInfo, DWORD *pcbDecoded)
2824 struct AsnDecodeSequenceItem items[] = {
2825 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2826 pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2827 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2828 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2829 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2830 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2831 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2833 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2835 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2836 pvStructInfo, *pcbStructInfo);
2838 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2839 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2840 pcbDecoded, notice ? notice->pNoticeReference : NULL);
2841 TRACE("returning %d\n", ret);
2845 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2846 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2847 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2848 void *pvStructInfo, DWORD *pcbStructInfo)
2852 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2853 pDecodePara, pvStructInfo, *pcbStructInfo);
2859 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2860 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2865 *pcbStructInfo = bytesNeeded;
2866 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2867 pvStructInfo, pcbStructInfo, bytesNeeded)))
2869 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2871 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2872 pvStructInfo = *(BYTE **)pvStructInfo;
2873 notice = pvStructInfo;
2874 notice->pNoticeReference =
2875 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2876 ((BYTE *)pvStructInfo +
2877 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2878 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2879 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2880 pvStructInfo, &bytesNeeded, NULL);
2886 SetLastError(STATUS_ACCESS_VIOLATION);
2889 TRACE("returning %d\n", ret);
2893 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
2894 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2898 struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
2899 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2902 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2903 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
2905 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
2906 NULL, NULL, &bytesNeeded, pcbDecoded)))
2908 bytesNeeded += FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue);
2910 *pcbStructInfo = bytesNeeded;
2911 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
2912 pcbStructInfo, bytesNeeded)))
2914 CRYPT_ATTRIBUTE *attr = (CRYPT_ATTRIBUTE *)((BYTE *)pvStructInfo -
2915 offsetof(CRYPT_ATTRIBUTE, cValue));
2917 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
2918 &attr->cValue, attr->rgValue, pcbStructInfo, pcbDecoded);
2924 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2925 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2929 struct AsnDecodeSequenceItem items[] = {
2930 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2931 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2932 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2933 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2934 CRYPT_AsnDecodePKCSAttributeValue,
2935 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
2936 TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2938 PCRYPT_ATTRIBUTE attr = pvStructInfo;
2940 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2941 pvStructInfo, *pcbStructInfo);
2943 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2944 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2945 pcbDecoded, attr ? attr->pszObjId : NULL);
2946 TRACE("returning %d\n", ret);
2950 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2951 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2952 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2956 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2957 pDecodePara, pvStructInfo, *pcbStructInfo);
2963 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2964 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2968 *pcbStructInfo = bytesNeeded;
2969 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2970 pvStructInfo, pcbStructInfo, bytesNeeded)))
2972 PCRYPT_ATTRIBUTE attr;
2974 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2975 pvStructInfo = *(BYTE **)pvStructInfo;
2976 attr = pvStructInfo;
2977 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2978 sizeof(CRYPT_ATTRIBUTE));
2979 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2980 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2987 SetLastError(STATUS_ACCESS_VIOLATION);
2990 TRACE("returning %d\n", ret);
2994 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2995 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2998 struct AsnArrayDescriptor arrayDesc = { 0,
2999 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
3000 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
3001 PCRYPT_ATTRIBUTES attrs = pvStructInfo;
3004 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3005 NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
3010 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
3011 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3012 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3016 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3017 pDecodePara, pvStructInfo, *pcbStructInfo);
3023 if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
3024 SetLastError(CRYPT_E_ASN1_CORRUPT);
3025 else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
3026 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
3030 *pcbStructInfo = bytesNeeded;
3031 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3032 pvStructInfo, pcbStructInfo, bytesNeeded)))
3034 PCRYPT_ATTRIBUTES attrs;
3036 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3037 pvStructInfo = *(BYTE **)pvStructInfo;
3038 attrs = pvStructInfo;
3039 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
3040 sizeof(CRYPT_ATTRIBUTES));
3041 ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
3042 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3043 &bytesNeeded, NULL);
3049 SetLastError(STATUS_ACCESS_VIOLATION);
3052 TRACE("returning %d\n", ret);
3056 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
3057 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3059 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
3061 struct AsnDecodeSequenceItem items[] = {
3062 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
3063 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3064 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
3065 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
3066 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3067 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
3070 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3071 pvStructInfo, *pcbStructInfo, pcbDecoded);
3073 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3074 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3075 pcbDecoded, algo ? algo->pszObjId : NULL);
3076 if (ret && pvStructInfo)
3078 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
3079 debugstr_a(algo->pszObjId));
3084 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
3085 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3089 struct AsnDecodeSequenceItem items[] = {
3090 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
3091 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3092 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
3093 Algorithm.pszObjId) },
3094 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
3095 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3096 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
3098 PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
3100 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3101 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3102 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
3106 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
3107 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3108 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3116 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
3117 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3120 *pcbStructInfo = bytesNeeded;
3121 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3122 pvStructInfo, pcbStructInfo, bytesNeeded)))
3124 PCERT_PUBLIC_KEY_INFO info;
3126 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3127 pvStructInfo = *(BYTE **)pvStructInfo;
3128 info = pvStructInfo;
3129 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
3130 sizeof(CERT_PUBLIC_KEY_INFO);
3131 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
3132 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3133 &bytesNeeded, NULL);
3139 SetLastError(STATUS_ACCESS_VIOLATION);
3146 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
3147 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3153 SetLastError(CRYPT_E_ASN1_CORRUPT);
3156 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
3158 SetLastError(CRYPT_E_ASN1_CORRUPT);
3161 if (pbEncoded[1] > 1)
3163 SetLastError(CRYPT_E_ASN1_CORRUPT);
3170 *pcbStructInfo = sizeof(BOOL);
3173 else if (*pcbStructInfo < sizeof(BOOL))
3175 *pcbStructInfo = sizeof(BOOL);
3176 SetLastError(ERROR_MORE_DATA);
3181 *pcbStructInfo = sizeof(BOOL);
3182 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
3185 TRACE("returning %d (%08x)\n", ret, GetLastError());
3189 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
3190 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3192 PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
3193 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
3196 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3197 pvStructInfo, *pcbStructInfo);
3201 SetLastError(CRYPT_E_ASN1_CORRUPT);
3204 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3205 if (1 + lenBytes > cbEncoded)
3207 SetLastError(CRYPT_E_ASN1_CORRUPT);
3210 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3212 switch (pbEncoded[0] & ASN_TYPE_MASK)
3214 case 1: /* rfc822Name */
3215 case 2: /* dNSName */
3216 case 6: /* uniformResourceIdentifier */
3217 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
3219 case 4: /* directoryName */
3220 case 7: /* iPAddress */
3221 bytesNeeded += dataLen;
3223 case 8: /* registeredID */
3224 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
3228 /* FIXME: ugly, shouldn't need to know internals of OID decode
3229 * function to use it.
3231 bytesNeeded += dataLen - sizeof(LPSTR);
3234 case 0: /* otherName */
3235 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
3236 SetLastError(CRYPT_E_ASN1_BADTAG);
3239 case 3: /* x400Address, unimplemented */
3240 case 5: /* ediPartyName, unimplemented */
3241 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
3242 SetLastError(CRYPT_E_ASN1_BADTAG);
3246 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
3247 SetLastError(CRYPT_E_ASN1_CORRUPT);
3253 *pcbDecoded = 1 + lenBytes + dataLen;
3255 *pcbStructInfo = bytesNeeded;
3256 else if (*pcbStructInfo < bytesNeeded)
3258 *pcbStructInfo = bytesNeeded;
3259 SetLastError(ERROR_MORE_DATA);
3264 *pcbStructInfo = bytesNeeded;
3265 /* MS used values one greater than the asn1 ones.. sigh */
3266 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
3267 switch (pbEncoded[0] & ASN_TYPE_MASK)
3269 case 1: /* rfc822Name */
3270 case 2: /* dNSName */
3271 case 6: /* uniformResourceIdentifier */
3275 for (i = 0; i < dataLen; i++)
3276 entry->u.pwszURL[i] =
3277 (WCHAR)pbEncoded[1 + lenBytes + i];
3278 entry->u.pwszURL[i] = 0;
3279 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3280 debugstr_w(entry->u.pwszURL));
3283 case 4: /* directoryName */
3284 /* The data are memory-equivalent with the IPAddress case,
3287 case 7: /* iPAddress */
3288 /* The next data pointer is in the pwszURL spot, that is,
3289 * the first 4 bytes. Need to move it to the next spot.
3291 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3292 entry->u.IPAddress.cbData = dataLen;
3293 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3296 case 8: /* registeredID */
3297 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
3298 &entry->u.pszRegisteredID, &dataLen, NULL);
3307 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
3308 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3312 struct AsnArrayDescriptor arrayDesc = { 0,
3313 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3314 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3315 PCERT_ALT_NAME_INFO info = pvStructInfo;
3317 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3318 pvStructInfo, *pcbStructInfo, pcbDecoded);
3321 TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
3322 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3323 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
3324 info ? info->rgAltEntry : NULL);
3328 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
3329 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
3330 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3335 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3336 pvStructInfo, *pcbStructInfo, pcbDecoded);
3338 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
3341 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3342 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
3344 if (ret && pvStructInfo)
3346 CRYPT_DATA_BLOB *blob = pvStructInfo;
3353 for (i = 0; i < blob->cbData / 2; i++)
3355 temp = blob->pbData[i];
3356 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
3357 blob->pbData[blob->cbData - i - 1] = temp;
3361 TRACE("returning %d (%08x)\n", ret, GetLastError());
3365 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3366 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3367 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3373 struct AsnDecodeSequenceItem items[] = {
3374 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3375 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3376 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3377 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3378 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3379 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3380 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3381 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3382 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3383 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3384 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3387 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3388 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3389 pcbStructInfo, NULL, NULL);
3393 SetLastError(STATUS_ACCESS_VIOLATION);
3400 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3401 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3402 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3408 struct AsnDecodeSequenceItem items[] = {
3409 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3410 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3411 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3412 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3413 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3414 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3415 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3416 AuthorityCertIssuer.rgAltEntry), 0 },
3417 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3418 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3419 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3420 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3421 AuthorityCertSerialNumber.pbData), 0 },
3424 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3425 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3426 pcbStructInfo, NULL, NULL);
3430 SetLastError(STATUS_ACCESS_VIOLATION);
3437 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3438 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3441 struct AsnDecodeSequenceItem items[] = {
3442 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3443 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3444 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3445 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3446 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3447 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3449 CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3451 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3452 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3453 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3456 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3457 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3458 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3462 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3463 pDecodePara, pvStructInfo, *pcbStructInfo);
3467 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3468 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3469 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3471 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3472 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
3476 SetLastError(STATUS_ACCESS_VIOLATION);
3483 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3484 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3489 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3490 pvStructInfo, *pcbStructInfo, pcbDecoded);
3492 /* The caller has already checked the tag, no need to check it again.
3493 * Check the outer length is valid:
3495 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3497 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3500 pbEncoded += 1 + lenBytes;
3501 cbEncoded -= 1 + lenBytes;
3502 if (dataLen == CMSG_INDEFINITE_LENGTH)
3503 cbEncoded -= 2; /* space for 0 TLV */
3504 /* Check the inner length is valid: */
3505 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3509 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3510 pvStructInfo, pcbStructInfo, &decodedLen);
3511 if (dataLen == CMSG_INDEFINITE_LENGTH)
3513 if (*(pbEncoded + decodedLen) != 0 ||
3514 *(pbEncoded + decodedLen + 1) != 0)
3516 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3517 *(pbEncoded + decodedLen),
3518 *(pbEncoded + decodedLen + 1));
3519 SetLastError(CRYPT_E_ASN1_CORRUPT);
3525 if (ret && pcbDecoded)
3527 *pcbDecoded = 1 + lenBytes + decodedLen;
3528 TRACE("decoded %d bytes\n", *pcbDecoded);
3535 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3536 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3539 CRYPT_CONTENT_INFO *info = pvStructInfo;
3540 struct AsnDecodeSequenceItem items[] = {
3541 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3542 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3543 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3544 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3545 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3546 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3547 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3551 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3552 pvStructInfo, *pcbStructInfo, pcbDecoded);
3554 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3555 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3556 pcbDecoded, info ? info->pszObjId : NULL);
3560 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3561 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3562 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3566 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3567 pDecodePara, pvStructInfo, *pcbStructInfo);
3571 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3572 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3573 if (ret && pvStructInfo)
3575 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3576 pcbStructInfo, *pcbStructInfo);
3579 CRYPT_CONTENT_INFO *info;
3581 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3582 pvStructInfo = *(BYTE **)pvStructInfo;
3583 info = pvStructInfo;
3584 info->pszObjId = (LPSTR)((BYTE *)info +
3585 sizeof(CRYPT_CONTENT_INFO));
3586 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3587 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3588 pcbStructInfo, NULL);
3594 SetLastError(STATUS_ACCESS_VIOLATION);
3600 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3601 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3602 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3605 struct AsnDecodeSequenceItem items[] = {
3606 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3607 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3608 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3609 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3610 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3612 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3613 CRYPT_AsnDecodePKCSContentInfoInternal,
3614 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3615 ContentInfo.pszObjId), 0 },
3616 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3617 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3618 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3621 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3622 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3627 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3628 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3629 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3633 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3634 pDecodePara, pvStructInfo, *pcbStructInfo);
3640 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3641 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3644 *pcbStructInfo = bytesNeeded;
3645 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3646 pvStructInfo, pcbStructInfo, bytesNeeded)))
3648 CERT_ALT_NAME_INFO *name;
3650 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3651 pvStructInfo = *(BYTE **)pvStructInfo;
3652 name = pvStructInfo;
3653 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3654 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3655 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3656 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3657 &bytesNeeded, NULL);
3663 SetLastError(STATUS_ACCESS_VIOLATION);
3670 struct PATH_LEN_CONSTRAINT
3672 BOOL fPathLenConstraint;
3673 DWORD dwPathLenConstraint;
3676 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3677 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3681 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3683 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3684 pvStructInfo, *pcbStructInfo, pcbDecoded);
3688 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3690 *pcbStructInfo = bytesNeeded;
3692 else if (*pcbStructInfo < bytesNeeded)
3694 SetLastError(ERROR_MORE_DATA);
3695 *pcbStructInfo = bytesNeeded;
3700 struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3702 *pcbStructInfo = bytesNeeded;
3703 size = sizeof(constraint->dwPathLenConstraint);
3704 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3705 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3707 constraint->fPathLenConstraint = TRUE;
3708 TRACE("got an int, dwPathLenConstraint is %d\n",
3709 constraint->dwPathLenConstraint);
3711 TRACE("returning %d (%08x)\n", ret, GetLastError());
3715 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3716 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3720 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3721 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3722 offsetof(CERT_NAME_BLOB, pbData) };
3723 struct GenericArray *entries = pvStructInfo;
3725 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3726 pvStructInfo, *pcbStructInfo, pcbDecoded);
3728 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3729 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
3730 entries ? entries->rgItems : NULL);
3731 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3735 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3736 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3737 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3743 struct AsnDecodeSequenceItem items[] = {
3744 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3745 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3746 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3747 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3748 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3749 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3750 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3751 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3752 sizeof(struct GenericArray), TRUE, TRUE,
3753 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3756 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3757 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3758 pcbStructInfo, NULL, NULL);
3762 SetLastError(STATUS_ACCESS_VIOLATION);
3769 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3770 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3771 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3777 struct AsnDecodeSequenceItem items[] = {
3778 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3779 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3780 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3781 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3782 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3785 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3786 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3787 pcbStructInfo, NULL, NULL);
3791 SetLastError(STATUS_ACCESS_VIOLATION);
3798 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
3799 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3802 struct AsnDecodeSequenceItem items[] = {
3803 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
3804 pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3805 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3807 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3808 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3809 offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3812 CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3814 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3815 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3817 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3818 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3819 pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3823 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
3824 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3828 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3829 CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
3830 offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3831 struct GenericArray *entries = pvStructInfo;
3833 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3834 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3836 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3837 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
3838 entries ? entries->rgItems : NULL);
3839 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3843 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
3844 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3846 struct AsnDecodeSequenceItem items[] = {
3847 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3848 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3849 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3850 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3851 CRYPT_AsnDecodePolicyQualifiers, sizeof(struct GenericArray), TRUE,
3852 TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3854 CERT_POLICY_INFO *info = pvStructInfo;
3857 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3858 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3860 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3861 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3862 pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
3866 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
3867 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3868 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3872 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3873 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3877 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3878 CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
3879 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
3881 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3882 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
3886 SetLastError(STATUS_ACCESS_VIOLATION);
3892 #define RSA1_MAGIC 0x31415352
3894 struct DECODED_RSA_PUB_KEY
3897 CRYPT_INTEGER_BLOB modulus;
3900 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3901 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3902 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3908 struct AsnDecodeSequenceItem items[] = {
3909 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3910 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3911 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3913 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3914 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3916 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3919 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3920 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3924 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3925 decodedKey->modulus.cbData;
3929 *pcbStructInfo = bytesNeeded;
3932 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3933 pvStructInfo, pcbStructInfo, bytesNeeded)))
3936 RSAPUBKEY *rsaPubKey;
3938 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3939 pvStructInfo = *(BYTE **)pvStructInfo;
3941 hdr->bType = PUBLICKEYBLOB;
3942 hdr->bVersion = CUR_BLOB_VERSION;
3944 hdr->aiKeyAlg = CALG_RSA_KEYX;
3945 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3946 sizeof(BLOBHEADER));
3947 rsaPubKey->magic = RSA1_MAGIC;
3948 rsaPubKey->pubexp = decodedKey->pubexp;
3949 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3950 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3951 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3952 decodedKey->modulus.cbData);
3954 LocalFree(decodedKey);
3959 SetLastError(STATUS_ACCESS_VIOLATION);
3966 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3967 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3971 DWORD bytesNeeded, dataLen;
3973 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3974 pvStructInfo, *pcbStructInfo, pcbDecoded);
3976 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3978 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3980 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3981 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3983 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3985 *pcbDecoded = 1 + lenBytes + dataLen;
3987 *pcbStructInfo = bytesNeeded;
3988 else if (*pcbStructInfo < bytesNeeded)
3990 SetLastError(ERROR_MORE_DATA);
3991 *pcbStructInfo = bytesNeeded;
3996 CRYPT_DATA_BLOB *blob;
3998 *pcbStructInfo = bytesNeeded;
3999 blob = pvStructInfo;
4000 blob->cbData = dataLen;
4001 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4002 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
4005 assert(blob->pbData);
4007 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
4015 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
4016 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4017 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4021 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4022 pDecodePara, pvStructInfo, *pcbStructInfo);
4030 SetLastError(CRYPT_E_ASN1_CORRUPT);
4033 else if (pbEncoded[0] != ASN_OCTETSTRING)
4035 SetLastError(CRYPT_E_ASN1_BADTAG);
4038 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
4039 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4042 *pcbStructInfo = bytesNeeded;
4043 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4044 pvStructInfo, pcbStructInfo, bytesNeeded)))
4046 CRYPT_DATA_BLOB *blob;
4048 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4049 pvStructInfo = *(BYTE **)pvStructInfo;
4050 blob = pvStructInfo;
4051 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
4052 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
4053 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4054 &bytesNeeded, NULL);
4060 SetLastError(STATUS_ACCESS_VIOLATION);
4067 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4068 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4071 DWORD bytesNeeded, dataLen;
4072 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4074 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
4075 pvStructInfo, *pcbStructInfo, pcbDecoded);
4077 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4079 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4080 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
4082 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
4084 *pcbDecoded = 1 + lenBytes + dataLen;
4086 *pcbStructInfo = bytesNeeded;
4087 else if (*pcbStructInfo < bytesNeeded)
4089 *pcbStructInfo = bytesNeeded;
4090 SetLastError(ERROR_MORE_DATA);
4095 CRYPT_BIT_BLOB *blob;
4097 *pcbStructInfo = bytesNeeded;
4098 blob = pvStructInfo;
4099 blob->cbData = dataLen - 1;
4100 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
4101 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4103 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
4107 assert(blob->pbData);
4110 BYTE mask = 0xff << blob->cUnusedBits;
4112 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
4114 blob->pbData[blob->cbData - 1] &= mask;
4122 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
4123 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4124 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4128 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
4129 pDecodePara, pvStructInfo, pcbStructInfo);
4137 SetLastError(CRYPT_E_ASN1_CORRUPT);
4140 else if (pbEncoded[0] != ASN_BITSTRING)
4142 SetLastError(CRYPT_E_ASN1_BADTAG);
4145 else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4146 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4149 *pcbStructInfo = bytesNeeded;
4150 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4151 pvStructInfo, pcbStructInfo, bytesNeeded)))
4153 CRYPT_BIT_BLOB *blob;
4155 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4156 pvStructInfo = *(BYTE **)pvStructInfo;
4157 blob = pvStructInfo;
4158 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
4159 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4160 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4161 &bytesNeeded, NULL);
4167 SetLastError(STATUS_ACCESS_VIOLATION);
4171 TRACE("returning %d (%08x)\n", ret, GetLastError());
4175 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4176 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4177 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4180 BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
4181 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
4182 DWORD size = sizeof(buf);
4184 blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
4185 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, buf,
4190 *pcbStructInfo = sizeof(int);
4191 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
4195 if (blob->pbData[blob->cbData - 1] & 0x80)
4197 /* initialize to a negative value to sign-extend */
4202 for (i = 0; i < blob->cbData; i++)
4205 val |= blob->pbData[blob->cbData - i - 1];
4207 memcpy(pvStructInfo, &val, sizeof(int));
4210 else if (GetLastError() == ERROR_MORE_DATA)
4211 SetLastError(CRYPT_E_ASN1_LARGE);
4215 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
4216 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4217 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4227 SetLastError(CRYPT_E_ASN1_EOD);
4230 else if (pbEncoded[0] != ASN_INTEGER)
4232 SetLastError(CRYPT_E_ASN1_BADTAG);
4236 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4237 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4241 *pcbStructInfo = bytesNeeded;
4242 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4243 pvStructInfo, pcbStructInfo, bytesNeeded)))
4245 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4246 pvStructInfo = *(BYTE **)pvStructInfo;
4247 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4248 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4249 &bytesNeeded, NULL);
4255 SetLastError(STATUS_ACCESS_VIOLATION);
4262 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
4263 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4267 DWORD bytesNeeded, dataLen;
4269 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4271 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4273 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4275 *pcbDecoded = 1 + lenBytes + dataLen;
4277 *pcbStructInfo = bytesNeeded;
4278 else if (*pcbStructInfo < bytesNeeded)
4280 *pcbStructInfo = bytesNeeded;
4281 SetLastError(ERROR_MORE_DATA);
4286 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4288 *pcbStructInfo = bytesNeeded;
4289 blob->cbData = dataLen;
4290 assert(blob->pbData);
4295 for (i = 0; i < blob->cbData; i++)
4297 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4306 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
4307 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4308 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4316 if (pbEncoded[0] != ASN_INTEGER)
4318 SetLastError(CRYPT_E_ASN1_BADTAG);
4322 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4323 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4327 *pcbStructInfo = bytesNeeded;
4328 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4329 pvStructInfo, pcbStructInfo, bytesNeeded)))
4331 CRYPT_INTEGER_BLOB *blob;
4333 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4334 pvStructInfo = *(BYTE **)pvStructInfo;
4335 blob = pvStructInfo;
4336 blob->pbData = (BYTE *)pvStructInfo +
4337 sizeof(CRYPT_INTEGER_BLOB);
4338 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4339 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4340 &bytesNeeded, NULL);
4346 SetLastError(STATUS_ACCESS_VIOLATION);
4353 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
4354 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4359 if (pbEncoded[0] == ASN_INTEGER)
4361 DWORD bytesNeeded, dataLen;
4363 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4365 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4368 *pcbDecoded = 1 + lenBytes + dataLen;
4369 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4371 *pcbStructInfo = bytesNeeded;
4372 else if (*pcbStructInfo < bytesNeeded)
4374 *pcbStructInfo = bytesNeeded;
4375 SetLastError(ERROR_MORE_DATA);
4380 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4382 *pcbStructInfo = bytesNeeded;
4383 blob->cbData = dataLen;
4384 assert(blob->pbData);
4385 /* remove leading zero byte if it exists */
4386 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
4395 for (i = 0; i < blob->cbData; i++)
4397 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4406 SetLastError(CRYPT_E_ASN1_BADTAG);
4412 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
4413 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4414 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4422 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
4423 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4426 *pcbStructInfo = bytesNeeded;
4427 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4428 pvStructInfo, pcbStructInfo, bytesNeeded)))
4430 CRYPT_INTEGER_BLOB *blob;
4432 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4433 pvStructInfo = *(BYTE **)pvStructInfo;
4434 blob = pvStructInfo;
4435 blob->pbData = (BYTE *)pvStructInfo +
4436 sizeof(CRYPT_INTEGER_BLOB);
4437 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
4438 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4439 &bytesNeeded, NULL);
4445 SetLastError(STATUS_ACCESS_VIOLATION);
4452 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
4453 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4454 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4460 *pcbStructInfo = sizeof(int);
4465 if (pbEncoded[0] == ASN_ENUMERATED)
4467 unsigned int val = 0, i;
4471 SetLastError(CRYPT_E_ASN1_EOD);
4474 else if (pbEncoded[1] == 0)
4476 SetLastError(CRYPT_E_ASN1_CORRUPT);
4481 /* A little strange looking, but we have to accept a sign byte:
4482 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4483 * assuming a small length is okay here, it has to be in short
4486 if (pbEncoded[1] > sizeof(unsigned int) + 1)
4488 SetLastError(CRYPT_E_ASN1_LARGE);
4491 for (i = 0; i < pbEncoded[1]; i++)
4494 val |= pbEncoded[2 + i];
4496 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4497 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
4499 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4500 pvStructInfo = *(BYTE **)pvStructInfo;
4501 memcpy(pvStructInfo, &val, sizeof(unsigned int));
4507 SetLastError(CRYPT_E_ASN1_BADTAG);
4513 SetLastError(STATUS_ACCESS_VIOLATION);
4520 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4523 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4528 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4530 if (!isdigit(*(pbEncoded))) \
4532 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4538 (word) += *(pbEncoded)++ - '0'; \
4543 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
4544 SYSTEMTIME *sysTime)
4548 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
4550 WORD hours, minutes = 0;
4551 BYTE sign = *pbEncoded++;
4554 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
4555 if (ret && hours >= 24)
4557 SetLastError(CRYPT_E_ASN1_CORRUPT);
4562 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
4563 if (ret && minutes >= 60)
4565 SetLastError(CRYPT_E_ASN1_CORRUPT);
4573 sysTime->wHour += hours;
4574 sysTime->wMinute += minutes;
4578 if (hours > sysTime->wHour)
4581 sysTime->wHour = 24 - (hours - sysTime->wHour);
4584 sysTime->wHour -= hours;
4585 if (minutes > sysTime->wMinute)
4588 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
4591 sysTime->wMinute -= minutes;
4598 #define MIN_ENCODED_TIME_LENGTH 10
4600 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
4601 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4606 if (pbEncoded[0] == ASN_UTCTIME)
4609 SetLastError(CRYPT_E_ASN1_EOD);
4610 else if (pbEncoded[1] > 0x7f)
4612 /* long-form date strings really can't be valid */
4613 SetLastError(CRYPT_E_ASN1_CORRUPT);
4617 SYSTEMTIME sysTime = { 0 };
4618 BYTE len = pbEncoded[1];
4620 if (len < MIN_ENCODED_TIME_LENGTH)
4621 SetLastError(CRYPT_E_ASN1_CORRUPT);
4626 *pcbDecoded = 2 + len;
4628 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
4629 if (sysTime.wYear >= 50)
4630 sysTime.wYear += 1900;
4632 sysTime.wYear += 2000;
4633 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4634 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4635 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4636 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
4639 if (len >= 2 && isdigit(*pbEncoded) &&
4640 isdigit(*(pbEncoded + 1)))
4641 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4643 else if (isdigit(*pbEncoded))
4644 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
4647 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4653 *pcbStructInfo = sizeof(FILETIME);
4654 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4656 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4662 SetLastError(CRYPT_E_ASN1_BADTAG);
4666 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
4667 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4668 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4676 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4677 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4681 *pcbStructInfo = bytesNeeded;
4682 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
4683 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
4685 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4686 pvStructInfo = *(BYTE **)pvStructInfo;
4687 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4688 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4689 &bytesNeeded, NULL);
4695 SetLastError(STATUS_ACCESS_VIOLATION);
4701 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
4702 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4707 if (pbEncoded[0] == ASN_GENERALTIME)
4710 SetLastError(CRYPT_E_ASN1_EOD);
4711 else if (pbEncoded[1] > 0x7f)
4713 /* long-form date strings really can't be valid */
4714 SetLastError(CRYPT_E_ASN1_CORRUPT);
4718 BYTE len = pbEncoded[1];
4720 if (len < MIN_ENCODED_TIME_LENGTH)
4721 SetLastError(CRYPT_E_ASN1_CORRUPT);
4724 SYSTEMTIME sysTime = { 0 };
4728 *pcbDecoded = 2 + len;
4730 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
4731 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4732 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4733 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4736 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4739 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4741 if (ret && len > 0 && (*pbEncoded == '.' ||
4748 /* workaround macro weirdness */
4749 digits = min(len, 3);
4750 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
4751 sysTime.wMilliseconds);
4754 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4760 *pcbStructInfo = sizeof(FILETIME);
4761 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4763 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4769 SetLastError(CRYPT_E_ASN1_BADTAG);
4773 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
4774 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4778 InternalDecodeFunc decode = NULL;
4780 if (pbEncoded[0] == ASN_UTCTIME)
4781 decode = CRYPT_AsnDecodeUtcTimeInternal;
4782 else if (pbEncoded[0] == ASN_GENERALTIME)
4783 decode = CRYPT_AsnDecodeGeneralizedTime;
4785 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
4786 pcbStructInfo, pcbDecoded);
4789 SetLastError(CRYPT_E_ASN1_BADTAG);
4795 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
4796 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4797 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4805 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4806 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4810 *pcbStructInfo = bytesNeeded;
4811 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4812 pvStructInfo, pcbStructInfo, bytesNeeded)))
4814 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4815 pvStructInfo = *(BYTE **)pvStructInfo;
4816 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4817 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4818 &bytesNeeded, NULL);
4824 SetLastError(STATUS_ACCESS_VIOLATION);
4831 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
4832 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4833 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4839 if (pbEncoded[0] == ASN_SEQUENCEOF)
4841 DWORD bytesNeeded, dataLen, remainingLen, cValue;
4843 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4848 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4849 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
4851 ptr = pbEncoded + 1 + lenBytes;
4852 remainingLen = dataLen;
4853 while (ret && remainingLen)
4857 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4860 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4862 remainingLen -= 1 + nextLenBytes + nextLen;
4863 ptr += 1 + nextLenBytes + nextLen;
4864 bytesNeeded += sizeof(CRYPT_DER_BLOB);
4865 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
4866 bytesNeeded += 1 + nextLenBytes + nextLen;
4872 CRYPT_SEQUENCE_OF_ANY *seq;
4877 *pcbStructInfo = bytesNeeded;
4878 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4879 pvStructInfo, pcbStructInfo, bytesNeeded)))
4881 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4882 pvStructInfo = *(BYTE **)pvStructInfo;
4884 seq->cValue = cValue;
4885 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
4887 nextPtr = (BYTE *)seq->rgValue +
4888 cValue * sizeof(CRYPT_DER_BLOB);
4889 ptr = pbEncoded + 1 + lenBytes;
4890 remainingLen = dataLen;
4892 while (ret && remainingLen)
4896 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4899 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4901 seq->rgValue[i].cbData = 1 + nextLenBytes +
4903 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4904 seq->rgValue[i].pbData = (BYTE *)ptr;
4907 seq->rgValue[i].pbData = nextPtr;
4908 memcpy(nextPtr, ptr, 1 + nextLenBytes +
4910 nextPtr += 1 + nextLenBytes + nextLen;
4912 remainingLen -= 1 + nextLenBytes + nextLen;
4913 ptr += 1 + nextLenBytes + nextLen;
4923 SetLastError(CRYPT_E_ASN1_BADTAG);
4929 SetLastError(STATUS_ACCESS_VIOLATION);
4936 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
4937 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4942 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
4944 DWORD bytesNeeded, dataLen;
4946 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4948 struct AsnArrayDescriptor arrayDesc = {
4949 ASN_CONTEXT | ASN_CONSTRUCTOR | 0, CRYPT_AsnDecodeAltNameEntry,
4950 sizeof(CERT_ALT_NAME_ENTRY), TRUE,
4951 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
4952 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4957 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc,
4958 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4959 NULL, NULL, &nameLen, NULL);
4960 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen;
4963 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
4965 *pcbDecoded = 1 + lenBytes + dataLen;
4967 *pcbStructInfo = bytesNeeded;
4968 else if (*pcbStructInfo < bytesNeeded)
4970 *pcbStructInfo = bytesNeeded;
4971 SetLastError(ERROR_MORE_DATA);
4976 CRL_DIST_POINT_NAME *name = pvStructInfo;
4978 *pcbStructInfo = bytesNeeded;
4981 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
4982 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc,
4983 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4984 &name->u.FullName.cAltEntry, name->u.FullName.rgAltEntry,
4988 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
4994 SetLastError(CRYPT_E_ASN1_BADTAG);
5000 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
5001 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5003 struct AsnDecodeSequenceItem items[] = {
5004 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
5005 DistPointName), CRYPT_AsnDecodeDistPointName,
5006 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
5007 DistPointName.u.FullName.rgAltEntry), 0 },
5008 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
5009 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
5010 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
5011 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
5012 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
5013 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
5015 CRL_DIST_POINT *point = pvStructInfo;
5018 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5019 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5020 pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
5024 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
5025 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5026 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5030 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5031 pDecodePara, pvStructInfo, *pcbStructInfo);
5035 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5036 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
5037 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
5039 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
5040 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
5044 SetLastError(STATUS_ACCESS_VIOLATION);
5051 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
5052 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5053 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5057 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5058 pDecodePara, pvStructInfo, *pcbStructInfo);
5062 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5063 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
5065 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
5066 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
5070 SetLastError(STATUS_ACCESS_VIOLATION);
5077 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
5078 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5079 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5083 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5084 pDecodePara, pvStructInfo, *pcbStructInfo);
5088 struct AsnDecodeSequenceItem items[] = {
5089 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
5090 DistPointName), CRYPT_AsnDecodeDistPointName,
5091 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
5092 offsetof(CRL_ISSUING_DIST_POINT,
5093 DistPointName.u.FullName.rgAltEntry), 0 },
5094 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
5095 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5097 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
5098 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5100 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
5101 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
5102 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
5103 OnlySomeReasonFlags.pbData), 0 },
5104 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
5105 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
5108 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5109 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5110 pcbStructInfo, NULL, NULL);
5114 SetLastError(STATUS_ACCESS_VIOLATION);
5121 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
5122 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5127 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5128 pvStructInfo, *pcbStructInfo, pcbDecoded);
5132 SetLastError(CRYPT_E_ASN1_EOD);
5135 if (pbEncoded[0] != (ASN_CONTEXT | 1))
5137 SetLastError(CRYPT_E_ASN1_BADTAG);
5140 /* The BOOL is implicit: if the integer is present, then it's TRUE */
5141 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
5142 pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
5144 if (ret && pvStructInfo)
5145 *(BOOL *)pvStructInfo = TRUE;
5146 TRACE("returning %d\n", ret);
5150 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
5151 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5155 struct AsnDecodeSequenceItem items[] = {
5156 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
5157 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
5158 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
5159 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
5160 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
5161 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
5162 CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
5165 CERT_GENERAL_SUBTREE *subtree = pvStructInfo;
5167 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5168 pvStructInfo, *pcbStructInfo, pcbDecoded);
5170 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5171 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5172 pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
5175 TRACE("%d\n", *pcbDecoded);
5176 if (*pcbDecoded < cbEncoded)
5177 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
5178 *(pbEncoded + *pcbDecoded + 1));
5180 TRACE("returning %d\n", ret);
5184 static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded,
5185 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5189 struct AsnArrayDescriptor arrayDesc = { 0,
5190 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5191 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5194 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5195 pvStructInfo, *pcbStructInfo, pcbDecoded);
5197 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5198 NULL, NULL, &bytesNeeded, pcbDecoded)))
5200 bytesNeeded += MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO,
5201 cPermittedSubtree, cExcludedSubtree);
5203 *pcbStructInfo = bytesNeeded;
5204 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
5205 pcbStructInfo, bytesNeeded)))
5207 CERT_NAME_CONSTRAINTS_INFO *info = (CERT_NAME_CONSTRAINTS_INFO *)
5208 ((BYTE *)pvStructInfo -
5209 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree));
5211 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5212 &info->cPermittedSubtree, info->rgPermittedSubtree, &bytesNeeded,
5219 static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded,
5220 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5224 struct AsnArrayDescriptor arrayDesc = { 0,
5225 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5226 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5229 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5230 pvStructInfo, *pcbStructInfo, pcbDecoded);
5232 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5233 NULL, NULL, &bytesNeeded, pcbDecoded)))
5235 bytesNeeded += FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO,
5238 *pcbStructInfo = bytesNeeded;
5239 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
5240 pcbStructInfo, bytesNeeded)))
5242 CERT_NAME_CONSTRAINTS_INFO *info = (CERT_NAME_CONSTRAINTS_INFO *)
5243 ((BYTE *)pvStructInfo -
5244 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree));
5246 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5247 &info->cExcludedSubtree, info->rgExcludedSubtree, &bytesNeeded,
5254 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
5255 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5256 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5260 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5261 pDecodePara, pvStructInfo, *pcbStructInfo);
5265 struct AsnDecodeSequenceItem items[] = {
5266 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
5267 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5268 CRYPT_AsnDecodePermittedSubtree,
5269 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5270 cExcludedSubtree), TRUE, TRUE,
5271 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
5272 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
5273 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5274 CRYPT_AsnDecodeExcludedSubtree,
5275 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5277 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
5280 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5281 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5282 pcbStructInfo, NULL, NULL);
5286 SetLastError(STATUS_ACCESS_VIOLATION);
5292 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
5293 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5297 struct AsnDecodeSequenceItem items[] = {
5298 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
5299 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
5301 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
5302 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
5303 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
5305 CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;
5307 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5308 pvStructInfo, *pcbStructInfo, pcbDecoded);
5310 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5311 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5312 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
5313 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
5315 SetLastError(CRYPT_E_ASN1_CORRUPT);
5318 TRACE("returning %d\n", ret);
5322 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
5323 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5326 CMSG_SIGNER_INFO *info = pvStructInfo;
5327 struct AsnDecodeSequenceItem items[] = {
5328 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
5329 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5330 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
5331 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
5332 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
5333 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
5334 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5335 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5336 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5337 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
5338 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5339 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5340 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
5341 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5342 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
5343 HashEncryptionAlgorithm.pszObjId), 0 },
5344 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
5345 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5346 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
5347 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5348 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
5349 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5350 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5354 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5355 pvStructInfo, *pcbStructInfo);
5357 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5358 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5359 pcbDecoded, info ? info->Issuer.pbData : NULL);
5363 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
5364 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5365 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5369 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5370 pDecodePara, pvStructInfo, *pcbStructInfo);
5374 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
5375 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5376 if (ret && pvStructInfo)
5378 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5379 pcbStructInfo, *pcbStructInfo);
5382 CMSG_SIGNER_INFO *info;
5384 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5385 pvStructInfo = *(BYTE **)pvStructInfo;
5386 info = pvStructInfo;
5387 info->Issuer.pbData = ((BYTE *)info +
5388 sizeof(CMSG_SIGNER_INFO));
5389 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
5390 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5391 pcbStructInfo, NULL);
5397 SetLastError(STATUS_ACCESS_VIOLATION);
5400 TRACE("returning %d\n", ret);
5404 static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded,
5405 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5409 struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
5410 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5413 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5414 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5416 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5417 NULL, NULL, &bytesNeeded, pcbDecoded)))
5419 bytesNeeded += MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded);
5421 *pcbStructInfo = bytesNeeded;
5422 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
5423 pcbStructInfo, bytesNeeded)))
5425 CRYPT_SIGNED_INFO *info = (CRYPT_SIGNED_INFO *)
5426 ((BYTE *)pvStructInfo - offsetof(CRYPT_SIGNED_INFO, cCertEncoded));
5428 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5429 &info->cCertEncoded, info->rgCertEncoded, &bytesNeeded,
5436 static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded,
5437 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5441 struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
5442 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5445 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5446 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5448 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5449 NULL, NULL, &bytesNeeded, pcbDecoded)))
5451 bytesNeeded += MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content);
5453 *pcbStructInfo = bytesNeeded;
5454 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
5455 pcbStructInfo, bytesNeeded)))
5457 CRYPT_SIGNED_INFO *info = (CRYPT_SIGNED_INFO *)
5458 ((BYTE *)pvStructInfo - offsetof(CRYPT_SIGNED_INFO, cCrlEncoded));
5460 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5461 &info->cCrlEncoded, info->rgCrlEncoded, &bytesNeeded,
5468 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
5469 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5472 CERT_ID *id = pvStructInfo;
5475 if (*pbEncoded == ASN_SEQUENCEOF)
5477 ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
5478 id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
5482 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5483 if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
5484 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5485 sizeof(CERT_ISSUER_SERIAL_NUMBER);
5487 *pcbStructInfo = sizeof(CERT_ID);
5490 else if (*pbEncoded == (ASN_CONTEXT | 0))
5492 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
5493 id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
5497 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5498 if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
5499 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5500 sizeof(CRYPT_DATA_BLOB);
5502 *pcbStructInfo = sizeof(CERT_ID);
5506 SetLastError(CRYPT_E_ASN1_BADTAG);
5510 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
5511 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5514 CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
5515 struct AsnDecodeSequenceItem items[] = {
5516 { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
5517 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5518 { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
5519 CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
5520 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
5521 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
5522 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5523 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5524 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5525 offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
5526 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5527 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5528 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
5529 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5530 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
5531 HashEncryptionAlgorithm.pszObjId), 0 },
5532 { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
5533 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5534 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
5535 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5536 offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
5537 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5538 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5542 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5543 pvStructInfo, *pcbStructInfo);
5545 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5546 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5547 pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
5551 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
5552 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5553 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5557 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5558 pDecodePara, pvStructInfo, *pcbStructInfo);
5562 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
5563 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5564 if (ret && pvStructInfo)
5566 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5567 pcbStructInfo, *pcbStructInfo);
5570 CMSG_CMS_SIGNER_INFO *info;
5572 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5573 pvStructInfo = *(BYTE **)pvStructInfo;
5574 info = pvStructInfo;
5575 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
5576 sizeof(CMSG_CMS_SIGNER_INFO));
5577 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
5578 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5579 pcbStructInfo, NULL);
5585 SetLastError(STATUS_ACCESS_VIOLATION);
5588 TRACE("returning %d\n", ret);
5592 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
5593 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5596 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5597 CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
5598 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
5601 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5602 pvStructInfo, *pcbStructInfo, pcbDecoded);
5604 if ((ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5605 NULL, NULL, &bytesNeeded, pcbDecoded)))
5607 bytesNeeded += FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo);
5609 *pcbStructInfo = bytesNeeded;
5610 else if ((ret = CRYPT_DecodeEnsureSpace(0, NULL, pvStructInfo,
5611 pcbStructInfo, bytesNeeded)))
5613 CRYPT_SIGNED_INFO *info = (CRYPT_SIGNED_INFO *)
5614 ((BYTE *)pvStructInfo - offsetof(CRYPT_SIGNED_INFO, cSignerInfo));
5616 ret = CRYPT_AsnDecodeArrayNoAlloc(&arrayDesc, pbEncoded, cbEncoded,
5617 &info->cSignerInfo, info->rgSignerInfo, &bytesNeeded,
5624 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5625 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5626 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
5629 struct AsnDecodeSequenceItem items[] = {
5630 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
5631 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5632 /* Placeholder for the hash algorithms - redundant with those in the
5633 * signers, so just ignore them.
5635 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5636 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
5637 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
5638 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
5639 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5640 offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded,
5641 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE,
5642 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
5643 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5644 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded,
5645 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE,
5646 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
5647 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5648 CRYPT_DecodeSignerArray,
5649 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE,
5650 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
5653 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5654 pDecodePara, signedInfo, *pcbSignedInfo);
5656 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5657 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
5659 TRACE("returning %d\n", ret);
5663 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
5664 LPCSTR lpszStructType)
5666 CryptDecodeObjectExFunc decodeFunc = NULL;
5668 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
5669 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
5671 SetLastError(ERROR_FILE_NOT_FOUND);
5674 if (!HIWORD(lpszStructType))
5676 switch (LOWORD(lpszStructType))
5678 case LOWORD(X509_CERT):
5679 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
5681 case LOWORD(X509_CERT_TO_BE_SIGNED):
5682 decodeFunc = CRYPT_AsnDecodeCert;
5684 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
5685 decodeFunc = CRYPT_AsnDecodeCRL;
5687 case LOWORD(X509_EXTENSIONS):
5688 decodeFunc = CRYPT_AsnDecodeExtensions;
5690 case LOWORD(X509_NAME_VALUE):
5691 decodeFunc = CRYPT_AsnDecodeNameValue;
5693 case LOWORD(X509_NAME):
5694 decodeFunc = CRYPT_AsnDecodeName;
5696 case LOWORD(X509_PUBLIC_KEY_INFO):
5697 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
5699 case LOWORD(X509_AUTHORITY_KEY_ID):
5700 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5702 case LOWORD(X509_ALTERNATE_NAME):
5703 decodeFunc = CRYPT_AsnDecodeAltName;
5705 case LOWORD(X509_BASIC_CONSTRAINTS):
5706 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5708 case LOWORD(X509_BASIC_CONSTRAINTS2):
5709 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5711 case LOWORD(X509_CERT_POLICIES):
5712 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5714 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
5715 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
5717 case LOWORD(X509_UNICODE_NAME):
5718 decodeFunc = CRYPT_AsnDecodeUnicodeName;
5720 case LOWORD(PKCS_ATTRIBUTE):
5721 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
5723 case LOWORD(X509_UNICODE_NAME_VALUE):
5724 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
5726 case LOWORD(X509_OCTET_STRING):
5727 decodeFunc = CRYPT_AsnDecodeOctets;
5729 case LOWORD(X509_BITS):
5730 case LOWORD(X509_KEY_USAGE):
5731 decodeFunc = CRYPT_AsnDecodeBits;
5733 case LOWORD(X509_INTEGER):
5734 decodeFunc = CRYPT_AsnDecodeInt;
5736 case LOWORD(X509_MULTI_BYTE_INTEGER):
5737 decodeFunc = CRYPT_AsnDecodeInteger;
5739 case LOWORD(X509_MULTI_BYTE_UINT):
5740 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
5742 case LOWORD(X509_ENUMERATED):
5743 decodeFunc = CRYPT_AsnDecodeEnumerated;
5745 case LOWORD(X509_CHOICE_OF_TIME):
5746 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
5748 case LOWORD(X509_AUTHORITY_KEY_ID2):
5749 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5751 case LOWORD(X509_AUTHORITY_INFO_ACCESS):
5752 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5754 case LOWORD(PKCS_CONTENT_INFO):
5755 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
5757 case LOWORD(X509_SEQUENCE_OF_ANY):
5758 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
5760 case LOWORD(PKCS_UTC_TIME):
5761 decodeFunc = CRYPT_AsnDecodeUtcTime;
5763 case LOWORD(X509_CRL_DIST_POINTS):
5764 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5766 case LOWORD(X509_ENHANCED_KEY_USAGE):
5767 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5769 case LOWORD(PKCS_CTL):
5770 decodeFunc = CRYPT_AsnDecodeCTL;
5772 case LOWORD(PKCS_SMIME_CAPABILITIES):
5773 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5775 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
5776 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5778 case LOWORD(PKCS_ATTRIBUTES):
5779 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
5781 case LOWORD(X509_ISSUING_DIST_POINT):
5782 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5784 case LOWORD(X509_NAME_CONSTRAINTS):
5785 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5787 case LOWORD(PKCS7_SIGNER_INFO):
5788 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
5790 case LOWORD(CMS_SIGNER_INFO):
5791 decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
5795 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
5796 decodeFunc = CRYPT_AsnDecodeExtensions;
5797 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
5798 decodeFunc = CRYPT_AsnDecodeUtcTime;
5799 else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
5800 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5801 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
5802 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5803 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
5804 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5805 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
5806 decodeFunc = CRYPT_AsnDecodeEnumerated;
5807 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
5808 decodeFunc = CRYPT_AsnDecodeBits;
5809 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
5810 decodeFunc = CRYPT_AsnDecodeOctets;
5811 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
5812 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5813 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
5814 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5815 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
5816 decodeFunc = CRYPT_AsnDecodeAltName;
5817 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
5818 decodeFunc = CRYPT_AsnDecodeAltName;
5819 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
5820 decodeFunc = CRYPT_AsnDecodeAltName;
5821 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
5822 decodeFunc = CRYPT_AsnDecodeAltName;
5823 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
5824 decodeFunc = CRYPT_AsnDecodeAltName;
5825 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
5826 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5827 else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
5828 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5829 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
5830 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5831 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
5832 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5833 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
5834 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5835 else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
5836 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5837 else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
5838 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5839 else if (!strcmp(lpszStructType, szOID_CTL))
5840 decodeFunc = CRYPT_AsnDecodeCTL;
5844 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
5845 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5847 static HCRYPTOIDFUNCSET set = NULL;
5848 CryptDecodeObjectFunc decodeFunc = NULL;
5851 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
5852 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5853 (void **)&decodeFunc, hFunc);
5857 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
5858 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5860 static HCRYPTOIDFUNCSET set = NULL;
5861 CryptDecodeObjectExFunc decodeFunc = NULL;
5864 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
5865 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5866 (void **)&decodeFunc, hFunc);
5870 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5871 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
5872 DWORD *pcbStructInfo)
5875 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
5876 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
5877 HCRYPTOIDFUNCADDR hFunc = NULL;
5879 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
5880 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
5881 pvStructInfo, pcbStructInfo);
5883 if (!pvStructInfo && !pcbStructInfo)
5885 SetLastError(ERROR_INVALID_PARAMETER);
5888 if (cbEncoded > MAX_ENCODED_LEN)
5890 SetLastError(CRYPT_E_ASN1_LARGE);
5894 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
5897 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5898 debugstr_a(lpszStructType));
5899 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
5900 lpszStructType, &hFunc);
5901 if (!pCryptDecodeObject)
5902 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
5903 lpszStructType, &hFunc);
5905 if (pCryptDecodeObject)
5906 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5907 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5908 else if (pCryptDecodeObjectEx)
5909 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
5910 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
5911 pvStructInfo, pcbStructInfo);
5913 CryptFreeOIDFunctionAddress(hFunc, 0);
5914 TRACE_(crypt)("returning %d\n", ret);
5918 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5919 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5920 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5923 CryptDecodeObjectExFunc decodeFunc;
5924 HCRYPTOIDFUNCADDR hFunc = NULL;
5926 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5927 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
5928 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5930 if (!pvStructInfo && !pcbStructInfo)
5932 SetLastError(ERROR_INVALID_PARAMETER);
5935 if (cbEncoded > MAX_ENCODED_LEN)
5937 SetLastError(CRYPT_E_ASN1_LARGE);
5941 SetLastError(NOERROR);
5942 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
5943 *(BYTE **)pvStructInfo = NULL;
5944 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
5947 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5948 debugstr_a(lpszStructType));
5949 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
5953 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
5954 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5957 CryptDecodeObjectFunc pCryptDecodeObject =
5958 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
5960 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5961 * directly, as that could cause an infinite loop.
5963 if (pCryptDecodeObject)
5965 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5967 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5968 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
5969 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
5970 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
5971 ret = pCryptDecodeObject(dwCertEncodingType,
5972 lpszStructType, pbEncoded, cbEncoded, dwFlags,
5973 *(BYTE **)pvStructInfo, pcbStructInfo);
5976 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5977 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5981 CryptFreeOIDFunctionAddress(hFunc, 0);
5982 TRACE_(crypt)("returning %d\n", ret);
5986 BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
5990 TRACE_(crypt)("(%p)\n", pPFX);
5992 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
5993 * version integer of length 1 (3 encoded byes) and at least one other
5994 * datum (two encoded bytes), plus at least two bytes for the outer
5995 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
5997 if (pPFX->cbData < 7)
5999 else if (pPFX->pbData[0] == ASN_SEQUENCE)
6003 if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
6005 BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);
6007 /* Need at least three bytes for the integer version */
6008 if (pPFX->cbData < 1 + lenLen + 3)
6010 else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
6011 pPFX->pbData[1 + lenLen + 1] != 1 || /* Definite length */
6012 pPFX->pbData[1 + lenLen + 2] != 3) /* PFX version */
6021 HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
6024 FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);