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;
764 if (itemSizes != &itemSize)
765 CryptMemFree(itemSizes);
770 SetLastError(CRYPT_E_ASN1_BADTAG);
776 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
777 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
778 * to CRYPT_E_ASN1_CORRUPT.
779 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
782 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
783 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
788 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
790 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
791 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
793 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
794 bytesNeeded += 1 + lenBytes + dataLen;
797 *pcbDecoded = 1 + lenBytes + dataLen;
799 *pcbStructInfo = bytesNeeded;
800 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
802 CRYPT_DER_BLOB *blob;
804 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
805 pvStructInfo = *(BYTE **)pvStructInfo;
807 blob->cbData = 1 + lenBytes + dataLen;
810 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
811 blob->pbData = (BYTE *)pbEncoded;
814 assert(blob->pbData);
815 memcpy(blob->pbData, pbEncoded, blob->cbData);
820 SetLastError(CRYPT_E_ASN1_CORRUPT);
828 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
829 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
830 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
835 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
836 pvStructInfo, *pcbStructInfo, pcbDecoded);
838 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
841 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
842 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
844 if (ret && pvStructInfo)
846 CRYPT_BIT_BLOB *blob = pvStructInfo;
853 for (i = 0; i < blob->cbData / 2; i++)
855 temp = blob->pbData[i];
856 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
857 blob->pbData[blob->cbData - i - 1] = temp;
861 TRACE("returning %d (%08x)\n", ret, GetLastError());
865 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
866 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
867 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
871 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
872 pDecodePara, pvStructInfo, *pcbStructInfo);
876 struct AsnDecodeSequenceItem items[] = {
877 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
878 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
879 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
880 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
881 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
882 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
883 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
884 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
885 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
886 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
889 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
890 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
891 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
892 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
893 pcbStructInfo, NULL, NULL);
897 SetLastError(STATUS_ACCESS_VIOLATION);
902 TRACE("Returning %d (%08x)\n", ret, GetLastError());
906 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
907 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
912 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
914 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
916 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
917 dwFlags, pvStructInfo, pcbStructInfo, NULL);
919 *pcbDecoded = 1 + lenBytes + dataLen;
924 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
925 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
929 struct AsnDecodeSequenceItem items[] = {
930 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
931 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
932 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
933 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
936 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
937 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
942 static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded,
943 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
947 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
948 offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
949 FINALMEMBERSIZE(CERT_INFO, cExtension),
950 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
951 offsetof(CERT_EXTENSION, pszObjId) };
953 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
954 pvStructInfo, *pcbStructInfo, pcbDecoded);
956 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
957 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
961 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
962 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
968 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
970 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
972 ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes,
973 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
974 if (ret && pcbDecoded)
975 *pcbDecoded = 1 + lenBytes + dataLen;
980 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
981 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
982 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
985 struct AsnDecodeSequenceItem items[] = {
986 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
987 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
988 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
989 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
990 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
991 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
992 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
993 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
994 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
995 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
997 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
998 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
1000 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
1001 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
1003 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
1004 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
1005 FALSE, TRUE, offsetof(CERT_INFO,
1006 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
1007 { ASN_CONTEXT | 1, offsetof(CERT_INFO, IssuerUniqueId),
1008 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1009 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
1010 { ASN_CONTEXT | 2, offsetof(CERT_INFO, SubjectUniqueId),
1011 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1012 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
1013 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
1014 CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension),
1015 TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
1018 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1019 pDecodePara, pvStructInfo, *pcbStructInfo);
1021 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1022 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1024 if (ret && pvStructInfo)
1028 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1029 info = *(CERT_INFO **)pvStructInfo;
1031 info = pvStructInfo;
1032 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1033 !info->Subject.cbData)
1035 SetLastError(CRYPT_E_ASN1_CORRUPT);
1036 /* Don't need to deallocate, because it should have failed on the
1037 * first pass (and no memory was allocated.)
1043 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1047 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1048 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1049 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1053 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1054 pDecodePara, pvStructInfo, *pcbStructInfo);
1060 /* Unless told not to, first try to decode it as a signed cert. */
1061 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1063 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1065 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1066 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1067 &signedCert, &size);
1071 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1072 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1073 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1074 pvStructInfo, pcbStructInfo);
1075 LocalFree(signedCert);
1078 /* Failing that, try it as an unsigned cert */
1082 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1083 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1084 pDecodePara, pvStructInfo, pcbStructInfo);
1089 SetLastError(STATUS_ACCESS_VIOLATION);
1093 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1097 static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded,
1098 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1102 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1103 offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
1104 FINALMEMBERSIZE(CRL_ENTRY, cExtension),
1105 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1106 offsetof(CERT_EXTENSION, pszObjId) };
1108 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1109 pvStructInfo, *pcbStructInfo, pcbDecoded);
1111 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1112 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1116 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1117 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1120 struct AsnDecodeSequenceItem items[] = {
1121 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1122 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1123 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1124 { 0, offsetof(CRL_ENTRY, RevocationDate),
1125 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1126 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1127 CRYPT_AsnDecodeCRLEntryExtensions,
1128 FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
1129 offsetof(CRL_ENTRY, rgExtension), 0 },
1131 PCRL_ENTRY entry = pvStructInfo;
1133 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1136 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1137 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1138 entry ? entry->SerialNumber.pbData : NULL);
1139 if (ret && entry && !entry->SerialNumber.cbData)
1141 WARN("empty CRL entry serial number\n");
1142 SetLastError(CRYPT_E_ASN1_CORRUPT);
1148 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1149 * whose rgCRLEntry member has been set prior to calling.
1151 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1152 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1155 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1156 offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
1157 MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1158 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1159 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1161 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1162 pvStructInfo, *pcbStructInfo, pcbDecoded);
1164 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1165 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1166 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1170 static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded,
1171 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1175 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1176 offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
1177 FINALMEMBERSIZE(CRL_INFO, cExtension),
1178 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1179 offsetof(CERT_EXTENSION, pszObjId) };
1181 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1182 pvStructInfo, *pcbStructInfo, pcbDecoded);
1184 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1185 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1189 static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded,
1190 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1196 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1198 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1200 ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes,
1201 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1202 if (ret && pcbDecoded)
1203 *pcbDecoded = 1 + lenBytes + dataLen;
1208 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1209 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1210 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1212 struct AsnDecodeSequenceItem items[] = {
1213 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1214 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1215 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1216 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1217 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1218 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1219 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1221 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1222 sizeof(FILETIME), FALSE, FALSE, 0 },
1223 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1224 sizeof(FILETIME), TRUE, FALSE, 0 },
1225 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1226 CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1227 TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
1228 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1229 CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension),
1230 TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
1234 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1235 pDecodePara, pvStructInfo, *pcbStructInfo);
1237 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1238 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1241 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1245 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1246 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1247 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1251 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1252 pDecodePara, pvStructInfo, *pcbStructInfo);
1258 /* Unless told not to, first try to decode it as a signed crl. */
1259 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1261 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1263 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1264 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1269 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1270 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1271 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1272 pvStructInfo, pcbStructInfo);
1273 LocalFree(signedCrl);
1276 /* Failing that, try it as an unsigned crl */
1280 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1281 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1282 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1287 SetLastError(STATUS_ACCESS_VIOLATION);
1291 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1295 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1296 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1301 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1302 pvStructInfo, *pcbStructInfo);
1304 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1306 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1307 DWORD bytesNeeded = sizeof(LPSTR);
1311 /* The largest possible string for the first two components
1312 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1317 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1318 pbEncoded[1 + lenBytes] / 40,
1319 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1321 bytesNeeded += strlen(firstTwo) + 1;
1322 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1323 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1325 /* large enough for ".4000000" */
1329 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1336 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1339 SetLastError(CRYPT_E_ASN1_CORRUPT);
1346 snprintf(str, sizeof(str), ".%d", val);
1347 bytesNeeded += strlen(str);
1352 *pcbDecoded = 1 + lenBytes + dataLen;
1354 *pcbStructInfo = bytesNeeded;
1355 else if (*pcbStructInfo < bytesNeeded)
1357 *pcbStructInfo = bytesNeeded;
1358 SetLastError(ERROR_MORE_DATA);
1366 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1369 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1370 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1372 pszObjId += strlen(pszObjId);
1373 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1374 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1378 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1387 sprintf(pszObjId, ".%d", val);
1388 pszObjId += strlen(pszObjId);
1392 *(LPSTR *)pvStructInfo = NULL;
1393 *pcbStructInfo = bytesNeeded;
1399 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1400 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1404 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1405 pvStructInfo, *pcbStructInfo);
1407 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1408 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1409 pvStructInfo, pcbStructInfo, pcbDecoded);
1412 SetLastError(CRYPT_E_ASN1_BADTAG);
1418 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1419 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1421 struct AsnDecodeSequenceItem items[] = {
1422 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1423 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1424 offsetof(CERT_EXTENSION, pszObjId), 0 },
1425 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1426 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1427 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1428 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1429 offsetof(CERT_EXTENSION, Value.pbData) },
1432 PCERT_EXTENSION ext = pvStructInfo;
1434 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1438 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1439 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1440 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1441 pcbDecoded, ext ? ext->pszObjId : NULL);
1443 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1444 debugstr_a(ext->pszObjId));
1445 TRACE("returning %d (%08x)\n", ret, GetLastError());
1449 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1450 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1451 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1455 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1456 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1460 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1461 offsetof(CERT_EXTENSIONS, cExtension),
1462 offsetof(CERT_EXTENSIONS, rgExtension),
1463 sizeof(CERT_EXTENSIONS),
1464 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1465 offsetof(CERT_EXTENSION, pszObjId) };
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);
1663 SetLastError(STATUS_ACCESS_VIOLATION);
1670 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1671 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1676 CERT_NAME_VALUE *value = pvStructInfo;
1678 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1680 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1681 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1683 switch (pbEncoded[0])
1685 case ASN_NUMERICSTRING:
1686 valueType = CERT_RDN_NUMERIC_STRING;
1688 bytesNeeded += (dataLen + 1) * 2;
1690 case ASN_PRINTABLESTRING:
1691 valueType = CERT_RDN_PRINTABLE_STRING;
1693 bytesNeeded += (dataLen + 1) * 2;
1696 valueType = CERT_RDN_IA5_STRING;
1698 bytesNeeded += (dataLen + 1) * 2;
1701 valueType = CERT_RDN_T61_STRING;
1703 bytesNeeded += (dataLen + 1) * 2;
1705 case ASN_VIDEOTEXSTRING:
1706 valueType = CERT_RDN_VIDEOTEX_STRING;
1708 bytesNeeded += (dataLen + 1) * 2;
1710 case ASN_GRAPHICSTRING:
1711 valueType = CERT_RDN_GRAPHIC_STRING;
1713 bytesNeeded += (dataLen + 1) * 2;
1715 case ASN_VISIBLESTRING:
1716 valueType = CERT_RDN_VISIBLE_STRING;
1718 bytesNeeded += (dataLen + 1) * 2;
1720 case ASN_GENERALSTRING:
1721 valueType = CERT_RDN_GENERAL_STRING;
1723 bytesNeeded += (dataLen + 1) * 2;
1725 case ASN_UNIVERSALSTRING:
1726 valueType = CERT_RDN_UNIVERSAL_STRING;
1728 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1731 valueType = CERT_RDN_BMP_STRING;
1733 bytesNeeded += dataLen + sizeof(WCHAR);
1735 case ASN_UTF8STRING:
1736 valueType = CERT_RDN_UTF8_STRING;
1738 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1739 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1742 SetLastError(CRYPT_E_ASN1_BADTAG);
1747 *pcbDecoded = 1 + lenBytes + dataLen;
1749 *pcbStructInfo = bytesNeeded;
1750 else if (*pcbStructInfo < bytesNeeded)
1752 *pcbStructInfo = bytesNeeded;
1753 SetLastError(ERROR_MORE_DATA);
1758 *pcbStructInfo = bytesNeeded;
1759 value->dwValueType = valueType;
1763 LPWSTR str = (LPWSTR)value->Value.pbData;
1765 assert(value->Value.pbData);
1766 switch (pbEncoded[0])
1768 case ASN_NUMERICSTRING:
1769 case ASN_PRINTABLESTRING:
1772 case ASN_VIDEOTEXSTRING:
1773 case ASN_GRAPHICSTRING:
1774 case ASN_VISIBLESTRING:
1775 case ASN_GENERALSTRING:
1776 value->Value.cbData = dataLen * 2;
1777 for (i = 0; i < dataLen; i++)
1778 str[i] = pbEncoded[1 + lenBytes + i];
1781 case ASN_UNIVERSALSTRING:
1782 value->Value.cbData = dataLen / 2;
1783 for (i = 0; i < dataLen / 4; i++)
1784 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1785 | pbEncoded[1 + lenBytes + 2 * i + 3];
1789 value->Value.cbData = dataLen;
1790 for (i = 0; i < dataLen / 2; i++)
1791 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1792 pbEncoded[1 + lenBytes + 2 * i + 1];
1795 case ASN_UTF8STRING:
1796 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1797 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1798 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
1799 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
1800 value->Value.cbData += sizeof(WCHAR);
1806 value->Value.cbData = 0;
1807 value->Value.pbData = NULL;
1814 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1815 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1816 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1822 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1823 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1824 if (ret && pvStructInfo)
1826 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1827 pcbStructInfo, *pcbStructInfo);
1830 CERT_NAME_VALUE *value;
1832 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1833 pvStructInfo = *(BYTE **)pvStructInfo;
1834 value = pvStructInfo;
1835 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1836 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1837 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1838 pcbStructInfo, NULL);
1844 SetLastError(STATUS_ACCESS_VIOLATION);
1851 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1852 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1855 struct AsnDecodeSequenceItem items[] = {
1856 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1857 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1858 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1859 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1860 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1861 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1863 CERT_RDN_ATTR *attr = pvStructInfo;
1865 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1866 pvStructInfo, *pcbStructInfo);
1869 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1870 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1871 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1872 attr ? attr->pszObjId : NULL);
1875 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1876 debugstr_a(attr->pszObjId));
1877 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1879 TRACE("returning %d (%08x)\n", ret, GetLastError());
1883 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1884 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1887 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1888 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1890 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1891 offsetof(CERT_RDN_ATTR, pszObjId) };
1893 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1894 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1898 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1899 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1900 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1906 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1907 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
1908 sizeof(CERT_NAME_INFO),
1909 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1910 offsetof(CERT_RDN, rgRDNAttr) };
1913 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1914 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
1919 *pcbStructInfo = bytesNeeded;
1920 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
1921 pvStructInfo, pcbStructInfo, bytesNeeded)))
1923 CERT_NAME_INFO *info;
1925 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1926 pvStructInfo = *(BYTE **)pvStructInfo;
1927 info = pvStructInfo;
1928 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
1929 sizeof(CERT_NAME_INFO));
1930 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1931 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
1932 &bytesNeeded, NULL);
1938 SetLastError(STATUS_ACCESS_VIOLATION);
1945 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1946 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1950 struct AsnDecodeSequenceItem items[] = {
1951 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1952 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1953 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1954 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1955 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1956 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1958 CERT_RDN_ATTR *attr = pvStructInfo;
1960 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1961 pvStructInfo, *pcbStructInfo);
1964 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1965 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1966 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1967 attr ? attr->pszObjId : NULL);
1970 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1971 debugstr_a(attr->pszObjId));
1972 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1974 TRACE("returning %d (%08x)\n", ret, GetLastError());
1978 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1979 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1982 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1983 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1985 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1986 offsetof(CERT_RDN_ATTR, pszObjId) };
1988 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1989 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1993 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1994 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1995 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2001 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2002 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
2003 sizeof(CERT_NAME_INFO),
2004 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
2005 offsetof(CERT_RDN, rgRDNAttr) };
2008 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2009 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded,
2014 *pcbStructInfo = bytesNeeded;
2015 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2016 pvStructInfo, pcbStructInfo, bytesNeeded)))
2018 CERT_NAME_INFO *info;
2020 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2021 pvStructInfo = *(BYTE **)pvStructInfo;
2022 info = pvStructInfo;
2023 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo +
2024 sizeof(CERT_NAME_INFO));
2025 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2026 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo,
2027 &bytesNeeded, NULL);
2033 SetLastError(STATUS_ACCESS_VIOLATION);
2040 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
2043 BOOL ret = TRUE, done = FALSE;
2044 DWORD indefiniteNestingLevels = 0, decoded = 0;
2046 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2053 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2056 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2058 if (dataLen == CMSG_INDEFINITE_LENGTH)
2060 indefiniteNestingLevels++;
2061 pbEncoded += 1 + lenBytes;
2062 cbEncoded -= 1 + lenBytes;
2063 decoded += 1 + lenBytes;
2064 TRACE("indefiniteNestingLevels = %d\n",
2065 indefiniteNestingLevels);
2069 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2070 indefiniteNestingLevels)
2072 indefiniteNestingLevels--;
2073 TRACE("indefiniteNestingLevels = %d\n",
2074 indefiniteNestingLevels);
2076 pbEncoded += 1 + lenBytes + dataLen;
2077 cbEncoded -= 1 + lenBytes + dataLen;
2078 decoded += 1 + lenBytes + dataLen;
2079 if (!indefiniteNestingLevels)
2083 } while (ret && !done);
2084 /* If we haven't found all 0 TLVs, we haven't found the end */
2085 if (ret && indefiniteNestingLevels)
2087 SetLastError(CRYPT_E_ASN1_EOD);
2091 *pcbDecoded = decoded;
2092 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2096 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
2097 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2101 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2103 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2104 pvStructInfo, *pcbStructInfo);
2106 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2108 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
2109 bytesNeeded += encodedLen;
2111 *pcbStructInfo = bytesNeeded;
2112 else if (*pcbStructInfo < bytesNeeded)
2114 SetLastError(ERROR_MORE_DATA);
2115 *pcbStructInfo = bytesNeeded;
2120 PCRYPT_OBJID_BLOB blob = pvStructInfo;
2122 *pcbStructInfo = bytesNeeded;
2123 blob->cbData = encodedLen;
2126 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2127 blob->pbData = (LPBYTE)pbEncoded;
2130 assert(blob->pbData);
2131 memcpy(blob->pbData, pbEncoded, blob->cbData);
2135 blob->pbData = NULL;
2138 *pcbDecoded = encodedLen;
2143 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2144 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2147 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2148 offsetof(CTL_USAGE, cUsageIdentifier),
2149 offsetof(CTL_USAGE, rgpszUsageIdentifier),
2151 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2153 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2154 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2158 static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded,
2159 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2162 struct AsnArrayDescriptor arrayDesc = { 0,
2163 offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
2164 FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
2165 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2166 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2169 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2170 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2174 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2175 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2177 struct AsnDecodeSequenceItem items[] = {
2178 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2179 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2180 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2181 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2182 CRYPT_AsnDecodeCTLEntryAttributes,
2183 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
2184 offsetof(CTL_ENTRY, rgAttribute), 0 },
2187 CTL_ENTRY *entry = pvStructInfo;
2189 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2192 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2193 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2194 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2198 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2199 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2202 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2203 offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
2204 FINALMEMBERSIZE(CTL_INFO, cExtension),
2205 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2206 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2208 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2209 pvStructInfo, *pcbStructInfo, pcbDecoded);
2211 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2212 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2216 static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded,
2217 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2221 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2222 offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
2223 FINALMEMBERSIZE(CTL_INFO, cExtension),
2224 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
2225 offsetof(CERT_EXTENSION, pszObjId) };
2227 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2228 pvStructInfo, *pcbStructInfo, pcbDecoded);
2230 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2231 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2235 static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded,
2236 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2242 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2244 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2246 ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes,
2247 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
2248 if (ret && pcbDecoded)
2249 *pcbDecoded = 1 + lenBytes + dataLen;
2254 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2255 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2256 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2260 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2261 pDecodePara, pvStructInfo, *pcbStructInfo);
2265 struct AsnDecodeSequenceItem items[] = {
2266 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2267 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2268 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2269 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2270 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2271 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2272 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2273 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2274 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2275 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2276 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2277 { 0, offsetof(CTL_INFO, ThisUpdate),
2278 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2280 { 0, offsetof(CTL_INFO, NextUpdate),
2281 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2283 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2284 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2285 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2286 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2287 CRYPT_AsnDecodeCTLEntries,
2288 MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2289 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2290 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2291 CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension),
2292 TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
2295 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2296 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2297 pcbStructInfo, NULL, NULL);
2301 SetLastError(STATUS_ACCESS_VIOLATION);
2307 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2308 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2312 struct AsnDecodeSequenceItem items[] = {
2313 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2314 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2315 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2316 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2317 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2318 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2320 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2322 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2323 pvStructInfo, *pcbStructInfo);
2325 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2326 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2327 pcbDecoded, capability ? capability->pszObjId : NULL);
2328 TRACE("returning %d\n", ret);
2332 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2333 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2334 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2338 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2339 pDecodePara, pvStructInfo, *pcbStructInfo);
2343 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2344 offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
2345 offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
2346 sizeof(CRYPT_SMIME_CAPABILITIES),
2347 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2348 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2350 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2351 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2355 SetLastError(STATUS_ACCESS_VIOLATION);
2358 TRACE("returning %d\n", ret);
2362 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2363 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2368 LPSTR *pStr = pvStructInfo;
2370 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2372 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2373 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2375 if (pbEncoded[0] != ASN_IA5STRING)
2377 SetLastError(CRYPT_E_ASN1_CORRUPT);
2382 bytesNeeded += dataLen;
2384 *pcbDecoded = 1 + lenBytes + dataLen;
2386 *pcbStructInfo = bytesNeeded;
2387 else if (*pcbStructInfo < bytesNeeded)
2389 *pcbStructInfo = bytesNeeded;
2390 SetLastError(ERROR_MORE_DATA);
2395 *pcbStructInfo = bytesNeeded;
2401 memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2412 static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded,
2413 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2416 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2417 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2418 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers),
2419 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2420 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2423 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2424 pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2426 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2427 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2428 TRACE("returning %d\n", ret);
2432 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2433 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2437 struct AsnDecodeSequenceItem items[] = {
2438 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2439 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2440 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2441 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2442 cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
2443 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2444 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2445 rgNoticeNumbers), 0 },
2449 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2450 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2452 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2453 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2457 /* The caller is expecting a pointer to a
2458 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2459 * CRYPT_AsnDecodeSequence is decoding a
2460 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2461 * needed, and decode again if the requisite space is available.
2463 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2465 *pcbStructInfo = bytesNeeded;
2466 else if (*pcbStructInfo < bytesNeeded)
2468 *pcbStructInfo = bytesNeeded;
2469 SetLastError(ERROR_MORE_DATA);
2474 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2476 *pcbStructInfo = bytesNeeded;
2477 /* The pointer (pvStructInfo) passed in points to the first dynamic
2478 * pointer, so use it as the pointer to the
2479 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2480 * appropriate offset for the first dynamic pointer within the
2481 * notice reference by pointing to the first memory location past
2482 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2485 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2486 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2487 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2488 ret = CRYPT_AsnDecodeSequence(items,
2489 sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2490 NULL, noticeRef, &bytesNeeded, pcbDecoded,
2491 noticeRef->pszOrganization);
2494 TRACE("returning %d\n", ret);
2498 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2499 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2505 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2507 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2508 DWORD bytesNeeded = sizeof(LPWSTR);
2510 switch (pbEncoded[0])
2512 case ASN_NUMERICSTRING:
2514 bytesNeeded += (dataLen + 1) * 2;
2516 case ASN_PRINTABLESTRING:
2518 bytesNeeded += (dataLen + 1) * 2;
2522 bytesNeeded += (dataLen + 1) * 2;
2526 bytesNeeded += (dataLen + 1) * 2;
2528 case ASN_VIDEOTEXSTRING:
2530 bytesNeeded += (dataLen + 1) * 2;
2532 case ASN_GRAPHICSTRING:
2534 bytesNeeded += (dataLen + 1) * 2;
2536 case ASN_VISIBLESTRING:
2538 bytesNeeded += (dataLen + 1) * 2;
2540 case ASN_GENERALSTRING:
2542 bytesNeeded += (dataLen + 1) * 2;
2544 case ASN_UNIVERSALSTRING:
2546 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2550 bytesNeeded += dataLen + sizeof(WCHAR);
2552 case ASN_UTF8STRING:
2554 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2555 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2558 SetLastError(CRYPT_E_ASN1_BADTAG);
2563 *pcbDecoded = 1 + lenBytes + dataLen;
2565 *pcbStructInfo = bytesNeeded;
2566 else if (*pcbStructInfo < bytesNeeded)
2568 *pcbStructInfo = bytesNeeded;
2569 SetLastError(ERROR_MORE_DATA);
2574 LPWSTR *pStr = pvStructInfo;
2576 *pcbStructInfo = bytesNeeded;
2580 LPWSTR str = *(LPWSTR *)pStr;
2583 switch (pbEncoded[0])
2585 case ASN_NUMERICSTRING:
2586 case ASN_PRINTABLESTRING:
2589 case ASN_VIDEOTEXSTRING:
2590 case ASN_GRAPHICSTRING:
2591 case ASN_VISIBLESTRING:
2592 case ASN_GENERALSTRING:
2593 for (i = 0; i < dataLen; i++)
2594 str[i] = pbEncoded[1 + lenBytes + i];
2597 case ASN_UNIVERSALSTRING:
2598 for (i = 0; i < dataLen / 4; i++)
2599 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2600 | pbEncoded[1 + lenBytes + 2 * i + 3];
2604 for (i = 0; i < dataLen / 2; i++)
2605 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2606 pbEncoded[1 + lenBytes + 2 * i + 1];
2609 case ASN_UTF8STRING:
2611 int len = MultiByteToWideChar(CP_UTF8, 0,
2612 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2613 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2626 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2627 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2628 DWORD *pcbStructInfo, DWORD *pcbDecoded)
2631 struct AsnDecodeSequenceItem items[] = {
2632 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2633 pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2634 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2635 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2636 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2637 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2638 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2640 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2642 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2643 pvStructInfo, *pcbStructInfo);
2645 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2646 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2647 pcbDecoded, notice ? notice->pNoticeReference : NULL);
2648 TRACE("returning %d\n", ret);
2652 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2653 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2654 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2655 void *pvStructInfo, DWORD *pcbStructInfo)
2659 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2660 pDecodePara, pvStructInfo, *pcbStructInfo);
2666 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2667 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2672 *pcbStructInfo = bytesNeeded;
2673 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2674 pvStructInfo, pcbStructInfo, bytesNeeded)))
2676 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2678 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2679 pvStructInfo = *(BYTE **)pvStructInfo;
2680 notice = pvStructInfo;
2681 notice->pNoticeReference =
2682 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2683 ((BYTE *)pvStructInfo +
2684 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2685 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2686 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2687 pvStructInfo, &bytesNeeded, NULL);
2693 SetLastError(STATUS_ACCESS_VIOLATION);
2696 TRACE("returning %d\n", ret);
2700 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
2701 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2705 struct AsnArrayDescriptor arrayDesc = { 0,
2706 offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
2707 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue),
2708 CRYPT_AsnDecodeCopyBytes,
2709 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2711 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2712 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
2714 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2715 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2719 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2720 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2724 struct AsnDecodeSequenceItem items[] = {
2725 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2726 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2727 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2728 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2729 CRYPT_AsnDecodePKCSAttributeValue,
2730 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
2731 TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2733 PCRYPT_ATTRIBUTE attr = pvStructInfo;
2735 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2736 pvStructInfo, *pcbStructInfo);
2738 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2739 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2740 pcbDecoded, attr ? attr->pszObjId : NULL);
2741 TRACE("returning %d\n", ret);
2745 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2746 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2747 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2751 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2752 pDecodePara, pvStructInfo, *pcbStructInfo);
2758 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2759 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2763 *pcbStructInfo = bytesNeeded;
2764 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2765 pvStructInfo, pcbStructInfo, bytesNeeded)))
2767 PCRYPT_ATTRIBUTE attr;
2769 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2770 pvStructInfo = *(BYTE **)pvStructInfo;
2771 attr = pvStructInfo;
2772 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2773 sizeof(CRYPT_ATTRIBUTE));
2774 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2775 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2782 SetLastError(STATUS_ACCESS_VIOLATION);
2785 TRACE("returning %d\n", ret);
2789 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2790 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2793 struct AsnArrayDescriptor arrayDesc = { 0,
2794 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2795 sizeof(CRYPT_ATTRIBUTES),
2796 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2797 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2800 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2801 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2805 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2806 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2807 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2811 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2812 pDecodePara, pvStructInfo, *pcbStructInfo);
2816 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2817 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2818 sizeof(CRYPT_ATTRIBUTES),
2819 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
2820 TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2822 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2823 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2827 SetLastError(STATUS_ACCESS_VIOLATION);
2830 TRACE("returning %d\n", ret);
2834 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2835 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2837 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2839 struct AsnDecodeSequenceItem items[] = {
2840 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2841 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2842 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2843 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2844 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2845 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2848 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2849 pvStructInfo, *pcbStructInfo, pcbDecoded);
2851 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2852 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2853 pcbDecoded, algo ? algo->pszObjId : NULL);
2854 if (ret && pvStructInfo)
2856 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2857 debugstr_a(algo->pszObjId));
2862 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2863 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2867 struct AsnDecodeSequenceItem items[] = {
2868 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2869 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2870 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2871 Algorithm.pszObjId) },
2872 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2873 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2874 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2876 PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2878 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2879 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2880 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2884 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2885 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2886 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2894 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2895 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2898 *pcbStructInfo = bytesNeeded;
2899 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2900 pvStructInfo, pcbStructInfo, bytesNeeded)))
2902 PCERT_PUBLIC_KEY_INFO info;
2904 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2905 pvStructInfo = *(BYTE **)pvStructInfo;
2906 info = pvStructInfo;
2907 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2908 sizeof(CERT_PUBLIC_KEY_INFO);
2909 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2910 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2911 &bytesNeeded, NULL);
2917 SetLastError(STATUS_ACCESS_VIOLATION);
2924 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2925 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2931 SetLastError(CRYPT_E_ASN1_CORRUPT);
2934 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2936 SetLastError(CRYPT_E_ASN1_CORRUPT);
2939 if (pbEncoded[1] > 1)
2941 SetLastError(CRYPT_E_ASN1_CORRUPT);
2948 *pcbStructInfo = sizeof(BOOL);
2951 else if (*pcbStructInfo < sizeof(BOOL))
2953 *pcbStructInfo = sizeof(BOOL);
2954 SetLastError(ERROR_MORE_DATA);
2959 *pcbStructInfo = sizeof(BOOL);
2960 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2963 TRACE("returning %d (%08x)\n", ret, GetLastError());
2967 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2968 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2970 PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2971 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2974 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2975 pvStructInfo, *pcbStructInfo);
2979 SetLastError(CRYPT_E_ASN1_CORRUPT);
2982 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2983 if (1 + lenBytes > cbEncoded)
2985 SetLastError(CRYPT_E_ASN1_CORRUPT);
2988 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2990 switch (pbEncoded[0] & ASN_TYPE_MASK)
2992 case 1: /* rfc822Name */
2993 case 2: /* dNSName */
2994 case 6: /* uniformResourceIdentifier */
2995 if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen))
2997 SetLastError(CRYPT_E_ASN1_RULE);
3001 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
3003 case 4: /* directoryName */
3004 case 7: /* iPAddress */
3005 bytesNeeded += dataLen;
3007 case 8: /* registeredID */
3008 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
3012 /* FIXME: ugly, shouldn't need to know internals of OID decode
3013 * function to use it.
3015 bytesNeeded += dataLen - sizeof(LPSTR);
3018 case 0: /* otherName */
3019 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
3020 SetLastError(CRYPT_E_ASN1_BADTAG);
3023 case 3: /* x400Address, unimplemented */
3024 case 5: /* ediPartyName, unimplemented */
3025 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
3026 SetLastError(CRYPT_E_ASN1_BADTAG);
3030 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
3031 SetLastError(CRYPT_E_ASN1_CORRUPT);
3037 *pcbDecoded = 1 + lenBytes + dataLen;
3039 *pcbStructInfo = bytesNeeded;
3040 else if (*pcbStructInfo < bytesNeeded)
3042 *pcbStructInfo = bytesNeeded;
3043 SetLastError(ERROR_MORE_DATA);
3048 *pcbStructInfo = bytesNeeded;
3049 /* MS used values one greater than the asn1 ones.. sigh */
3050 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
3051 switch (pbEncoded[0] & ASN_TYPE_MASK)
3053 case 1: /* rfc822Name */
3054 case 2: /* dNSName */
3055 case 6: /* uniformResourceIdentifier */
3059 for (i = 0; i < dataLen; i++)
3060 entry->u.pwszURL[i] =
3061 (WCHAR)pbEncoded[1 + lenBytes + i];
3062 entry->u.pwszURL[i] = 0;
3063 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3064 debugstr_w(entry->u.pwszURL));
3067 case 4: /* directoryName */
3068 /* The data are memory-equivalent with the IPAddress case,
3071 case 7: /* iPAddress */
3072 /* The next data pointer is in the pwszURL spot, that is,
3073 * the first 4 bytes. Need to move it to the next spot.
3075 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3076 entry->u.IPAddress.cbData = dataLen;
3077 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3080 case 8: /* registeredID */
3081 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
3082 &entry->u.pszRegisteredID, &dataLen, NULL);
3091 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
3092 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3096 struct AsnArrayDescriptor arrayDesc = { 0,
3097 offsetof(CERT_ALT_NAME_INFO, cAltEntry),
3098 offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
3099 sizeof(CERT_ALT_NAME_INFO),
3100 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3101 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3103 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3104 pvStructInfo, *pcbStructInfo, pcbDecoded);
3106 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3107 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3111 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3112 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3113 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3119 struct AsnDecodeSequenceItem items[] = {
3120 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3121 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB),
3122 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3123 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3124 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3125 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3126 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3127 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3128 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3129 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3130 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3133 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3134 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3135 pcbStructInfo, NULL, NULL);
3139 SetLastError(STATUS_ACCESS_VIOLATION);
3146 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3147 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3148 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3154 struct AsnDecodeSequenceItem items[] = {
3155 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3156 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB),
3157 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3158 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3159 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3160 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3161 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3162 AuthorityCertIssuer.rgAltEntry), 0 },
3163 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3164 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3165 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3166 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3167 AuthorityCertSerialNumber.pbData), 0 },
3170 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3171 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3172 pcbStructInfo, NULL, NULL);
3176 SetLastError(STATUS_ACCESS_VIOLATION);
3183 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3184 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3187 struct AsnDecodeSequenceItem items[] = {
3188 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3189 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3190 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3191 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3192 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3193 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3195 CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3197 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3198 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3199 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3202 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3203 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3204 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3208 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3209 pDecodePara, pvStructInfo, *pcbStructInfo);
3213 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3214 offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr),
3215 offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr),
3216 sizeof(CERT_AUTHORITY_INFO_ACCESS),
3217 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3218 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3220 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3221 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3225 SetLastError(STATUS_ACCESS_VIOLATION);
3232 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3233 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3238 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3239 pvStructInfo, *pcbStructInfo, pcbDecoded);
3241 /* The caller has already checked the tag, no need to check it again.
3242 * Check the outer length is valid:
3244 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3246 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3249 pbEncoded += 1 + lenBytes;
3250 cbEncoded -= 1 + lenBytes;
3251 if (dataLen == CMSG_INDEFINITE_LENGTH)
3252 cbEncoded -= 2; /* space for 0 TLV */
3253 /* Check the inner length is valid: */
3254 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3258 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3259 pvStructInfo, pcbStructInfo, &decodedLen);
3260 if (dataLen == CMSG_INDEFINITE_LENGTH)
3262 if (*(pbEncoded + decodedLen) != 0 ||
3263 *(pbEncoded + decodedLen + 1) != 0)
3265 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3266 *(pbEncoded + decodedLen),
3267 *(pbEncoded + decodedLen + 1));
3268 SetLastError(CRYPT_E_ASN1_CORRUPT);
3274 if (ret && pcbDecoded)
3276 *pcbDecoded = 1 + lenBytes + decodedLen;
3277 TRACE("decoded %d bytes\n", *pcbDecoded);
3284 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3285 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3288 CRYPT_CONTENT_INFO *info = pvStructInfo;
3289 struct AsnDecodeSequenceItem items[] = {
3290 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3291 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3292 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3293 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3294 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3295 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3296 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3300 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3301 pvStructInfo, *pcbStructInfo, pcbDecoded);
3303 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3304 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3305 pcbDecoded, info ? info->pszObjId : NULL);
3309 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3310 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3311 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3315 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3316 pDecodePara, pvStructInfo, *pcbStructInfo);
3320 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3321 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3322 if (ret && pvStructInfo)
3324 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3325 pcbStructInfo, *pcbStructInfo);
3328 CRYPT_CONTENT_INFO *info;
3330 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3331 pvStructInfo = *(BYTE **)pvStructInfo;
3332 info = pvStructInfo;
3333 info->pszObjId = (LPSTR)((BYTE *)info +
3334 sizeof(CRYPT_CONTENT_INFO));
3335 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3336 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3337 pcbStructInfo, NULL);
3343 SetLastError(STATUS_ACCESS_VIOLATION);
3349 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3350 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3351 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3354 struct AsnDecodeSequenceItem items[] = {
3355 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3356 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3357 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3358 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3359 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3361 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3362 CRYPT_AsnDecodePKCSContentInfoInternal,
3363 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3364 ContentInfo.pszObjId), 0 },
3365 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3366 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3367 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3370 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3371 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3376 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3377 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3378 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3382 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3383 pDecodePara, pvStructInfo, *pcbStructInfo);
3389 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3390 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3393 *pcbStructInfo = bytesNeeded;
3394 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3395 pvStructInfo, pcbStructInfo, bytesNeeded)))
3397 CERT_ALT_NAME_INFO *name;
3399 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3400 pvStructInfo = *(BYTE **)pvStructInfo;
3401 name = pvStructInfo;
3402 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3403 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3404 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3405 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3406 &bytesNeeded, NULL);
3412 SetLastError(STATUS_ACCESS_VIOLATION);
3419 struct PATH_LEN_CONSTRAINT
3421 BOOL fPathLenConstraint;
3422 DWORD dwPathLenConstraint;
3425 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3426 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3430 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3432 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3433 pvStructInfo, *pcbStructInfo, pcbDecoded);
3437 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3439 *pcbStructInfo = bytesNeeded;
3441 else if (*pcbStructInfo < bytesNeeded)
3443 SetLastError(ERROR_MORE_DATA);
3444 *pcbStructInfo = bytesNeeded;
3449 struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3451 *pcbStructInfo = bytesNeeded;
3452 size = sizeof(constraint->dwPathLenConstraint);
3453 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3454 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3456 constraint->fPathLenConstraint = TRUE;
3457 TRACE("got an int, dwPathLenConstraint is %d\n",
3458 constraint->dwPathLenConstraint);
3460 TRACE("returning %d (%08x)\n", ret, GetLastError());
3464 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3465 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3469 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3470 offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3471 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
3472 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3473 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3474 offsetof(CERT_NAME_BLOB, pbData) };
3476 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3477 pvStructInfo, *pcbStructInfo, pcbDecoded);
3479 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3480 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3481 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3485 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3486 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3487 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3493 struct AsnDecodeSequenceItem items[] = {
3494 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3495 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3496 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3497 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3498 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3499 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3500 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3501 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3502 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3504 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3507 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3508 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3509 pcbStructInfo, NULL, NULL);
3513 SetLastError(STATUS_ACCESS_VIOLATION);
3520 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3521 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3522 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3528 struct AsnDecodeSequenceItem items[] = {
3529 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3530 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3531 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3532 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3533 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3536 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3537 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3538 pcbStructInfo, NULL, NULL);
3542 SetLastError(STATUS_ACCESS_VIOLATION);
3549 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
3550 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3553 struct AsnDecodeSequenceItem items[] = {
3554 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
3555 pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3556 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3558 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3559 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3560 offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3563 CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3565 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3566 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3568 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3569 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3570 pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3574 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
3575 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3579 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3580 offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3581 offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
3582 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
3583 CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
3584 offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3586 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3587 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3589 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3590 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3591 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3595 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
3596 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3598 struct AsnDecodeSequenceItem items[] = {
3599 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3600 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3601 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3602 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3603 CRYPT_AsnDecodePolicyQualifiers,
3604 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE,
3605 TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3607 CERT_POLICY_INFO *info = pvStructInfo;
3610 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3611 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3613 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3614 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3615 pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
3619 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
3620 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3621 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3625 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3626 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3630 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3631 offsetof(CERT_POLICIES_INFO, cPolicyInfo),
3632 offsetof(CERT_POLICIES_INFO, rgPolicyInfo),
3633 sizeof(CERT_POLICIES_INFO),
3634 CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
3635 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
3637 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3638 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3642 SetLastError(STATUS_ACCESS_VIOLATION);
3648 static BOOL CRYPT_AsnDecodeCertPolicyMapping(const BYTE *pbEncoded,
3649 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3652 struct AsnDecodeSequenceItem items[] = {
3653 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
3654 pszIssuerDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3655 FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy), 0 },
3656 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING,
3657 pszSubjectDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3658 FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszSubjectDomainPolicy), 0 },
3660 CERT_POLICY_MAPPING *mapping = pvStructInfo;
3663 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3664 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3666 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3667 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3668 pcbDecoded, mapping ? mapping->pszIssuerDomainPolicy : NULL);
3672 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType,
3673 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3674 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3678 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3679 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3683 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3684 offsetof(CERT_POLICY_MAPPINGS_INFO, cPolicyMapping),
3685 offsetof(CERT_POLICY_MAPPINGS_INFO, rgPolicyMapping),
3686 sizeof(CERT_POLICY_MAPPING),
3687 CRYPT_AsnDecodeCertPolicyMapping, sizeof(CERT_POLICY_MAPPING), TRUE,
3688 offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy) };
3690 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3691 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3695 SetLastError(STATUS_ACCESS_VIOLATION);
3701 static BOOL CRYPT_AsnDecodeRequireExplicit(const BYTE *pbEncoded,
3702 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3706 DWORD skip, size = sizeof(skip);
3710 SetLastError(CRYPT_E_ASN1_EOD);
3713 if (pbEncoded[0] != (ASN_CONTEXT | 0))
3715 SetLastError(CRYPT_E_ASN1_BADTAG);
3718 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3719 &skip, &size, pcbDecoded)))
3721 DWORD bytesNeeded = MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
3722 fRequireExplicitPolicy, fInhibitPolicyMapping);
3725 *pcbStructInfo = bytesNeeded;
3726 else if (*pcbStructInfo < bytesNeeded)
3728 *pcbStructInfo = bytesNeeded;
3729 SetLastError(ERROR_MORE_DATA);
3734 CERT_POLICY_CONSTRAINTS_INFO *info = CONTAINING_RECORD(pvStructInfo,
3735 CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy);
3737 *pcbStructInfo = bytesNeeded;
3738 /* The BOOL is implicit: if the integer is present, then it's
3741 info->fRequireExplicitPolicy = TRUE;
3742 info->dwRequireExplicitPolicySkipCerts = skip;
3748 static BOOL CRYPT_AsnDecodeInhibitMapping(const BYTE *pbEncoded,
3749 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3753 DWORD skip, size = sizeof(skip);
3757 SetLastError(CRYPT_E_ASN1_EOD);
3760 if (pbEncoded[0] != (ASN_CONTEXT | 1))
3762 SetLastError(CRYPT_E_ASN1_BADTAG);
3765 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3766 &skip, &size, pcbDecoded)))
3768 DWORD bytesNeeded = FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO,
3769 fInhibitPolicyMapping);
3772 *pcbStructInfo = bytesNeeded;
3773 else if (*pcbStructInfo < bytesNeeded)
3775 *pcbStructInfo = bytesNeeded;
3776 SetLastError(ERROR_MORE_DATA);
3781 CERT_POLICY_CONSTRAINTS_INFO *info = CONTAINING_RECORD(pvStructInfo,
3782 CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping);
3784 *pcbStructInfo = bytesNeeded;
3785 /* The BOOL is implicit: if the integer is present, then it's
3788 info->fInhibitPolicyMapping = TRUE;
3789 info->dwInhibitPolicyMappingSkipCerts = skip;
3795 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints(
3796 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
3797 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3798 void *pvStructInfo, DWORD *pcbStructInfo)
3802 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3803 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3807 struct AsnDecodeSequenceItem items[] = {
3809 offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy),
3810 CRYPT_AsnDecodeRequireExplicit,
3811 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy,
3812 fInhibitPolicyMapping), TRUE, FALSE, 0, 0 },
3814 offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3815 CRYPT_AsnDecodeInhibitMapping,
3816 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping),
3817 TRUE, FALSE, 0, 0 },
3820 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3821 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3822 pcbStructInfo, NULL, NULL);
3826 SetLastError(STATUS_ACCESS_VIOLATION);
3832 #define RSA1_MAGIC 0x31415352
3834 struct DECODED_RSA_PUB_KEY
3837 CRYPT_INTEGER_BLOB modulus;
3840 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3841 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3842 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3848 struct AsnDecodeSequenceItem items[] = {
3849 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3850 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3851 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3853 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3854 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3856 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3859 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3860 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3864 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3865 decodedKey->modulus.cbData;
3869 *pcbStructInfo = bytesNeeded;
3872 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3873 pvStructInfo, pcbStructInfo, bytesNeeded)))
3876 RSAPUBKEY *rsaPubKey;
3878 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3879 pvStructInfo = *(BYTE **)pvStructInfo;
3881 hdr->bType = PUBLICKEYBLOB;
3882 hdr->bVersion = CUR_BLOB_VERSION;
3884 hdr->aiKeyAlg = CALG_RSA_KEYX;
3885 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3886 sizeof(BLOBHEADER));
3887 rsaPubKey->magic = RSA1_MAGIC;
3888 rsaPubKey->pubexp = decodedKey->pubexp;
3889 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3890 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3891 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3892 decodedKey->modulus.cbData);
3894 LocalFree(decodedKey);
3899 SetLastError(STATUS_ACCESS_VIOLATION);
3906 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3907 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3911 DWORD bytesNeeded, dataLen;
3913 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3914 pvStructInfo, *pcbStructInfo, pcbDecoded);
3916 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3918 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3920 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3921 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3923 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3925 *pcbDecoded = 1 + lenBytes + dataLen;
3927 *pcbStructInfo = bytesNeeded;
3928 else if (*pcbStructInfo < bytesNeeded)
3930 SetLastError(ERROR_MORE_DATA);
3931 *pcbStructInfo = bytesNeeded;
3936 CRYPT_DATA_BLOB *blob;
3938 *pcbStructInfo = bytesNeeded;
3939 blob = pvStructInfo;
3940 blob->cbData = dataLen;
3941 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3942 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
3945 assert(blob->pbData);
3947 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
3955 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
3956 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3957 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3961 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3962 pDecodePara, pvStructInfo, *pcbStructInfo);
3970 SetLastError(CRYPT_E_ASN1_CORRUPT);
3973 else if (pbEncoded[0] != ASN_OCTETSTRING)
3975 SetLastError(CRYPT_E_ASN1_BADTAG);
3978 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3979 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3982 *pcbStructInfo = bytesNeeded;
3983 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3984 pvStructInfo, pcbStructInfo, bytesNeeded)))
3986 CRYPT_DATA_BLOB *blob;
3988 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3989 pvStructInfo = *(BYTE **)pvStructInfo;
3990 blob = pvStructInfo;
3991 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3992 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3993 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3994 &bytesNeeded, NULL);
4000 SetLastError(STATUS_ACCESS_VIOLATION);
4007 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4008 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4011 DWORD bytesNeeded, dataLen;
4012 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4014 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
4015 pvStructInfo, *pcbStructInfo, pcbDecoded);
4017 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4019 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4020 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
4022 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
4024 *pcbDecoded = 1 + lenBytes + dataLen;
4026 *pcbStructInfo = bytesNeeded;
4027 else if (*pcbStructInfo < bytesNeeded)
4029 *pcbStructInfo = bytesNeeded;
4030 SetLastError(ERROR_MORE_DATA);
4035 CRYPT_BIT_BLOB *blob;
4037 *pcbStructInfo = bytesNeeded;
4038 blob = pvStructInfo;
4039 blob->cbData = dataLen - 1;
4040 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
4041 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4043 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
4047 assert(blob->pbData);
4050 BYTE mask = 0xff << blob->cUnusedBits;
4052 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
4054 blob->pbData[blob->cbData - 1] &= mask;
4062 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
4063 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4064 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4068 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
4069 pDecodePara, pvStructInfo, pcbStructInfo);
4077 SetLastError(CRYPT_E_ASN1_CORRUPT);
4080 else if (pbEncoded[0] != ASN_BITSTRING)
4082 SetLastError(CRYPT_E_ASN1_BADTAG);
4085 else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4086 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4089 *pcbStructInfo = bytesNeeded;
4090 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4091 pvStructInfo, pcbStructInfo, bytesNeeded)))
4093 CRYPT_BIT_BLOB *blob;
4095 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4096 pvStructInfo = *(BYTE **)pvStructInfo;
4097 blob = pvStructInfo;
4098 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
4099 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
4100 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4101 &bytesNeeded, NULL);
4107 SetLastError(STATUS_ACCESS_VIOLATION);
4111 TRACE("returning %d (%08x)\n", ret, GetLastError());
4115 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4116 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
4117 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4122 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4124 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4127 *pcbDecoded = 1 + lenBytes + dataLen;
4128 if (dataLen > sizeof(int))
4130 SetLastError(CRYPT_E_ASN1_LARGE);
4133 else if (!pvStructInfo)
4134 *pcbStructInfo = sizeof(int);
4135 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
4139 if (dataLen && pbEncoded[1 + lenBytes] & 0x80)
4141 /* initialize to a negative value to sign-extend */
4146 for (i = 0; i < dataLen; i++)
4149 val |= pbEncoded[1 + lenBytes + i];
4151 memcpy(pvStructInfo, &val, sizeof(int));
4157 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
4158 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4159 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4169 SetLastError(CRYPT_E_ASN1_EOD);
4172 else if (pbEncoded[0] != ASN_INTEGER)
4174 SetLastError(CRYPT_E_ASN1_BADTAG);
4178 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4179 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4183 *pcbStructInfo = bytesNeeded;
4184 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4185 pvStructInfo, pcbStructInfo, bytesNeeded)))
4187 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4188 pvStructInfo = *(BYTE **)pvStructInfo;
4189 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
4190 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4191 &bytesNeeded, NULL);
4197 SetLastError(STATUS_ACCESS_VIOLATION);
4204 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
4205 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4209 DWORD bytesNeeded, dataLen;
4211 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4213 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4215 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4217 *pcbDecoded = 1 + lenBytes + dataLen;
4219 *pcbStructInfo = bytesNeeded;
4220 else if (*pcbStructInfo < bytesNeeded)
4222 *pcbStructInfo = bytesNeeded;
4223 SetLastError(ERROR_MORE_DATA);
4228 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4230 *pcbStructInfo = bytesNeeded;
4231 blob->cbData = dataLen;
4232 assert(blob->pbData);
4237 for (i = 0; i < blob->cbData; i++)
4239 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4248 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
4249 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4250 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4258 if (pbEncoded[0] != ASN_INTEGER)
4260 SetLastError(CRYPT_E_ASN1_BADTAG);
4264 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4265 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4269 *pcbStructInfo = bytesNeeded;
4270 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4271 pvStructInfo, pcbStructInfo, bytesNeeded)))
4273 CRYPT_INTEGER_BLOB *blob;
4275 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4276 pvStructInfo = *(BYTE **)pvStructInfo;
4277 blob = pvStructInfo;
4278 blob->pbData = (BYTE *)pvStructInfo +
4279 sizeof(CRYPT_INTEGER_BLOB);
4280 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4281 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4282 &bytesNeeded, NULL);
4288 SetLastError(STATUS_ACCESS_VIOLATION);
4295 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
4296 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4301 if (pbEncoded[0] == ASN_INTEGER)
4303 DWORD bytesNeeded, dataLen;
4305 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4307 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4310 *pcbDecoded = 1 + lenBytes + dataLen;
4311 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4313 *pcbStructInfo = bytesNeeded;
4314 else if (*pcbStructInfo < bytesNeeded)
4316 *pcbStructInfo = bytesNeeded;
4317 SetLastError(ERROR_MORE_DATA);
4322 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4324 *pcbStructInfo = bytesNeeded;
4325 blob->cbData = dataLen;
4326 assert(blob->pbData);
4327 /* remove leading zero byte if it exists */
4328 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
4337 for (i = 0; i < blob->cbData; i++)
4339 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4348 SetLastError(CRYPT_E_ASN1_BADTAG);
4354 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
4355 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4356 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4364 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
4365 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4368 *pcbStructInfo = bytesNeeded;
4369 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4370 pvStructInfo, pcbStructInfo, bytesNeeded)))
4372 CRYPT_INTEGER_BLOB *blob;
4374 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4375 pvStructInfo = *(BYTE **)pvStructInfo;
4376 blob = pvStructInfo;
4377 blob->pbData = (BYTE *)pvStructInfo +
4378 sizeof(CRYPT_INTEGER_BLOB);
4379 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
4380 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4381 &bytesNeeded, NULL);
4387 SetLastError(STATUS_ACCESS_VIOLATION);
4394 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
4395 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4396 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4402 *pcbStructInfo = sizeof(int);
4407 if (pbEncoded[0] == ASN_ENUMERATED)
4409 unsigned int val = 0, i;
4413 SetLastError(CRYPT_E_ASN1_EOD);
4416 else if (pbEncoded[1] == 0)
4418 SetLastError(CRYPT_E_ASN1_CORRUPT);
4423 /* A little strange looking, but we have to accept a sign byte:
4424 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4425 * assuming a small length is okay here, it has to be in short
4428 if (pbEncoded[1] > sizeof(unsigned int) + 1)
4430 SetLastError(CRYPT_E_ASN1_LARGE);
4433 for (i = 0; i < pbEncoded[1]; i++)
4436 val |= pbEncoded[2 + i];
4438 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4439 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
4441 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4442 pvStructInfo = *(BYTE **)pvStructInfo;
4443 memcpy(pvStructInfo, &val, sizeof(unsigned int));
4449 SetLastError(CRYPT_E_ASN1_BADTAG);
4455 SetLastError(STATUS_ACCESS_VIOLATION);
4462 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4465 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4470 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4472 if (!isdigit(*(pbEncoded))) \
4474 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4480 (word) += *(pbEncoded)++ - '0'; \
4485 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
4486 SYSTEMTIME *sysTime)
4490 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
4492 WORD hours, minutes = 0;
4493 BYTE sign = *pbEncoded++;
4496 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
4497 if (ret && hours >= 24)
4499 SetLastError(CRYPT_E_ASN1_CORRUPT);
4504 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
4505 if (ret && minutes >= 60)
4507 SetLastError(CRYPT_E_ASN1_CORRUPT);
4515 sysTime->wHour += hours;
4516 sysTime->wMinute += minutes;
4520 if (hours > sysTime->wHour)
4523 sysTime->wHour = 24 - (hours - sysTime->wHour);
4526 sysTime->wHour -= hours;
4527 if (minutes > sysTime->wMinute)
4530 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
4533 sysTime->wMinute -= minutes;
4540 #define MIN_ENCODED_TIME_LENGTH 10
4542 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
4543 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4548 if (pbEncoded[0] == ASN_UTCTIME)
4551 SetLastError(CRYPT_E_ASN1_EOD);
4552 else if (pbEncoded[1] > 0x7f)
4554 /* long-form date strings really can't be valid */
4555 SetLastError(CRYPT_E_ASN1_CORRUPT);
4559 SYSTEMTIME sysTime = { 0 };
4560 BYTE len = pbEncoded[1];
4562 if (len < MIN_ENCODED_TIME_LENGTH)
4563 SetLastError(CRYPT_E_ASN1_CORRUPT);
4568 *pcbDecoded = 2 + len;
4570 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
4571 if (sysTime.wYear >= 50)
4572 sysTime.wYear += 1900;
4574 sysTime.wYear += 2000;
4575 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4576 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4577 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4578 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
4581 if (len >= 2 && isdigit(*pbEncoded) &&
4582 isdigit(*(pbEncoded + 1)))
4583 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4585 else if (isdigit(*pbEncoded))
4586 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
4589 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4595 *pcbStructInfo = sizeof(FILETIME);
4596 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4598 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4604 SetLastError(CRYPT_E_ASN1_BADTAG);
4608 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
4609 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4610 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4618 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4619 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4623 *pcbStructInfo = bytesNeeded;
4624 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
4625 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
4627 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4628 pvStructInfo = *(BYTE **)pvStructInfo;
4629 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4630 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4631 &bytesNeeded, NULL);
4637 SetLastError(STATUS_ACCESS_VIOLATION);
4643 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
4644 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4649 if (pbEncoded[0] == ASN_GENERALTIME)
4652 SetLastError(CRYPT_E_ASN1_EOD);
4653 else if (pbEncoded[1] > 0x7f)
4655 /* long-form date strings really can't be valid */
4656 SetLastError(CRYPT_E_ASN1_CORRUPT);
4660 BYTE len = pbEncoded[1];
4662 if (len < MIN_ENCODED_TIME_LENGTH)
4663 SetLastError(CRYPT_E_ASN1_CORRUPT);
4666 SYSTEMTIME sysTime = { 0 };
4670 *pcbDecoded = 2 + len;
4672 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
4673 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4674 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4675 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4678 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4681 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4683 if (ret && len > 0 && (*pbEncoded == '.' ||
4690 /* workaround macro weirdness */
4691 digits = min(len, 3);
4692 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
4693 sysTime.wMilliseconds);
4696 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4702 *pcbStructInfo = sizeof(FILETIME);
4703 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4705 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4711 SetLastError(CRYPT_E_ASN1_BADTAG);
4715 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
4716 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4720 InternalDecodeFunc decode = NULL;
4722 if (pbEncoded[0] == ASN_UTCTIME)
4723 decode = CRYPT_AsnDecodeUtcTimeInternal;
4724 else if (pbEncoded[0] == ASN_GENERALTIME)
4725 decode = CRYPT_AsnDecodeGeneralizedTime;
4727 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
4728 pcbStructInfo, pcbDecoded);
4731 SetLastError(CRYPT_E_ASN1_BADTAG);
4737 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
4738 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4739 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4747 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4748 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4752 *pcbStructInfo = bytesNeeded;
4753 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4754 pvStructInfo, pcbStructInfo, bytesNeeded)))
4756 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4757 pvStructInfo = *(BYTE **)pvStructInfo;
4758 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4759 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4760 &bytesNeeded, NULL);
4766 SetLastError(STATUS_ACCESS_VIOLATION);
4773 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
4774 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4775 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4781 if (pbEncoded[0] == ASN_SEQUENCEOF)
4783 DWORD bytesNeeded, dataLen, remainingLen, cValue;
4785 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4790 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4791 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
4793 ptr = pbEncoded + 1 + lenBytes;
4794 remainingLen = dataLen;
4795 while (ret && remainingLen)
4799 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4802 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4804 remainingLen -= 1 + nextLenBytes + nextLen;
4805 ptr += 1 + nextLenBytes + nextLen;
4806 bytesNeeded += sizeof(CRYPT_DER_BLOB);
4807 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
4808 bytesNeeded += 1 + nextLenBytes + nextLen;
4814 CRYPT_SEQUENCE_OF_ANY *seq;
4819 *pcbStructInfo = bytesNeeded;
4820 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4821 pvStructInfo, pcbStructInfo, bytesNeeded)))
4823 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4824 pvStructInfo = *(BYTE **)pvStructInfo;
4826 seq->cValue = cValue;
4827 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
4829 nextPtr = (BYTE *)seq->rgValue +
4830 cValue * sizeof(CRYPT_DER_BLOB);
4831 ptr = pbEncoded + 1 + lenBytes;
4832 remainingLen = dataLen;
4834 while (ret && remainingLen)
4838 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4841 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4843 seq->rgValue[i].cbData = 1 + nextLenBytes +
4845 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4846 seq->rgValue[i].pbData = (BYTE *)ptr;
4849 seq->rgValue[i].pbData = nextPtr;
4850 memcpy(nextPtr, ptr, 1 + nextLenBytes +
4852 nextPtr += 1 + nextLenBytes + nextLen;
4854 remainingLen -= 1 + nextLenBytes + nextLen;
4855 ptr += 1 + nextLenBytes + nextLen;
4865 SetLastError(CRYPT_E_ASN1_BADTAG);
4871 SetLastError(STATUS_ACCESS_VIOLATION);
4878 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
4879 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4884 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
4886 DWORD bytesNeeded, dataLen;
4888 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4890 struct AsnArrayDescriptor arrayDesc = {
4891 ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4892 offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry),
4893 offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry),
4894 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u),
4895 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
4896 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
4897 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4902 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4903 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4904 dwFlags, NULL, NULL, &nameLen, NULL);
4905 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
4906 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u);
4909 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
4911 *pcbDecoded = 1 + lenBytes + dataLen;
4913 *pcbStructInfo = bytesNeeded;
4914 else if (*pcbStructInfo < bytesNeeded)
4916 *pcbStructInfo = bytesNeeded;
4917 SetLastError(ERROR_MORE_DATA);
4922 CRL_DIST_POINT_NAME *name = pvStructInfo;
4924 *pcbStructInfo = bytesNeeded;
4927 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
4928 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4929 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4930 dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen,
4934 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
4940 SetLastError(CRYPT_E_ASN1_BADTAG);
4946 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
4947 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4949 struct AsnDecodeSequenceItem items[] = {
4950 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
4951 DistPointName), CRYPT_AsnDecodeDistPointName,
4952 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
4953 DistPointName.u.FullName.rgAltEntry), 0 },
4954 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
4955 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
4956 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
4957 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
4958 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
4959 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
4961 CRL_DIST_POINT *point = pvStructInfo;
4964 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4965 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4966 pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
4970 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
4971 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4972 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4976 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4977 pDecodePara, pvStructInfo, *pcbStructInfo);
4981 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4982 offsetof(CRL_DIST_POINTS_INFO, cDistPoint),
4983 offsetof(CRL_DIST_POINTS_INFO, rgDistPoint),
4984 sizeof(CRL_DIST_POINTS_INFO),
4985 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
4986 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
4988 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
4989 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
4993 SetLastError(STATUS_ACCESS_VIOLATION);
5000 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
5001 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5002 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5006 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5007 pDecodePara, pvStructInfo, *pcbStructInfo);
5011 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
5012 offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier),
5013 offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier),
5014 sizeof(CERT_ENHKEY_USAGE),
5015 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
5017 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5018 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
5022 SetLastError(STATUS_ACCESS_VIOLATION);
5029 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
5030 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5031 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5035 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5036 pDecodePara, pvStructInfo, *pcbStructInfo);
5040 struct AsnDecodeSequenceItem items[] = {
5041 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
5042 DistPointName), CRYPT_AsnDecodeDistPointName,
5043 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
5044 offsetof(CRL_ISSUING_DIST_POINT,
5045 DistPointName.u.FullName.rgAltEntry), 0 },
5046 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
5047 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5049 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
5050 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
5052 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
5053 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
5054 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
5055 OnlySomeReasonFlags.pbData), 0 },
5056 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
5057 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
5060 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5061 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5062 pcbStructInfo, NULL, NULL);
5066 SetLastError(STATUS_ACCESS_VIOLATION);
5073 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
5074 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5078 DWORD max, size = sizeof(max);
5080 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5081 pvStructInfo, *pcbStructInfo, pcbDecoded);
5085 SetLastError(CRYPT_E_ASN1_EOD);
5088 if (pbEncoded[0] != (ASN_CONTEXT | 1))
5090 SetLastError(CRYPT_E_ASN1_BADTAG);
5093 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
5094 &max, &size, pcbDecoded)))
5096 DWORD bytesNeeded = FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum);
5099 *pcbStructInfo = bytesNeeded;
5100 else if (*pcbStructInfo < bytesNeeded)
5102 *pcbStructInfo = bytesNeeded;
5103 SetLastError(ERROR_MORE_DATA);
5108 CERT_GENERAL_SUBTREE *subtree = CONTAINING_RECORD(pvStructInfo,
5109 CERT_GENERAL_SUBTREE, fMaximum);
5111 *pcbStructInfo = bytesNeeded;
5112 /* The BOOL is implicit: if the integer is present, then it's
5115 subtree->fMaximum = TRUE;
5116 subtree->dwMaximum = max;
5119 TRACE("returning %d\n", ret);
5123 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
5124 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5128 struct AsnDecodeSequenceItem items[] = {
5129 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
5130 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
5131 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
5132 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
5133 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
5134 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
5135 CRYPT_AsnDecodeMaximum, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum),
5136 TRUE, FALSE, 0, 0 },
5138 CERT_GENERAL_SUBTREE *subtree = pvStructInfo;
5140 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5141 pvStructInfo, *pcbStructInfo, pcbDecoded);
5143 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5144 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5145 pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
5148 TRACE("%d\n", *pcbDecoded);
5149 if (*pcbDecoded < cbEncoded)
5150 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
5151 *(pbEncoded + *pcbDecoded + 1));
5153 TRACE("returning %d\n", ret);
5157 static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded,
5158 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5162 struct AsnArrayDescriptor arrayDesc = { 0,
5163 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5164 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree),
5165 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5167 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5168 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5170 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5171 pvStructInfo, *pcbStructInfo, pcbDecoded);
5173 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5174 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5178 static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded,
5179 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5183 struct AsnArrayDescriptor arrayDesc = { 0,
5184 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5185 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree),
5186 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5187 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
5188 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
5190 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5191 pvStructInfo, *pcbStructInfo, pcbDecoded);
5193 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5194 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5198 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
5199 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5200 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5204 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5205 pDecodePara, pvStructInfo, *pcbStructInfo);
5209 struct AsnDecodeSequenceItem items[] = {
5210 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
5211 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
5212 CRYPT_AsnDecodePermittedSubtree,
5213 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
5214 cExcludedSubtree), TRUE, TRUE,
5215 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
5216 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
5217 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5218 CRYPT_AsnDecodeExcludedSubtree,
5219 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
5221 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
5224 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5225 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5226 pcbStructInfo, NULL, NULL);
5230 SetLastError(STATUS_ACCESS_VIOLATION);
5236 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
5237 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5241 struct AsnDecodeSequenceItem items[] = {
5242 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
5243 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
5245 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
5246 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
5247 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
5249 CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;
5251 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5252 pvStructInfo, *pcbStructInfo, pcbDecoded);
5254 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5255 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5256 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
5257 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
5259 SetLastError(CRYPT_E_ASN1_CORRUPT);
5262 TRACE("returning %d\n", ret);
5266 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
5267 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5270 CMSG_SIGNER_INFO *info = pvStructInfo;
5271 struct AsnDecodeSequenceItem items[] = {
5272 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
5273 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5274 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
5275 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
5276 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
5277 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
5278 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5279 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5280 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5281 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
5282 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5283 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5284 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
5285 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5286 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
5287 HashEncryptionAlgorithm.pszObjId), 0 },
5288 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
5289 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5290 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
5291 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5292 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
5293 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5294 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5298 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5299 pvStructInfo, *pcbStructInfo);
5301 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5302 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5303 pcbDecoded, info ? info->Issuer.pbData : NULL);
5307 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
5308 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5309 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5313 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5314 pDecodePara, pvStructInfo, *pcbStructInfo);
5318 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
5319 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5320 if (ret && pvStructInfo)
5322 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5323 pcbStructInfo, *pcbStructInfo);
5326 CMSG_SIGNER_INFO *info;
5328 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5329 pvStructInfo = *(BYTE **)pvStructInfo;
5330 info = pvStructInfo;
5331 info->Issuer.pbData = ((BYTE *)info +
5332 sizeof(CMSG_SIGNER_INFO));
5333 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
5334 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5335 pcbStructInfo, NULL);
5341 SetLastError(STATUS_ACCESS_VIOLATION);
5344 TRACE("returning %d\n", ret);
5348 static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded,
5349 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5353 struct AsnArrayDescriptor arrayDesc = { 0,
5354 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
5355 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded),
5356 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded),
5357 CRYPT_AsnDecodeCopyBytes,
5358 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5360 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5361 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5363 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5364 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5368 static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded,
5369 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5373 struct AsnArrayDescriptor arrayDesc = { 0,
5374 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded),
5375 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded),
5376 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content),
5377 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB),
5378 TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5380 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5381 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5383 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5384 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5388 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
5389 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5392 CERT_ID *id = pvStructInfo;
5395 if (*pbEncoded == ASN_SEQUENCEOF)
5397 ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
5398 id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
5402 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5403 if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
5404 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5405 sizeof(CERT_ISSUER_SERIAL_NUMBER);
5407 *pcbStructInfo = sizeof(CERT_ID);
5410 else if (*pbEncoded == (ASN_CONTEXT | 0))
5412 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
5413 id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
5417 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5418 if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
5419 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5420 sizeof(CRYPT_DATA_BLOB);
5422 *pcbStructInfo = sizeof(CERT_ID);
5426 SetLastError(CRYPT_E_ASN1_BADTAG);
5430 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
5431 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5434 CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
5435 struct AsnDecodeSequenceItem items[] = {
5436 { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
5437 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5438 { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
5439 CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
5440 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
5441 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
5442 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5443 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5444 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5445 offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
5446 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5447 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5448 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
5449 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5450 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
5451 HashEncryptionAlgorithm.pszObjId), 0 },
5452 { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
5453 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5454 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
5455 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5456 offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
5457 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5458 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5462 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5463 pvStructInfo, *pcbStructInfo);
5465 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5466 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5467 pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
5471 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
5472 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5473 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5477 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5478 pDecodePara, pvStructInfo, *pcbStructInfo);
5482 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
5483 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5484 if (ret && pvStructInfo)
5486 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5487 pcbStructInfo, *pcbStructInfo);
5490 CMSG_CMS_SIGNER_INFO *info;
5492 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5493 pvStructInfo = *(BYTE **)pvStructInfo;
5494 info = pvStructInfo;
5495 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
5496 sizeof(CMSG_CMS_SIGNER_INFO));
5497 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
5498 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5499 pcbStructInfo, NULL);
5505 SetLastError(STATUS_ACCESS_VIOLATION);
5508 TRACE("returning %d\n", ret);
5512 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
5513 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5516 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5517 offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5518 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo),
5519 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo),
5520 CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
5521 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
5523 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5524 pvStructInfo, *pcbStructInfo, pcbDecoded);
5526 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5527 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5531 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5532 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5533 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
5536 struct AsnDecodeSequenceItem items[] = {
5537 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
5538 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5539 /* Placeholder for the hash algorithms - redundant with those in the
5540 * signers, so just ignore them.
5542 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5543 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
5544 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
5545 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
5546 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5547 offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded,
5548 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE,
5549 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
5550 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5551 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded,
5552 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE,
5553 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
5554 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5555 CRYPT_DecodeSignerArray,
5556 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE,
5557 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
5560 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5561 pDecodePara, signedInfo, *pcbSignedInfo);
5563 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5564 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
5566 TRACE("returning %d\n", ret);
5570 static BOOL CRYPT_AsnDecodeRecipientInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5571 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5574 CMSG_KEY_TRANS_RECIPIENT_INFO *info = pvStructInfo;
5575 struct AsnDecodeSequenceItem items[] = {
5576 { ASN_INTEGER, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, dwVersion),
5577 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5578 { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5579 RecipientId.u.IssuerSerialNumber), CRYPT_AsnDecodeIssuerSerialNumber,
5580 sizeof(CERT_ISSUER_SERIAL_NUMBER), FALSE, TRUE,
5581 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5582 RecipientId.u.IssuerSerialNumber.Issuer.pbData), 0 },
5583 { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5584 KeyEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId,
5585 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
5586 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5587 KeyEncryptionAlgorithm.pszObjId), 0 },
5588 { ASN_OCTETSTRING, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, EncryptedKey),
5589 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
5590 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, EncryptedKey.pbData), 0 },
5593 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5594 pvStructInfo, *pcbStructInfo, pcbDecoded);
5596 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5597 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5598 pcbDecoded, info ? info->RecipientId.u.IssuerSerialNumber.Issuer.pbData :
5601 info->RecipientId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5602 TRACE("returning %d\n", ret);
5606 static BOOL CRYPT_DecodeRecipientInfoArray(const BYTE *pbEncoded,
5607 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5611 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5612 offsetof(CRYPT_ENVELOPED_DATA, cRecipientInfo),
5613 offsetof(CRYPT_ENVELOPED_DATA, rgRecipientInfo),
5614 MEMBERSIZE(CRYPT_ENVELOPED_DATA, cRecipientInfo, encryptedContentInfo),
5615 CRYPT_AsnDecodeRecipientInfo, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO), TRUE,
5616 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO,
5617 RecipientId.u.IssuerSerialNumber.Issuer.pbData) };
5619 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5620 pvStructInfo, *pcbStructInfo, pcbDecoded);
5622 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5623 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5624 TRACE("returning %d\n", ret);
5628 static BOOL CRYPT_AsnDecodeEncryptedContentInfo(const BYTE *pbEncoded,
5629 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5633 CRYPT_ENCRYPTED_CONTENT_INFO *info = pvStructInfo;
5634 struct AsnDecodeSequenceItem items[] = {
5635 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5636 contentType), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
5637 FALSE, TRUE, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5639 { ASN_SEQUENCEOF, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5640 contentEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId,
5641 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
5642 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5643 contentEncryptionAlgorithm.pszObjId), 0 },
5644 { ASN_CONTEXT | 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO,
5645 encryptedContent), CRYPT_AsnDecodeOctetsInternal,
5646 sizeof(CRYPT_DATA_BLOB), TRUE, TRUE,
5647 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO, encryptedContent.pbData) },
5650 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5651 pvStructInfo, *pcbStructInfo, pcbDecoded);
5653 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5654 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5655 pcbDecoded, info ? info->contentType : NULL);
5656 TRACE("returning %d\n", ret);
5660 BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
5661 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5662 CRYPT_ENVELOPED_DATA *envelopedData, DWORD *pcbEnvelopedData)
5665 struct AsnDecodeSequenceItem items[] = {
5666 { ASN_INTEGER, offsetof(CRYPT_ENVELOPED_DATA, version),
5667 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5668 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ENVELOPED_DATA,
5669 cRecipientInfo), CRYPT_DecodeRecipientInfoArray,
5670 MEMBERSIZE(CRYPT_ENVELOPED_DATA, cRecipientInfo, encryptedContentInfo),
5671 FALSE, TRUE, offsetof(CRYPT_ENVELOPED_DATA, rgRecipientInfo), 0 },
5672 { ASN_SEQUENCEOF, offsetof(CRYPT_ENVELOPED_DATA, encryptedContentInfo),
5673 CRYPT_AsnDecodeEncryptedContentInfo,
5674 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO), FALSE, TRUE,
5675 offsetof(CRYPT_ENVELOPED_DATA, encryptedContentInfo.contentType), 0 },
5678 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5679 pDecodePara, envelopedData, *pcbEnvelopedData);
5681 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5682 pbEncoded, cbEncoded, dwFlags, pDecodePara, envelopedData,
5683 pcbEnvelopedData, NULL, NULL);
5684 TRACE("returning %d\n", ret);
5688 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
5689 LPCSTR lpszStructType)
5691 CryptDecodeObjectExFunc decodeFunc = NULL;
5693 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
5694 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
5696 SetLastError(ERROR_FILE_NOT_FOUND);
5699 if (IS_INTOID(lpszStructType))
5701 switch (LOWORD(lpszStructType))
5703 case LOWORD(X509_CERT):
5704 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
5706 case LOWORD(X509_CERT_TO_BE_SIGNED):
5707 decodeFunc = CRYPT_AsnDecodeCert;
5709 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
5710 decodeFunc = CRYPT_AsnDecodeCRL;
5712 case LOWORD(X509_EXTENSIONS):
5713 decodeFunc = CRYPT_AsnDecodeExtensions;
5715 case LOWORD(X509_NAME_VALUE):
5716 decodeFunc = CRYPT_AsnDecodeNameValue;
5718 case LOWORD(X509_NAME):
5719 decodeFunc = CRYPT_AsnDecodeName;
5721 case LOWORD(X509_PUBLIC_KEY_INFO):
5722 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
5724 case LOWORD(X509_AUTHORITY_KEY_ID):
5725 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5727 case LOWORD(X509_ALTERNATE_NAME):
5728 decodeFunc = CRYPT_AsnDecodeAltName;
5730 case LOWORD(X509_BASIC_CONSTRAINTS):
5731 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5733 case LOWORD(X509_BASIC_CONSTRAINTS2):
5734 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5736 case LOWORD(X509_CERT_POLICIES):
5737 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5739 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
5740 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
5742 case LOWORD(X509_UNICODE_NAME):
5743 decodeFunc = CRYPT_AsnDecodeUnicodeName;
5745 case LOWORD(PKCS_ATTRIBUTE):
5746 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
5748 case LOWORD(X509_UNICODE_NAME_VALUE):
5749 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
5751 case LOWORD(X509_OCTET_STRING):
5752 decodeFunc = CRYPT_AsnDecodeOctets;
5754 case LOWORD(X509_BITS):
5755 case LOWORD(X509_KEY_USAGE):
5756 decodeFunc = CRYPT_AsnDecodeBits;
5758 case LOWORD(X509_INTEGER):
5759 decodeFunc = CRYPT_AsnDecodeInt;
5761 case LOWORD(X509_MULTI_BYTE_INTEGER):
5762 decodeFunc = CRYPT_AsnDecodeInteger;
5764 case LOWORD(X509_MULTI_BYTE_UINT):
5765 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
5767 case LOWORD(X509_ENUMERATED):
5768 decodeFunc = CRYPT_AsnDecodeEnumerated;
5770 case LOWORD(X509_CHOICE_OF_TIME):
5771 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
5773 case LOWORD(X509_AUTHORITY_KEY_ID2):
5774 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5776 case LOWORD(X509_AUTHORITY_INFO_ACCESS):
5777 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5779 case LOWORD(PKCS_CONTENT_INFO):
5780 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
5782 case LOWORD(X509_SEQUENCE_OF_ANY):
5783 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
5785 case LOWORD(PKCS_UTC_TIME):
5786 decodeFunc = CRYPT_AsnDecodeUtcTime;
5788 case LOWORD(X509_CRL_DIST_POINTS):
5789 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5791 case LOWORD(X509_ENHANCED_KEY_USAGE):
5792 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5794 case LOWORD(PKCS_CTL):
5795 decodeFunc = CRYPT_AsnDecodeCTL;
5797 case LOWORD(PKCS_SMIME_CAPABILITIES):
5798 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5800 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
5801 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5803 case LOWORD(PKCS_ATTRIBUTES):
5804 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
5806 case LOWORD(X509_ISSUING_DIST_POINT):
5807 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5809 case LOWORD(X509_NAME_CONSTRAINTS):
5810 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5812 case LOWORD(X509_POLICY_MAPPINGS):
5813 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5815 case LOWORD(X509_POLICY_CONSTRAINTS):
5816 decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
5818 case LOWORD(PKCS7_SIGNER_INFO):
5819 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
5821 case LOWORD(CMS_SIGNER_INFO):
5822 decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
5826 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
5827 decodeFunc = CRYPT_AsnDecodeExtensions;
5828 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
5829 decodeFunc = CRYPT_AsnDecodeUtcTime;
5830 else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
5831 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5832 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
5833 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5834 else if (!strcmp(lpszStructType, szOID_LEGACY_POLICY_MAPPINGS))
5835 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5836 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
5837 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5838 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
5839 decodeFunc = CRYPT_AsnDecodeEnumerated;
5840 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
5841 decodeFunc = CRYPT_AsnDecodeBits;
5842 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
5843 decodeFunc = CRYPT_AsnDecodeOctets;
5844 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
5845 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5846 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
5847 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5848 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
5849 decodeFunc = CRYPT_AsnDecodeAltName;
5850 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
5851 decodeFunc = CRYPT_AsnDecodeAltName;
5852 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
5853 decodeFunc = CRYPT_AsnDecodeAltName;
5854 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
5855 decodeFunc = CRYPT_AsnDecodeAltName;
5856 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
5857 decodeFunc = CRYPT_AsnDecodeAltName;
5858 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
5859 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5860 else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
5861 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5862 else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS))
5863 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings;
5864 else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS))
5865 decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints;
5866 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
5867 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5868 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
5869 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5870 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
5871 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5872 else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
5873 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5874 else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
5875 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5876 else if (!strcmp(lpszStructType, szOID_CTL))
5877 decodeFunc = CRYPT_AsnDecodeCTL;
5881 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
5882 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5884 static HCRYPTOIDFUNCSET set = NULL;
5885 CryptDecodeObjectFunc decodeFunc = NULL;
5888 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
5889 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5890 (void **)&decodeFunc, hFunc);
5894 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
5895 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5897 static HCRYPTOIDFUNCSET set = NULL;
5898 CryptDecodeObjectExFunc decodeFunc = NULL;
5901 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
5902 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5903 (void **)&decodeFunc, hFunc);
5907 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5908 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
5909 DWORD *pcbStructInfo)
5912 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
5913 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
5914 HCRYPTOIDFUNCADDR hFunc = NULL;
5916 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
5917 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
5918 pvStructInfo, pcbStructInfo);
5920 if (!pvStructInfo && !pcbStructInfo)
5922 SetLastError(ERROR_INVALID_PARAMETER);
5925 if (cbEncoded > MAX_ENCODED_LEN)
5927 SetLastError(CRYPT_E_ASN1_LARGE);
5931 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
5934 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5935 debugstr_a(lpszStructType));
5936 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
5937 lpszStructType, &hFunc);
5938 if (!pCryptDecodeObject)
5939 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
5940 lpszStructType, &hFunc);
5942 if (pCryptDecodeObject)
5943 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5944 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5945 else if (pCryptDecodeObjectEx)
5946 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
5947 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
5948 pvStructInfo, pcbStructInfo);
5950 CryptFreeOIDFunctionAddress(hFunc, 0);
5951 TRACE_(crypt)("returning %d\n", ret);
5955 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5956 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5957 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5960 CryptDecodeObjectExFunc decodeFunc;
5961 HCRYPTOIDFUNCADDR hFunc = NULL;
5963 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5964 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
5965 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5967 if (!pvStructInfo && !pcbStructInfo)
5969 SetLastError(ERROR_INVALID_PARAMETER);
5972 if (cbEncoded > MAX_ENCODED_LEN)
5974 SetLastError(CRYPT_E_ASN1_LARGE);
5978 SetLastError(NOERROR);
5979 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5983 SetLastError(ERROR_INVALID_PARAMETER);
5986 *(BYTE **)pvStructInfo = NULL;
5988 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
5991 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5992 debugstr_a(lpszStructType));
5993 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
5997 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
5998 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
6001 CryptDecodeObjectFunc pCryptDecodeObject =
6002 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
6004 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6005 * directly, as that could cause an infinite loop.
6007 if (pCryptDecodeObject)
6009 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
6011 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6012 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
6013 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
6014 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
6015 ret = pCryptDecodeObject(dwCertEncodingType,
6016 lpszStructType, pbEncoded, cbEncoded, dwFlags,
6017 *(BYTE **)pvStructInfo, pcbStructInfo);
6020 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
6021 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
6025 CryptFreeOIDFunctionAddress(hFunc, 0);
6026 TRACE_(crypt)("returning %d\n", ret);
6030 BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
6034 TRACE_(crypt)("(%p)\n", pPFX);
6036 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6037 * version integer of length 1 (3 encoded byes) and at least one other
6038 * datum (two encoded bytes), plus at least two bytes for the outer
6039 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6041 if (pPFX->cbData < 7)
6043 else if (pPFX->pbData[0] == ASN_SEQUENCE)
6047 if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
6049 BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);
6051 /* Need at least three bytes for the integer version */
6052 if (pPFX->cbData < 1 + lenLen + 3)
6054 else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
6055 pPFX->pbData[1 + lenLen + 1] != 1 || /* Definite length */
6056 pPFX->pbData[1 + lenLen + 2] != 3) /* PFX version */
6065 HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
6068 FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);