2 * Copyright 2005-2009 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);
61 typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *,
62 DWORD, DWORD, void *, DWORD *);
63 typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *,
64 DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *);
66 /* Internal decoders don't do memory allocation or exception handling, and
67 * they report how many bytes they decoded.
69 typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded,
70 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
72 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
73 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
75 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
76 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
78 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
80 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
81 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
82 /* Assumes algo->Parameters.pbData is set ahead of time. */
83 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
84 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
85 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
86 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
87 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
88 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
89 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
91 /* Doesn't check the tag, assumes the caller does so */
92 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
93 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
94 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
95 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded);
96 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
97 * member has been initialized, doesn't do exception handling, and doesn't do
98 * memory allocation. Also doesn't check tag, assumes the caller has checked
101 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
102 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
104 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
105 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
106 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
108 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
109 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
112 /* Gets the number of length bytes from the given (leading) length byte */
113 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
115 /* Helper function to get the encoded length of the data starting at pbEncoded,
116 * where pbEncoded[0] is the tag. If the data are too short to contain a
117 * length or if the length is too large for cbEncoded, sets an appropriate
118 * error code and returns FALSE. If the encoded length is unknown due to
119 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
121 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded,
128 SetLastError(CRYPT_E_ASN1_CORRUPT);
131 else if (pbEncoded[1] <= 0x7f)
133 if (pbEncoded[1] + 1 > cbEncoded)
135 SetLastError(CRYPT_E_ASN1_EOD);
144 else if (pbEncoded[1] == 0x80)
146 *len = CMSG_INDEFINITE_LENGTH;
151 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]);
153 if (lenLen > sizeof(DWORD) + 1)
155 SetLastError(CRYPT_E_ASN1_LARGE);
158 else if (lenLen + 2 > cbEncoded)
160 SetLastError(CRYPT_E_ASN1_CORRUPT);
173 if (out + lenLen + 1 > cbEncoded)
175 SetLastError(CRYPT_E_ASN1_EOD);
188 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
189 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len)
193 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) &&
194 *len == CMSG_INDEFINITE_LENGTH)
196 SetLastError(CRYPT_E_ASN1_CORRUPT);
202 /* Helper function to check *pcbStructInfo, set it to the required size, and
203 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
204 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
205 * pointer to the newly allocated memory.
207 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags,
208 const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
213 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
215 if (pDecodePara && pDecodePara->pfnAlloc)
216 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded);
218 *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded);
219 if (!*(BYTE **)pvStructInfo)
222 *pcbStructInfo = bytesNeeded;
224 else if (*pcbStructInfo < bytesNeeded)
226 *pcbStructInfo = bytesNeeded;
227 SetLastError(ERROR_MORE_DATA);
231 *pcbStructInfo = bytesNeeded;
235 static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA *pDecodePara, LPVOID pv)
237 if (pDecodePara && pDecodePara->pfnFree)
238 pDecodePara->pfnFree(pv);
243 /* Helper function to check *pcbStructInfo and set it to the required size.
244 * Assumes pvStructInfo is not NULL.
246 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded)
250 if (*pcbStructInfo < bytesNeeded)
252 *pcbStructInfo = bytesNeeded;
253 SetLastError(ERROR_MORE_DATA);
258 *pcbStructInfo = bytesNeeded;
265 * The expected tag of the item. If tag is 0, decodeFunc is called
266 * regardless of the tag value seen.
268 * A sequence is decoded into a struct. The offset member is the
269 * offset of this item within that struct.
271 * The decoder function to use. If this is NULL, then the member isn't
272 * decoded, but minSize space is reserved for it.
274 * The minimum amount of space occupied after decoding. You must set this.
276 * If true, and the tag doesn't match the expected tag for this item,
277 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
278 * filled with 0 for this member.
279 * hasPointer, pointerOffset:
280 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
281 * the offset within the struct of the data pointer (or to the
282 * first data pointer, if more than one exist).
284 * Used by CRYPT_AsnDecodeSequence, not for your use.
286 struct AsnDecodeSequenceItem
290 InternalDecodeFunc decodeFunc;
298 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
299 #define MEMBERSIZE(s, member, nextmember) \
300 (offsetof(s, nextmember) - offsetof(s, member))
302 /* Decodes the items in a sequence, where the items are described in items,
303 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
304 * pvStructInfo. nextData is a pointer to the memory location at which the
305 * first decoded item with a dynamic pointer should point.
306 * Upon decoding, *cbDecoded is the total number of bytes decoded.
307 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
309 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[],
310 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
311 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded)
314 DWORD i, decoded = 0;
315 const BYTE *ptr = pbEncoded;
317 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded,
318 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded);
320 for (i = 0, ret = TRUE; ret && i < cItem; i++)
322 if (cbEncoded - (ptr - pbEncoded) != 0)
326 if ((ret = CRYPT_GetLengthIndefinite(ptr,
327 cbEncoded - (ptr - pbEncoded), &itemLen)))
329 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]);
331 if (ptr[0] == items[i].tag || !items[i].tag)
333 DWORD itemEncodedLen;
335 if (itemLen == CMSG_INDEFINITE_LENGTH)
336 itemEncodedLen = cbEncoded - (ptr - pbEncoded);
338 itemEncodedLen = 1 + itemLenBytes + itemLen;
339 if (nextData && pvStructInfo && items[i].hasPointer)
341 TRACE("Setting next pointer to %p\n",
343 *(BYTE **)((BYTE *)pvStructInfo +
344 items[i].pointerOffset) = nextData;
346 if (items[i].decodeFunc)
351 TRACE("decoding item %d\n", i);
353 TRACE("sizing item %d\n", i);
354 ret = items[i].decodeFunc(ptr, itemEncodedLen,
355 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
356 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset
357 : NULL, &items[i].size, &itemDecoded);
360 if (items[i].size < items[i].minSize)
361 items[i].size = items[i].minSize;
362 else if (items[i].size > items[i].minSize)
364 /* Account for alignment padding */
365 items[i].size = ALIGN_DWORD_PTR(items[i].size);
367 TRACE("item %d size: %d\n", i, items[i].size);
368 if (nextData && items[i].hasPointer &&
369 items[i].size > items[i].minSize)
370 nextData += items[i].size - items[i].minSize;
371 if (itemDecoded > itemEncodedLen)
373 WARN("decoded length %d exceeds encoded %d\n",
374 itemDecoded, itemEncodedLen);
375 SetLastError(CRYPT_E_ASN1_CORRUPT);
381 decoded += itemDecoded;
382 TRACE("item %d: decoded %d bytes\n", i,
386 else if (items[i].optional &&
387 GetLastError() == CRYPT_E_ASN1_BADTAG)
389 TRACE("skipping optional item %d\n", i);
390 items[i].size = items[i].minSize;
391 SetLastError(NOERROR);
395 TRACE("item %d failed: %08x\n", i,
398 else if (itemLen == CMSG_INDEFINITE_LENGTH)
400 ERR("can't use indefinite length encoding without a decoder\n");
401 SetLastError(CRYPT_E_ASN1_CORRUPT);
406 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
407 ptr += itemEncodedLen;
408 decoded += itemEncodedLen;
409 items[i].size = items[i].minSize;
412 else if (items[i].optional)
414 TRACE("skipping optional item %d\n", i);
415 items[i].size = items[i].minSize;
419 TRACE("item %d: tag %02x doesn't match expected %02x\n",
420 i, ptr[0], items[i].tag);
421 SetLastError(CRYPT_E_ASN1_BADTAG);
426 else if (items[i].optional)
428 TRACE("missing optional item %d, skipping\n", i);
429 items[i].size = items[i].minSize;
433 TRACE("not enough bytes for item %d, failing\n", i);
434 SetLastError(CRYPT_E_ASN1_CORRUPT);
439 *cbDecoded = decoded;
440 TRACE("returning %d\n", ret);
444 /* This decodes an arbitrary sequence into a contiguous block of memory
445 * (basically, a struct.) Each element being decoded is described by a struct
446 * AsnDecodeSequenceItem, see above.
447 * startingPointer is an optional pointer to the first place where dynamic
448 * data will be stored. If you know the starting offset, you may pass it
449 * here. Otherwise, pass NULL, and one will be inferred from the items.
451 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
452 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
453 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
454 DWORD *pcbDecoded, void *startingPointer)
458 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
459 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
464 SetLastError(CRYPT_E_ASN1_EOD);
467 if (pbEncoded[0] == ASN_SEQUENCE)
471 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
473 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
474 const BYTE *ptr = pbEncoded + 1 + lenBytes;
475 BOOL indefinite = FALSE;
477 cbEncoded -= 1 + lenBytes;
478 if (dataLen == CMSG_INDEFINITE_LENGTH)
483 else if (cbEncoded < dataLen)
485 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
487 SetLastError(CRYPT_E_ASN1_CORRUPT);
492 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
493 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
494 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
496 if (cbDecoded > cbEncoded - 2)
498 /* Not enough space for 0 TLV */
499 SetLastError(CRYPT_E_ASN1_CORRUPT);
502 else if (*(ptr + cbDecoded) != 0 ||
503 *(ptr + cbDecoded + 1) != 0)
505 TRACE("expected 0 TLV\n");
506 SetLastError(CRYPT_E_ASN1_CORRUPT);
513 if (ret && !indefinite && cbDecoded != dataLen)
515 TRACE("expected %d decoded, got %d, failing\n", dataLen,
517 SetLastError(CRYPT_E_ASN1_CORRUPT);
522 DWORD i, bytesNeeded = 0, structSize = 0;
524 for (i = 0; i < cItem; i++)
526 if (items[i].size > items[i].minSize)
527 bytesNeeded += items[i].size - items[i].minSize;
528 structSize = max( structSize, items[i].offset + items[i].minSize );
530 bytesNeeded += structSize;
532 *pcbDecoded = 1 + lenBytes + cbDecoded;
534 *pcbStructInfo = bytesNeeded;
535 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
536 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
540 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
541 pvStructInfo = *(BYTE **)pvStructInfo;
543 nextData = startingPointer;
545 nextData = (BYTE *)pvStructInfo + structSize;
546 memset(pvStructInfo, 0, structSize);
547 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
548 ptr, dataLen, dwFlags, pvStructInfo, nextData,
550 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
551 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
558 SetLastError(CRYPT_E_ASN1_BADTAG);
561 TRACE("returning %d (%08x)\n", ret, GetLastError());
566 * The expected tag of the entire encoded array (usually a variant
567 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
568 * regardless of the tag seen.
570 * The offset within the outer structure at which the count exists.
571 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
572 * while CRYPT_ATTRIBUTE has countOffset ==
573 * offsetof(CRYPT_ATTRIBUTE, cValue).
575 * The offset within the outer structure at which the array pointer exists.
576 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
577 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
579 * The minimum size of the decoded array. On WIN32, this is always 8:
580 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
583 * used to decode each item in the array
585 * is the minimum size of each decoded item
587 * indicates whether each item has a dynamic pointer
589 * indicates the offset within itemSize at which the pointer exists
591 struct AsnArrayDescriptor
597 InternalDecodeFunc decodeFunc;
603 struct AsnArrayItemSize
609 /* Decodes an array of like types into a structure described by a struct
610 * AsnArrayDescriptor.
612 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
613 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
614 const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
619 TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded,
620 cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
624 SetLastError(CRYPT_E_ASN1_EOD);
627 else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
631 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
633 DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded;
634 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
635 /* There can be arbitrarily many items, but there is often only one.
637 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
639 decoded = 1 + lenBytes;
643 BOOL doneDecoding = FALSE;
645 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
647 if (dataLen == CMSG_INDEFINITE_LENGTH)
654 SetLastError(CRYPT_E_ASN1_CORRUPT);
661 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
665 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
667 /* Each item decoded may not tolerate extraneous bytes,
668 * so get the length of the next element if known.
670 if ((ret = CRYPT_GetLengthIndefinite(ptr,
671 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
673 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
674 itemEncoded = cbEncoded - (ptr - pbEncoded);
676 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
680 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
681 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
686 if (itemSizes != &itemSize)
687 itemSizes = CryptMemRealloc(itemSizes,
688 cItems * sizeof(struct AsnArrayItemSize));
693 cItems * sizeof(struct AsnArrayItemSize));
695 memcpy(itemSizes, &itemSize,
700 decoded += itemDecoded;
701 itemSizes[cItems - 1].encodedLen = itemEncoded;
702 itemSizes[cItems - 1].size = size;
715 *pcbDecoded = decoded;
717 *pcbStructInfo = bytesNeeded;
718 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
719 pvStructInfo, pcbStructInfo, bytesNeeded)))
726 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
727 pvStructInfo = *(void **)pvStructInfo;
728 pcItems = pvStructInfo;
730 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
732 rgItems = (BYTE *)pvStructInfo +
733 arrayDesc->minArraySize;
734 *(void **)((BYTE *)pcItems -
735 arrayDesc->countOffset + arrayDesc->arrayOffset) =
739 rgItems = *(void **)((BYTE *)pcItems -
740 arrayDesc->countOffset + arrayDesc->arrayOffset);
741 nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize;
742 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
743 i < cItems && ptr - pbEncoded - 1 - lenBytes <
748 if (arrayDesc->hasPointer)
749 *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize
750 + arrayDesc->pointerOffset) = nextData;
751 ret = arrayDesc->decodeFunc(ptr,
752 itemSizes[i].encodedLen,
753 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
754 (BYTE *)rgItems + i * arrayDesc->itemSize,
755 &itemSizes[i].size, &itemDecoded);
758 nextData += itemSizes[i].size - arrayDesc->itemSize;
762 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
763 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
766 if (itemSizes != &itemSize)
767 CryptMemFree(itemSizes);
772 SetLastError(CRYPT_E_ASN1_BADTAG);
778 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
779 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
780 * to CRYPT_E_ASN1_CORRUPT.
781 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
784 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
785 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
790 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
792 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
793 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
795 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
796 bytesNeeded += 1 + lenBytes + dataLen;
799 *pcbDecoded = 1 + lenBytes + dataLen;
801 *pcbStructInfo = bytesNeeded;
802 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
804 CRYPT_DER_BLOB *blob;
806 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
807 pvStructInfo = *(BYTE **)pvStructInfo;
809 blob->cbData = 1 + lenBytes + dataLen;
812 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
813 blob->pbData = (BYTE *)pbEncoded;
816 assert(blob->pbData);
817 memcpy(blob->pbData, pbEncoded, blob->cbData);
822 SetLastError(CRYPT_E_ASN1_CORRUPT);
830 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
831 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
832 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
837 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
838 pvStructInfo, *pcbStructInfo, pcbDecoded);
840 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
843 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
844 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
846 if (ret && pvStructInfo)
848 CRYPT_BIT_BLOB *blob = pvStructInfo;
855 for (i = 0; i < blob->cbData / 2; i++)
857 temp = blob->pbData[i];
858 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
859 blob->pbData[blob->cbData - i - 1] = temp;
863 TRACE("returning %d (%08x)\n", ret, GetLastError());
867 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
868 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
869 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
873 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
874 pDecodePara, pvStructInfo, *pcbStructInfo);
878 struct AsnDecodeSequenceItem items[] = {
879 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
880 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
881 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
882 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
883 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
884 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
885 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
886 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
887 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
888 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
891 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
892 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
893 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
894 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
895 pcbStructInfo, NULL, NULL);
899 SetLastError(STATUS_ACCESS_VIOLATION);
904 TRACE("Returning %d (%08x)\n", ret, GetLastError());
908 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
909 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
914 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
916 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
918 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
919 dwFlags, pvStructInfo, pcbStructInfo, NULL);
921 *pcbDecoded = 1 + lenBytes + dataLen;
926 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
927 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
931 struct AsnDecodeSequenceItem items[] = {
932 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
933 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
934 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
935 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
938 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
939 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
944 static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded,
945 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
949 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
950 offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
951 FINALMEMBERSIZE(CERT_INFO, cExtension),
952 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
953 offsetof(CERT_EXTENSION, pszObjId) };
955 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
956 pvStructInfo, *pcbStructInfo, pcbDecoded);
958 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
959 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
963 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
964 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
970 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
972 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
974 ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes,
975 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
976 if (ret && pcbDecoded)
977 *pcbDecoded = 1 + lenBytes + dataLen;
982 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
983 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
984 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
987 struct AsnDecodeSequenceItem items[] = {
988 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
989 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
990 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
991 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
992 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
993 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
994 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
995 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
996 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
997 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
999 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
1000 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
1002 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
1003 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
1005 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
1006 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
1007 FALSE, TRUE, offsetof(CERT_INFO,
1008 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
1009 { ASN_CONTEXT | 1, offsetof(CERT_INFO, IssuerUniqueId),
1010 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1011 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
1012 { ASN_CONTEXT | 2, offsetof(CERT_INFO, SubjectUniqueId),
1013 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1014 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
1015 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
1016 CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension),
1017 TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
1020 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1021 pDecodePara, pvStructInfo, *pcbStructInfo);
1023 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1024 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1026 if (ret && pvStructInfo)
1030 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1031 info = *(CERT_INFO **)pvStructInfo;
1033 info = pvStructInfo;
1034 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1035 !info->Subject.cbData)
1037 SetLastError(CRYPT_E_ASN1_CORRUPT);
1038 /* Don't need to deallocate, because it should have failed on the
1039 * first pass (and no memory was allocated.)
1045 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1049 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1050 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1051 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1055 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1056 pDecodePara, pvStructInfo, *pcbStructInfo);
1062 /* Unless told not to, first try to decode it as a signed cert. */
1063 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1065 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1067 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1068 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1069 &signedCert, &size);
1073 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1074 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1075 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1076 pvStructInfo, pcbStructInfo);
1077 LocalFree(signedCert);
1080 /* Failing that, try it as an unsigned cert */
1084 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1085 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1086 pDecodePara, pvStructInfo, pcbStructInfo);
1091 SetLastError(STATUS_ACCESS_VIOLATION);
1095 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1099 static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded,
1100 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1104 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1105 offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
1106 FINALMEMBERSIZE(CRL_ENTRY, cExtension),
1107 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1108 offsetof(CERT_EXTENSION, pszObjId) };
1110 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1111 pvStructInfo, *pcbStructInfo, pcbDecoded);
1113 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1114 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1118 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1119 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1122 struct AsnDecodeSequenceItem items[] = {
1123 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1124 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1125 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1126 { 0, offsetof(CRL_ENTRY, RevocationDate),
1127 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1128 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1129 CRYPT_AsnDecodeCRLEntryExtensions,
1130 FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
1131 offsetof(CRL_ENTRY, rgExtension), 0 },
1133 PCRL_ENTRY entry = pvStructInfo;
1135 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1138 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1139 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1140 entry ? entry->SerialNumber.pbData : NULL);
1141 if (ret && entry && !entry->SerialNumber.cbData)
1143 WARN("empty CRL entry serial number\n");
1144 SetLastError(CRYPT_E_ASN1_CORRUPT);
1150 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1151 * whose rgCRLEntry member has been set prior to calling.
1153 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1154 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1157 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1158 offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
1159 MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1160 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1161 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1163 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1164 pvStructInfo, *pcbStructInfo, pcbDecoded);
1166 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1167 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1168 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1172 static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded,
1173 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1177 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1178 offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
1179 FINALMEMBERSIZE(CRL_INFO, cExtension),
1180 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1181 offsetof(CERT_EXTENSION, pszObjId) };
1183 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1184 pvStructInfo, *pcbStructInfo, pcbDecoded);
1186 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1187 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1191 static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded,
1192 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1198 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1200 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1202 ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes,
1203 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1204 if (ret && pcbDecoded)
1205 *pcbDecoded = 1 + lenBytes + dataLen;
1210 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1211 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1212 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1214 struct AsnDecodeSequenceItem items[] = {
1215 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1216 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1217 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1218 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1219 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1220 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1221 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1223 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1224 sizeof(FILETIME), FALSE, FALSE, 0 },
1225 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1226 sizeof(FILETIME), TRUE, FALSE, 0 },
1227 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1228 CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1229 TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
1230 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1231 CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension),
1232 TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
1236 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1237 pDecodePara, pvStructInfo, *pcbStructInfo);
1239 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1240 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1243 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1247 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1248 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1249 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1253 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1254 pDecodePara, pvStructInfo, *pcbStructInfo);
1260 /* Unless told not to, first try to decode it as a signed crl. */
1261 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1263 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1265 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1266 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1271 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1272 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1273 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1274 pvStructInfo, pcbStructInfo);
1275 LocalFree(signedCrl);
1278 /* Failing that, try it as an unsigned crl */
1282 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1283 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1284 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1289 SetLastError(STATUS_ACCESS_VIOLATION);
1293 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1297 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1298 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1303 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1304 pvStructInfo, *pcbStructInfo);
1306 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1308 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1309 DWORD bytesNeeded = sizeof(LPSTR);
1316 snprintf(str, sizeof(str), "%d.%d",
1317 pbEncoded[1 + lenBytes] / 40,
1318 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1320 bytesNeeded += strlen(str) + 1;
1321 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1322 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1326 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1333 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1336 SetLastError(CRYPT_E_ASN1_CORRUPT);
1343 snprintf(str, sizeof(str), ".%d", val);
1344 bytesNeeded += strlen(str);
1349 *pcbDecoded = 1 + lenBytes + dataLen;
1351 *pcbStructInfo = bytesNeeded;
1352 else if (*pcbStructInfo < bytesNeeded)
1354 *pcbStructInfo = bytesNeeded;
1355 SetLastError(ERROR_MORE_DATA);
1363 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1366 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1367 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1369 pszObjId += strlen(pszObjId);
1370 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1371 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1375 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1384 sprintf(pszObjId, ".%d", val);
1385 pszObjId += strlen(pszObjId);
1389 *(LPSTR *)pvStructInfo = NULL;
1390 *pcbStructInfo = bytesNeeded;
1396 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1397 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1401 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1402 pvStructInfo, *pcbStructInfo);
1404 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1405 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1406 pvStructInfo, pcbStructInfo, pcbDecoded);
1409 SetLastError(CRYPT_E_ASN1_BADTAG);
1415 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1416 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1418 struct AsnDecodeSequenceItem items[] = {
1419 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1420 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1421 offsetof(CERT_EXTENSION, pszObjId), 0 },
1422 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1423 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1424 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1425 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1426 offsetof(CERT_EXTENSION, Value.pbData) },
1429 PCERT_EXTENSION ext = pvStructInfo;
1431 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1435 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1436 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1437 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1438 pcbDecoded, ext ? ext->pszObjId : NULL);
1440 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1441 debugstr_a(ext->pszObjId));
1442 TRACE("returning %d (%08x)\n", ret, GetLastError());
1446 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1447 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1448 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1452 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1453 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1457 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1458 offsetof(CERT_EXTENSIONS, cExtension),
1459 offsetof(CERT_EXTENSIONS, rgExtension),
1460 sizeof(CERT_EXTENSIONS),
1461 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1462 offsetof(CERT_EXTENSION, pszObjId) };
1463 CERT_EXTENSIONS *exts = pvStructInfo;
1465 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1466 exts->rgExtension = (CERT_EXTENSION *)(exts + 1);
1467 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1468 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1472 SetLastError(STATUS_ACCESS_VIOLATION);
1479 /* Warning: this assumes the address of value->Value.pbData is already set, in
1480 * order to avoid overwriting memory. (In some cases, it may change it, if it
1481 * doesn't copy anything to memory.) Be sure to set it correctly!
1483 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1484 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1489 CERT_NAME_VALUE *value = pvStructInfo;
1491 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1493 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1494 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1496 switch (pbEncoded[0])
1498 case ASN_OCTETSTRING:
1499 valueType = CERT_RDN_OCTET_STRING;
1500 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1501 bytesNeeded += dataLen;
1503 case ASN_NUMERICSTRING:
1504 valueType = CERT_RDN_NUMERIC_STRING;
1505 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1506 bytesNeeded += dataLen;
1508 case ASN_PRINTABLESTRING:
1509 valueType = CERT_RDN_PRINTABLE_STRING;
1510 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1511 bytesNeeded += dataLen;
1514 valueType = CERT_RDN_IA5_STRING;
1515 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1516 bytesNeeded += dataLen;
1519 valueType = CERT_RDN_T61_STRING;
1520 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1521 bytesNeeded += dataLen;
1523 case ASN_VIDEOTEXSTRING:
1524 valueType = CERT_RDN_VIDEOTEX_STRING;
1525 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1526 bytesNeeded += dataLen;
1528 case ASN_GRAPHICSTRING:
1529 valueType = CERT_RDN_GRAPHIC_STRING;
1530 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1531 bytesNeeded += dataLen;
1533 case ASN_VISIBLESTRING:
1534 valueType = CERT_RDN_VISIBLE_STRING;
1535 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1536 bytesNeeded += dataLen;
1538 case ASN_GENERALSTRING:
1539 valueType = CERT_RDN_GENERAL_STRING;
1540 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1541 bytesNeeded += dataLen;
1543 case ASN_UNIVERSALSTRING:
1544 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1545 SetLastError(CRYPT_E_ASN1_BADTAG);
1548 valueType = CERT_RDN_BMP_STRING;
1549 bytesNeeded += dataLen;
1551 case ASN_UTF8STRING:
1552 valueType = CERT_RDN_UTF8_STRING;
1553 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1554 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1557 SetLastError(CRYPT_E_ASN1_BADTAG);
1562 *pcbDecoded = 1 + lenBytes + dataLen;
1564 *pcbStructInfo = bytesNeeded;
1565 else if (*pcbStructInfo < bytesNeeded)
1567 *pcbStructInfo = bytesNeeded;
1568 SetLastError(ERROR_MORE_DATA);
1573 *pcbStructInfo = bytesNeeded;
1574 value->dwValueType = valueType;
1579 assert(value->Value.pbData);
1580 switch (pbEncoded[0])
1582 case ASN_OCTETSTRING:
1583 case ASN_NUMERICSTRING:
1584 case ASN_PRINTABLESTRING:
1587 case ASN_VIDEOTEXSTRING:
1588 case ASN_GRAPHICSTRING:
1589 case ASN_VISIBLESTRING:
1590 case ASN_GENERALSTRING:
1591 value->Value.cbData = dataLen;
1594 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1595 memcpy(value->Value.pbData,
1596 pbEncoded + 1 + lenBytes, dataLen);
1598 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1604 LPWSTR str = (LPWSTR)value->Value.pbData;
1606 value->Value.cbData = dataLen;
1607 for (i = 0; i < dataLen / 2; i++)
1608 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1609 pbEncoded[1 + lenBytes + 2 * i + 1];
1612 case ASN_UTF8STRING:
1614 LPWSTR str = (LPWSTR)value->Value.pbData;
1616 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1617 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1618 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1625 value->Value.cbData = 0;
1626 value->Value.pbData = NULL;
1633 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1634 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1635 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1641 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1642 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1643 if (ret && pvStructInfo)
1645 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1646 pcbStructInfo, *pcbStructInfo);
1649 CERT_NAME_VALUE *value;
1651 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1652 pvStructInfo = *(BYTE **)pvStructInfo;
1653 value = pvStructInfo;
1654 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1655 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1656 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1657 pcbStructInfo, NULL);
1658 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1659 CRYPT_FreeSpace(pDecodePara, value);
1665 SetLastError(STATUS_ACCESS_VIOLATION);
1672 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1673 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1678 CERT_NAME_VALUE *value = pvStructInfo;
1680 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1682 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1683 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1685 switch (pbEncoded[0])
1687 case ASN_NUMERICSTRING:
1688 valueType = CERT_RDN_NUMERIC_STRING;
1690 bytesNeeded += (dataLen + 1) * 2;
1692 case ASN_PRINTABLESTRING:
1693 valueType = CERT_RDN_PRINTABLE_STRING;
1695 bytesNeeded += (dataLen + 1) * 2;
1698 valueType = CERT_RDN_IA5_STRING;
1700 bytesNeeded += (dataLen + 1) * 2;
1703 valueType = CERT_RDN_T61_STRING;
1705 bytesNeeded += (dataLen + 1) * 2;
1707 case ASN_VIDEOTEXSTRING:
1708 valueType = CERT_RDN_VIDEOTEX_STRING;
1710 bytesNeeded += (dataLen + 1) * 2;
1712 case ASN_GRAPHICSTRING:
1713 valueType = CERT_RDN_GRAPHIC_STRING;
1715 bytesNeeded += (dataLen + 1) * 2;
1717 case ASN_VISIBLESTRING:
1718 valueType = CERT_RDN_VISIBLE_STRING;
1720 bytesNeeded += (dataLen + 1) * 2;
1722 case ASN_GENERALSTRING:
1723 valueType = CERT_RDN_GENERAL_STRING;
1725 bytesNeeded += (dataLen + 1) * 2;
1727 case ASN_UNIVERSALSTRING:
1728 valueType = CERT_RDN_UNIVERSAL_STRING;
1730 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1733 valueType = CERT_RDN_BMP_STRING;
1735 bytesNeeded += dataLen + sizeof(WCHAR);
1737 case ASN_UTF8STRING:
1738 valueType = CERT_RDN_UTF8_STRING;
1740 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1741 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1744 SetLastError(CRYPT_E_ASN1_BADTAG);
1749 *pcbDecoded = 1 + lenBytes + dataLen;
1751 *pcbStructInfo = bytesNeeded;
1752 else if (*pcbStructInfo < bytesNeeded)
1754 *pcbStructInfo = bytesNeeded;
1755 SetLastError(ERROR_MORE_DATA);
1760 *pcbStructInfo = bytesNeeded;
1761 value->dwValueType = valueType;
1765 LPWSTR str = (LPWSTR)value->Value.pbData;
1767 assert(value->Value.pbData);
1768 switch (pbEncoded[0])
1770 case ASN_NUMERICSTRING:
1771 case ASN_PRINTABLESTRING:
1774 case ASN_VIDEOTEXSTRING:
1775 case ASN_GRAPHICSTRING:
1776 case ASN_VISIBLESTRING:
1777 case ASN_GENERALSTRING:
1778 value->Value.cbData = dataLen * 2;
1779 for (i = 0; i < dataLen; i++)
1780 str[i] = pbEncoded[1 + lenBytes + i];
1783 case ASN_UNIVERSALSTRING:
1784 value->Value.cbData = dataLen / 2;
1785 for (i = 0; i < dataLen / 4; i++)
1786 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1787 | pbEncoded[1 + lenBytes + 2 * i + 3];
1791 value->Value.cbData = dataLen;
1792 for (i = 0; i < dataLen / 2; i++)
1793 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1794 pbEncoded[1 + lenBytes + 2 * i + 1];
1797 case ASN_UTF8STRING:
1798 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1799 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1800 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
1801 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
1802 value->Value.cbData += sizeof(WCHAR);
1808 value->Value.cbData = 0;
1809 value->Value.pbData = NULL;
1816 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1817 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1818 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1824 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1825 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1826 if (ret && pvStructInfo)
1828 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1829 pcbStructInfo, *pcbStructInfo);
1832 CERT_NAME_VALUE *value;
1834 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1835 pvStructInfo = *(BYTE **)pvStructInfo;
1836 value = pvStructInfo;
1837 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1838 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1839 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1840 pcbStructInfo, NULL);
1841 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1842 CRYPT_FreeSpace(pDecodePara, value);
1848 SetLastError(STATUS_ACCESS_VIOLATION);
1855 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1856 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1859 struct AsnDecodeSequenceItem items[] = {
1860 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1861 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1862 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1863 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1864 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1865 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1867 CERT_RDN_ATTR *attr = pvStructInfo;
1869 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1870 pvStructInfo, *pcbStructInfo);
1873 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1874 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1875 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1876 attr ? attr->pszObjId : NULL);
1879 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1880 debugstr_a(attr->pszObjId));
1881 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1883 TRACE("returning %d (%08x)\n", ret, GetLastError());
1887 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1888 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1891 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1892 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1894 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1895 offsetof(CERT_RDN_ATTR, pszObjId) };
1897 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1898 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1902 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1903 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1904 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1910 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1911 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
1912 sizeof(CERT_NAME_INFO),
1913 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1914 offsetof(CERT_RDN, rgRDNAttr) };
1917 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1918 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
1923 *pcbStructInfo = bytesNeeded;
1924 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
1925 pvStructInfo, pcbStructInfo, bytesNeeded)))
1927 CERT_NAME_INFO *info;
1929 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1930 pvStructInfo = *(BYTE **)pvStructInfo;
1931 info = pvStructInfo;
1932 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
1933 sizeof(CERT_NAME_INFO));
1934 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1935 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
1936 &bytesNeeded, NULL);
1937 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
1938 CRYPT_FreeSpace(pDecodePara, info);
1944 SetLastError(STATUS_ACCESS_VIOLATION);
1951 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1952 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1956 struct AsnDecodeSequenceItem items[] = {
1957 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1958 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1959 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1960 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1961 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1962 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1964 CERT_RDN_ATTR *attr = pvStructInfo;
1966 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1967 pvStructInfo, *pcbStructInfo);
1970 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1971 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1972 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1973 attr ? attr->pszObjId : NULL);
1976 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1977 debugstr_a(attr->pszObjId));
1978 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1980 TRACE("returning %d (%08x)\n", ret, GetLastError());
1984 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1985 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1988 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1989 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1991 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1992 offsetof(CERT_RDN_ATTR, pszObjId) };
1994 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1995 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1999 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
2000 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2001 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2007 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2008 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
2009 sizeof(CERT_NAME_INFO),
2010 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
2011 offsetof(CERT_RDN, rgRDNAttr) };
2014 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2015 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
2020 *pcbStructInfo = bytesNeeded;
2021 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2022 pvStructInfo, pcbStructInfo, bytesNeeded)))
2024 CERT_NAME_INFO *info;
2026 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2027 pvStructInfo = *(BYTE **)pvStructInfo;
2028 info = pvStructInfo;
2029 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
2030 sizeof(CERT_NAME_INFO));
2031 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2032 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
2033 &bytesNeeded, NULL);
2034 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2035 CRYPT_FreeSpace(pDecodePara, info);
2041 SetLastError(STATUS_ACCESS_VIOLATION);
2048 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
2051 BOOL ret = TRUE, done = FALSE;
2052 DWORD indefiniteNestingLevels = 0, decoded = 0;
2054 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2061 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2064 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2066 if (dataLen == CMSG_INDEFINITE_LENGTH)
2068 indefiniteNestingLevels++;
2069 pbEncoded += 1 + lenBytes;
2070 cbEncoded -= 1 + lenBytes;
2071 decoded += 1 + lenBytes;
2072 TRACE("indefiniteNestingLevels = %d\n",
2073 indefiniteNestingLevels);
2077 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2078 indefiniteNestingLevels)
2080 indefiniteNestingLevels--;
2081 TRACE("indefiniteNestingLevels = %d\n",
2082 indefiniteNestingLevels);
2084 pbEncoded += 1 + lenBytes + dataLen;
2085 cbEncoded -= 1 + lenBytes + dataLen;
2086 decoded += 1 + lenBytes + dataLen;
2087 if (!indefiniteNestingLevels)
2091 } while (ret && !done);
2092 /* If we haven't found all 0 TLVs, we haven't found the end */
2093 if (ret && indefiniteNestingLevels)
2095 SetLastError(CRYPT_E_ASN1_EOD);
2099 *pcbDecoded = decoded;
2100 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2104 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
2105 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2109 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2111 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2112 pvStructInfo, *pcbStructInfo);
2114 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2116 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
2117 bytesNeeded += encodedLen;
2119 *pcbStructInfo = bytesNeeded;
2120 else if (*pcbStructInfo < bytesNeeded)
2122 SetLastError(ERROR_MORE_DATA);
2123 *pcbStructInfo = bytesNeeded;
2128 PCRYPT_OBJID_BLOB blob = pvStructInfo;
2130 *pcbStructInfo = bytesNeeded;
2131 blob->cbData = encodedLen;
2134 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2135 blob->pbData = (LPBYTE)pbEncoded;
2138 assert(blob->pbData);
2139 memcpy(blob->pbData, pbEncoded, blob->cbData);
2143 blob->pbData = NULL;
2146 *pcbDecoded = encodedLen;
2151 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2152 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2155 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2156 offsetof(CTL_USAGE, cUsageIdentifier),
2157 offsetof(CTL_USAGE, rgpszUsageIdentifier),
2159 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2161 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2162 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2166 static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded,
2167 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2170 struct AsnArrayDescriptor arrayDesc = { 0,
2171 offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
2172 FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
2173 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2174 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2177 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2178 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2182 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2183 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2185 struct AsnDecodeSequenceItem items[] = {
2186 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2187 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2188 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2189 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2190 CRYPT_AsnDecodeCTLEntryAttributes,
2191 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
2192 offsetof(CTL_ENTRY, rgAttribute), 0 },
2195 CTL_ENTRY *entry = pvStructInfo;
2197 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2200 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2201 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2202 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2206 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2207 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2210 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2211 offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
2212 FINALMEMBERSIZE(CTL_INFO, cExtension),
2213 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2214 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2216 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2217 pvStructInfo, *pcbStructInfo, pcbDecoded);
2219 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2220 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2224 static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded,
2225 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2229 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2230 offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
2231 FINALMEMBERSIZE(CTL_INFO, cExtension),
2232 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
2233 offsetof(CERT_EXTENSION, pszObjId) };
2235 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2236 pvStructInfo, *pcbStructInfo, pcbDecoded);
2238 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2239 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2243 static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded,
2244 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2250 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2252 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2254 ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes,
2255 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
2256 if (ret && pcbDecoded)
2257 *pcbDecoded = 1 + lenBytes + dataLen;
2262 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2263 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2264 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2268 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2269 pDecodePara, pvStructInfo, *pcbStructInfo);
2273 struct AsnDecodeSequenceItem items[] = {
2274 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2275 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2276 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2277 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2278 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2279 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2280 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2281 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2282 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2283 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2284 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2285 { 0, offsetof(CTL_INFO, ThisUpdate),
2286 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2288 { 0, offsetof(CTL_INFO, NextUpdate),
2289 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2291 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2292 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2293 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2294 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2295 CRYPT_AsnDecodeCTLEntries,
2296 MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2297 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2298 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2299 CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension),
2300 TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
2303 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2304 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2305 pcbStructInfo, NULL, NULL);
2309 SetLastError(STATUS_ACCESS_VIOLATION);
2315 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2316 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2320 struct AsnDecodeSequenceItem items[] = {
2321 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2322 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2323 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2324 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2325 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2326 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2328 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2330 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2331 pvStructInfo, *pcbStructInfo);
2333 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2334 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2335 pcbDecoded, capability ? capability->pszObjId : NULL);
2336 TRACE("returning %d\n", ret);
2340 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2341 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2342 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2346 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2347 pDecodePara, pvStructInfo, *pcbStructInfo);
2351 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2352 offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
2353 offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
2354 sizeof(CRYPT_SMIME_CAPABILITIES),
2355 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2356 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2357 CRYPT_SMIME_CAPABILITIES *capabilities = pvStructInfo;
2359 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2360 capabilities->rgCapability = (CRYPT_SMIME_CAPABILITY *)(capabilities + 1);
2361 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2362 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2366 SetLastError(STATUS_ACCESS_VIOLATION);
2369 TRACE("returning %d\n", ret);
2373 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2374 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2379 LPSTR *pStr = pvStructInfo;
2381 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2383 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2384 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2386 if (pbEncoded[0] != ASN_IA5STRING)
2388 SetLastError(CRYPT_E_ASN1_CORRUPT);
2393 bytesNeeded += dataLen;
2395 *pcbDecoded = 1 + lenBytes + dataLen;
2397 *pcbStructInfo = bytesNeeded;
2398 else if (*pcbStructInfo < bytesNeeded)
2400 *pcbStructInfo = bytesNeeded;
2401 SetLastError(ERROR_MORE_DATA);
2406 *pcbStructInfo = bytesNeeded;
2412 memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2423 static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded,
2424 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2427 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2428 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2429 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers),
2430 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2431 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2434 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2435 pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2437 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2438 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2439 TRACE("returning %d\n", ret);
2443 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2444 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2448 struct AsnDecodeSequenceItem items[] = {
2449 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2450 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2451 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2452 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2453 cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
2454 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2455 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2456 rgNoticeNumbers), 0 },
2460 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2461 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2463 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2464 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2468 /* The caller is expecting a pointer to a
2469 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2470 * CRYPT_AsnDecodeSequence is decoding a
2471 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2472 * needed, and decode again if the requisite space is available.
2474 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2476 *pcbStructInfo = bytesNeeded;
2477 else if (*pcbStructInfo < bytesNeeded)
2479 *pcbStructInfo = bytesNeeded;
2480 SetLastError(ERROR_MORE_DATA);
2485 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2487 *pcbStructInfo = bytesNeeded;
2488 /* The pointer (pvStructInfo) passed in points to the first dynamic
2489 * pointer, so use it as the pointer to the
2490 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2491 * appropriate offset for the first dynamic pointer within the
2492 * notice reference by pointing to the first memory location past
2493 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2496 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2497 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2498 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2499 ret = CRYPT_AsnDecodeSequence(items,
2500 sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2501 NULL, noticeRef, &bytesNeeded, pcbDecoded,
2502 noticeRef->pszOrganization);
2505 TRACE("returning %d\n", ret);
2509 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2510 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2516 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2518 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2519 DWORD bytesNeeded = sizeof(LPWSTR);
2521 switch (pbEncoded[0])
2523 case ASN_NUMERICSTRING:
2525 bytesNeeded += (dataLen + 1) * 2;
2527 case ASN_PRINTABLESTRING:
2529 bytesNeeded += (dataLen + 1) * 2;
2533 bytesNeeded += (dataLen + 1) * 2;
2537 bytesNeeded += (dataLen + 1) * 2;
2539 case ASN_VIDEOTEXSTRING:
2541 bytesNeeded += (dataLen + 1) * 2;
2543 case ASN_GRAPHICSTRING:
2545 bytesNeeded += (dataLen + 1) * 2;
2547 case ASN_VISIBLESTRING:
2549 bytesNeeded += (dataLen + 1) * 2;
2551 case ASN_GENERALSTRING:
2553 bytesNeeded += (dataLen + 1) * 2;
2555 case ASN_UNIVERSALSTRING:
2557 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2561 bytesNeeded += dataLen + sizeof(WCHAR);
2563 case ASN_UTF8STRING:
2565 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2566 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2569 SetLastError(CRYPT_E_ASN1_BADTAG);
2574 *pcbDecoded = 1 + lenBytes + dataLen;
2576 *pcbStructInfo = bytesNeeded;
2577 else if (*pcbStructInfo < bytesNeeded)
2579 *pcbStructInfo = bytesNeeded;
2580 SetLastError(ERROR_MORE_DATA);
2585 LPWSTR *pStr = pvStructInfo;
2587 *pcbStructInfo = bytesNeeded;
2591 LPWSTR str = *(LPWSTR *)pStr;
2594 switch (pbEncoded[0])
2596 case ASN_NUMERICSTRING:
2597 case ASN_PRINTABLESTRING:
2600 case ASN_VIDEOTEXSTRING:
2601 case ASN_GRAPHICSTRING:
2602 case ASN_VISIBLESTRING:
2603 case ASN_GENERALSTRING:
2604 for (i = 0; i < dataLen; i++)
2605 str[i] = pbEncoded[1 + lenBytes + i];
2608 case ASN_UNIVERSALSTRING:
2609 for (i = 0; i < dataLen / 4; i++)
2610 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2611 | pbEncoded[1 + lenBytes + 2 * i + 3];
2615 for (i = 0; i < dataLen / 2; i++)
2616 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2617 pbEncoded[1 + lenBytes + 2 * i + 1];
2620 case ASN_UTF8STRING:
2622 int len = MultiByteToWideChar(CP_UTF8, 0,
2623 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2624 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2637 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2638 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2639 DWORD *pcbStructInfo, DWORD *pcbDecoded)
2642 struct AsnDecodeSequenceItem items[] = {
2643 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2644 pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2645 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2646 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2647 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2648 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2649 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2651 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2653 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2654 pvStructInfo, *pcbStructInfo);
2656 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2657 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2658 pcbDecoded, notice ? notice->pNoticeReference : NULL);
2659 TRACE("returning %d\n", ret);
2663 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2664 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2665 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2666 void *pvStructInfo, DWORD *pcbStructInfo)
2670 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2671 pDecodePara, pvStructInfo, *pcbStructInfo);
2677 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2678 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2683 *pcbStructInfo = bytesNeeded;
2684 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2685 pvStructInfo, pcbStructInfo, bytesNeeded)))
2687 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2689 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2690 pvStructInfo = *(BYTE **)pvStructInfo;
2691 notice = pvStructInfo;
2692 notice->pNoticeReference =
2693 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2694 ((BYTE *)pvStructInfo +
2695 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2696 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2697 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2698 pvStructInfo, &bytesNeeded, NULL);
2699 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2700 CRYPT_FreeSpace(pDecodePara, notice);
2706 SetLastError(STATUS_ACCESS_VIOLATION);
2709 TRACE("returning %d\n", ret);
2713 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
2714 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2718 struct AsnArrayDescriptor arrayDesc = { 0,
2719 offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
2720 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue),
2721 CRYPT_AsnDecodeCopyBytes,
2722 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2724 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2725 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
2727 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2728 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2732 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2733 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2737 struct AsnDecodeSequenceItem items[] = {
2738 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2739 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2740 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2741 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2742 CRYPT_AsnDecodePKCSAttributeValue,
2743 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
2744 TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2746 PCRYPT_ATTRIBUTE attr = pvStructInfo;
2748 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2749 pvStructInfo, *pcbStructInfo);
2751 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2752 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2753 pcbDecoded, attr ? attr->pszObjId : NULL);
2754 TRACE("returning %d\n", ret);
2758 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2759 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2760 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2764 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2765 pDecodePara, pvStructInfo, *pcbStructInfo);
2771 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2772 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2776 *pcbStructInfo = bytesNeeded;
2777 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2778 pvStructInfo, pcbStructInfo, bytesNeeded)))
2780 PCRYPT_ATTRIBUTE attr;
2782 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2783 pvStructInfo = *(BYTE **)pvStructInfo;
2784 attr = pvStructInfo;
2785 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2786 sizeof(CRYPT_ATTRIBUTE));
2787 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2788 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2790 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2791 CRYPT_FreeSpace(pDecodePara, attr);
2797 SetLastError(STATUS_ACCESS_VIOLATION);
2800 TRACE("returning %d\n", ret);
2804 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2805 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2808 struct AsnArrayDescriptor arrayDesc = { 0,
2809 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2810 sizeof(CRYPT_ATTRIBUTES),
2811 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2812 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2815 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2816 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2820 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2821 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2822 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2826 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2827 pDecodePara, pvStructInfo, *pcbStructInfo);
2831 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2832 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2833 sizeof(CRYPT_ATTRIBUTES),
2834 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
2835 TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2836 CRYPT_ATTRIBUTES *attrs = pvStructInfo;
2838 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2839 attrs->rgAttr = (CRYPT_ATTRIBUTE *)(attrs + 1);
2840 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2841 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2845 SetLastError(STATUS_ACCESS_VIOLATION);
2848 TRACE("returning %d\n", ret);
2852 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2853 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2855 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2857 struct AsnDecodeSequenceItem items[] = {
2858 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2859 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2860 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2861 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2862 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2863 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2866 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2867 pvStructInfo, *pcbStructInfo, pcbDecoded);
2869 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2870 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2871 pcbDecoded, algo ? algo->pszObjId : NULL);
2872 if (ret && pvStructInfo)
2874 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2875 debugstr_a(algo->pszObjId));
2880 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2881 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2885 struct AsnDecodeSequenceItem items[] = {
2886 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2887 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2888 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2889 Algorithm.pszObjId) },
2890 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2891 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2892 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2894 PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2896 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2897 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2898 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2902 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2903 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2904 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2912 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2913 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2916 *pcbStructInfo = bytesNeeded;
2917 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2918 pvStructInfo, pcbStructInfo, bytesNeeded)))
2920 PCERT_PUBLIC_KEY_INFO info;
2922 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2923 pvStructInfo = *(BYTE **)pvStructInfo;
2924 info = pvStructInfo;
2925 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2926 sizeof(CERT_PUBLIC_KEY_INFO);
2927 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2928 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2929 &bytesNeeded, NULL);
2930 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
2931 CRYPT_FreeSpace(pDecodePara, info);
2937 SetLastError(STATUS_ACCESS_VIOLATION);
2944 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2945 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2951 SetLastError(CRYPT_E_ASN1_CORRUPT);
2954 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2956 SetLastError(CRYPT_E_ASN1_CORRUPT);
2959 if (pbEncoded[1] > 1)
2961 SetLastError(CRYPT_E_ASN1_CORRUPT);
2968 *pcbStructInfo = sizeof(BOOL);
2971 else if (*pcbStructInfo < sizeof(BOOL))
2973 *pcbStructInfo = sizeof(BOOL);
2974 SetLastError(ERROR_MORE_DATA);
2979 *pcbStructInfo = sizeof(BOOL);
2980 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2983 TRACE("returning %d (%08x)\n", ret, GetLastError());
2987 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2988 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2990 PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2991 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2994 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2995 pvStructInfo, *pcbStructInfo);
2999 SetLastError(CRYPT_E_ASN1_CORRUPT);
3002 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3003 if (1 + lenBytes > cbEncoded)
3005 SetLastError(CRYPT_E_ASN1_CORRUPT);
3008 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3010 switch (pbEncoded[0] & ASN_TYPE_MASK)
3012 case 1: /* rfc822Name */
3013 case 2: /* dNSName */
3014 case 6: /* uniformResourceIdentifier */
3015 if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen))
3017 SetLastError(CRYPT_E_ASN1_RULE);
3021 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
3023 case 4: /* directoryName */
3024 case 7: /* iPAddress */
3025 bytesNeeded += dataLen;
3027 case 8: /* registeredID */
3028 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
3032 /* FIXME: ugly, shouldn't need to know internals of OID decode
3033 * function to use it.
3035 bytesNeeded += dataLen - sizeof(LPSTR);
3038 case 0: /* otherName */
3039 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
3040 SetLastError(CRYPT_E_ASN1_BADTAG);
3043 case 3: /* x400Address, unimplemented */
3044 case 5: /* ediPartyName, unimplemented */
3045 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
3046 SetLastError(CRYPT_E_ASN1_BADTAG);
3050 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
3051 SetLastError(CRYPT_E_ASN1_CORRUPT);
3057 *pcbDecoded = 1 + lenBytes + dataLen;
3059 *pcbStructInfo = bytesNeeded;
3060 else if (*pcbStructInfo < bytesNeeded)
3062 *pcbStructInfo = bytesNeeded;
3063 SetLastError(ERROR_MORE_DATA);
3068 *pcbStructInfo = bytesNeeded;
3069 /* MS used values one greater than the asn1 ones.. sigh */
3070 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
3071 switch (pbEncoded[0] & ASN_TYPE_MASK)
3073 case 1: /* rfc822Name */
3074 case 2: /* dNSName */
3075 case 6: /* uniformResourceIdentifier */
3079 for (i = 0; i < dataLen; i++)
3080 entry->u.pwszURL[i] =
3081 (WCHAR)pbEncoded[1 + lenBytes + i];
3082 entry->u.pwszURL[i] = 0;
3083 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3084 debugstr_w(entry->u.pwszURL));
3087 case 4: /* directoryName */
3088 /* The data are memory-equivalent with the IPAddress case,
3091 case 7: /* iPAddress */
3092 /* The next data pointer is in the pwszURL spot, that is,
3093 * the first 4 bytes. Need to move it to the next spot.
3095 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3096 entry->u.IPAddress.cbData = dataLen;
3097 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3100 case 8: /* registeredID */
3101 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
3102 &entry->u.pszRegisteredID, &dataLen, NULL);
3111 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
3112 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3116 struct AsnArrayDescriptor arrayDesc = { 0,
3117 offsetof(CERT_ALT_NAME_INFO, cAltEntry),
3118 offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
3119 sizeof(CERT_ALT_NAME_INFO),
3120 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3121 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3123 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3124 pvStructInfo, *pcbStructInfo, pcbDecoded);
3126 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3127 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3131 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3132 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3133 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3139 struct AsnDecodeSequenceItem items[] = {
3140 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3141 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB),
3142 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3143 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3144 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3145 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3146 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3147 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3148 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3149 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3150 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3153 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3154 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3155 pcbStructInfo, NULL, NULL);
3159 SetLastError(STATUS_ACCESS_VIOLATION);
3166 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3167 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3168 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3174 struct AsnDecodeSequenceItem items[] = {
3175 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3176 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB),
3177 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3178 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3179 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3180 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3181 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3182 AuthorityCertIssuer.rgAltEntry), 0 },
3183 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3184 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3185 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3186 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3187 AuthorityCertSerialNumber.pbData), 0 },
3190 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3191 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3192 pcbStructInfo, NULL, NULL);
3196 SetLastError(STATUS_ACCESS_VIOLATION);
3203 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3204 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3207 struct AsnDecodeSequenceItem items[] = {
3208 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3209 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3210 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3211 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3212 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3213 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3215 CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3217 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3218 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3219 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3222 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3223 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3224 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3228 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3229 pDecodePara, pvStructInfo, *pcbStructInfo);
3233 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3234 offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr),
3235 offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr),
3236 sizeof(CERT_AUTHORITY_INFO_ACCESS),
3237 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3238 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3239 CERT_AUTHORITY_INFO_ACCESS *info = pvStructInfo;
3241 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3242 info->rgAccDescr = (CERT_ACCESS_DESCRIPTION *)(info + 1);
3243 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3244 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3248 SetLastError(STATUS_ACCESS_VIOLATION);
3255 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3256 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3261 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3262 pvStructInfo, *pcbStructInfo, pcbDecoded);
3264 /* The caller has already checked the tag, no need to check it again.
3265 * Check the outer length is valid:
3267 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3269 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3272 pbEncoded += 1 + lenBytes;
3273 cbEncoded -= 1 + lenBytes;
3274 if (dataLen == CMSG_INDEFINITE_LENGTH)
3275 cbEncoded -= 2; /* space for 0 TLV */
3276 /* Check the inner length is valid: */
3277 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3281 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3282 pvStructInfo, pcbStructInfo, &decodedLen);
3283 if (dataLen == CMSG_INDEFINITE_LENGTH)
3285 if (*(pbEncoded + decodedLen) != 0 ||
3286 *(pbEncoded + decodedLen + 1) != 0)
3288 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3289 *(pbEncoded + decodedLen),
3290 *(pbEncoded + decodedLen + 1));
3291 SetLastError(CRYPT_E_ASN1_CORRUPT);
3297 if (ret && pcbDecoded)
3299 *pcbDecoded = 1 + lenBytes + decodedLen;
3300 TRACE("decoded %d bytes\n", *pcbDecoded);
3307 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3308 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3311 CRYPT_CONTENT_INFO *info = pvStructInfo;
3312 struct AsnDecodeSequenceItem items[] = {
3313 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3314 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3315 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3316 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3317 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3318 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3319 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3323 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3324 pvStructInfo, *pcbStructInfo, pcbDecoded);
3326 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3327 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3328 pcbDecoded, info ? info->pszObjId : NULL);
3332 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3333 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3334 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3338 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3339 pDecodePara, pvStructInfo, *pcbStructInfo);
3343 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3344 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3345 if (ret && pvStructInfo)
3347 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3348 pcbStructInfo, *pcbStructInfo);
3351 CRYPT_CONTENT_INFO *info;
3353 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3354 pvStructInfo = *(BYTE **)pvStructInfo;
3355 info = pvStructInfo;
3356 info->pszObjId = (LPSTR)((BYTE *)info +
3357 sizeof(CRYPT_CONTENT_INFO));
3358 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3359 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3360 pcbStructInfo, NULL);
3361 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3362 CRYPT_FreeSpace(pDecodePara, info);
3368 SetLastError(STATUS_ACCESS_VIOLATION);
3374 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3375 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3376 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3379 struct AsnDecodeSequenceItem items[] = {
3380 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3381 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3382 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3383 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3384 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3386 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3387 CRYPT_AsnDecodePKCSContentInfoInternal,
3388 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3389 ContentInfo.pszObjId), 0 },
3390 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3391 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3392 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3395 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3396 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3401 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3402 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3403 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3407 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3408 pDecodePara, pvStructInfo, *pcbStructInfo);
3414 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3415 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3418 *pcbStructInfo = bytesNeeded;
3419 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3420 pvStructInfo, pcbStructInfo, bytesNeeded)))
3422 CERT_ALT_NAME_INFO *name;
3424 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3425 pvStructInfo = *(BYTE **)pvStructInfo;
3426 name = pvStructInfo;
3427 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3428 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3429 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3430 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3431 &bytesNeeded, NULL);
3432 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3433 CRYPT_FreeSpace(pDecodePara, name);
3439 SetLastError(STATUS_ACCESS_VIOLATION);
3446 struct PATH_LEN_CONSTRAINT
3448 BOOL fPathLenConstraint;
3449 DWORD dwPathLenConstraint;
3452 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3453 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3457 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3459 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3460 pvStructInfo, *pcbStructInfo, pcbDecoded);
3464 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3466 *pcbStructInfo = bytesNeeded;
3468 else if (*pcbStructInfo < bytesNeeded)
3470 SetLastError(ERROR_MORE_DATA);
3471 *pcbStructInfo = bytesNeeded;
3476 struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3478 *pcbStructInfo = bytesNeeded;
3479 size = sizeof(constraint->dwPathLenConstraint);
3480 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3481 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3483 constraint->fPathLenConstraint = TRUE;
3484 TRACE("got an int, dwPathLenConstraint is %d\n",
3485 constraint->dwPathLenConstraint);
3487 TRACE("returning %d (%08x)\n", ret, GetLastError());
3491 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3492 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3496 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3497 offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3498 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
3499 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3500 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3501 offsetof(CERT_NAME_BLOB, pbData) };
3503 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3504 pvStructInfo, *pcbStructInfo, pcbDecoded);
3506 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3507 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3508 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3512 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3513 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3514 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3520 struct AsnDecodeSequenceItem items[] = {
3521 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3522 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3523 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3524 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3525 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3526 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3527 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3528 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3529 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3531 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3534 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3535 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3536 pcbStructInfo, NULL, NULL);
3540 SetLastError(STATUS_ACCESS_VIOLATION);
3547 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3548 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3549 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3555 struct AsnDecodeSequenceItem items[] = {
3556 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3557 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3558 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3559 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3560 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3563 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3564 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3565 pcbStructInfo, NULL, NULL);
3569 SetLastError(STATUS_ACCESS_VIOLATION);
3576 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
3577 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3580 struct AsnDecodeSequenceItem items[] = {
3581 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
3582 pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3583 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3585 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3586 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3587 offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3590 CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3592 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3593 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3595 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3596 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3597 pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3601 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
3602 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3606 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3607 offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3608 offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
3609 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
3610 CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
3611 offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3613 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3614 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3616 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3617 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3618 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3622 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
3623 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3625 struct AsnDecodeSequenceItem items[] = {
3626 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3627 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3628 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3629 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3630 CRYPT_AsnDecodePolicyQualifiers,
3631 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE,
3632 TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3634 CERT_POLICY_INFO *info = pvStructInfo;
3637 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3638 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3640 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3641 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3642 pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
3646 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
3647 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3648 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3652 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3653 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3657 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3658 offsetof(CERT_POLICIES_INFO, cPolicyInfo),
3659 offsetof(CERT_POLICIES_INFO, rgPolicyInfo),
3660 sizeof(CERT_POLICIES_INFO),
3661 CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
3662 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
3663 CERT_POLICIES_INFO *info = pvStructInfo;
3665 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3666 info->rgPolicyInfo = (CERT_POLICY_INFO *)(info + 1);
3668 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3669 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3673 SetLastError(STATUS_ACCESS_VIOLATION);
3679 static BOOL CRYPT_AsnDecodeCertPolicyMapping(const BYTE *pbEncoded,
3680 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3683 struct AsnDecodeSequenceItem items[] = {
3684 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
3685 pszIssuerDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3686 FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy), 0 },
3687 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
3688 pszSubjectDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3689 FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszSubjectDomainPolicy), 0 },
3691 CERT_POLICY_MAPPING *mapping = pvStructInfo;
3694 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3695 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3697 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3698 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3699 pcbDecoded, mapping ? mapping->pszIssuerDomainPolicy : NULL);
3703 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType,
3704 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3705 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3709 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3710 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3714 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3715 offsetof(CERT_POLICY_MAPPINGS_INFO, cPolicyMapping),
3716 offsetof(CERT_POLICY_MAPPINGS_INFO, rgPolicyMapping),
3717 sizeof(CERT_POLICY_MAPPING),
3718 CRYPT_AsnDecodeCertPolicyMapping, sizeof(CERT_POLICY_MAPPING), TRUE,
3719 offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy) };
3720 CERT_POLICY_MAPPINGS_INFO *info = pvStructInfo;
3722 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
3723 info->rgPolicyMapping = (CERT_POLICY_MAPPING *)(info + 1);
3724 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3725 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3729 SetLastError(STATUS_ACCESS_VIOLATION);
3735 static BOOL CRYPT_AsnDecodeRequireExplicit(const BYTE *pbEncoded,
3736 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3740 DWORD skip, size = sizeof(skip);
3744 SetLastError(CRYPT_E_ASN1_EOD);
3747 if (pbEncoded[0] != (ASN_CONTEXT | 0))
3749 SetLastError(CRYPT_E_ASN1_BADTAG);
3752 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3753 &skip, &size, pcbDecoded)))
3755 DWORD bytesNeeded = MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
3756 fRequireExplicitPolicy, fInhibitPolicyMapping);
3759 *pcbStructInfo = bytesNeeded;
3760 else if (*pcbStructInfo < bytesNeeded)
3762 *pcbStructInfo = bytesNeeded;
3763 SetLastError(ERROR_MORE_DATA);
3768 CERT_POLICY_CONSTRAINTS_INFO *info = CONTAINING_RECORD(pvStructInfo,
3769 CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy);
3771 *pcbStructInfo = bytesNeeded;
3772 /* The BOOL is implicit: if the integer is present, then it's
3775 info->fRequireExplicitPolicy = TRUE;
3776 info->dwRequireExplicitPolicySkipCerts = skip;
3782 static BOOL CRYPT_AsnDecodeInhibitMapping(const BYTE *pbEncoded,
3783 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3787 DWORD skip, size = sizeof(skip);
3791 SetLastError(CRYPT_E_ASN1_EOD);
3794 if (pbEncoded[0] != (ASN_CONTEXT | 1))
3796 SetLastError(CRYPT_E_ASN1_BADTAG);
3799 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3800 &skip, &size, pcbDecoded)))
3802 DWORD bytesNeeded = FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
3803 fInhibitPolicyMapping);
3806 *pcbStructInfo = bytesNeeded;
3807 else if (*pcbStructInfo < bytesNeeded)
3809 *pcbStructInfo = bytesNeeded;
3810 SetLastError(ERROR_MORE_DATA);
3815 CERT_POLICY_CONSTRAINTS_INFO *info = CONTAINING_RECORD(pvStructInfo,
3816 CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping);
3818 *pcbStructInfo = bytesNeeded;
3819 /* The BOOL is implicit: if the integer is present, then it's
3822 info->fInhibitPolicyMapping = TRUE;
3823 info->dwInhibitPolicyMappingSkipCerts = skip;
3829 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints(
3830 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
3831 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3832 void *pvStructInfo, DWORD *pcbStructInfo)
3836 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3837 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3841 struct AsnDecodeSequenceItem items[] = {
3843 offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy),
3844 CRYPT_AsnDecodeRequireExplicit,
3845 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy,
3846 fInhibitPolicyMapping), TRUE, FALSE, 0, 0 },
3848 offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3849 CRYPT_AsnDecodeInhibitMapping,
3850 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3851 TRUE, FALSE, 0, 0 },
3854 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3855 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3856 pcbStructInfo, NULL, NULL);
3860 SetLastError(STATUS_ACCESS_VIOLATION);
3866 #define RSA1_MAGIC 0x31415352
3868 struct DECODED_RSA_PUB_KEY
3871 CRYPT_INTEGER_BLOB modulus;
3874 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3875 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3876 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3882 struct AsnDecodeSequenceItem items[] = {
3883 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3884 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3885 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3887 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3888 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3890 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3893 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3894 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3898 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3899 decodedKey->modulus.cbData;
3903 *pcbStructInfo = bytesNeeded;
3906 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3907 pvStructInfo, pcbStructInfo, bytesNeeded)))
3910 RSAPUBKEY *rsaPubKey;
3912 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3913 pvStructInfo = *(BYTE **)pvStructInfo;
3915 hdr->bType = PUBLICKEYBLOB;
3916 hdr->bVersion = CUR_BLOB_VERSION;
3918 hdr->aiKeyAlg = CALG_RSA_KEYX;
3919 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3920 sizeof(BLOBHEADER));
3921 rsaPubKey->magic = RSA1_MAGIC;
3922 rsaPubKey->pubexp = decodedKey->pubexp;
3923 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3924 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3925 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3926 decodedKey->modulus.cbData);
3928 LocalFree(decodedKey);
3933 SetLastError(STATUS_ACCESS_VIOLATION);
3940 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3941 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3945 DWORD bytesNeeded, dataLen;
3947 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3948 pvStructInfo, *pcbStructInfo, pcbDecoded);
3950 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3952 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3954 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3955 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3957 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3959 *pcbDecoded = 1 + lenBytes + dataLen;
3961 *pcbStructInfo = bytesNeeded;
3962 else if (*pcbStructInfo < bytesNeeded)
3964 SetLastError(ERROR_MORE_DATA);
3965 *pcbStructInfo = bytesNeeded;
3970 CRYPT_DATA_BLOB *blob;
3972 *pcbStructInfo = bytesNeeded;
3973 blob = pvStructInfo;
3974 blob->cbData = dataLen;
3975 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3976 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
3979 assert(blob->pbData);
3981 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
3989 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
3990 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3991 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3995 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3996 pDecodePara, pvStructInfo, *pcbStructInfo);
4004 SetLastError(CRYPT_E_ASN1_CORRUPT);
4007 else if (pbEncoded[0] != ASN_OCTETSTRING)
4009 SetLastError(CRYPT_E_ASN1_BADTAG);
4012 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
4013 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4016 *pcbStructInfo = bytesNeeded;
4017 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4018 pvStructInfo, pcbStructInfo, bytesNeeded)))
4020 CRYPT_DATA_BLOB *blob;
4022 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4023 pvStructInfo = *(BYTE **)pvStructInfo;
4024 blob = pvStructInfo;
4025 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
4026 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
4027 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4028 &bytesNeeded, NULL);
4029 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4030 CRYPT_FreeSpace(pDecodePara, blob);
4036 SetLastError(STATUS_ACCESS_VIOLATION);
4043 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4044 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4047 DWORD bytesNeeded, dataLen;
4048 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4050 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
4051 pvStructInfo, *pcbStructInfo, pcbDecoded);
4053 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4055 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4056 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
4058 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
4060 *pcbDecoded = 1 + lenBytes + dataLen;
4062 *pcbStructInfo = bytesNeeded;
4063 else if (*pcbStructInfo < bytesNeeded)
4065 *pcbStructInfo = bytesNeeded;
4066 SetLastError(ERROR_MORE_DATA);
4071 CRYPT_BIT_BLOB *blob;
4073 *pcbStructInfo = bytesNeeded;
4074 blob = pvStructInfo;
4075 blob->cbData = dataLen - 1;
4076 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
4077 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4079 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
4083 assert(blob->pbData);
4086 BYTE mask = 0xff << blob->cUnusedBits;
4088 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
4090 blob->pbData[blob->cbData - 1] &= mask;
4098 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
4099 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4100 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4104 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
4105 pDecodePara, pvStructInfo, pcbStructInfo);
4113 SetLastError(CRYPT_E_ASN1_CORRUPT);
4116 else if (pbEncoded[0] != ASN_BITSTRING)
4118 SetLastError(CRYPT_E_ASN1_BADTAG);
4121 else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4122 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4125 *pcbStructInfo = bytesNeeded;
4126 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4127 pvStructInfo, pcbStructInfo, bytesNeeded)))
4129 CRYPT_BIT_BLOB *blob;
4131 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4132 pvStructInfo = *(BYTE **)pvStructInfo;
4133 blob = pvStructInfo;
4134 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
4135 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4136 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4137 &bytesNeeded, NULL);
4138 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4139 CRYPT_FreeSpace(pDecodePara, blob);
4145 SetLastError(STATUS_ACCESS_VIOLATION);
4149 TRACE("returning %d (%08x)\n", ret, GetLastError());
4153 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4154 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4155 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4160 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4162 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4165 *pcbDecoded = 1 + lenBytes + dataLen;
4166 if (dataLen > sizeof(int))
4168 SetLastError(CRYPT_E_ASN1_LARGE);
4171 else if (!pvStructInfo)
4172 *pcbStructInfo = sizeof(int);
4173 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
4177 if (dataLen && pbEncoded[1 + lenBytes] & 0x80)
4179 /* initialize to a negative value to sign-extend */
4184 for (i = 0; i < dataLen; i++)
4187 val |= pbEncoded[1 + lenBytes + i];
4189 memcpy(pvStructInfo, &val, sizeof(int));
4195 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
4196 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4197 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4207 SetLastError(CRYPT_E_ASN1_EOD);
4210 else if (pbEncoded[0] != ASN_INTEGER)
4212 SetLastError(CRYPT_E_ASN1_BADTAG);
4216 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4217 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4221 *pcbStructInfo = bytesNeeded;
4222 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4223 pvStructInfo, pcbStructInfo, bytesNeeded)))
4225 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4226 pvStructInfo = *(BYTE **)pvStructInfo;
4227 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4228 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4229 &bytesNeeded, NULL);
4230 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4231 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
4237 SetLastError(STATUS_ACCESS_VIOLATION);
4244 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
4245 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4249 DWORD bytesNeeded, dataLen;
4251 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4253 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4255 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4257 *pcbDecoded = 1 + lenBytes + dataLen;
4259 *pcbStructInfo = bytesNeeded;
4260 else if (*pcbStructInfo < bytesNeeded)
4262 *pcbStructInfo = bytesNeeded;
4263 SetLastError(ERROR_MORE_DATA);
4268 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4270 *pcbStructInfo = bytesNeeded;
4271 blob->cbData = dataLen;
4272 assert(blob->pbData);
4277 for (i = 0; i < blob->cbData; i++)
4279 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4288 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
4289 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4290 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4298 if (pbEncoded[0] != ASN_INTEGER)
4300 SetLastError(CRYPT_E_ASN1_BADTAG);
4304 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4305 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4309 *pcbStructInfo = bytesNeeded;
4310 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4311 pvStructInfo, pcbStructInfo, bytesNeeded)))
4313 CRYPT_INTEGER_BLOB *blob;
4315 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4316 pvStructInfo = *(BYTE **)pvStructInfo;
4317 blob = pvStructInfo;
4318 blob->pbData = (BYTE *)pvStructInfo +
4319 sizeof(CRYPT_INTEGER_BLOB);
4320 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4321 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4322 &bytesNeeded, NULL);
4323 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4324 CRYPT_FreeSpace(pDecodePara, blob);
4330 SetLastError(STATUS_ACCESS_VIOLATION);
4337 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
4338 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4343 if (pbEncoded[0] == ASN_INTEGER)
4345 DWORD bytesNeeded, dataLen;
4347 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4349 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4352 *pcbDecoded = 1 + lenBytes + dataLen;
4353 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4355 *pcbStructInfo = bytesNeeded;
4356 else if (*pcbStructInfo < bytesNeeded)
4358 *pcbStructInfo = bytesNeeded;
4359 SetLastError(ERROR_MORE_DATA);
4364 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4366 *pcbStructInfo = bytesNeeded;
4367 blob->cbData = dataLen;
4368 assert(blob->pbData);
4369 /* remove leading zero byte if it exists */
4370 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
4379 for (i = 0; i < blob->cbData; i++)
4381 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4390 SetLastError(CRYPT_E_ASN1_BADTAG);
4396 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
4397 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4398 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4406 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
4407 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4410 *pcbStructInfo = bytesNeeded;
4411 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4412 pvStructInfo, pcbStructInfo, bytesNeeded)))
4414 CRYPT_INTEGER_BLOB *blob;
4416 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4417 pvStructInfo = *(BYTE **)pvStructInfo;
4418 blob = pvStructInfo;
4419 blob->pbData = (BYTE *)pvStructInfo +
4420 sizeof(CRYPT_INTEGER_BLOB);
4421 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
4422 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4423 &bytesNeeded, NULL);
4424 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4425 CRYPT_FreeSpace(pDecodePara, blob);
4431 SetLastError(STATUS_ACCESS_VIOLATION);
4438 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
4439 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4440 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4446 *pcbStructInfo = sizeof(int);
4451 if (pbEncoded[0] == ASN_ENUMERATED)
4453 unsigned int val = 0, i;
4457 SetLastError(CRYPT_E_ASN1_EOD);
4460 else if (pbEncoded[1] == 0)
4462 SetLastError(CRYPT_E_ASN1_CORRUPT);
4467 /* A little strange looking, but we have to accept a sign byte:
4468 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4469 * assuming a small length is okay here, it has to be in short
4472 if (pbEncoded[1] > sizeof(unsigned int) + 1)
4474 SetLastError(CRYPT_E_ASN1_LARGE);
4477 for (i = 0; i < pbEncoded[1]; i++)
4480 val |= pbEncoded[2 + i];
4482 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4483 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
4485 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4486 pvStructInfo = *(BYTE **)pvStructInfo;
4487 memcpy(pvStructInfo, &val, sizeof(unsigned int));
4493 SetLastError(CRYPT_E_ASN1_BADTAG);
4499 SetLastError(STATUS_ACCESS_VIOLATION);
4506 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4509 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4514 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4516 if (!isdigit(*(pbEncoded))) \
4518 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4524 (word) += *(pbEncoded)++ - '0'; \
4529 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
4530 SYSTEMTIME *sysTime)
4534 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
4536 WORD hours, minutes = 0;
4537 BYTE sign = *pbEncoded++;
4540 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
4541 if (ret && hours >= 24)
4543 SetLastError(CRYPT_E_ASN1_CORRUPT);
4548 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
4549 if (ret && minutes >= 60)
4551 SetLastError(CRYPT_E_ASN1_CORRUPT);
4559 sysTime->wHour += hours;
4560 sysTime->wMinute += minutes;
4564 if (hours > sysTime->wHour)
4567 sysTime->wHour = 24 - (hours - sysTime->wHour);
4570 sysTime->wHour -= hours;
4571 if (minutes > sysTime->wMinute)
4574 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
4577 sysTime->wMinute -= minutes;
4584 #define MIN_ENCODED_TIME_LENGTH 10
4586 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
4587 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4592 if (pbEncoded[0] == ASN_UTCTIME)
4595 SetLastError(CRYPT_E_ASN1_EOD);
4596 else if (pbEncoded[1] > 0x7f)
4598 /* long-form date strings really can't be valid */
4599 SetLastError(CRYPT_E_ASN1_CORRUPT);
4603 SYSTEMTIME sysTime = { 0 };
4604 BYTE len = pbEncoded[1];
4606 if (len < MIN_ENCODED_TIME_LENGTH)
4607 SetLastError(CRYPT_E_ASN1_CORRUPT);
4612 *pcbDecoded = 2 + len;
4614 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
4615 if (sysTime.wYear >= 50)
4616 sysTime.wYear += 1900;
4618 sysTime.wYear += 2000;
4619 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4620 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4621 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4622 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
4625 if (len >= 2 && isdigit(*pbEncoded) &&
4626 isdigit(*(pbEncoded + 1)))
4627 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4629 else if (isdigit(*pbEncoded))
4630 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
4633 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4639 *pcbStructInfo = sizeof(FILETIME);
4640 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4642 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4648 SetLastError(CRYPT_E_ASN1_BADTAG);
4652 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
4653 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4654 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4662 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4663 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4667 *pcbStructInfo = bytesNeeded;
4668 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
4669 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
4671 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4672 pvStructInfo = *(BYTE **)pvStructInfo;
4673 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4674 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4675 &bytesNeeded, NULL);
4676 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4677 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
4683 SetLastError(STATUS_ACCESS_VIOLATION);
4689 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
4690 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4695 if (pbEncoded[0] == ASN_GENERALTIME)
4698 SetLastError(CRYPT_E_ASN1_EOD);
4699 else if (pbEncoded[1] > 0x7f)
4701 /* long-form date strings really can't be valid */
4702 SetLastError(CRYPT_E_ASN1_CORRUPT);
4706 BYTE len = pbEncoded[1];
4708 if (len < MIN_ENCODED_TIME_LENGTH)
4709 SetLastError(CRYPT_E_ASN1_CORRUPT);
4712 SYSTEMTIME sysTime = { 0 };
4716 *pcbDecoded = 2 + len;
4718 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
4719 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4720 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4721 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4724 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4727 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4729 if (ret && len > 0 && (*pbEncoded == '.' ||
4736 /* workaround macro weirdness */
4737 digits = min(len, 3);
4738 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
4739 sysTime.wMilliseconds);
4742 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4748 *pcbStructInfo = sizeof(FILETIME);
4749 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4751 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4757 SetLastError(CRYPT_E_ASN1_BADTAG);
4761 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
4762 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4766 InternalDecodeFunc decode = NULL;
4768 if (pbEncoded[0] == ASN_UTCTIME)
4769 decode = CRYPT_AsnDecodeUtcTimeInternal;
4770 else if (pbEncoded[0] == ASN_GENERALTIME)
4771 decode = CRYPT_AsnDecodeGeneralizedTime;
4773 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
4774 pcbStructInfo, pcbDecoded);
4777 SetLastError(CRYPT_E_ASN1_BADTAG);
4783 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
4784 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4785 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4793 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4794 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4798 *pcbStructInfo = bytesNeeded;
4799 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4800 pvStructInfo, pcbStructInfo, bytesNeeded)))
4802 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4803 pvStructInfo = *(BYTE **)pvStructInfo;
4804 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4805 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4806 &bytesNeeded, NULL);
4807 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4808 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
4814 SetLastError(STATUS_ACCESS_VIOLATION);
4821 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
4822 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4823 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4829 if (pbEncoded[0] == ASN_SEQUENCEOF)
4831 DWORD bytesNeeded, dataLen, remainingLen, cValue;
4833 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4838 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4839 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
4841 ptr = pbEncoded + 1 + lenBytes;
4842 remainingLen = dataLen;
4843 while (ret && remainingLen)
4847 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4850 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4852 remainingLen -= 1 + nextLenBytes + nextLen;
4853 ptr += 1 + nextLenBytes + nextLen;
4854 bytesNeeded += sizeof(CRYPT_DER_BLOB);
4855 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
4856 bytesNeeded += 1 + nextLenBytes + nextLen;
4862 CRYPT_SEQUENCE_OF_ANY *seq;
4867 *pcbStructInfo = bytesNeeded;
4868 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4869 pvStructInfo, pcbStructInfo, bytesNeeded)))
4871 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4872 pvStructInfo = *(BYTE **)pvStructInfo;
4874 seq->cValue = cValue;
4875 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
4877 nextPtr = (BYTE *)seq->rgValue +
4878 cValue * sizeof(CRYPT_DER_BLOB);
4879 ptr = pbEncoded + 1 + lenBytes;
4880 remainingLen = dataLen;
4882 while (ret && remainingLen)
4886 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4889 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4891 seq->rgValue[i].cbData = 1 + nextLenBytes +
4893 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4894 seq->rgValue[i].pbData = (BYTE *)ptr;
4897 seq->rgValue[i].pbData = nextPtr;
4898 memcpy(nextPtr, ptr, 1 + nextLenBytes +
4900 nextPtr += 1 + nextLenBytes + nextLen;
4902 remainingLen -= 1 + nextLenBytes + nextLen;
4903 ptr += 1 + nextLenBytes + nextLen;
4907 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
4908 CRYPT_FreeSpace(pDecodePara, seq);
4915 SetLastError(CRYPT_E_ASN1_BADTAG);
4921 SetLastError(STATUS_ACCESS_VIOLATION);
4928 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
4929 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4934 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
4936 DWORD bytesNeeded, dataLen;
4938 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4940 struct AsnArrayDescriptor arrayDesc = {
4941 ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4942 offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry),
4943 offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry),
4944 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u),
4945 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
4946 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
4947 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4952 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4953 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4954 dwFlags, NULL, NULL, &nameLen, NULL);
4955 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
4956 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u);
4959 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
4961 *pcbDecoded = 1 + lenBytes + dataLen;
4963 *pcbStructInfo = bytesNeeded;
4964 else if (*pcbStructInfo < bytesNeeded)
4966 *pcbStructInfo = bytesNeeded;
4967 SetLastError(ERROR_MORE_DATA);
4972 CRL_DIST_POINT_NAME *name = pvStructInfo;
4974 *pcbStructInfo = bytesNeeded;
4977 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
4978 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4979 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4980 dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen,
4984 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
4990 SetLastError(CRYPT_E_ASN1_BADTAG);
4996 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
4997 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4999 struct AsnDecodeSequenceItem items[] = {
5000 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
5001 DistPointName), CRYPT_AsnDecodeDistPointName,
5002 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
5003 DistPointName.u.FullName.rgAltEntry), 0 },
5004 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
5005 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
5006 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
5007 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
5008 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
5009 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
5011 CRL_DIST_POINT *point = pvStructInfo;
5014 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5015 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5016 pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
5020 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
5021 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5022 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5026 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5027 pDecodePara, pvStructInfo, *pcbStructInfo);
5031 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5032 offsetof(CRL_DIST_POINTS_INFO, cDistPoint),
5033 offsetof(CRL_DIST_POINTS_INFO, rgDistPoint),
5034 sizeof(CRL_DIST_POINTS_INFO),
5035 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
5036 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
5037 CRL_DIST_POINTS_INFO *info = pvStructInfo;
5039 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5040 info->rgDistPoint = (CRL_DIST_POINT *)(info + 1);
5041 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5042 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
5046 SetLastError(STATUS_ACCESS_VIOLATION);
5053 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
5054 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5055 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5059 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5060 pDecodePara, pvStructInfo, *pcbStructInfo);
5064 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5065 offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier),
5066 offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier),
5067 sizeof(CERT_ENHKEY_USAGE),
5068 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
5069 CERT_ENHKEY_USAGE *usage = pvStructInfo;
5071 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5072 usage->rgpszUsageIdentifier = (LPSTR *)(usage + 1);
5073 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5074 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
5078 SetLastError(STATUS_ACCESS_VIOLATION);
5085 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
5086 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5087 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5091 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5092 pDecodePara, pvStructInfo, *pcbStructInfo);
5096 struct AsnDecodeSequenceItem items[] = {
5097 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
5098 DistPointName), CRYPT_AsnDecodeDistPointName,
5099 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
5100 offsetof(CRL_ISSUING_DIST_POINT,
5101 DistPointName.u.FullName.rgAltEntry), 0 },
5102 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
5103 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5105 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
5106 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5108 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
5109 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
5110 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
5111 OnlySomeReasonFlags.pbData), 0 },
5112 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
5113 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
5116 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5117 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5118 pcbStructInfo, NULL, NULL);
5122 SetLastError(STATUS_ACCESS_VIOLATION);
5129 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
5130 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5134 DWORD max, size = sizeof(max);
5136 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5137 pvStructInfo, *pcbStructInfo, pcbDecoded);
5141 SetLastError(CRYPT_E_ASN1_EOD);
5144 if (pbEncoded[0] != (ASN_CONTEXT | 1))
5146 SetLastError(CRYPT_E_ASN1_BADTAG);
5149 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
5150 &max, &size, pcbDecoded)))
5152 DWORD bytesNeeded = FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum);
5155 *pcbStructInfo = bytesNeeded;
5156 else if (*pcbStructInfo < bytesNeeded)
5158 *pcbStructInfo = bytesNeeded;
5159 SetLastError(ERROR_MORE_DATA);
5164 CERT_GENERAL_SUBTREE *subtree = CONTAINING_RECORD(pvStructInfo,
5165 CERT_GENERAL_SUBTREE, fMaximum);
5167 *pcbStructInfo = bytesNeeded;
5168 /* The BOOL is implicit: if the integer is present, then it's
5171 subtree->fMaximum = TRUE;
5172 subtree->dwMaximum = max;
5175 TRACE("returning %d\n", ret);
5179 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
5180 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5184 struct AsnDecodeSequenceItem items[] = {
5185 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
5186 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
5187 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
5188 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
5189 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
5190 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
5191 CRYPT_AsnDecodeMaximum, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum),
5192 TRUE, FALSE, 0, 0 },
5194 CERT_GENERAL_SUBTREE *subtree = pvStructInfo;
5196 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5197 pvStructInfo, *pcbStructInfo, pcbDecoded);
5199 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5200 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5201 pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
5204 TRACE("%d\n", *pcbDecoded);
5205 if (*pcbDecoded < cbEncoded)
5206 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
5207 *(pbEncoded + *pcbDecoded + 1));
5209 TRACE("returning %d\n", ret);
5213 static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded,
5214 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5218 struct AsnArrayDescriptor arrayDesc = { 0,
5219 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5220 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree),
5221 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5223 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5224 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5226 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5227 pvStructInfo, *pcbStructInfo, pcbDecoded);
5229 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5230 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5234 static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded,
5235 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5239 struct AsnArrayDescriptor arrayDesc = { 0,
5240 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5241 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree),
5242 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5243 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5244 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5246 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5247 pvStructInfo, *pcbStructInfo, pcbDecoded);
5249 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5250 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5254 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
5255 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5256 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5260 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5261 pDecodePara, pvStructInfo, *pcbStructInfo);
5265 struct AsnDecodeSequenceItem items[] = {
5266 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
5267 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5268 CRYPT_AsnDecodePermittedSubtree,
5269 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5270 cExcludedSubtree), TRUE, TRUE,
5271 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
5272 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
5273 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5274 CRYPT_AsnDecodeExcludedSubtree,
5275 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5277 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
5280 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5281 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5282 pcbStructInfo, NULL, NULL);
5286 SetLastError(STATUS_ACCESS_VIOLATION);
5292 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
5293 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5297 struct AsnDecodeSequenceItem items[] = {
5298 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
5299 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
5301 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
5302 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
5303 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
5305 CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;
5307 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5308 pvStructInfo, *pcbStructInfo, pcbDecoded);
5310 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5311 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5312 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
5313 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
5315 SetLastError(CRYPT_E_ASN1_CORRUPT);
5318 TRACE("returning %d\n", ret);
5322 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
5323 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5326 CMSG_SIGNER_INFO *info = pvStructInfo;
5327 struct AsnDecodeSequenceItem items[] = {
5328 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
5329 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5330 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
5331 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
5332 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
5333 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
5334 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5335 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5336 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5337 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
5338 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5339 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5340 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
5341 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5342 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
5343 HashEncryptionAlgorithm.pszObjId), 0 },
5344 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
5345 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5346 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
5347 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5348 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
5349 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5350 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5354 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5355 pvStructInfo, *pcbStructInfo);
5357 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5358 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5359 pcbDecoded, info ? info->Issuer.pbData : NULL);
5363 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
5364 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5365 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5369 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5370 pDecodePara, pvStructInfo, *pcbStructInfo);
5374 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
5375 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5376 if (ret && pvStructInfo)
5378 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5379 pcbStructInfo, *pcbStructInfo);
5382 CMSG_SIGNER_INFO *info;
5384 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5385 pvStructInfo = *(BYTE **)pvStructInfo;
5386 info = pvStructInfo;
5387 info->Issuer.pbData = ((BYTE *)info +
5388 sizeof(CMSG_SIGNER_INFO));
5389 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
5390 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5391 pcbStructInfo, NULL);
5392 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5393 CRYPT_FreeSpace(pDecodePara, info);
5399 SetLastError(STATUS_ACCESS_VIOLATION);
5402 TRACE("returning %d\n", ret);
5406 static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded,
5407 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5411 struct AsnArrayDescriptor arrayDesc = { 0,
5412 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
5413 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded),
5414 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded),
5415 CRYPT_AsnDecodeCopyBytes,
5416 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5418 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5419 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5421 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5422 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5426 static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded,
5427 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5431 struct AsnArrayDescriptor arrayDesc = { 0,
5432 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded),
5433 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded),
5434 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content),
5435 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB),
5436 TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5438 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5439 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5441 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5442 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5446 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
5447 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5450 CERT_ID *id = pvStructInfo;
5453 if (*pbEncoded == ASN_SEQUENCEOF)
5455 ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
5456 id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
5460 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5461 if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
5462 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5463 sizeof(CERT_ISSUER_SERIAL_NUMBER);
5465 *pcbStructInfo = sizeof(CERT_ID);
5468 else if (*pbEncoded == (ASN_CONTEXT | 0))
5470 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
5471 id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
5475 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5476 if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
5477 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5478 sizeof(CRYPT_DATA_BLOB);
5480 *pcbStructInfo = sizeof(CERT_ID);
5484 SetLastError(CRYPT_E_ASN1_BADTAG);
5488 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
5489 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5492 CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
5493 struct AsnDecodeSequenceItem items[] = {
5494 { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
5495 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5496 { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
5497 CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
5498 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
5499 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
5500 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5501 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5502 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5503 offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
5504 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5505 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5506 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
5507 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5508 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
5509 HashEncryptionAlgorithm.pszObjId), 0 },
5510 { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
5511 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5512 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
5513 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5514 offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
5515 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5516 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5520 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5521 pvStructInfo, *pcbStructInfo);
5523 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5524 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5525 pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
5529 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
5530 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5531 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5535 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5536 pDecodePara, pvStructInfo, *pcbStructInfo);
5540 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
5541 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5542 if (ret && pvStructInfo)
5544 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5545 pcbStructInfo, *pcbStructInfo);
5548 CMSG_CMS_SIGNER_INFO *info;
5550 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5551 pvStructInfo = *(BYTE **)pvStructInfo;
5552 info = pvStructInfo;
5553 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
5554 sizeof(CMSG_CMS_SIGNER_INFO));
5555 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
5556 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5557 pcbStructInfo, NULL);
5558 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
5559 CRYPT_FreeSpace(pDecodePara, info);
5565 SetLastError(STATUS_ACCESS_VIOLATION);
5568 TRACE("returning %d\n", ret);
5572 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
5573 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5576 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5577 offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5578 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo),
5579 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo),
5580 CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
5581 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
5583 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5584 pvStructInfo, *pcbStructInfo, pcbDecoded);
5586 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5587 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5591 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5592 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5593 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
5596 struct AsnDecodeSequenceItem items[] = {
5597 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
5598 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5599 /* Placeholder for the hash algorithms - redundant with those in the
5600 * signers, so just ignore them.
5602 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5603 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
5604 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
5605 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
5606 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5607 offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded,
5608 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE,
5609 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
5610 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5611 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded,
5612 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE,
5613 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
5614 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5615 CRYPT_DecodeSignerArray,
5616 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE,
5617 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
5620 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5621 pDecodePara, signedInfo, *pcbSignedInfo);
5623 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5624 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
5626 TRACE("returning %d\n", ret);
5630 static BOOL CRYPT_AsnDecodeRecipientInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5631 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5634 CMSG_KEY_TRANS_RECIPIENT_INFO *info = pvStructInfo;
5635 struct AsnDecodeSequenceItem items[] = {
5636 { ASN_INTEGER, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, dwVersion),
5637 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5638 { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5639 RecipientId.u.IssuerSerialNumber), CRYPT_AsnDecodeIssuerSerialNumber,
5640 sizeof(CERT_ISSUER_SERIAL_NUMBER), FALSE, TRUE,
5641 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5642 RecipientId.u.IssuerSerialNumber.Issuer.pbData), 0 },
5643 { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5644 KeyEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId,
5645 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
5646 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5647 KeyEncryptionAlgorithm.pszObjId), 0 },
5648 { ASN_OCTETSTRING, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, EncryptedKey),
5649 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
5650 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, EncryptedKey.pbData), 0 },
5653 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5654 pvStructInfo, *pcbStructInfo, pcbDecoded);
5656 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5657 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5658 pcbDecoded, info ? info->RecipientId.u.IssuerSerialNumber.Issuer.pbData :
5661 info->RecipientId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5662 TRACE("returning %d\n", ret);
5666 static BOOL CRYPT_DecodeRecipientInfoArray(const BYTE *pbEncoded,
5667 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5671 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5672 offsetof(CRYPT_ENVELOPED_DATA, cRecipientInfo),
5673 offsetof(CRYPT_ENVELOPED_DATA, rgRecipientInfo),
5674 MEMBERSIZE(CRYPT_ENVELOPED_DATA, cRecipientInfo, encryptedContentInfo),
5675 CRYPT_AsnDecodeRecipientInfo, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO), TRUE,
5676 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5677 RecipientId.u.IssuerSerialNumber.Issuer.pbData) };
5679 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5680 pvStructInfo, *pcbStructInfo, pcbDecoded);
5682 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5683 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5684 TRACE("returning %d\n", ret);
5688 static BOOL CRYPT_AsnDecodeEncryptedContentInfo(const BYTE *pbEncoded,
5689 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5693 CRYPT_ENCRYPTED_CONTENT_INFO *info = pvStructInfo;
5694 struct AsnDecodeSequenceItem items[] = {
5695 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5696 contentType), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
5697 FALSE, TRUE, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5699 { ASN_SEQUENCEOF, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5700 contentEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId,
5701 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
5702 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5703 contentEncryptionAlgorithm.pszObjId), 0 },
5704 { ASN_CONTEXT | 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5705 encryptedContent), CRYPT_AsnDecodeOctetsInternal,
5706 sizeof(CRYPT_DATA_BLOB), TRUE, TRUE,
5707 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO, encryptedContent.pbData) },
5710 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5711 pvStructInfo, *pcbStructInfo, pcbDecoded);
5713 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5714 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5715 pcbDecoded, info ? info->contentType : NULL);
5716 TRACE("returning %d\n", ret);
5720 BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
5721 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5722 CRYPT_ENVELOPED_DATA *envelopedData, DWORD *pcbEnvelopedData)
5725 struct AsnDecodeSequenceItem items[] = {
5726 { ASN_INTEGER, offsetof(CRYPT_ENVELOPED_DATA, version),
5727 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5728 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ENVELOPED_DATA,
5729 cRecipientInfo), CRYPT_DecodeRecipientInfoArray,
5730 MEMBERSIZE(CRYPT_ENVELOPED_DATA, cRecipientInfo, encryptedContentInfo),
5731 FALSE, TRUE, offsetof(CRYPT_ENVELOPED_DATA, rgRecipientInfo), 0 },
5732 { ASN_SEQUENCEOF, offsetof(CRYPT_ENVELOPED_DATA, encryptedContentInfo),
5733 CRYPT_AsnDecodeEncryptedContentInfo,
5734 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO), FALSE, TRUE,
5735 offsetof(CRYPT_ENVELOPED_DATA, encryptedContentInfo.contentType), 0 },
5738 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5739 pDecodePara, envelopedData, *pcbEnvelopedData);
5741 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5742 pbEncoded, cbEncoded, dwFlags, pDecodePara, envelopedData,
5743 pcbEnvelopedData, NULL, NULL);
5744 TRACE("returning %d\n", ret);
5748 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
5749 LPCSTR lpszStructType)
5751 CryptDecodeObjectExFunc decodeFunc = NULL;
5753 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
5754 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
5756 SetLastError(ERROR_FILE_NOT_FOUND);
5759 if (IS_INTOID(lpszStructType))
5761 switch (LOWORD(lpszStructType))
5763 case LOWORD(X509_CERT):
5764 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
5766 case LOWORD(X509_CERT_TO_BE_SIGNED):
5767 decodeFunc = CRYPT_AsnDecodeCert;
5769 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
5770 decodeFunc = CRYPT_AsnDecodeCRL;
5772 case LOWORD(X509_EXTENSIONS):
5773 decodeFunc = CRYPT_AsnDecodeExtensions;
5775 case LOWORD(X509_NAME_VALUE):
5776 decodeFunc = CRYPT_AsnDecodeNameValue;
5778 case LOWORD(X509_NAME):
5779 decodeFunc = CRYPT_AsnDecodeName;
5781 case LOWORD(X509_PUBLIC_KEY_INFO):
5782 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
5784 case LOWORD(X509_AUTHORITY_KEY_ID):
5785 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5787 case LOWORD(X509_ALTERNATE_NAME):
5788 decodeFunc = CRYPT_AsnDecodeAltName;
5790 case LOWORD(X509_BASIC_CONSTRAINTS):
5791 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5793 case LOWORD(X509_BASIC_CONSTRAINTS2):
5794 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5796 case LOWORD(X509_CERT_POLICIES):
5797 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5799 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
5800 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
5802 case LOWORD(X509_UNICODE_NAME):
5803 decodeFunc = CRYPT_AsnDecodeUnicodeName;
5805 case LOWORD(PKCS_ATTRIBUTE):
5806 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
5808 case LOWORD(X509_UNICODE_NAME_VALUE):
5809 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
5811 case LOWORD(X509_OCTET_STRING):
5812 decodeFunc = CRYPT_AsnDecodeOctets;
5814 case LOWORD(X509_BITS):
5815 case LOWORD(X509_KEY_USAGE):
5816 decodeFunc = CRYPT_AsnDecodeBits;
5818 case LOWORD(X509_INTEGER):
5819 decodeFunc = CRYPT_AsnDecodeInt;
5821 case LOWORD(X509_MULTI_BYTE_INTEGER):
5822 decodeFunc = CRYPT_AsnDecodeInteger;
5824 case LOWORD(X509_MULTI_BYTE_UINT):
5825 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
5827 case LOWORD(X509_ENUMERATED):
5828 decodeFunc = CRYPT_AsnDecodeEnumerated;
5830 case LOWORD(X509_CHOICE_OF_TIME):
5831 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
5833 case LOWORD(X509_AUTHORITY_KEY_ID2):
5834 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5836 case LOWORD(X509_AUTHORITY_INFO_ACCESS):
5837 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5839 case LOWORD(PKCS_CONTENT_INFO):
5840 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
5842 case LOWORD(X509_SEQUENCE_OF_ANY):
5843 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
5845 case LOWORD(PKCS_UTC_TIME):
5846 decodeFunc = CRYPT_AsnDecodeUtcTime;
5848 case LOWORD(X509_CRL_DIST_POINTS):
5849 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5851 case LOWORD(X509_ENHANCED_KEY_USAGE):
5852 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5854 case LOWORD(PKCS_CTL):
5855 decodeFunc = CRYPT_AsnDecodeCTL;
5857 case LOWORD(PKCS_SMIME_CAPABILITIES):
5858 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5860 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
5861 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5863 case LOWORD(PKCS_ATTRIBUTES):
5864 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
5866 case LOWORD(X509_ISSUING_DIST_POINT):
5867 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5869 case LOWORD(X509_NAME_CONSTRAINTS):
5870 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5872 case LOWORD(X509_POLICY_MAPPINGS):
5873 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5875 case LOWORD(X509_POLICY_CONSTRAINTS):
5876 decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
5878 case LOWORD(PKCS7_SIGNER_INFO):
5879 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
5881 case LOWORD(CMS_SIGNER_INFO):
5882 decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
5886 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
5887 decodeFunc = CRYPT_AsnDecodeExtensions;
5888 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
5889 decodeFunc = CRYPT_AsnDecodeUtcTime;
5890 else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
5891 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5892 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
5893 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5894 else if (!strcmp(lpszStructType, szOID_LEGACY_POLICY_MAPPINGS))
5895 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5896 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
5897 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5898 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
5899 decodeFunc = CRYPT_AsnDecodeEnumerated;
5900 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
5901 decodeFunc = CRYPT_AsnDecodeBits;
5902 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
5903 decodeFunc = CRYPT_AsnDecodeOctets;
5904 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
5905 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5906 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
5907 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5908 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
5909 decodeFunc = CRYPT_AsnDecodeAltName;
5910 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
5911 decodeFunc = CRYPT_AsnDecodeAltName;
5912 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
5913 decodeFunc = CRYPT_AsnDecodeAltName;
5914 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
5915 decodeFunc = CRYPT_AsnDecodeAltName;
5916 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
5917 decodeFunc = CRYPT_AsnDecodeAltName;
5918 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
5919 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5920 else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
5921 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5922 else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS))
5923 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5924 else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS))
5925 decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
5926 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
5927 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5928 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
5929 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5930 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
5931 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5932 else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
5933 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5934 else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
5935 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5936 else if (!strcmp(lpszStructType, szOID_CTL))
5937 decodeFunc = CRYPT_AsnDecodeCTL;
5941 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
5942 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5944 static HCRYPTOIDFUNCSET set = NULL;
5945 CryptDecodeObjectFunc decodeFunc = NULL;
5948 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
5949 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5950 (void **)&decodeFunc, hFunc);
5954 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
5955 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5957 static HCRYPTOIDFUNCSET set = NULL;
5958 CryptDecodeObjectExFunc decodeFunc = NULL;
5961 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
5962 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5963 (void **)&decodeFunc, hFunc);
5967 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5968 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
5969 DWORD *pcbStructInfo)
5972 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
5973 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
5974 HCRYPTOIDFUNCADDR hFunc = NULL;
5976 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
5977 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
5978 pvStructInfo, pcbStructInfo);
5980 if (!pvStructInfo && !pcbStructInfo)
5982 SetLastError(ERROR_INVALID_PARAMETER);
5985 if (cbEncoded > MAX_ENCODED_LEN)
5987 SetLastError(CRYPT_E_ASN1_LARGE);
5991 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
5994 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5995 debugstr_a(lpszStructType));
5996 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
5997 lpszStructType, &hFunc);
5998 if (!pCryptDecodeObject)
5999 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
6000 lpszStructType, &hFunc);
6002 if (pCryptDecodeObject)
6003 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6004 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
6005 else if (pCryptDecodeObjectEx)
6006 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
6007 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
6008 pvStructInfo, pcbStructInfo);
6010 CryptFreeOIDFunctionAddress(hFunc, 0);
6011 TRACE_(crypt)("returning %d\n", ret);
6015 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
6016 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
6017 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
6020 CryptDecodeObjectExFunc decodeFunc;
6021 HCRYPTOIDFUNCADDR hFunc = NULL;
6023 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6024 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
6025 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
6027 if (!pvStructInfo && !pcbStructInfo)
6029 SetLastError(ERROR_INVALID_PARAMETER);
6032 if (cbEncoded > MAX_ENCODED_LEN)
6034 SetLastError(CRYPT_E_ASN1_LARGE);
6038 SetLastError(NOERROR);
6039 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
6043 SetLastError(ERROR_INVALID_PARAMETER);
6046 *(BYTE **)pvStructInfo = NULL;
6048 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
6051 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
6052 debugstr_a(lpszStructType));
6053 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
6057 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
6058 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
6061 CryptDecodeObjectFunc pCryptDecodeObject =
6062 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
6064 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6065 * directly, as that could cause an infinite loop.
6067 if (pCryptDecodeObject)
6069 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
6071 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6072 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
6073 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
6074 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
6076 ret = pCryptDecodeObject(dwCertEncodingType,
6077 lpszStructType, pbEncoded, cbEncoded, dwFlags,
6078 *(BYTE **)pvStructInfo, pcbStructInfo);
6080 CRYPT_FreeSpace(pDecodePara, *(BYTE **)pvStructInfo);
6084 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6085 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
6089 CryptFreeOIDFunctionAddress(hFunc, 0);
6090 TRACE_(crypt)("returning %d\n", ret);
6094 BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
6098 TRACE_(crypt)("(%p)\n", pPFX);
6100 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6101 * version integer of length 1 (3 encoded byes) and at least one other
6102 * datum (two encoded bytes), plus at least two bytes for the outer
6103 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6105 if (pPFX->cbData < 7)
6107 else if (pPFX->pbData[0] == ASN_SEQUENCE)
6111 if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
6113 BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);
6115 /* Need at least three bytes for the integer version */
6116 if (pPFX->cbData < 1 + lenLen + 3)
6118 else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
6119 pPFX->pbData[1 + lenLen + 1] != 1 || /* Definite length */
6120 pPFX->pbData[1 + lenLen + 2] != 3) /* PFX version */
6129 HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
6132 FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);
6136 BOOL WINAPI PFXVerifyPassword(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
6139 FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);