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 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
85 * time, doesn't do memory allocation, and doesn't do exception handling.
87 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
88 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
90 /* Assumes algo->Parameters.pbData is set ahead of time. */
91 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
92 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
93 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
94 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
95 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
96 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
97 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
99 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
100 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
101 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
102 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
103 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
104 * member has been initialized, doesn't do exception handling, and doesn't do
105 * memory allocation. Also doesn't check tag, assumes the caller has checked
108 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
109 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
111 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
112 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
113 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
116 /* Gets the number of length bytes from the given (leading) length byte */
117 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
119 /* Helper function to get the encoded length of the data starting at pbEncoded,
120 * where pbEncoded[0] is the tag. If the data are too short to contain a
121 * length or if the length is too large for cbEncoded, sets an appropriate
122 * error code and returns FALSE. If the encoded length is unknown due to
123 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
125 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
132 SetLastError(CRYPT_E_ASN1_CORRUPT);
135 else if (pbEncoded[1] <= 0x7f)
137 if (pbEncoded[1] + 1 > cbEncoded)
139 SetLastError(CRYPT_E_ASN1_EOD);
148 else if (pbEncoded[1] == 0x80)
150 *len = CMSG_INDEFINITE_LENGTH;
155 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
157 if (lenLen > sizeof(DWORD) + 1)
159 SetLastError(CRYPT_E_ASN1_LARGE);
162 else if (lenLen + 2 > cbEncoded)
164 SetLastError(CRYPT_E_ASN1_CORRUPT);
177 if (out + lenLen + 1 > cbEncoded)
179 SetLastError(CRYPT_E_ASN1_EOD);
192 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
193 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
197 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
198 *len == CMSG_INDEFINITE_LENGTH)
200 SetLastError(CRYPT_E_ASN1_CORRUPT);
206 /* Helper function to check *pcbStructInfo, set it to the required size, and
207 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
208 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
209 * pointer to the newly allocated memory.
211 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
212 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
217 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
219 if (pDecodePara && pDecodePara->pfnAlloc)
220 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
222 *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
223 if (!*(BYTE **)pvStructInfo)
226 *pcbStructInfo = bytesNeeded;
228 else if (*pcbStructInfo < bytesNeeded)
230 *pcbStructInfo = bytesNeeded;
231 SetLastError(ERROR_MORE_DATA);
237 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara, LPVOID pv)
239 if (pDecodePara && pDecodePara->pfnFree)
240 pDecodePara->pfnFree(pv);
245 /* Helper function to check *pcbStructInfo and set it to the required size.
246 * Assumes pvStructInfo is not NULL.
248 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
252 if (*pcbStructInfo < bytesNeeded)
254 *pcbStructInfo = bytesNeeded;
255 SetLastError(ERROR_MORE_DATA);
260 *pcbStructInfo = bytesNeeded;
267 * The expected tag of the item. If tag is 0, decodeFunc is called
268 * regardless of the tag value seen.
270 * A sequence is decoded into a struct. The offset member is the
271 * offset of this item within that struct.
273 * The decoder function to use. If this is NULL, then the member isn't
274 * decoded, but minSize space is reserved for it.
276 * The minimum amount of space occupied after decoding. You must set this.
278 * If true, and the tag doesn't match the expected tag for this item,
279 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
280 * filled with 0 for this member.
281 * hasPointer, pointerOffset:
282 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
283 * the offset within the struct of the data pointer (or to the
284 * first data pointer, if more than one exist).
286 * Used by CRYPT_AsnDecodeSequence, not for your use.
288 struct AsnDecodeSequenceItem
292 InternalDecodeFunc decodeFunc;
300 /* Decodes the items in a sequence, where the items are described in items,
301 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
302 * pvStructInfo. nextData is a pointer to the memory location at which the
303 * first decoded item with a dynamic pointer should point.
304 * Upon decoding, *cbDecoded is the total number of bytes decoded.
305 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
307 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
308 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
309 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
312 DWORD i, decoded = 0;
313 const BYTE *ptr = pbEncoded;
315 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
316 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
318 for (i = 0, ret = TRUE; ret && i < cItem; i++)
320 if (cbEncoded - (ptr - pbEncoded) != 0)
324 if ((ret = CRYPT_GetLengthIndefinite(ptr,
325 cbEncoded - (ptr - pbEncoded), &itemLen)))
327 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
329 if (ptr[0] == items[i].tag || !items[i].tag)
331 DWORD itemEncodedLen;
333 if (itemLen == CMSG_INDEFINITE_LENGTH)
334 itemEncodedLen = cbEncoded - (ptr - pbEncoded);
336 itemEncodedLen = 1 + itemLenBytes + itemLen;
337 if (nextData && pvStructInfo && items[i].hasPointer)
339 TRACE("Setting next pointer to %p\n",
341 *(BYTE **)((BYTE *)pvStructInfo +
342 items[i].pointerOffset) = nextData;
344 if (items[i].decodeFunc)
349 TRACE("decoding item %d\n", i);
351 TRACE("sizing item %d\n", i);
352 ret = items[i].decodeFunc(ptr, itemEncodedLen,
353 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
354 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
355 : NULL, &items[i].size, &itemDecoded);
358 /* Account for alignment padding */
359 if (items[i].size % sizeof(DWORD_PTR))
360 items[i].size += sizeof(DWORD_PTR) -
361 items[i].size % sizeof(DWORD_PTR);
362 TRACE("item %d size: %d\n", i, items[i].size);
363 if (nextData && items[i].hasPointer &&
364 items[i].size > items[i].minSize)
365 nextData += items[i].size - items[i].minSize;
366 if (itemDecoded > itemEncodedLen)
368 WARN("decoded length %d exceeds encoded %d\n",
369 itemDecoded, itemEncodedLen);
370 SetLastError(CRYPT_E_ASN1_CORRUPT);
375 if (itemLen == CMSG_INDEFINITE_LENGTH)
377 if (itemDecoded > itemEncodedLen - 2 ||
378 *(ptr + itemDecoded) != 0 ||
379 *(ptr + itemDecoded + 1) != 0)
381 TRACE("expected 0 TLV\n");
382 SetLastError(CRYPT_E_ASN1_CORRUPT);
391 decoded += itemDecoded;
392 TRACE("item %d: decoded %d bytes\n", i,
397 else if (items[i].optional &&
398 GetLastError() == CRYPT_E_ASN1_BADTAG)
400 TRACE("skipping optional item %d\n", i);
401 items[i].size = items[i].minSize;
402 SetLastError(NOERROR);
406 TRACE("item %d failed: %08x\n", i,
409 else if (itemLen == CMSG_INDEFINITE_LENGTH)
411 ERR("can't use indefinite length encoding without a decoder\n");
412 SetLastError(CRYPT_E_ASN1_CORRUPT);
417 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
418 ptr += itemEncodedLen;
419 decoded += itemEncodedLen;
420 items[i].size = items[i].minSize;
423 else if (items[i].optional)
425 TRACE("skipping optional item %d\n", i);
426 items[i].size = items[i].minSize;
430 TRACE("item %d: tag %02x doesn't match expected %02x\n",
431 i, ptr[0], items[i].tag);
432 SetLastError(CRYPT_E_ASN1_BADTAG);
437 else if (items[i].optional)
439 TRACE("missing optional item %d, skipping\n", i);
440 items[i].size = items[i].minSize;
444 TRACE("not enough bytes for item %d, failing\n", i);
445 SetLastError(CRYPT_E_ASN1_CORRUPT);
450 *cbDecoded = decoded;
451 TRACE("returning %d\n", ret);
455 /* This decodes an arbitrary sequence into a contiguous block of memory
456 * (basically, a struct.) Each element being decoded is described by a struct
457 * AsnDecodeSequenceItem, see above.
458 * startingPointer is an optional pointer to the first place where dynamic
459 * data will be stored. If you know the starting offset, you may pass it
460 * here. Otherwise, pass NULL, and one will be inferred from the items.
462 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
463 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
464 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
465 DWORD *pcbDecoded, void *startingPointer)
469 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
470 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
473 if (pbEncoded[0] == ASN_SEQUENCE)
477 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
479 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
480 const BYTE *ptr = pbEncoded + 1 + lenBytes;
481 BOOL indefinite = FALSE;
483 cbEncoded -= 1 + lenBytes;
484 if (dataLen == CMSG_INDEFINITE_LENGTH)
489 else if (cbEncoded < dataLen)
491 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
493 SetLastError(CRYPT_E_ASN1_CORRUPT);
498 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
499 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
500 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
502 if (cbDecoded > cbEncoded - 2)
504 /* Not enough space for 0 TLV */
505 SetLastError(CRYPT_E_ASN1_CORRUPT);
508 else if (*(ptr + cbDecoded) != 0 ||
509 *(ptr + cbDecoded + 1) != 0)
511 TRACE("expected 0 TLV\n");
512 SetLastError(CRYPT_E_ASN1_CORRUPT);
519 if (ret && !indefinite && cbDecoded != dataLen)
521 TRACE("expected %d decoded, got %d, failing\n", dataLen,
523 SetLastError(CRYPT_E_ASN1_CORRUPT);
528 DWORD i, bytesNeeded = 0, structSize = 0;
530 for (i = 0; i < cItem; i++)
532 bytesNeeded += items[i].size;
533 structSize += items[i].minSize;
536 *pcbDecoded = 1 + lenBytes + cbDecoded;
538 *pcbStructInfo = bytesNeeded;
539 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
540 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
544 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
545 pvStructInfo = *(BYTE **)pvStructInfo;
547 nextData = (BYTE *)startingPointer;
549 nextData = (BYTE *)pvStructInfo + structSize;
550 memset(pvStructInfo, 0, structSize);
551 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
552 ptr, dataLen, dwFlags, pvStructInfo, nextData,
554 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
555 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
562 SetLastError(CRYPT_E_ASN1_BADTAG);
565 TRACE("returning %d (%08x)\n", ret, GetLastError());
570 * The expected tag of the entire encoded array (usually a variant
571 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
572 * regardless of the tag seen.
574 * used to decode each item in the array
576 * is the minimum size of each decoded item
578 * indicates whether each item has a dynamic pointer
580 * indicates the offset within itemSize at which the pointer exists
582 struct AsnArrayDescriptor
585 InternalDecodeFunc decodeFunc;
591 struct AsnArrayItemSize
597 /* Decodes an array of like types into a struct GenericArray.
598 * The layout and decoding of the array are described by a struct
599 * AsnArrayDescriptor.
601 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
602 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
603 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
604 DWORD *pcbDecoded, void *startingPointer)
608 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded,
609 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
612 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 = (struct GenericArray *)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 a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
760 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
761 * to CRYPT_E_ASN1_CORRUPT.
762 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
765 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
766 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
771 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
773 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
774 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
776 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
777 bytesNeeded += 1 + lenBytes + dataLen;
780 *pcbDecoded = 1 + lenBytes + dataLen;
782 *pcbStructInfo = bytesNeeded;
783 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
785 CRYPT_DER_BLOB *blob;
787 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
788 pvStructInfo = *(BYTE **)pvStructInfo;
789 blob = (CRYPT_DER_BLOB *)pvStructInfo;
790 blob->cbData = 1 + lenBytes + dataLen;
793 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
794 blob->pbData = (BYTE *)pbEncoded;
797 assert(blob->pbData);
798 memcpy(blob->pbData, pbEncoded, blob->cbData);
803 SetLastError(CRYPT_E_ASN1_CORRUPT);
811 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
812 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
813 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
818 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
819 pvStructInfo, *pcbStructInfo, pcbDecoded);
821 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
824 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
825 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
827 if (ret && pvStructInfo)
829 CRYPT_BIT_BLOB *blob = (CRYPT_BIT_BLOB *)pvStructInfo;
836 for (i = 0; i < blob->cbData / 2; i++)
838 temp = blob->pbData[i];
839 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
840 blob->pbData[blob->cbData - i - 1] = temp;
844 TRACE("returning %d (%08x)\n", ret, GetLastError());
848 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
849 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
850 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
854 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
855 pDecodePara, pvStructInfo, *pcbStructInfo);
859 struct AsnDecodeSequenceItem items[] = {
860 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
861 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
862 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
863 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
864 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
865 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
866 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
867 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
868 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
869 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
872 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
873 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
874 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
875 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
876 pcbStructInfo, NULL, NULL);
880 SetLastError(STATUS_ACCESS_VIOLATION);
885 TRACE("Returning %d (%08x)\n", ret, GetLastError());
889 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
890 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
895 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
897 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
899 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
900 dwFlags, pvStructInfo, pcbStructInfo, NULL);
902 *pcbDecoded = 1 + lenBytes + dataLen;
907 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
908 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
912 struct AsnDecodeSequenceItem items[] = {
913 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
914 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
915 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
916 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
919 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
920 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
925 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
926 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
932 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
934 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
936 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded + 1 + lenBytes,
937 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
938 if (ret && pcbDecoded)
939 *pcbDecoded = 1 + lenBytes + dataLen;
944 static BOOL WINAPI CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
945 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
946 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
949 struct AsnDecodeSequenceItem items[] = {
950 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
951 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
952 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
953 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
954 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
955 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
956 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
957 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
958 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
959 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
961 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
962 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
964 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
965 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
967 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
968 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
969 FALSE, TRUE, offsetof(CERT_INFO,
970 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
971 { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
972 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
973 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
974 { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
975 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
976 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
977 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
978 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
979 offsetof(CERT_INFO, rgExtension), 0 },
982 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
983 pDecodePara, pvStructInfo, *pcbStructInfo);
985 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
986 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
988 if (ret && pvStructInfo)
992 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
993 info = *(CERT_INFO **)pvStructInfo;
995 info = (CERT_INFO *)pvStructInfo;
996 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
997 !info->Subject.cbData)
999 SetLastError(CRYPT_E_ASN1_CORRUPT);
1000 /* Don't need to deallocate, because it should have failed on the
1001 * first pass (and no memory was allocated.)
1007 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1011 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1012 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1013 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1017 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1018 pDecodePara, pvStructInfo, *pcbStructInfo);
1024 /* Unless told not to, first try to decode it as a signed cert. */
1025 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1027 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1029 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1030 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1031 (BYTE *)&signedCert, &size);
1035 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1036 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1037 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1038 pvStructInfo, pcbStructInfo);
1039 LocalFree(signedCert);
1042 /* Failing that, try it as an unsigned cert */
1046 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1047 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1048 pDecodePara, pvStructInfo, pcbStructInfo);
1053 SetLastError(STATUS_ACCESS_VIOLATION);
1057 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1061 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1062 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1065 struct AsnDecodeSequenceItem items[] = {
1066 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1067 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1068 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1069 { 0, offsetof(CRL_ENTRY, RevocationDate),
1070 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1071 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1072 CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1073 offsetof(CRL_ENTRY, rgExtension), 0 },
1075 PCRL_ENTRY entry = (PCRL_ENTRY)pvStructInfo;
1077 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1080 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1081 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1082 entry ? entry->SerialNumber.pbData : NULL);
1083 if (ret && entry && !entry->SerialNumber.cbData)
1085 WARN("empty CRL entry serial number\n");
1086 SetLastError(CRYPT_E_ASN1_CORRUPT);
1092 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1093 * been set prior to calling.
1095 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1096 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1099 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1100 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1101 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1102 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
1104 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1105 pvStructInfo, *pcbStructInfo, pcbDecoded);
1107 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1108 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1109 entries ? entries->rgItems : NULL);
1110 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1114 static BOOL WINAPI CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1115 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1116 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1118 struct AsnDecodeSequenceItem items[] = {
1119 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1120 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1121 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1122 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1123 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1124 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1125 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1127 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1128 sizeof(FILETIME), FALSE, FALSE, 0 },
1129 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1130 sizeof(FILETIME), TRUE, FALSE, 0 },
1131 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1132 CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE,
1133 offsetof(CRL_INFO, rgCRLEntry), 0 },
1134 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1135 CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE,
1136 offsetof(CRL_INFO, rgExtension), 0 },
1140 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1141 pDecodePara, pvStructInfo, *pcbStructInfo);
1143 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1144 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1147 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1151 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1152 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1153 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1157 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1158 pDecodePara, pvStructInfo, *pcbStructInfo);
1164 /* Unless told not to, first try to decode it as a signed crl. */
1165 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1167 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1169 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1170 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1171 (BYTE *)&signedCrl, &size);
1175 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1176 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1177 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1178 pvStructInfo, pcbStructInfo);
1179 LocalFree(signedCrl);
1182 /* Failing that, try it as an unsigned crl */
1186 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1187 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1188 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1193 SetLastError(STATUS_ACCESS_VIOLATION);
1197 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1201 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1202 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1207 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1208 pvStructInfo, *pcbStructInfo);
1210 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1212 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1213 DWORD bytesNeeded = sizeof(LPSTR);
1217 /* The largest possible string for the first two components
1218 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1223 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1224 pbEncoded[1 + lenBytes] / 40,
1225 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1227 bytesNeeded += strlen(firstTwo) + 1;
1228 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1229 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1231 /* large enough for ".4000000" */
1235 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1242 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1245 SetLastError(CRYPT_E_ASN1_CORRUPT);
1252 snprintf(str, sizeof(str), ".%d", val);
1253 bytesNeeded += strlen(str);
1258 *pcbDecoded = 1 + lenBytes + dataLen;
1260 *pcbStructInfo = bytesNeeded;
1261 else if (*pcbStructInfo < bytesNeeded)
1263 *pcbStructInfo = bytesNeeded;
1264 SetLastError(ERROR_MORE_DATA);
1272 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1275 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1276 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1278 pszObjId += strlen(pszObjId);
1279 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1280 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1284 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1293 sprintf(pszObjId, ".%d", val);
1294 pszObjId += strlen(pszObjId);
1298 *(LPSTR *)pvStructInfo = NULL;
1299 *pcbStructInfo = bytesNeeded;
1305 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1306 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1310 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1311 pvStructInfo, *pcbStructInfo);
1313 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1314 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1315 pvStructInfo, pcbStructInfo, pcbDecoded);
1318 SetLastError(CRYPT_E_ASN1_BADTAG);
1324 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1327 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1328 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1330 struct AsnDecodeSequenceItem items[] = {
1331 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1332 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1333 offsetof(CERT_EXTENSION, pszObjId), 0 },
1334 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1335 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1336 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1337 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1338 offsetof(CERT_EXTENSION, Value.pbData) },
1341 PCERT_EXTENSION ext = (PCERT_EXTENSION)pvStructInfo;
1343 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1347 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1348 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1349 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1350 pcbDecoded, ext ? ext->pszObjId : NULL);
1352 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1353 debugstr_a(ext->pszObjId));
1354 TRACE("returning %d (%08x)\n", ret, GetLastError());
1358 static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded,
1359 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1363 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1364 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1365 offsetof(CERT_EXTENSION, pszObjId) };
1366 PCERT_EXTENSIONS exts = (PCERT_EXTENSIONS)pvStructInfo;
1368 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1369 pvStructInfo, *pcbStructInfo, pcbDecoded);
1371 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1372 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1373 exts ? exts->rgExtension : NULL);
1377 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1378 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1379 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1385 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1386 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1387 if (ret && pvStructInfo)
1389 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1390 pcbStructInfo, *pcbStructInfo);
1393 CERT_EXTENSIONS *exts;
1395 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1396 pvStructInfo = *(BYTE **)pvStructInfo;
1397 exts = (CERT_EXTENSIONS *)pvStructInfo;
1398 exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts +
1399 sizeof(CERT_EXTENSIONS));
1400 ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded,
1401 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1402 pcbStructInfo, NULL);
1408 SetLastError(STATUS_ACCESS_VIOLATION);
1415 /* Warning: this assumes the address of value->Value.pbData is already set, in
1416 * order to avoid overwriting memory. (In some cases, it may change it, if it
1417 * doesn't copy anything to memory.) Be sure to set it correctly!
1419 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1420 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1425 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1427 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1429 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1430 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1432 switch (pbEncoded[0])
1434 case ASN_OCTETSTRING:
1435 valueType = CERT_RDN_OCTET_STRING;
1436 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1437 bytesNeeded += dataLen;
1439 case ASN_NUMERICSTRING:
1440 valueType = CERT_RDN_NUMERIC_STRING;
1441 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1442 bytesNeeded += dataLen;
1444 case ASN_PRINTABLESTRING:
1445 valueType = CERT_RDN_PRINTABLE_STRING;
1446 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1447 bytesNeeded += dataLen;
1450 valueType = CERT_RDN_IA5_STRING;
1451 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1452 bytesNeeded += dataLen;
1455 valueType = CERT_RDN_T61_STRING;
1456 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1457 bytesNeeded += dataLen;
1459 case ASN_VIDEOTEXSTRING:
1460 valueType = CERT_RDN_VIDEOTEX_STRING;
1461 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1462 bytesNeeded += dataLen;
1464 case ASN_GRAPHICSTRING:
1465 valueType = CERT_RDN_GRAPHIC_STRING;
1466 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1467 bytesNeeded += dataLen;
1469 case ASN_VISIBLESTRING:
1470 valueType = CERT_RDN_VISIBLE_STRING;
1471 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1472 bytesNeeded += dataLen;
1474 case ASN_GENERALSTRING:
1475 valueType = CERT_RDN_GENERAL_STRING;
1476 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1477 bytesNeeded += dataLen;
1479 case ASN_UNIVERSALSTRING:
1480 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1481 SetLastError(CRYPT_E_ASN1_BADTAG);
1484 valueType = CERT_RDN_BMP_STRING;
1485 bytesNeeded += dataLen;
1487 case ASN_UTF8STRING:
1488 valueType = CERT_RDN_UTF8_STRING;
1489 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1490 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1493 SetLastError(CRYPT_E_ASN1_BADTAG);
1498 *pcbDecoded = 1 + lenBytes + dataLen;
1500 *pcbStructInfo = bytesNeeded;
1501 else if (*pcbStructInfo < bytesNeeded)
1503 *pcbStructInfo = bytesNeeded;
1504 SetLastError(ERROR_MORE_DATA);
1509 *pcbStructInfo = bytesNeeded;
1510 value->dwValueType = valueType;
1515 assert(value->Value.pbData);
1516 switch (pbEncoded[0])
1518 case ASN_OCTETSTRING:
1519 case ASN_NUMERICSTRING:
1520 case ASN_PRINTABLESTRING:
1523 case ASN_VIDEOTEXSTRING:
1524 case ASN_GRAPHICSTRING:
1525 case ASN_VISIBLESTRING:
1526 case ASN_GENERALSTRING:
1527 value->Value.cbData = dataLen;
1530 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1531 memcpy(value->Value.pbData,
1532 pbEncoded + 1 + lenBytes, dataLen);
1534 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1540 LPWSTR str = (LPWSTR)value->Value.pbData;
1542 value->Value.cbData = dataLen;
1543 for (i = 0; i < dataLen / 2; i++)
1544 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1545 pbEncoded[1 + lenBytes + 2 * i + 1];
1548 case ASN_UTF8STRING:
1550 LPWSTR str = (LPWSTR)value->Value.pbData;
1552 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1553 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1554 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1561 value->Value.cbData = 0;
1562 value->Value.pbData = NULL;
1569 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1570 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1571 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1577 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1578 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1579 if (ret && pvStructInfo)
1581 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1582 pcbStructInfo, *pcbStructInfo);
1585 CERT_NAME_VALUE *value;
1587 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1588 pvStructInfo = *(BYTE **)pvStructInfo;
1589 value = (CERT_NAME_VALUE *)pvStructInfo;
1590 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1591 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1592 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1593 pcbStructInfo, NULL);
1599 SetLastError(STATUS_ACCESS_VIOLATION);
1606 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1607 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1612 CERT_NAME_VALUE *value = (CERT_NAME_VALUE *)pvStructInfo;
1614 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1616 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1617 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1619 switch (pbEncoded[0])
1621 case ASN_NUMERICSTRING:
1622 valueType = CERT_RDN_NUMERIC_STRING;
1623 bytesNeeded += dataLen * 2;
1625 case ASN_PRINTABLESTRING:
1626 valueType = CERT_RDN_PRINTABLE_STRING;
1627 bytesNeeded += dataLen * 2;
1630 valueType = CERT_RDN_IA5_STRING;
1631 bytesNeeded += dataLen * 2;
1634 valueType = CERT_RDN_T61_STRING;
1635 bytesNeeded += dataLen * 2;
1637 case ASN_VIDEOTEXSTRING:
1638 valueType = CERT_RDN_VIDEOTEX_STRING;
1639 bytesNeeded += dataLen * 2;
1641 case ASN_GRAPHICSTRING:
1642 valueType = CERT_RDN_GRAPHIC_STRING;
1643 bytesNeeded += dataLen * 2;
1645 case ASN_VISIBLESTRING:
1646 valueType = CERT_RDN_VISIBLE_STRING;
1647 bytesNeeded += dataLen * 2;
1649 case ASN_GENERALSTRING:
1650 valueType = CERT_RDN_GENERAL_STRING;
1651 bytesNeeded += dataLen * 2;
1653 case ASN_UNIVERSALSTRING:
1654 valueType = CERT_RDN_UNIVERSAL_STRING;
1655 bytesNeeded += dataLen / 2;
1658 valueType = CERT_RDN_BMP_STRING;
1659 bytesNeeded += dataLen;
1661 case ASN_UTF8STRING:
1662 valueType = CERT_RDN_UTF8_STRING;
1663 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1664 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1667 SetLastError(CRYPT_E_ASN1_BADTAG);
1672 *pcbDecoded = 1 + lenBytes + dataLen;
1674 *pcbStructInfo = bytesNeeded;
1675 else if (*pcbStructInfo < bytesNeeded)
1677 *pcbStructInfo = bytesNeeded;
1678 SetLastError(ERROR_MORE_DATA);
1683 *pcbStructInfo = bytesNeeded;
1684 value->dwValueType = valueType;
1688 LPWSTR str = (LPWSTR)value->Value.pbData;
1690 assert(value->Value.pbData);
1691 switch (pbEncoded[0])
1693 case ASN_NUMERICSTRING:
1694 case ASN_PRINTABLESTRING:
1697 case ASN_VIDEOTEXSTRING:
1698 case ASN_GRAPHICSTRING:
1699 case ASN_VISIBLESTRING:
1700 case ASN_GENERALSTRING:
1701 value->Value.cbData = dataLen * 2;
1702 for (i = 0; i < dataLen; i++)
1703 str[i] = pbEncoded[1 + lenBytes + i];
1705 case ASN_UNIVERSALSTRING:
1706 value->Value.cbData = dataLen / 2;
1707 for (i = 0; i < dataLen / 4; i++)
1708 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1709 | pbEncoded[1 + lenBytes + 2 * i + 3];
1712 value->Value.cbData = dataLen;
1713 for (i = 0; i < dataLen / 2; i++)
1714 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1715 pbEncoded[1 + lenBytes + 2 * i + 1];
1717 case ASN_UTF8STRING:
1718 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1719 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1720 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1726 value->Value.cbData = 0;
1727 value->Value.pbData = NULL;
1734 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1735 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1736 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1742 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1743 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1744 if (ret && pvStructInfo)
1746 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1747 pcbStructInfo, *pcbStructInfo);
1750 CERT_NAME_VALUE *value;
1752 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1753 pvStructInfo = *(BYTE **)pvStructInfo;
1754 value = (CERT_NAME_VALUE *)pvStructInfo;
1755 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1756 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1757 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1758 pcbStructInfo, NULL);
1764 SetLastError(STATUS_ACCESS_VIOLATION);
1771 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1772 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1775 struct AsnDecodeSequenceItem items[] = {
1776 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1777 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1778 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1779 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1780 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1781 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1783 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1785 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1786 pvStructInfo, *pcbStructInfo);
1789 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1790 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1791 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1792 attr ? attr->pszObjId : NULL);
1795 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1796 debugstr_a(attr->pszObjId));
1797 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1799 TRACE("returning %d (%08x)\n", ret, GetLastError());
1803 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1804 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1807 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1808 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1809 offsetof(CERT_RDN_ATTR, pszObjId) };
1810 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1812 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1813 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1814 rdn ? rdn->rgRDNAttr : NULL);
1818 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1819 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1820 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1826 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1827 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1828 offsetof(CERT_RDN, rgRDNAttr) };
1830 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1831 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1835 SetLastError(STATUS_ACCESS_VIOLATION);
1842 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1843 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1847 struct AsnDecodeSequenceItem items[] = {
1848 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1849 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1850 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1851 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1852 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1853 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1855 CERT_RDN_ATTR *attr = (CERT_RDN_ATTR *)pvStructInfo;
1857 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1858 pvStructInfo, *pcbStructInfo);
1861 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1862 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1863 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1864 attr ? attr->pszObjId : NULL);
1867 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1868 debugstr_a(attr->pszObjId));
1869 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1871 TRACE("returning %d (%08x)\n", ret, GetLastError());
1875 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1876 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1879 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1880 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1881 offsetof(CERT_RDN_ATTR, pszObjId) };
1882 PCERT_RDN rdn = (PCERT_RDN)pvStructInfo;
1884 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1885 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
1886 rdn ? rdn->rgRDNAttr : NULL);
1890 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1891 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1892 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1898 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1899 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
1900 offsetof(CERT_RDN, rgRDNAttr) };
1902 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1903 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
1907 SetLastError(STATUS_ACCESS_VIOLATION);
1914 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
1917 BOOL ret = TRUE, done = FALSE;
1918 DWORD indefiniteNestingLevels = 0, decoded = 0;
1920 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
1927 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
1930 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1932 if (dataLen == CMSG_INDEFINITE_LENGTH)
1934 indefiniteNestingLevels++;
1935 pbEncoded += 1 + lenBytes;
1936 cbEncoded -= 1 + lenBytes;
1937 decoded += 1 + lenBytes;
1938 TRACE("indefiniteNestingLevels = %d\n",
1939 indefiniteNestingLevels);
1943 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
1944 indefiniteNestingLevels)
1946 indefiniteNestingLevels--;
1947 TRACE("indefiniteNestingLevels = %d\n",
1948 indefiniteNestingLevels);
1950 pbEncoded += 1 + lenBytes + dataLen;
1951 cbEncoded -= 1 + lenBytes + dataLen;
1952 decoded += 1 + lenBytes + dataLen;
1953 if (!indefiniteNestingLevels)
1957 } while (ret && !done);
1958 /* If we haven't found all 0 TLVs, we haven't found the end */
1959 if (ret && indefiniteNestingLevels)
1961 SetLastError(CRYPT_E_ASN1_EOD);
1965 *pcbDecoded = decoded;
1966 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
1970 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
1971 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1975 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
1977 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1978 pvStructInfo, *pcbStructInfo);
1980 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
1982 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1983 bytesNeeded += encodedLen;
1985 *pcbStructInfo = bytesNeeded;
1986 else if (*pcbStructInfo < bytesNeeded)
1988 SetLastError(ERROR_MORE_DATA);
1989 *pcbStructInfo = bytesNeeded;
1994 PCRYPT_OBJID_BLOB blob = (PCRYPT_OBJID_BLOB)pvStructInfo;
1996 *pcbStructInfo = bytesNeeded;
1997 blob->cbData = encodedLen;
1998 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
1999 blob->pbData = (LPBYTE)pbEncoded;
2002 assert(blob->pbData);
2003 memcpy(blob->pbData, pbEncoded, blob->cbData);
2007 *pcbDecoded = encodedLen;
2012 static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded,
2013 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2016 struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes,
2017 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2018 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
2020 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2021 pvStructInfo, *pcbStructInfo, pcbDecoded);
2023 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2024 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2025 array ? array->rgItems : NULL);
2029 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2030 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2034 struct AsnDecodeSequenceItem items[] = {
2035 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2036 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2037 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2038 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2039 CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE,
2040 offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2042 PCRYPT_ATTRIBUTE attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2044 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2045 pvStructInfo, *pcbStructInfo);
2047 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2048 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2049 pcbDecoded, attr ? attr->pszObjId : NULL);
2050 TRACE("returning %d\n", ret);
2054 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2055 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2056 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2060 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2061 pDecodePara, pvStructInfo, *pcbStructInfo);
2067 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2068 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2072 *pcbStructInfo = bytesNeeded;
2073 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2074 pvStructInfo, pcbStructInfo, bytesNeeded)))
2076 PCRYPT_ATTRIBUTE attr;
2078 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2079 pvStructInfo = *(BYTE **)pvStructInfo;
2080 attr = (PCRYPT_ATTRIBUTE)pvStructInfo;
2081 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2082 sizeof(CRYPT_ATTRIBUTE));
2083 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2084 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2091 SetLastError(STATUS_ACCESS_VIOLATION);
2094 TRACE("returning %d\n", ret);
2098 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2099 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2102 struct AsnArrayDescriptor arrayDesc = { 0,
2103 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2104 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2105 PCRYPT_ATTRIBUTES attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2108 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2109 NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr :
2114 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2115 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2116 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2120 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2121 pDecodePara, pvStructInfo, *pcbStructInfo);
2128 SetLastError(CRYPT_E_ASN1_EOD);
2129 else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF))
2130 SetLastError(CRYPT_E_ASN1_CORRUPT);
2131 else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2132 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2136 *pcbStructInfo = bytesNeeded;
2137 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2138 pvStructInfo, pcbStructInfo, bytesNeeded)))
2140 PCRYPT_ATTRIBUTES attrs;
2142 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2143 pvStructInfo = *(BYTE **)pvStructInfo;
2144 attrs = (PCRYPT_ATTRIBUTES)pvStructInfo;
2145 attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo +
2146 sizeof(CRYPT_ATTRIBUTES));
2147 ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded,
2148 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2149 &bytesNeeded, NULL);
2155 SetLastError(STATUS_ACCESS_VIOLATION);
2158 TRACE("returning %d\n", ret);
2162 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2163 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2165 CRYPT_ALGORITHM_IDENTIFIER *algo =
2166 (CRYPT_ALGORITHM_IDENTIFIER *)pvStructInfo;
2168 struct AsnDecodeSequenceItem items[] = {
2169 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2170 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2171 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2172 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2173 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2174 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2177 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2178 pvStructInfo, *pcbStructInfo, pcbDecoded);
2180 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2181 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2182 pcbDecoded, algo ? algo->pszObjId : NULL);
2183 if (ret && pvStructInfo)
2185 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2186 debugstr_a(algo->pszObjId));
2191 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2192 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2196 struct AsnDecodeSequenceItem items[] = {
2197 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2198 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2199 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2200 Algorithm.pszObjId) },
2201 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2202 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2203 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2205 PCERT_PUBLIC_KEY_INFO info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2207 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2208 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2209 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2213 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2214 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2215 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2223 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2224 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2227 *pcbStructInfo = bytesNeeded;
2228 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2229 pvStructInfo, pcbStructInfo, bytesNeeded)))
2231 PCERT_PUBLIC_KEY_INFO info;
2233 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2234 pvStructInfo = *(BYTE **)pvStructInfo;
2235 info = (PCERT_PUBLIC_KEY_INFO)pvStructInfo;
2236 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2237 sizeof(CERT_PUBLIC_KEY_INFO);
2238 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2239 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2240 &bytesNeeded, NULL);
2246 SetLastError(STATUS_ACCESS_VIOLATION);
2253 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2254 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2260 SetLastError(CRYPT_E_ASN1_CORRUPT);
2263 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2265 SetLastError(CRYPT_E_ASN1_CORRUPT);
2268 if (pbEncoded[1] > 1)
2270 SetLastError(CRYPT_E_ASN1_CORRUPT);
2277 *pcbStructInfo = sizeof(BOOL);
2280 else if (*pcbStructInfo < sizeof(BOOL))
2282 *pcbStructInfo = sizeof(BOOL);
2283 SetLastError(ERROR_MORE_DATA);
2288 *pcbStructInfo = sizeof(BOOL);
2289 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2292 TRACE("returning %d (%08x)\n", ret, GetLastError());
2296 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2297 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2299 PCERT_ALT_NAME_ENTRY entry = (PCERT_ALT_NAME_ENTRY)pvStructInfo;
2300 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2303 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2304 pvStructInfo, *pcbStructInfo);
2308 SetLastError(CRYPT_E_ASN1_CORRUPT);
2311 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2312 if (1 + lenBytes > cbEncoded)
2314 SetLastError(CRYPT_E_ASN1_CORRUPT);
2317 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2319 switch (pbEncoded[0] & ASN_TYPE_MASK)
2321 case 1: /* rfc822Name */
2322 case 2: /* dNSName */
2323 case 6: /* uniformResourceIdentifier */
2324 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2326 case 4: /* directoryName */
2327 case 7: /* iPAddress */
2328 bytesNeeded += dataLen;
2330 case 8: /* registeredID */
2331 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2335 /* FIXME: ugly, shouldn't need to know internals of OID decode
2336 * function to use it.
2338 bytesNeeded += dataLen - sizeof(LPSTR);
2341 case 0: /* otherName */
2342 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2343 SetLastError(CRYPT_E_ASN1_BADTAG);
2346 case 3: /* x400Address, unimplemented */
2347 case 5: /* ediPartyName, unimplemented */
2348 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2349 SetLastError(CRYPT_E_ASN1_BADTAG);
2353 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2354 SetLastError(CRYPT_E_ASN1_CORRUPT);
2360 *pcbDecoded = 1 + lenBytes + dataLen;
2362 *pcbStructInfo = bytesNeeded;
2363 else if (*pcbStructInfo < bytesNeeded)
2365 *pcbStructInfo = bytesNeeded;
2366 SetLastError(ERROR_MORE_DATA);
2371 *pcbStructInfo = bytesNeeded;
2372 /* MS used values one greater than the asn1 ones.. sigh */
2373 entry->dwAltNameChoice = (pbEncoded[0] & 0x7f) + 1;
2374 switch (pbEncoded[0] & ASN_TYPE_MASK)
2376 case 1: /* rfc822Name */
2377 case 2: /* dNSName */
2378 case 6: /* uniformResourceIdentifier */
2382 for (i = 0; i < dataLen; i++)
2383 entry->u.pwszURL[i] =
2384 (WCHAR)pbEncoded[1 + lenBytes + i];
2385 entry->u.pwszURL[i] = 0;
2386 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
2387 debugstr_w(entry->u.pwszURL));
2390 case 4: /* directoryName */
2391 entry->dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
2392 /* The data are memory-equivalent with the IPAddress case,
2395 case 7: /* iPAddress */
2396 /* The next data pointer is in the pwszURL spot, that is,
2397 * the first 4 bytes. Need to move it to the next spot.
2399 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
2400 entry->u.IPAddress.cbData = dataLen;
2401 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
2404 case 8: /* registeredID */
2405 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
2406 &entry->u.pszRegisteredID, &dataLen, NULL);
2415 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
2416 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2420 struct AsnArrayDescriptor arrayDesc = { 0,
2421 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
2422 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
2423 PCERT_ALT_NAME_INFO info = (PCERT_ALT_NAME_INFO)pvStructInfo;
2425 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2426 pvStructInfo, *pcbStructInfo, pcbDecoded);
2429 TRACE("info->rgAltEntry is %p\n", info->rgAltEntry);
2430 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2431 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2432 info ? info->rgAltEntry : NULL);
2436 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2437 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
2438 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2443 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
2444 pvStructInfo, *pcbStructInfo, pcbDecoded);
2446 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2449 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
2450 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
2452 if (ret && pvStructInfo)
2454 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2461 for (i = 0; i < blob->cbData / 2; i++)
2463 temp = blob->pbData[i];
2464 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
2465 blob->pbData[blob->cbData - i - 1] = temp;
2469 TRACE("returning %d (%08x)\n", ret, GetLastError());
2473 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
2474 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2475 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2481 struct AsnDecodeSequenceItem items[] = {
2482 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
2483 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2484 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
2485 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2486 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
2487 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
2488 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
2489 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
2490 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2491 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2492 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
2495 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2496 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2497 pcbStructInfo, NULL, NULL);
2501 SetLastError(STATUS_ACCESS_VIOLATION);
2508 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
2509 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2510 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2516 struct AsnDecodeSequenceItem items[] = {
2517 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
2518 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
2519 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
2520 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
2521 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
2522 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
2523 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2524 AuthorityCertIssuer.rgAltEntry), 0 },
2525 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2526 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
2527 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
2528 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
2529 AuthorityCertSerialNumber.pbData), 0 },
2532 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2533 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2534 pcbStructInfo, NULL, NULL);
2538 SetLastError(STATUS_ACCESS_VIOLATION);
2545 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
2546 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2551 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2552 pvStructInfo, *pcbStructInfo, pcbDecoded);
2554 /* The caller has already checked the tag, no need to check it again.
2555 * Check the outer length is valid:
2557 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
2559 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2562 pbEncoded += 1 + lenBytes;
2563 cbEncoded -= 1 + lenBytes;
2564 if (dataLen == CMSG_INDEFINITE_LENGTH)
2565 cbEncoded -= 2; /* space for 0 TLV */
2566 /* Check the inner length is valid: */
2567 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
2571 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
2572 pvStructInfo, pcbStructInfo, &decodedLen);
2573 if (dataLen == CMSG_INDEFINITE_LENGTH)
2575 if (*(pbEncoded + decodedLen) != 0 ||
2576 *(pbEncoded + decodedLen + 1) != 0)
2578 TRACE("expected 0 TLV, got {%02x,%02x}\n",
2579 *(pbEncoded + decodedLen),
2580 *(pbEncoded + decodedLen + 1));
2581 SetLastError(CRYPT_E_ASN1_CORRUPT);
2587 if (ret && pcbDecoded)
2589 *pcbDecoded = 1 + lenBytes + decodedLen;
2590 TRACE("decoded %d bytes\n", *pcbDecoded);
2597 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
2598 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2601 CRYPT_CONTENT_INFO *info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2602 struct AsnDecodeSequenceItem items[] = {
2603 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
2604 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2605 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
2606 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
2607 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
2608 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
2609 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
2613 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2614 pvStructInfo, *pcbStructInfo, pcbDecoded);
2616 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2617 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2618 pcbDecoded, info ? info->pszObjId : NULL);
2622 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
2623 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2624 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2628 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2629 pDecodePara, pvStructInfo, *pcbStructInfo);
2633 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
2634 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
2635 if (ret && pvStructInfo)
2637 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
2638 pcbStructInfo, *pcbStructInfo);
2641 CRYPT_CONTENT_INFO *info;
2643 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2644 pvStructInfo = *(BYTE **)pvStructInfo;
2645 info = (CRYPT_CONTENT_INFO *)pvStructInfo;
2646 info->pszObjId = (LPSTR)((BYTE *)info +
2647 sizeof(CRYPT_CONTENT_INFO));
2648 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
2649 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2650 pcbStructInfo, NULL);
2656 SetLastError(STATUS_ACCESS_VIOLATION);
2662 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
2663 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2664 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
2667 struct AsnDecodeSequenceItem items[] = {
2668 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
2669 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2670 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
2671 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2672 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
2674 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
2675 CRYPT_AsnDecodePKCSContentInfoInternal,
2676 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
2677 ContentInfo.pszObjId), 0 },
2678 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
2679 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
2680 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
2683 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2684 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
2689 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
2690 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2691 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2695 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2696 pDecodePara, pvStructInfo, *pcbStructInfo);
2702 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2703 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2706 *pcbStructInfo = bytesNeeded;
2707 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2708 pvStructInfo, pcbStructInfo, bytesNeeded)))
2710 CERT_ALT_NAME_INFO *name;
2712 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2713 pvStructInfo = *(BYTE **)pvStructInfo;
2714 name = (CERT_ALT_NAME_INFO *)pvStructInfo;
2715 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
2716 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
2717 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
2718 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2719 &bytesNeeded, NULL);
2725 SetLastError(STATUS_ACCESS_VIOLATION);
2732 struct PATH_LEN_CONSTRAINT
2734 BOOL fPathLenConstraint;
2735 DWORD dwPathLenConstraint;
2738 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
2739 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2743 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
2745 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2746 pvStructInfo, *pcbStructInfo, pcbDecoded);
2750 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
2752 *pcbStructInfo = bytesNeeded;
2754 else if (*pcbStructInfo < bytesNeeded)
2756 SetLastError(ERROR_MORE_DATA);
2757 *pcbStructInfo = bytesNeeded;
2762 struct PATH_LEN_CONSTRAINT *constraint =
2763 (struct PATH_LEN_CONSTRAINT *)pvStructInfo;
2765 *pcbStructInfo = bytesNeeded;
2766 size = sizeof(constraint->dwPathLenConstraint);
2767 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
2768 &constraint->dwPathLenConstraint, &size, pcbDecoded);
2770 constraint->fPathLenConstraint = TRUE;
2771 TRACE("got an int, dwPathLenConstraint is %d\n",
2772 constraint->dwPathLenConstraint);
2774 TRACE("returning %d (%08x)\n", ret, GetLastError());
2778 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
2779 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2783 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2784 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
2785 offsetof(CERT_NAME_BLOB, pbData) };
2786 struct GenericArray *entries = (struct GenericArray *)pvStructInfo;
2788 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2789 pvStructInfo, *pcbStructInfo, pcbDecoded);
2791 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2792 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
2793 entries ? entries->rgItems : NULL);
2794 TRACE("Returning %d (%08x)\n", ret, GetLastError());
2798 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
2799 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2800 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2806 struct AsnDecodeSequenceItem items[] = {
2807 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
2808 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2809 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
2810 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
2811 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
2812 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
2813 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
2814 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
2815 sizeof(struct GenericArray), TRUE, TRUE,
2816 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
2819 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2820 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2821 pcbStructInfo, NULL, NULL);
2825 SetLastError(STATUS_ACCESS_VIOLATION);
2832 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
2833 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2834 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2840 struct AsnDecodeSequenceItem items[] = {
2841 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
2842 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
2843 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
2844 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
2845 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
2848 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2849 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2850 pcbStructInfo, NULL, NULL);
2854 SetLastError(STATUS_ACCESS_VIOLATION);
2861 #define RSA1_MAGIC 0x31415352
2863 struct DECODED_RSA_PUB_KEY
2866 CRYPT_INTEGER_BLOB modulus;
2869 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
2870 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2871 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2877 struct AsnDecodeSequenceItem items[] = {
2878 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
2879 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2880 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
2882 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
2883 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
2885 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
2888 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2889 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
2893 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2894 decodedKey->modulus.cbData;
2898 *pcbStructInfo = bytesNeeded;
2901 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2902 pvStructInfo, pcbStructInfo, bytesNeeded)))
2905 RSAPUBKEY *rsaPubKey;
2907 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2908 pvStructInfo = *(BYTE **)pvStructInfo;
2909 hdr = (BLOBHEADER *)pvStructInfo;
2910 hdr->bType = PUBLICKEYBLOB;
2911 hdr->bVersion = CUR_BLOB_VERSION;
2913 hdr->aiKeyAlg = CALG_RSA_KEYX;
2914 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
2915 sizeof(BLOBHEADER));
2916 rsaPubKey->magic = RSA1_MAGIC;
2917 rsaPubKey->pubexp = decodedKey->pubexp;
2918 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
2919 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
2920 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
2921 decodedKey->modulus.cbData);
2923 LocalFree(decodedKey);
2928 SetLastError(STATUS_ACCESS_VIOLATION);
2935 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
2936 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2940 DWORD bytesNeeded, dataLen;
2942 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2943 pvStructInfo, *pcbStructInfo, pcbDecoded);
2945 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2947 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2949 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2950 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
2952 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
2954 *pcbDecoded = 1 + lenBytes + dataLen;
2956 *pcbStructInfo = bytesNeeded;
2957 else if (*pcbStructInfo < bytesNeeded)
2959 SetLastError(ERROR_MORE_DATA);
2960 *pcbStructInfo = bytesNeeded;
2965 CRYPT_DATA_BLOB *blob;
2967 *pcbStructInfo = bytesNeeded;
2968 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
2969 blob->cbData = dataLen;
2970 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2971 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
2974 assert(blob->pbData);
2976 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
2984 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
2985 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2986 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2990 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2991 pDecodePara, pvStructInfo, *pcbStructInfo);
2999 SetLastError(CRYPT_E_ASN1_CORRUPT);
3002 else if (pbEncoded[0] != ASN_OCTETSTRING)
3004 SetLastError(CRYPT_E_ASN1_BADTAG);
3007 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3008 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3011 *pcbStructInfo = bytesNeeded;
3012 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3013 pvStructInfo, pcbStructInfo, bytesNeeded)))
3015 CRYPT_DATA_BLOB *blob;
3017 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3018 pvStructInfo = *(BYTE **)pvStructInfo;
3019 blob = (CRYPT_DATA_BLOB *)pvStructInfo;
3020 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3021 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3022 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3023 &bytesNeeded, NULL);
3029 SetLastError(STATUS_ACCESS_VIOLATION);
3036 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3037 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3041 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3042 pvStructInfo, *pcbStructInfo, pcbDecoded);
3044 if (pbEncoded[0] == ASN_BITSTRING)
3046 DWORD bytesNeeded, dataLen;
3047 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3049 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3051 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3052 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
3054 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
3056 *pcbDecoded = 1 + lenBytes + dataLen;
3058 *pcbStructInfo = bytesNeeded;
3059 else if (*pcbStructInfo < bytesNeeded)
3061 *pcbStructInfo = bytesNeeded;
3062 SetLastError(ERROR_MORE_DATA);
3067 CRYPT_BIT_BLOB *blob;
3069 *pcbStructInfo = bytesNeeded;
3070 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3071 blob->cbData = dataLen - 1;
3072 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
3073 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3075 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
3079 assert(blob->pbData);
3082 BYTE mask = 0xff << blob->cUnusedBits;
3084 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
3086 blob->pbData[blob->cbData - 1] &= mask;
3094 SetLastError(CRYPT_E_ASN1_BADTAG);
3097 TRACE("returning %d (%08x)\n", ret, GetLastError());
3101 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
3102 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3103 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3107 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
3108 pDecodePara, pvStructInfo, pcbStructInfo);
3114 if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3115 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3118 *pcbStructInfo = bytesNeeded;
3119 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3120 pvStructInfo, pcbStructInfo, bytesNeeded)))
3122 CRYPT_BIT_BLOB *blob;
3124 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3125 pvStructInfo = *(BYTE **)pvStructInfo;
3126 blob = (CRYPT_BIT_BLOB *)pvStructInfo;
3127 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
3128 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3129 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3130 &bytesNeeded, NULL);
3136 SetLastError(STATUS_ACCESS_VIOLATION);
3140 TRACE("returning %d (%08x)\n", ret, GetLastError());
3144 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3145 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3146 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3149 BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
3150 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
3151 DWORD size = sizeof(buf);
3153 blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
3154 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, buf,
3159 *pcbStructInfo = sizeof(int);
3160 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
3164 if (blob->pbData[blob->cbData - 1] & 0x80)
3166 /* initialize to a negative value to sign-extend */
3171 for (i = 0; i < blob->cbData; i++)
3174 val |= blob->pbData[blob->cbData - i - 1];
3176 memcpy(pvStructInfo, &val, sizeof(int));
3179 else if (GetLastError() == ERROR_MORE_DATA)
3180 SetLastError(CRYPT_E_ASN1_LARGE);
3184 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
3185 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3186 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3196 SetLastError(CRYPT_E_ASN1_CORRUPT);
3199 else if (pbEncoded[0] != ASN_INTEGER)
3201 SetLastError(CRYPT_E_ASN1_BADTAG);
3205 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3206 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3210 *pcbStructInfo = bytesNeeded;
3211 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3212 pvStructInfo, pcbStructInfo, bytesNeeded)))
3214 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3215 pvStructInfo = *(BYTE **)pvStructInfo;
3216 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3217 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3218 &bytesNeeded, NULL);
3224 SetLastError(STATUS_ACCESS_VIOLATION);
3231 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
3232 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3236 DWORD bytesNeeded, dataLen;
3238 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3240 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3242 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3244 *pcbDecoded = 1 + lenBytes + dataLen;
3246 *pcbStructInfo = bytesNeeded;
3247 else if (*pcbStructInfo < bytesNeeded)
3249 *pcbStructInfo = bytesNeeded;
3250 SetLastError(ERROR_MORE_DATA);
3255 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3257 *pcbStructInfo = bytesNeeded;
3258 blob->cbData = dataLen;
3259 assert(blob->pbData);
3264 for (i = 0; i < blob->cbData; i++)
3266 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3275 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
3276 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3277 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3285 if (pbEncoded[0] != ASN_INTEGER)
3287 SetLastError(CRYPT_E_ASN1_BADTAG);
3291 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3292 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3296 *pcbStructInfo = bytesNeeded;
3297 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3298 pvStructInfo, pcbStructInfo, bytesNeeded)))
3300 CRYPT_INTEGER_BLOB *blob;
3302 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3303 pvStructInfo = *(BYTE **)pvStructInfo;
3304 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3305 blob->pbData = (BYTE *)pvStructInfo +
3306 sizeof(CRYPT_INTEGER_BLOB);
3307 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3308 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
3309 &bytesNeeded, NULL);
3315 SetLastError(STATUS_ACCESS_VIOLATION);
3322 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
3323 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3328 if (pbEncoded[0] == ASN_INTEGER)
3330 DWORD bytesNeeded, dataLen;
3332 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3334 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3337 *pcbDecoded = 1 + lenBytes + dataLen;
3338 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
3340 *pcbStructInfo = bytesNeeded;
3341 else if (*pcbStructInfo < bytesNeeded)
3343 *pcbStructInfo = bytesNeeded;
3344 SetLastError(ERROR_MORE_DATA);
3349 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3351 *pcbStructInfo = bytesNeeded;
3352 blob->cbData = dataLen;
3353 assert(blob->pbData);
3354 /* remove leading zero byte if it exists */
3355 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
3364 for (i = 0; i < blob->cbData; i++)
3366 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
3375 SetLastError(CRYPT_E_ASN1_BADTAG);
3381 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
3382 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3383 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3391 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
3392 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3395 *pcbStructInfo = bytesNeeded;
3396 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3397 pvStructInfo, pcbStructInfo, bytesNeeded)))
3399 CRYPT_INTEGER_BLOB *blob;
3401 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3402 pvStructInfo = *(BYTE **)pvStructInfo;
3403 blob = (CRYPT_INTEGER_BLOB *)pvStructInfo;
3404 blob->pbData = (BYTE *)pvStructInfo +
3405 sizeof(CRYPT_INTEGER_BLOB);
3406 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
3407 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
3408 &bytesNeeded, NULL);
3414 SetLastError(STATUS_ACCESS_VIOLATION);
3421 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
3422 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3423 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3429 *pcbStructInfo = sizeof(int);
3434 if (pbEncoded[0] == ASN_ENUMERATED)
3436 unsigned int val = 0, i;
3440 SetLastError(CRYPT_E_ASN1_EOD);
3443 else if (pbEncoded[1] == 0)
3445 SetLastError(CRYPT_E_ASN1_CORRUPT);
3450 /* A little strange looking, but we have to accept a sign byte:
3451 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3452 * assuming a small length is okay here, it has to be in short
3455 if (pbEncoded[1] > sizeof(unsigned int) + 1)
3457 SetLastError(CRYPT_E_ASN1_LARGE);
3460 for (i = 0; i < pbEncoded[1]; i++)
3463 val |= pbEncoded[2 + i];
3465 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3466 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
3468 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3469 pvStructInfo = *(BYTE **)pvStructInfo;
3470 memcpy(pvStructInfo, &val, sizeof(unsigned int));
3476 SetLastError(CRYPT_E_ASN1_BADTAG);
3482 SetLastError(STATUS_ACCESS_VIOLATION);
3489 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3492 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3497 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3499 if (!isdigit(*(pbEncoded))) \
3501 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3507 (word) += *(pbEncoded)++ - '0'; \
3512 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
3513 SYSTEMTIME *sysTime)
3517 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
3519 WORD hours, minutes = 0;
3520 BYTE sign = *pbEncoded++;
3523 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
3524 if (ret && hours >= 24)
3526 SetLastError(CRYPT_E_ASN1_CORRUPT);
3531 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
3532 if (ret && minutes >= 60)
3534 SetLastError(CRYPT_E_ASN1_CORRUPT);
3542 sysTime->wHour += hours;
3543 sysTime->wMinute += minutes;
3547 if (hours > sysTime->wHour)
3550 sysTime->wHour = 24 - (hours - sysTime->wHour);
3553 sysTime->wHour -= hours;
3554 if (minutes > sysTime->wMinute)
3557 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
3560 sysTime->wMinute -= minutes;
3567 #define MIN_ENCODED_TIME_LENGTH 10
3569 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
3570 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3575 if (pbEncoded[0] == ASN_UTCTIME)
3578 SetLastError(CRYPT_E_ASN1_EOD);
3579 else if (pbEncoded[1] > 0x7f)
3581 /* long-form date strings really can't be valid */
3582 SetLastError(CRYPT_E_ASN1_CORRUPT);
3586 SYSTEMTIME sysTime = { 0 };
3587 BYTE len = pbEncoded[1];
3589 if (len < MIN_ENCODED_TIME_LENGTH)
3590 SetLastError(CRYPT_E_ASN1_CORRUPT);
3595 *pcbDecoded = 2 + len;
3597 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
3598 if (sysTime.wYear >= 50)
3599 sysTime.wYear += 1900;
3601 sysTime.wYear += 2000;
3602 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
3603 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
3604 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
3605 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
3608 if (len >= 2 && isdigit(*pbEncoded) &&
3609 isdigit(*(pbEncoded + 1)))
3610 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3612 else if (isdigit(*pbEncoded))
3613 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
3616 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
3622 *pcbStructInfo = sizeof(FILETIME);
3623 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
3625 ret = SystemTimeToFileTime(&sysTime,
3626 (FILETIME *)pvStructInfo);
3632 SetLastError(CRYPT_E_ASN1_BADTAG);
3636 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
3637 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3638 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3646 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
3647 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3651 *pcbStructInfo = bytesNeeded;
3652 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
3653 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
3655 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3656 pvStructInfo = *(BYTE **)pvStructInfo;
3657 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
3658 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3659 &bytesNeeded, NULL);
3665 SetLastError(STATUS_ACCESS_VIOLATION);
3671 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
3672 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3677 if (pbEncoded[0] == ASN_GENERALTIME)
3680 SetLastError(CRYPT_E_ASN1_EOD);
3681 else if (pbEncoded[1] > 0x7f)
3683 /* long-form date strings really can't be valid */
3684 SetLastError(CRYPT_E_ASN1_CORRUPT);
3688 BYTE len = pbEncoded[1];
3690 if (len < MIN_ENCODED_TIME_LENGTH)
3691 SetLastError(CRYPT_E_ASN1_CORRUPT);
3694 SYSTEMTIME sysTime = { 0 };
3698 *pcbDecoded = 2 + len;
3700 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
3701 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
3702 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
3703 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
3706 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3709 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
3711 if (ret && len > 0 && (*pbEncoded == '.' ||
3718 /* workaround macro weirdness */
3719 digits = min(len, 3);
3720 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
3721 sysTime.wMilliseconds);
3724 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
3730 *pcbStructInfo = sizeof(FILETIME);
3731 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
3733 ret = SystemTimeToFileTime(&sysTime,
3734 (FILETIME *)pvStructInfo);
3740 SetLastError(CRYPT_E_ASN1_BADTAG);
3744 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
3745 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3749 InternalDecodeFunc decode = NULL;
3751 if (pbEncoded[0] == ASN_UTCTIME)
3752 decode = CRYPT_AsnDecodeUtcTimeInternal;
3753 else if (pbEncoded[0] == ASN_GENERALTIME)
3754 decode = CRYPT_AsnDecodeGeneralizedTime;
3756 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
3757 pcbStructInfo, pcbDecoded);
3760 SetLastError(CRYPT_E_ASN1_BADTAG);
3766 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
3767 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3768 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3776 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
3777 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3781 *pcbStructInfo = bytesNeeded;
3782 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3783 pvStructInfo, pcbStructInfo, bytesNeeded)))
3785 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3786 pvStructInfo = *(BYTE **)pvStructInfo;
3787 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
3788 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3789 &bytesNeeded, NULL);
3795 SetLastError(STATUS_ACCESS_VIOLATION);
3802 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
3803 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3804 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3810 if (pbEncoded[0] == ASN_SEQUENCEOF)
3812 DWORD bytesNeeded, dataLen, remainingLen, cValue;
3814 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3819 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3820 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
3822 ptr = pbEncoded + 1 + lenBytes;
3823 remainingLen = dataLen;
3824 while (ret && remainingLen)
3828 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
3831 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
3833 remainingLen -= 1 + nextLenBytes + nextLen;
3834 ptr += 1 + nextLenBytes + nextLen;
3835 bytesNeeded += sizeof(CRYPT_DER_BLOB);
3836 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
3837 bytesNeeded += 1 + nextLenBytes + nextLen;
3843 CRYPT_SEQUENCE_OF_ANY *seq;
3847 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3848 pvStructInfo, pcbStructInfo, bytesNeeded)))
3850 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3851 pvStructInfo = *(BYTE **)pvStructInfo;
3852 seq = (CRYPT_SEQUENCE_OF_ANY *)pvStructInfo;
3853 seq->cValue = cValue;
3854 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
3856 nextPtr = (BYTE *)seq->rgValue +
3857 cValue * sizeof(CRYPT_DER_BLOB);
3858 ptr = pbEncoded + 1 + lenBytes;
3859 remainingLen = dataLen;
3861 while (ret && remainingLen)
3865 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
3868 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
3870 seq->rgValue[i].cbData = 1 + nextLenBytes +
3872 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3873 seq->rgValue[i].pbData = (BYTE *)ptr;
3876 seq->rgValue[i].pbData = nextPtr;
3877 memcpy(nextPtr, ptr, 1 + nextLenBytes +
3879 nextPtr += 1 + nextLenBytes + nextLen;
3881 remainingLen -= 1 + nextLenBytes + nextLen;
3882 ptr += 1 + nextLenBytes + nextLen;
3892 SetLastError(CRYPT_E_ASN1_BADTAG);
3898 SetLastError(STATUS_ACCESS_VIOLATION);
3905 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
3906 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3911 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
3913 DWORD bytesNeeded, dataLen;
3915 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3917 struct AsnArrayDescriptor arrayDesc = {
3918 ASN_CONTEXT | ASN_CONSTRUCTOR | 0, CRYPT_AsnDecodeAltNameEntry,
3919 sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3920 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3921 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3926 ret = CRYPT_AsnDecodeArray(&arrayDesc,
3927 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
3928 0, NULL, NULL, &nameLen, NULL, NULL);
3929 /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray
3930 * as the sizeof(struct GenericArray), so don't include it in the
3931 * total bytes needed.
3933 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
3934 sizeof(CERT_ALT_NAME_INFO);
3937 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
3939 *pcbDecoded = 1 + lenBytes + dataLen;
3941 *pcbStructInfo = bytesNeeded;
3942 else if (*pcbStructInfo < bytesNeeded)
3944 *pcbStructInfo = bytesNeeded;
3945 SetLastError(ERROR_MORE_DATA);
3950 CRL_DIST_POINT_NAME *name = (CRL_DIST_POINT_NAME *)pvStructInfo;
3952 *pcbStructInfo = bytesNeeded;
3955 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3956 ret = CRYPT_AsnDecodeArray(&arrayDesc,
3957 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
3958 0, NULL, &name->u.FullName, &nameLen, NULL,
3959 name->u.FullName.rgAltEntry);
3962 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3968 SetLastError(CRYPT_E_ASN1_BADTAG);
3974 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
3975 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3977 struct AsnDecodeSequenceItem items[] = {
3978 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
3979 DistPointName), CRYPT_AsnDecodeDistPointName,
3980 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
3981 DistPointName.u.FullName.rgAltEntry), 0 },
3982 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
3983 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
3984 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
3985 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
3986 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
3987 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
3991 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3992 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3997 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
3998 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3999 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4003 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4004 pDecodePara, pvStructInfo, *pcbStructInfo);
4008 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4009 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
4010 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
4012 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4013 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4017 SetLastError(STATUS_ACCESS_VIOLATION);
4024 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
4025 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4026 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4030 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4031 pDecodePara, pvStructInfo, *pcbStructInfo);
4035 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4036 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
4038 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4039 pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
4043 SetLastError(STATUS_ACCESS_VIOLATION);
4050 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
4051 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4052 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4056 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4057 pDecodePara, pvStructInfo, *pcbStructInfo);
4061 struct AsnDecodeSequenceItem items[] = {
4062 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
4063 DistPointName), CRYPT_AsnDecodeDistPointName,
4064 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
4065 offsetof(CRL_ISSUING_DIST_POINT,
4066 DistPointName.u.FullName.rgAltEntry), 0 },
4067 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
4068 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4070 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
4071 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4073 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
4074 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
4075 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
4076 OnlySomeReasonFlags.pbData), 0 },
4077 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
4078 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
4081 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4082 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4083 pcbStructInfo, NULL, NULL);
4087 SetLastError(STATUS_ACCESS_VIOLATION);
4094 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
4095 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4100 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4101 pvStructInfo, *pcbStructInfo, pcbDecoded);
4105 SetLastError(CRYPT_E_ASN1_EOD);
4108 if (pbEncoded[0] != (ASN_CONTEXT | 1))
4110 SetLastError(CRYPT_E_ASN1_BADTAG);
4113 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4114 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
4115 pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
4117 if (ret && pvStructInfo)
4118 *(BOOL *)pvStructInfo = TRUE;
4119 TRACE("returning %d\n", ret);
4123 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
4124 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4128 struct AsnDecodeSequenceItem items[] = {
4129 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
4130 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
4131 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
4132 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
4133 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
4134 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
4135 CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
4138 CERT_GENERAL_SUBTREE *subtree = (CERT_GENERAL_SUBTREE *)pvStructInfo;
4140 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4141 pvStructInfo, *pcbStructInfo, pcbDecoded);
4143 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4144 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4145 pcbDecoded, subtree ? (BYTE *)subtree->Base.u.pwszURL : NULL);
4148 TRACE("%d\n", *pcbDecoded);
4149 if (*pcbDecoded < cbEncoded)
4150 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
4151 *(pbEncoded + *pcbDecoded + 1));
4153 TRACE("returning %d\n", ret);
4157 static BOOL CRYPT_AsnDecodeSubtreeArray(const BYTE *pbEncoded,
4158 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4162 struct AsnArrayDescriptor arrayDesc = { 0,
4163 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
4164 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
4165 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
4167 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4168 pvStructInfo, *pcbStructInfo, pcbDecoded);
4170 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4171 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4172 array ? array->rgItems : NULL);
4177 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
4178 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4179 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4183 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4184 pDecodePara, pvStructInfo, *pcbStructInfo);
4188 struct AsnDecodeSequenceItem items[] = {
4189 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4190 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
4191 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4192 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
4193 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
4194 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4195 CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE,
4196 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
4199 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4200 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4201 pcbStructInfo, NULL, NULL);
4205 SetLastError(STATUS_ACCESS_VIOLATION);
4211 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
4212 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4216 struct AsnDecodeSequenceItem items[] = {
4217 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
4218 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
4220 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
4221 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
4222 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
4224 CERT_ISSUER_SERIAL_NUMBER *issuerSerial =
4225 (CERT_ISSUER_SERIAL_NUMBER *)pvStructInfo;
4227 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4228 pvStructInfo, *pcbStructInfo, pcbDecoded);
4230 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4231 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4232 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
4233 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
4235 SetLastError(CRYPT_E_ASN1_CORRUPT);
4238 TRACE("returning %d\n", ret);
4242 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
4243 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4246 CMSG_SIGNER_INFO *info = (CMSG_SIGNER_INFO *)pvStructInfo;
4247 struct AsnDecodeSequenceItem items[] = {
4248 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
4249 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4250 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
4251 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
4252 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
4253 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
4254 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4255 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
4256 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4257 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
4258 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4259 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
4260 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
4261 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4262 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
4263 HashEncryptionAlgorithm.pszObjId), 0 },
4264 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
4265 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
4266 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
4267 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4268 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
4269 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4270 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
4274 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4275 pvStructInfo, *pcbStructInfo);
4277 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4278 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4279 pcbDecoded, info ? info->Issuer.pbData : NULL);
4283 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
4284 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4285 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4289 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4290 pDecodePara, pvStructInfo, *pcbStructInfo);
4294 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
4295 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
4296 if (ret && pvStructInfo)
4298 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
4299 pcbStructInfo, *pcbStructInfo);
4302 CMSG_SIGNER_INFO *info;
4304 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4305 pvStructInfo = *(BYTE **)pvStructInfo;
4306 info = (CMSG_SIGNER_INFO *)pvStructInfo;
4307 info->Issuer.pbData = ((BYTE *)info +
4308 sizeof(CMSG_SIGNER_INFO));
4309 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
4310 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4311 pcbStructInfo, NULL);
4317 SetLastError(STATUS_ACCESS_VIOLATION);
4320 TRACE("returning %d\n", ret);
4324 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
4325 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4328 CERT_ID *id = (CERT_ID *)pvStructInfo;
4331 if (*pbEncoded == ASN_SEQUENCEOF)
4333 ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
4334 id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
4338 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
4339 if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
4340 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
4341 sizeof(CERT_ISSUER_SERIAL_NUMBER);
4343 *pcbStructInfo = sizeof(CERT_ID);
4346 else if (*pbEncoded == (ASN_CONTEXT | 0))
4348 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
4349 id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
4353 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
4354 if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
4355 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
4356 sizeof(CRYPT_DATA_BLOB);
4358 *pcbStructInfo = sizeof(CERT_ID);
4362 SetLastError(CRYPT_E_ASN1_BADTAG);
4366 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
4367 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4370 CMSG_CMS_SIGNER_INFO *info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
4371 struct AsnDecodeSequenceItem items[] = {
4372 { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
4373 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4374 { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
4375 CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
4376 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
4377 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
4378 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4379 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
4380 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4381 offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
4382 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4383 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
4384 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
4385 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
4386 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
4387 HashEncryptionAlgorithm.pszObjId), 0 },
4388 { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
4389 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
4390 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
4391 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4392 offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
4393 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
4394 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
4398 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4399 pvStructInfo, *pcbStructInfo);
4401 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4402 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4403 pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
4407 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
4408 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4409 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4413 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4414 pDecodePara, pvStructInfo, *pcbStructInfo);
4418 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
4419 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
4420 if (ret && pvStructInfo)
4422 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
4423 pcbStructInfo, *pcbStructInfo);
4426 CMSG_CMS_SIGNER_INFO *info;
4428 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4429 pvStructInfo = *(BYTE **)pvStructInfo;
4430 info = (CMSG_CMS_SIGNER_INFO *)pvStructInfo;
4431 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
4432 sizeof(CMSG_CMS_SIGNER_INFO));
4433 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
4434 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4435 pcbStructInfo, NULL);
4441 SetLastError(STATUS_ACCESS_VIOLATION);
4444 TRACE("returning %d\n", ret);
4448 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
4449 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4452 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
4453 CRYPT_AsnDecodePKCSSignerInfoInternal, sizeof(CMSG_SIGNER_INFO), TRUE,
4454 offsetof(CMSG_SIGNER_INFO, Issuer.pbData) };
4455 struct GenericArray *array = (struct GenericArray *)pvStructInfo;
4457 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4458 pvStructInfo, *pcbStructInfo, pcbDecoded);
4460 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
4461 NULL, pvStructInfo, pcbStructInfo, pcbDecoded,
4462 array ? array->rgItems : NULL);
4466 BOOL CRYPT_AsnDecodePKCSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
4467 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
4468 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
4471 struct AsnDecodeSequenceItem items[] = {
4472 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
4473 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
4474 /* Placeholder for the hash algorithms - redundant with those in the
4475 * signers, so just ignore them.
4477 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
4478 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
4479 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
4480 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
4481 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
4482 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
4483 CRYPT_DecodeDERArray, sizeof(struct GenericArray), TRUE, TRUE,
4484 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
4485 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
4486 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_DecodeDERArray,
4487 sizeof(struct GenericArray), TRUE, TRUE,
4488 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
4489 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
4490 CRYPT_DecodeSignerArray, sizeof(struct GenericArray), TRUE, TRUE,
4491 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
4494 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4495 pDecodePara, signedInfo, *pcbSignedInfo);
4497 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4498 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
4500 TRACE("returning %d\n", ret);
4504 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
4505 LPCSTR lpszStructType)
4507 CryptDecodeObjectExFunc decodeFunc = NULL;
4509 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
4510 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
4512 SetLastError(ERROR_FILE_NOT_FOUND);
4515 if (!HIWORD(lpszStructType))
4517 switch (LOWORD(lpszStructType))
4519 case LOWORD(X509_CERT):
4520 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
4522 case LOWORD(X509_CERT_TO_BE_SIGNED):
4523 decodeFunc = CRYPT_AsnDecodeCert;
4525 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
4526 decodeFunc = CRYPT_AsnDecodeCRL;
4528 case LOWORD(X509_EXTENSIONS):
4529 decodeFunc = CRYPT_AsnDecodeExtensions;
4531 case LOWORD(X509_NAME_VALUE):
4532 decodeFunc = CRYPT_AsnDecodeNameValue;
4534 case LOWORD(X509_NAME):
4535 decodeFunc = CRYPT_AsnDecodeName;
4537 case LOWORD(X509_PUBLIC_KEY_INFO):
4538 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
4540 case LOWORD(X509_AUTHORITY_KEY_ID):
4541 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
4543 case LOWORD(X509_ALTERNATE_NAME):
4544 decodeFunc = CRYPT_AsnDecodeAltName;
4546 case LOWORD(X509_BASIC_CONSTRAINTS):
4547 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
4549 case LOWORD(X509_BASIC_CONSTRAINTS2):
4550 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
4552 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
4553 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
4555 case LOWORD(X509_UNICODE_NAME):
4556 decodeFunc = CRYPT_AsnDecodeUnicodeName;
4558 case LOWORD(PKCS_ATTRIBUTE):
4559 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
4561 case LOWORD(X509_UNICODE_NAME_VALUE):
4562 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
4564 case LOWORD(X509_OCTET_STRING):
4565 decodeFunc = CRYPT_AsnDecodeOctets;
4567 case LOWORD(X509_BITS):
4568 case LOWORD(X509_KEY_USAGE):
4569 decodeFunc = CRYPT_AsnDecodeBits;
4571 case LOWORD(X509_INTEGER):
4572 decodeFunc = CRYPT_AsnDecodeInt;
4574 case LOWORD(X509_MULTI_BYTE_INTEGER):
4575 decodeFunc = CRYPT_AsnDecodeInteger;
4577 case LOWORD(X509_MULTI_BYTE_UINT):
4578 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
4580 case LOWORD(X509_ENUMERATED):
4581 decodeFunc = CRYPT_AsnDecodeEnumerated;
4583 case LOWORD(X509_CHOICE_OF_TIME):
4584 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
4586 case LOWORD(X509_AUTHORITY_KEY_ID2):
4587 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
4589 case LOWORD(PKCS_CONTENT_INFO):
4590 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
4592 case LOWORD(X509_SEQUENCE_OF_ANY):
4593 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
4595 case LOWORD(PKCS_UTC_TIME):
4596 decodeFunc = CRYPT_AsnDecodeUtcTime;
4598 case LOWORD(X509_CRL_DIST_POINTS):
4599 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
4601 case LOWORD(X509_ENHANCED_KEY_USAGE):
4602 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
4604 case LOWORD(PKCS_ATTRIBUTES):
4605 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
4607 case LOWORD(X509_ISSUING_DIST_POINT):
4608 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
4610 case LOWORD(X509_NAME_CONSTRAINTS):
4611 decodeFunc = CRYPT_AsnDecodeNameConstraints;
4613 case LOWORD(PKCS7_SIGNER_INFO):
4614 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
4616 case LOWORD(CMS_SIGNER_INFO):
4617 decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
4621 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
4622 decodeFunc = CRYPT_AsnDecodeExtensions;
4623 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
4624 decodeFunc = CRYPT_AsnDecodeUtcTime;
4625 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
4626 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
4627 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
4628 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
4629 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
4630 decodeFunc = CRYPT_AsnDecodeEnumerated;
4631 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
4632 decodeFunc = CRYPT_AsnDecodeBits;
4633 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
4634 decodeFunc = CRYPT_AsnDecodeOctets;
4635 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
4636 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
4637 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
4638 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
4639 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
4640 decodeFunc = CRYPT_AsnDecodeAltName;
4641 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
4642 decodeFunc = CRYPT_AsnDecodeAltName;
4643 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
4644 decodeFunc = CRYPT_AsnDecodeAltName;
4645 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
4646 decodeFunc = CRYPT_AsnDecodeAltName;
4647 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
4648 decodeFunc = CRYPT_AsnDecodeAltName;
4649 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
4650 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
4651 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
4652 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
4653 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
4654 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
4655 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
4656 decodeFunc = CRYPT_AsnDecodeNameConstraints;
4660 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
4661 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
4663 static HCRYPTOIDFUNCSET set = NULL;
4664 CryptDecodeObjectFunc decodeFunc = NULL;
4667 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
4668 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
4669 (void **)&decodeFunc, hFunc);
4673 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
4674 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
4676 static HCRYPTOIDFUNCSET set = NULL;
4677 CryptDecodeObjectExFunc decodeFunc = NULL;
4680 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
4681 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
4682 (void **)&decodeFunc, hFunc);
4686 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
4687 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
4688 DWORD *pcbStructInfo)
4691 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
4692 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
4693 HCRYPTOIDFUNCADDR hFunc = NULL;
4695 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
4696 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
4697 pvStructInfo, pcbStructInfo);
4699 if (!pvStructInfo && !pcbStructInfo)
4701 SetLastError(ERROR_INVALID_PARAMETER);
4706 SetLastError(CRYPT_E_ASN1_EOD);
4709 if (cbEncoded > MAX_ENCODED_LEN)
4711 SetLastError(CRYPT_E_ASN1_LARGE);
4715 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
4718 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
4719 debugstr_a(lpszStructType));
4720 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
4721 lpszStructType, &hFunc);
4722 if (!pCryptDecodeObject)
4723 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
4724 lpszStructType, &hFunc);
4726 if (pCryptDecodeObject)
4727 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4728 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
4729 else if (pCryptDecodeObjectEx)
4730 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
4731 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
4732 pvStructInfo, pcbStructInfo);
4734 CryptFreeOIDFunctionAddress(hFunc, 0);
4735 TRACE_(crypt)("returning %d\n", ret);
4739 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
4740 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4741 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4744 CryptDecodeObjectExFunc decodeFunc;
4745 HCRYPTOIDFUNCADDR hFunc = NULL;
4747 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
4748 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
4749 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
4751 if (!pvStructInfo && !pcbStructInfo)
4753 SetLastError(ERROR_INVALID_PARAMETER);
4758 SetLastError(CRYPT_E_ASN1_EOD);
4761 if (cbEncoded > MAX_ENCODED_LEN)
4763 SetLastError(CRYPT_E_ASN1_LARGE);
4767 SetLastError(NOERROR);
4768 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
4769 *(BYTE **)pvStructInfo = NULL;
4770 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
4773 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
4774 debugstr_a(lpszStructType));
4775 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
4779 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
4780 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
4783 CryptDecodeObjectFunc pCryptDecodeObject =
4784 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
4786 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
4787 * directly, as that could cause an infinite loop.
4789 if (pCryptDecodeObject)
4791 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4793 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4794 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
4795 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4796 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
4797 ret = pCryptDecodeObject(dwCertEncodingType,
4798 lpszStructType, pbEncoded, cbEncoded, dwFlags,
4799 *(BYTE **)pvStructInfo, pcbStructInfo);
4802 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
4803 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
4807 CryptFreeOIDFunctionAddress(hFunc, 0);
4808 TRACE_(crypt)("returning %d\n", ret);