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 PCRYPT_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(PCRYPT_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 /* Account for alignment padding */
361 items[i].size = ALIGN_DWORD_PTR(items[i].size);
362 TRACE("item %d size: %d\n", i, items[i].size);
363 if (nextData && items[i].hasPointer &&
364 items[i].size > items[i].minSize)
365 nextData += items[i].size - items[i].minSize;
366 if (itemDecoded > itemEncodedLen)
368 WARN("decoded length %d exceeds encoded %d\n",
369 itemDecoded, itemEncodedLen);
370 SetLastError(CRYPT_E_ASN1_CORRUPT);
376 decoded += itemDecoded;
377 TRACE("item %d: decoded %d bytes\n", i,
381 else if (items[i].optional &&
382 GetLastError() == CRYPT_E_ASN1_BADTAG)
384 TRACE("skipping optional item %d\n", i);
385 items[i].size = items[i].minSize;
386 SetLastError(NOERROR);
390 TRACE("item %d failed: %08x\n", i,
393 else if (itemLen == CMSG_INDEFINITE_LENGTH)
395 ERR("can't use indefinite length encoding without a decoder\n");
396 SetLastError(CRYPT_E_ASN1_CORRUPT);
401 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen);
402 ptr += itemEncodedLen;
403 decoded += itemEncodedLen;
404 items[i].size = items[i].minSize;
407 else if (items[i].optional)
409 TRACE("skipping optional item %d\n", i);
410 items[i].size = items[i].minSize;
414 TRACE("item %d: tag %02x doesn't match expected %02x\n",
415 i, ptr[0], items[i].tag);
416 SetLastError(CRYPT_E_ASN1_BADTAG);
421 else if (items[i].optional)
423 TRACE("missing optional item %d, skipping\n", i);
424 items[i].size = items[i].minSize;
428 TRACE("not enough bytes for item %d, failing\n", i);
429 SetLastError(CRYPT_E_ASN1_CORRUPT);
434 *cbDecoded = decoded;
435 TRACE("returning %d\n", ret);
439 /* This decodes an arbitrary sequence into a contiguous block of memory
440 * (basically, a struct.) Each element being decoded is described by a struct
441 * AsnDecodeSequenceItem, see above.
442 * startingPointer is an optional pointer to the first place where dynamic
443 * data will be stored. If you know the starting offset, you may pass it
444 * here. Otherwise, pass NULL, and one will be inferred from the items.
446 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[],
447 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
448 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
449 DWORD *pcbDecoded, void *startingPointer)
453 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded,
454 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
459 SetLastError(CRYPT_E_ASN1_EOD);
462 if (pbEncoded[0] == ASN_SEQUENCE)
466 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
468 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded;
469 const BYTE *ptr = pbEncoded + 1 + lenBytes;
470 BOOL indefinite = FALSE;
472 cbEncoded -= 1 + lenBytes;
473 if (dataLen == CMSG_INDEFINITE_LENGTH)
478 else if (cbEncoded < dataLen)
480 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen,
482 SetLastError(CRYPT_E_ASN1_CORRUPT);
487 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
488 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded);
489 if (ret && dataLen == CMSG_INDEFINITE_LENGTH)
491 if (cbDecoded > cbEncoded - 2)
493 /* Not enough space for 0 TLV */
494 SetLastError(CRYPT_E_ASN1_CORRUPT);
497 else if (*(ptr + cbDecoded) != 0 ||
498 *(ptr + cbDecoded + 1) != 0)
500 TRACE("expected 0 TLV\n");
501 SetLastError(CRYPT_E_ASN1_CORRUPT);
508 if (ret && !indefinite && cbDecoded != dataLen)
510 TRACE("expected %d decoded, got %d, failing\n", dataLen,
512 SetLastError(CRYPT_E_ASN1_CORRUPT);
517 DWORD i, bytesNeeded = 0, structSize = 0;
519 for (i = 0; i < cItem; i++)
521 bytesNeeded += items[i].size;
522 structSize = max( structSize, items[i].offset + items[i].minSize );
525 *pcbDecoded = 1 + lenBytes + cbDecoded;
527 *pcbStructInfo = bytesNeeded;
528 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
529 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
533 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
534 pvStructInfo = *(BYTE **)pvStructInfo;
536 nextData = startingPointer;
538 nextData = (BYTE *)pvStructInfo + structSize;
539 memset(pvStructInfo, 0, structSize);
540 ret = CRYPT_AsnDecodeSequenceItems(items, cItem,
541 ptr, dataLen, dwFlags, pvStructInfo, nextData,
543 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
544 CRYPT_FreeSpace(pDecodePara, pvStructInfo);
551 SetLastError(CRYPT_E_ASN1_BADTAG);
554 TRACE("returning %d (%08x)\n", ret, GetLastError());
559 * The expected tag of the entire encoded array (usually a variant
560 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
561 * regardless of the tag seen.
563 * The offset within the outer structure at which the count exists.
564 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
565 * while CRYPT_ATTRIBUTE has countOffset ==
566 * offsetof(CRYPT_ATTRIBUTE, cValue).
568 * The offset within the outer structure at which the array pointer exists.
569 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
570 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
572 * The minimum size of the decoded array. On WIN32, this is always 8:
573 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
576 * used to decode each item in the array
578 * is the minimum size of each decoded item
580 * indicates whether each item has a dynamic pointer
582 * indicates the offset within itemSize at which the pointer exists
584 struct AsnArrayDescriptor
590 InternalDecodeFunc decodeFunc;
596 struct AsnArrayItemSize
602 /* Decodes an array of like types into a structure described by a struct
603 * AsnArrayDescriptor.
605 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
606 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
607 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
612 TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded,
613 cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
617 SetLastError(CRYPT_E_ASN1_EOD);
620 else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag)
624 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
626 DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded;
627 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
628 /* There can be arbitrarily many items, but there is often only one.
630 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
632 decoded = 1 + lenBytes;
636 BOOL doneDecoding = FALSE;
638 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; )
640 if (dataLen == CMSG_INDEFINITE_LENGTH)
647 SetLastError(CRYPT_E_ASN1_CORRUPT);
654 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen)
658 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0;
660 /* Each item decoded may not tolerate extraneous bytes,
661 * so get the length of the next element if known.
663 if ((ret = CRYPT_GetLengthIndefinite(ptr,
664 cbEncoded - (ptr - pbEncoded), &itemDataLen)))
666 if (itemDataLen == CMSG_INDEFINITE_LENGTH)
667 itemEncoded = cbEncoded - (ptr - pbEncoded);
669 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) +
673 ret = arrayDesc->decodeFunc(ptr, itemEncoded,
674 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size,
679 if (itemSizes != &itemSize)
680 itemSizes = CryptMemRealloc(itemSizes,
681 cItems * sizeof(struct AsnArrayItemSize));
686 cItems * sizeof(struct AsnArrayItemSize));
688 memcpy(itemSizes, &itemSize,
693 decoded += itemDecoded;
694 itemSizes[cItems - 1].encodedLen = itemEncoded;
695 itemSizes[cItems - 1].size = size;
708 *pcbDecoded = decoded;
710 *pcbStructInfo = bytesNeeded;
711 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
712 pvStructInfo, pcbStructInfo, bytesNeeded)))
719 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
720 pvStructInfo = *(void **)pvStructInfo;
721 pcItems = pvStructInfo;
723 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
725 rgItems = (BYTE *)pvStructInfo +
726 arrayDesc->minArraySize;
727 *(void **)((BYTE *)pcItems -
728 arrayDesc->countOffset + arrayDesc->arrayOffset) =
732 rgItems = *(void **)((BYTE *)pcItems -
733 arrayDesc->countOffset + arrayDesc->arrayOffset);
734 nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize;
735 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
736 i < cItems && ptr - pbEncoded - 1 - lenBytes <
741 if (arrayDesc->hasPointer)
742 *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize
743 + arrayDesc->pointerOffset) = nextData;
744 ret = arrayDesc->decodeFunc(ptr,
745 itemSizes[i].encodedLen,
746 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
747 (BYTE *)rgItems + i * arrayDesc->itemSize,
748 &itemSizes[i].size, &itemDecoded);
751 nextData += itemSizes[i].size - arrayDesc->itemSize;
757 if (itemSizes != &itemSize)
758 CryptMemFree(itemSizes);
763 SetLastError(CRYPT_E_ASN1_BADTAG);
769 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
770 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
771 * to CRYPT_E_ASN1_CORRUPT.
772 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
775 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
776 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
781 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
783 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
784 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
786 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
787 bytesNeeded += 1 + lenBytes + dataLen;
790 *pcbDecoded = 1 + lenBytes + dataLen;
792 *pcbStructInfo = bytesNeeded;
793 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
795 CRYPT_DER_BLOB *blob;
797 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
798 pvStructInfo = *(BYTE **)pvStructInfo;
800 blob->cbData = 1 + lenBytes + dataLen;
803 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
804 blob->pbData = (BYTE *)pbEncoded;
807 assert(blob->pbData);
808 memcpy(blob->pbData, pbEncoded, blob->cbData);
813 SetLastError(CRYPT_E_ASN1_CORRUPT);
821 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
822 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
823 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
828 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
829 pvStructInfo, *pcbStructInfo, pcbDecoded);
831 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
834 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
835 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
837 if (ret && pvStructInfo)
839 CRYPT_BIT_BLOB *blob = pvStructInfo;
846 for (i = 0; i < blob->cbData / 2; i++)
848 temp = blob->pbData[i];
849 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
850 blob->pbData[blob->cbData - i - 1] = temp;
854 TRACE("returning %d (%08x)\n", ret, GetLastError());
858 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
859 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
860 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
864 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
865 pDecodePara, pvStructInfo, *pcbStructInfo);
869 struct AsnDecodeSequenceItem items[] = {
870 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
871 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
872 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
873 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
874 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
875 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
876 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
877 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
878 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
879 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
882 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
883 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
884 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
885 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
886 pcbStructInfo, NULL, NULL);
890 SetLastError(STATUS_ACCESS_VIOLATION);
895 TRACE("Returning %d (%08x)\n", ret, GetLastError());
899 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
900 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
905 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
907 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
909 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
910 dwFlags, pvStructInfo, pcbStructInfo, NULL);
912 *pcbDecoded = 1 + lenBytes + dataLen;
917 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
918 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
922 struct AsnDecodeSequenceItem items[] = {
923 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
924 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
925 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
926 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
929 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
930 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
935 static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded,
936 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
940 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
941 offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
942 FINALMEMBERSIZE(CERT_INFO, cExtension),
943 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
944 offsetof(CERT_EXTENSION, pszObjId) };
946 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
947 pvStructInfo, *pcbStructInfo, pcbDecoded);
949 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
950 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
954 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
955 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
961 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
963 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
965 ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes,
966 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
967 if (ret && pcbDecoded)
968 *pcbDecoded = 1 + lenBytes + dataLen;
973 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
974 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
975 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
978 struct AsnDecodeSequenceItem items[] = {
979 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
980 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
981 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
982 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
983 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
984 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
985 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
986 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
987 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
988 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
990 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
991 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
993 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
994 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
996 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
997 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
998 FALSE, TRUE, offsetof(CERT_INFO,
999 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
1000 { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
1001 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1002 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
1003 { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
1004 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1005 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
1006 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
1007 CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension),
1008 TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
1011 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1012 pDecodePara, pvStructInfo, *pcbStructInfo);
1014 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1015 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1017 if (ret && pvStructInfo)
1021 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1022 info = *(CERT_INFO **)pvStructInfo;
1024 info = pvStructInfo;
1025 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1026 !info->Subject.cbData)
1028 SetLastError(CRYPT_E_ASN1_CORRUPT);
1029 /* Don't need to deallocate, because it should have failed on the
1030 * first pass (and no memory was allocated.)
1036 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1040 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1041 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1042 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1046 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1047 pDecodePara, pvStructInfo, *pcbStructInfo);
1053 /* Unless told not to, first try to decode it as a signed cert. */
1054 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1056 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1058 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1059 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1060 &signedCert, &size);
1064 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1065 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1066 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1067 pvStructInfo, pcbStructInfo);
1068 LocalFree(signedCert);
1071 /* Failing that, try it as an unsigned cert */
1075 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1076 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1077 pDecodePara, pvStructInfo, pcbStructInfo);
1082 SetLastError(STATUS_ACCESS_VIOLATION);
1086 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1090 static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded,
1091 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1095 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1096 offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
1097 FINALMEMBERSIZE(CRL_ENTRY, cExtension),
1098 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1099 offsetof(CERT_EXTENSION, pszObjId) };
1101 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1102 pvStructInfo, *pcbStructInfo, pcbDecoded);
1104 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1105 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1109 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1110 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1113 struct AsnDecodeSequenceItem items[] = {
1114 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1115 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1116 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1117 { 0, offsetof(CRL_ENTRY, RevocationDate),
1118 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1119 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1120 CRYPT_AsnDecodeCRLEntryExtensions,
1121 FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
1122 offsetof(CRL_ENTRY, rgExtension), 0 },
1124 PCRL_ENTRY entry = pvStructInfo;
1126 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1129 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1130 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1131 entry ? entry->SerialNumber.pbData : NULL);
1132 if (ret && entry && !entry->SerialNumber.cbData)
1134 WARN("empty CRL entry serial number\n");
1135 SetLastError(CRYPT_E_ASN1_CORRUPT);
1141 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1142 * whose rgCRLEntry member has been set prior to calling.
1144 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1145 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1148 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1149 offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
1150 MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1151 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1152 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1154 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1155 pvStructInfo, *pcbStructInfo, pcbDecoded);
1157 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1158 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1159 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1163 static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded,
1164 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1168 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1169 offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
1170 FINALMEMBERSIZE(CRL_INFO, cExtension),
1171 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1172 offsetof(CERT_EXTENSION, pszObjId) };
1174 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1175 pvStructInfo, *pcbStructInfo, pcbDecoded);
1177 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1178 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1182 static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded,
1183 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1189 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1191 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1193 ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes,
1194 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1195 if (ret && pcbDecoded)
1196 *pcbDecoded = 1 + lenBytes + dataLen;
1201 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1202 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1203 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1205 struct AsnDecodeSequenceItem items[] = {
1206 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1207 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1208 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1209 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1210 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1211 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1212 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1214 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1215 sizeof(FILETIME), FALSE, FALSE, 0 },
1216 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1217 sizeof(FILETIME), TRUE, FALSE, 0 },
1218 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1219 CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1220 TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
1221 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1222 CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension),
1223 TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
1227 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1228 pDecodePara, pvStructInfo, *pcbStructInfo);
1230 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1231 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1234 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1238 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1239 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1240 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1244 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1245 pDecodePara, pvStructInfo, *pcbStructInfo);
1251 /* Unless told not to, first try to decode it as a signed crl. */
1252 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1254 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1256 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1257 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1262 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1263 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1264 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1265 pvStructInfo, pcbStructInfo);
1266 LocalFree(signedCrl);
1269 /* Failing that, try it as an unsigned crl */
1273 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1274 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1275 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1280 SetLastError(STATUS_ACCESS_VIOLATION);
1284 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1288 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1289 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1294 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1295 pvStructInfo, *pcbStructInfo);
1297 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1299 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1300 DWORD bytesNeeded = sizeof(LPSTR);
1304 /* The largest possible string for the first two components
1305 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1310 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1311 pbEncoded[1 + lenBytes] / 40,
1312 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1314 bytesNeeded += strlen(firstTwo) + 1;
1315 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1316 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1318 /* large enough for ".4000000" */
1322 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1329 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1332 SetLastError(CRYPT_E_ASN1_CORRUPT);
1339 snprintf(str, sizeof(str), ".%d", val);
1340 bytesNeeded += strlen(str);
1345 *pcbDecoded = 1 + lenBytes + dataLen;
1347 *pcbStructInfo = bytesNeeded;
1348 else if (*pcbStructInfo < bytesNeeded)
1350 *pcbStructInfo = bytesNeeded;
1351 SetLastError(ERROR_MORE_DATA);
1359 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1362 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1363 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1365 pszObjId += strlen(pszObjId);
1366 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1367 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1371 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1380 sprintf(pszObjId, ".%d", val);
1381 pszObjId += strlen(pszObjId);
1385 *(LPSTR *)pvStructInfo = NULL;
1386 *pcbStructInfo = bytesNeeded;
1392 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1393 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1397 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1398 pvStructInfo, *pcbStructInfo);
1400 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1401 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1402 pvStructInfo, pcbStructInfo, pcbDecoded);
1405 SetLastError(CRYPT_E_ASN1_BADTAG);
1411 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1412 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1414 struct AsnDecodeSequenceItem items[] = {
1415 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1416 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1417 offsetof(CERT_EXTENSION, pszObjId), 0 },
1418 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1419 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1420 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1421 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1422 offsetof(CERT_EXTENSION, Value.pbData) },
1425 PCERT_EXTENSION ext = pvStructInfo;
1427 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1431 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1432 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1433 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1434 pcbDecoded, ext ? ext->pszObjId : NULL);
1436 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1437 debugstr_a(ext->pszObjId));
1438 TRACE("returning %d (%08x)\n", ret, GetLastError());
1442 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1443 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1444 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1448 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1449 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1453 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1454 offsetof(CERT_EXTENSIONS, cExtension),
1455 offsetof(CERT_EXTENSIONS, rgExtension),
1456 sizeof(CERT_EXTENSIONS),
1457 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1458 offsetof(CERT_EXTENSION, pszObjId) };
1460 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1461 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1465 SetLastError(STATUS_ACCESS_VIOLATION);
1472 /* Warning: this assumes the address of value->Value.pbData is already set, in
1473 * order to avoid overwriting memory. (In some cases, it may change it, if it
1474 * doesn't copy anything to memory.) Be sure to set it correctly!
1476 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1477 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1482 CERT_NAME_VALUE *value = pvStructInfo;
1484 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1486 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1487 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1489 switch (pbEncoded[0])
1491 case ASN_OCTETSTRING:
1492 valueType = CERT_RDN_OCTET_STRING;
1493 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1494 bytesNeeded += dataLen;
1496 case ASN_NUMERICSTRING:
1497 valueType = CERT_RDN_NUMERIC_STRING;
1498 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1499 bytesNeeded += dataLen;
1501 case ASN_PRINTABLESTRING:
1502 valueType = CERT_RDN_PRINTABLE_STRING;
1503 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1504 bytesNeeded += dataLen;
1507 valueType = CERT_RDN_IA5_STRING;
1508 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1509 bytesNeeded += dataLen;
1512 valueType = CERT_RDN_T61_STRING;
1513 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1514 bytesNeeded += dataLen;
1516 case ASN_VIDEOTEXSTRING:
1517 valueType = CERT_RDN_VIDEOTEX_STRING;
1518 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1519 bytesNeeded += dataLen;
1521 case ASN_GRAPHICSTRING:
1522 valueType = CERT_RDN_GRAPHIC_STRING;
1523 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1524 bytesNeeded += dataLen;
1526 case ASN_VISIBLESTRING:
1527 valueType = CERT_RDN_VISIBLE_STRING;
1528 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1529 bytesNeeded += dataLen;
1531 case ASN_GENERALSTRING:
1532 valueType = CERT_RDN_GENERAL_STRING;
1533 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1534 bytesNeeded += dataLen;
1536 case ASN_UNIVERSALSTRING:
1537 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1538 SetLastError(CRYPT_E_ASN1_BADTAG);
1541 valueType = CERT_RDN_BMP_STRING;
1542 bytesNeeded += dataLen;
1544 case ASN_UTF8STRING:
1545 valueType = CERT_RDN_UTF8_STRING;
1546 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1547 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1550 SetLastError(CRYPT_E_ASN1_BADTAG);
1555 *pcbDecoded = 1 + lenBytes + dataLen;
1557 *pcbStructInfo = bytesNeeded;
1558 else if (*pcbStructInfo < bytesNeeded)
1560 *pcbStructInfo = bytesNeeded;
1561 SetLastError(ERROR_MORE_DATA);
1566 *pcbStructInfo = bytesNeeded;
1567 value->dwValueType = valueType;
1572 assert(value->Value.pbData);
1573 switch (pbEncoded[0])
1575 case ASN_OCTETSTRING:
1576 case ASN_NUMERICSTRING:
1577 case ASN_PRINTABLESTRING:
1580 case ASN_VIDEOTEXSTRING:
1581 case ASN_GRAPHICSTRING:
1582 case ASN_VISIBLESTRING:
1583 case ASN_GENERALSTRING:
1584 value->Value.cbData = dataLen;
1587 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1588 memcpy(value->Value.pbData,
1589 pbEncoded + 1 + lenBytes, dataLen);
1591 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1597 LPWSTR str = (LPWSTR)value->Value.pbData;
1599 value->Value.cbData = dataLen;
1600 for (i = 0; i < dataLen / 2; i++)
1601 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1602 pbEncoded[1 + lenBytes + 2 * i + 1];
1605 case ASN_UTF8STRING:
1607 LPWSTR str = (LPWSTR)value->Value.pbData;
1609 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1610 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1611 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1618 value->Value.cbData = 0;
1619 value->Value.pbData = NULL;
1626 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1627 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1628 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1634 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1635 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1636 if (ret && pvStructInfo)
1638 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1639 pcbStructInfo, *pcbStructInfo);
1642 CERT_NAME_VALUE *value;
1644 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1645 pvStructInfo = *(BYTE **)pvStructInfo;
1646 value = pvStructInfo;
1647 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1648 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1649 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1650 pcbStructInfo, NULL);
1656 SetLastError(STATUS_ACCESS_VIOLATION);
1663 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1664 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1669 CERT_NAME_VALUE *value = pvStructInfo;
1671 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1673 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1674 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1676 switch (pbEncoded[0])
1678 case ASN_NUMERICSTRING:
1679 valueType = CERT_RDN_NUMERIC_STRING;
1681 bytesNeeded += (dataLen + 1) * 2;
1683 case ASN_PRINTABLESTRING:
1684 valueType = CERT_RDN_PRINTABLE_STRING;
1686 bytesNeeded += (dataLen + 1) * 2;
1689 valueType = CERT_RDN_IA5_STRING;
1691 bytesNeeded += (dataLen + 1) * 2;
1694 valueType = CERT_RDN_T61_STRING;
1696 bytesNeeded += (dataLen + 1) * 2;
1698 case ASN_VIDEOTEXSTRING:
1699 valueType = CERT_RDN_VIDEOTEX_STRING;
1701 bytesNeeded += (dataLen + 1) * 2;
1703 case ASN_GRAPHICSTRING:
1704 valueType = CERT_RDN_GRAPHIC_STRING;
1706 bytesNeeded += (dataLen + 1) * 2;
1708 case ASN_VISIBLESTRING:
1709 valueType = CERT_RDN_VISIBLE_STRING;
1711 bytesNeeded += (dataLen + 1) * 2;
1713 case ASN_GENERALSTRING:
1714 valueType = CERT_RDN_GENERAL_STRING;
1716 bytesNeeded += (dataLen + 1) * 2;
1718 case ASN_UNIVERSALSTRING:
1719 valueType = CERT_RDN_UNIVERSAL_STRING;
1721 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1724 valueType = CERT_RDN_BMP_STRING;
1726 bytesNeeded += dataLen + sizeof(WCHAR);
1728 case ASN_UTF8STRING:
1729 valueType = CERT_RDN_UTF8_STRING;
1731 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1732 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1735 SetLastError(CRYPT_E_ASN1_BADTAG);
1740 *pcbDecoded = 1 + lenBytes + dataLen;
1742 *pcbStructInfo = bytesNeeded;
1743 else if (*pcbStructInfo < bytesNeeded)
1745 *pcbStructInfo = bytesNeeded;
1746 SetLastError(ERROR_MORE_DATA);
1751 *pcbStructInfo = bytesNeeded;
1752 value->dwValueType = valueType;
1756 LPWSTR str = (LPWSTR)value->Value.pbData;
1758 assert(value->Value.pbData);
1759 switch (pbEncoded[0])
1761 case ASN_NUMERICSTRING:
1762 case ASN_PRINTABLESTRING:
1765 case ASN_VIDEOTEXSTRING:
1766 case ASN_GRAPHICSTRING:
1767 case ASN_VISIBLESTRING:
1768 case ASN_GENERALSTRING:
1769 value->Value.cbData = dataLen * 2;
1770 for (i = 0; i < dataLen; i++)
1771 str[i] = pbEncoded[1 + lenBytes + i];
1774 case ASN_UNIVERSALSTRING:
1775 value->Value.cbData = dataLen / 2;
1776 for (i = 0; i < dataLen / 4; i++)
1777 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1778 | pbEncoded[1 + lenBytes + 2 * i + 3];
1782 value->Value.cbData = dataLen;
1783 for (i = 0; i < dataLen / 2; i++)
1784 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1785 pbEncoded[1 + lenBytes + 2 * i + 1];
1788 case ASN_UTF8STRING:
1789 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1790 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1791 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
1792 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
1793 value->Value.cbData += sizeof(WCHAR);
1799 value->Value.cbData = 0;
1800 value->Value.pbData = NULL;
1807 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1808 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1809 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1815 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1816 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1817 if (ret && pvStructInfo)
1819 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1820 pcbStructInfo, *pcbStructInfo);
1823 CERT_NAME_VALUE *value;
1825 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1826 pvStructInfo = *(BYTE **)pvStructInfo;
1827 value = pvStructInfo;
1828 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1829 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1830 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1831 pcbStructInfo, NULL);
1837 SetLastError(STATUS_ACCESS_VIOLATION);
1844 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1845 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1848 struct AsnDecodeSequenceItem items[] = {
1849 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1850 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1851 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1852 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1853 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1854 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1856 CERT_RDN_ATTR *attr = pvStructInfo;
1858 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1859 pvStructInfo, *pcbStructInfo);
1862 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1863 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1864 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1865 attr ? attr->pszObjId : NULL);
1868 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1869 debugstr_a(attr->pszObjId));
1870 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1872 TRACE("returning %d (%08x)\n", ret, GetLastError());
1876 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1877 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1880 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1881 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1883 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1884 offsetof(CERT_RDN_ATTR, pszObjId) };
1886 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1887 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1891 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1892 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1893 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1899 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1900 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
1901 sizeof(CERT_NAME_INFO),
1902 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1903 offsetof(CERT_RDN, rgRDNAttr) };
1905 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1906 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1910 SetLastError(STATUS_ACCESS_VIOLATION);
1917 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1918 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1922 struct AsnDecodeSequenceItem items[] = {
1923 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1924 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1925 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1926 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1927 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1928 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1930 CERT_RDN_ATTR *attr = pvStructInfo;
1932 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1933 pvStructInfo, *pcbStructInfo);
1936 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1937 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1938 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1939 attr ? attr->pszObjId : NULL);
1942 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1943 debugstr_a(attr->pszObjId));
1944 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1946 TRACE("returning %d (%08x)\n", ret, GetLastError());
1950 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1951 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1954 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1955 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1957 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1958 offsetof(CERT_RDN_ATTR, pszObjId) };
1960 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1961 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1965 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1966 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1967 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1973 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1974 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
1975 sizeof(CERT_NAME_INFO),
1976 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
1977 offsetof(CERT_RDN, rgRDNAttr) };
1979 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1980 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1984 SetLastError(STATUS_ACCESS_VIOLATION);
1991 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
1994 BOOL ret = TRUE, done = FALSE;
1995 DWORD indefiniteNestingLevels = 0, decoded = 0;
1997 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2004 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2007 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2009 if (dataLen == CMSG_INDEFINITE_LENGTH)
2011 indefiniteNestingLevels++;
2012 pbEncoded += 1 + lenBytes;
2013 cbEncoded -= 1 + lenBytes;
2014 decoded += 1 + lenBytes;
2015 TRACE("indefiniteNestingLevels = %d\n",
2016 indefiniteNestingLevels);
2020 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2021 indefiniteNestingLevels)
2023 indefiniteNestingLevels--;
2024 TRACE("indefiniteNestingLevels = %d\n",
2025 indefiniteNestingLevels);
2027 pbEncoded += 1 + lenBytes + dataLen;
2028 cbEncoded -= 1 + lenBytes + dataLen;
2029 decoded += 1 + lenBytes + dataLen;
2030 if (!indefiniteNestingLevels)
2034 } while (ret && !done);
2035 /* If we haven't found all 0 TLVs, we haven't found the end */
2036 if (ret && indefiniteNestingLevels)
2038 SetLastError(CRYPT_E_ASN1_EOD);
2042 *pcbDecoded = decoded;
2043 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2047 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
2048 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2052 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2054 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2055 pvStructInfo, *pcbStructInfo);
2057 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2059 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
2060 bytesNeeded += encodedLen;
2062 *pcbStructInfo = bytesNeeded;
2063 else if (*pcbStructInfo < bytesNeeded)
2065 SetLastError(ERROR_MORE_DATA);
2066 *pcbStructInfo = bytesNeeded;
2071 PCRYPT_OBJID_BLOB blob = pvStructInfo;
2073 *pcbStructInfo = bytesNeeded;
2074 blob->cbData = encodedLen;
2077 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2078 blob->pbData = (LPBYTE)pbEncoded;
2081 assert(blob->pbData);
2082 memcpy(blob->pbData, pbEncoded, blob->cbData);
2086 blob->pbData = NULL;
2089 *pcbDecoded = encodedLen;
2094 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2095 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2098 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2099 offsetof(CTL_USAGE, cUsageIdentifier),
2100 offsetof(CTL_USAGE, rgpszUsageIdentifier),
2102 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2104 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2105 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2109 static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded,
2110 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2113 struct AsnArrayDescriptor arrayDesc = { 0,
2114 offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
2115 FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
2116 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2117 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2120 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2121 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2125 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2126 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2128 struct AsnDecodeSequenceItem items[] = {
2129 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2130 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2131 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2132 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2133 CRYPT_AsnDecodeCTLEntryAttributes,
2134 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
2135 offsetof(CTL_ENTRY, rgAttribute), 0 },
2138 CTL_ENTRY *entry = pvStructInfo;
2140 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2143 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2144 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2145 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2149 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2150 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2153 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2154 offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
2155 FINALMEMBERSIZE(CTL_INFO, cExtension),
2156 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2157 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2159 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2160 pvStructInfo, *pcbStructInfo, pcbDecoded);
2162 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2163 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2167 static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded,
2168 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2172 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2173 offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
2174 FINALMEMBERSIZE(CTL_INFO, cExtension),
2175 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
2176 offsetof(CERT_EXTENSION, pszObjId) };
2178 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2179 pvStructInfo, *pcbStructInfo, pcbDecoded);
2181 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2182 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2186 static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded,
2187 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2193 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2195 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2197 ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes,
2198 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
2199 if (ret && pcbDecoded)
2200 *pcbDecoded = 1 + lenBytes + dataLen;
2205 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2206 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2207 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2211 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2212 pDecodePara, pvStructInfo, *pcbStructInfo);
2216 struct AsnDecodeSequenceItem items[] = {
2217 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2218 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2219 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2220 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2221 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2222 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2223 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2224 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2225 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2226 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2227 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2228 { 0, offsetof(CTL_INFO, ThisUpdate),
2229 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2231 { 0, offsetof(CTL_INFO, NextUpdate),
2232 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2234 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2235 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2236 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2237 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2238 CRYPT_AsnDecodeCTLEntries,
2239 MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2240 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2241 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2242 CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension),
2243 TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
2246 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2247 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2248 pcbStructInfo, NULL, NULL);
2252 SetLastError(STATUS_ACCESS_VIOLATION);
2258 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2259 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2263 struct AsnDecodeSequenceItem items[] = {
2264 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2265 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2266 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2267 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2268 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2269 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2271 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2273 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2274 pvStructInfo, *pcbStructInfo);
2276 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2277 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2278 pcbDecoded, capability ? capability->pszObjId : NULL);
2279 TRACE("returning %d\n", ret);
2283 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2284 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2285 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2289 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2290 pDecodePara, pvStructInfo, *pcbStructInfo);
2294 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2295 offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
2296 offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
2297 sizeof(CRYPT_SMIME_CAPABILITIES),
2298 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2299 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2301 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2302 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2306 SetLastError(STATUS_ACCESS_VIOLATION);
2309 TRACE("returning %d\n", ret);
2313 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2314 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2319 LPSTR *pStr = pvStructInfo;
2321 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2323 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2324 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2326 if (pbEncoded[0] != ASN_IA5STRING)
2328 SetLastError(CRYPT_E_ASN1_CORRUPT);
2333 bytesNeeded += dataLen;
2335 *pcbDecoded = 1 + lenBytes + dataLen;
2337 *pcbStructInfo = bytesNeeded;
2338 else if (*pcbStructInfo < bytesNeeded)
2340 *pcbStructInfo = bytesNeeded;
2341 SetLastError(ERROR_MORE_DATA);
2346 *pcbStructInfo = bytesNeeded;
2352 memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2363 static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded,
2364 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2367 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2368 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2369 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers),
2370 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2371 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2374 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2375 pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2377 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2378 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2379 TRACE("returning %d\n", ret);
2383 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2384 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2388 struct AsnDecodeSequenceItem items[] = {
2389 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2390 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2391 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2392 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2393 cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
2394 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2395 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2396 rgNoticeNumbers), 0 },
2400 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2401 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2403 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2404 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2408 /* The caller is expecting a pointer to a
2409 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2410 * CRYPT_AsnDecodeSequence is decoding a
2411 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2412 * needed, and decode again if the requisite space is available.
2414 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2416 *pcbStructInfo = bytesNeeded;
2417 else if (*pcbStructInfo < bytesNeeded)
2419 *pcbStructInfo = bytesNeeded;
2420 SetLastError(ERROR_MORE_DATA);
2425 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2427 *pcbStructInfo = bytesNeeded;
2428 /* The pointer (pvStructInfo) passed in points to the first dynamic
2429 * pointer, so use it as the pointer to the
2430 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2431 * appropriate offset for the first dynamic pointer within the
2432 * notice reference by pointing to the first memory location past
2433 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2436 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2437 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2438 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2439 ret = CRYPT_AsnDecodeSequence(items,
2440 sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2441 NULL, noticeRef, &bytesNeeded, pcbDecoded,
2442 noticeRef->pszOrganization);
2445 TRACE("returning %d\n", ret);
2449 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2450 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2456 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2458 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2459 DWORD bytesNeeded = sizeof(LPWSTR);
2461 switch (pbEncoded[0])
2463 case ASN_NUMERICSTRING:
2465 bytesNeeded += (dataLen + 1) * 2;
2467 case ASN_PRINTABLESTRING:
2469 bytesNeeded += (dataLen + 1) * 2;
2473 bytesNeeded += (dataLen + 1) * 2;
2477 bytesNeeded += (dataLen + 1) * 2;
2479 case ASN_VIDEOTEXSTRING:
2481 bytesNeeded += (dataLen + 1) * 2;
2483 case ASN_GRAPHICSTRING:
2485 bytesNeeded += (dataLen + 1) * 2;
2487 case ASN_VISIBLESTRING:
2489 bytesNeeded += (dataLen + 1) * 2;
2491 case ASN_GENERALSTRING:
2493 bytesNeeded += (dataLen + 1) * 2;
2495 case ASN_UNIVERSALSTRING:
2497 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2501 bytesNeeded += dataLen + sizeof(WCHAR);
2503 case ASN_UTF8STRING:
2505 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2506 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2509 SetLastError(CRYPT_E_ASN1_BADTAG);
2514 *pcbDecoded = 1 + lenBytes + dataLen;
2516 *pcbStructInfo = bytesNeeded;
2517 else if (*pcbStructInfo < bytesNeeded)
2519 *pcbStructInfo = bytesNeeded;
2520 SetLastError(ERROR_MORE_DATA);
2525 LPWSTR *pStr = pvStructInfo;
2527 *pcbStructInfo = bytesNeeded;
2531 LPWSTR str = *(LPWSTR *)pStr;
2534 switch (pbEncoded[0])
2536 case ASN_NUMERICSTRING:
2537 case ASN_PRINTABLESTRING:
2540 case ASN_VIDEOTEXSTRING:
2541 case ASN_GRAPHICSTRING:
2542 case ASN_VISIBLESTRING:
2543 case ASN_GENERALSTRING:
2544 for (i = 0; i < dataLen; i++)
2545 str[i] = pbEncoded[1 + lenBytes + i];
2548 case ASN_UNIVERSALSTRING:
2549 for (i = 0; i < dataLen / 4; i++)
2550 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2551 | pbEncoded[1 + lenBytes + 2 * i + 3];
2555 for (i = 0; i < dataLen / 2; i++)
2556 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2557 pbEncoded[1 + lenBytes + 2 * i + 1];
2560 case ASN_UTF8STRING:
2562 int len = MultiByteToWideChar(CP_UTF8, 0,
2563 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2564 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2577 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2578 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2579 DWORD *pcbStructInfo, DWORD *pcbDecoded)
2582 struct AsnDecodeSequenceItem items[] = {
2583 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2584 pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2585 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2586 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2587 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2588 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2589 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2591 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2593 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2594 pvStructInfo, *pcbStructInfo);
2596 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2597 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2598 pcbDecoded, notice ? notice->pNoticeReference : NULL);
2599 TRACE("returning %d\n", ret);
2603 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2604 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2605 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2606 void *pvStructInfo, DWORD *pcbStructInfo)
2610 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2611 pDecodePara, pvStructInfo, *pcbStructInfo);
2617 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2618 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2623 *pcbStructInfo = bytesNeeded;
2624 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2625 pvStructInfo, pcbStructInfo, bytesNeeded)))
2627 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2629 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2630 pvStructInfo = *(BYTE **)pvStructInfo;
2631 notice = pvStructInfo;
2632 notice->pNoticeReference =
2633 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2634 ((BYTE *)pvStructInfo +
2635 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2636 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2637 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2638 pvStructInfo, &bytesNeeded, NULL);
2644 SetLastError(STATUS_ACCESS_VIOLATION);
2647 TRACE("returning %d\n", ret);
2651 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
2652 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2656 struct AsnArrayDescriptor arrayDesc = { 0,
2657 offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
2658 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue),
2659 CRYPT_AsnDecodeCopyBytes,
2660 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2662 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2663 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
2665 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2666 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2670 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2671 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2675 struct AsnDecodeSequenceItem items[] = {
2676 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2677 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2678 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2679 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2680 CRYPT_AsnDecodePKCSAttributeValue,
2681 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
2682 TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2684 PCRYPT_ATTRIBUTE attr = pvStructInfo;
2686 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2687 pvStructInfo, *pcbStructInfo);
2689 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2690 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2691 pcbDecoded, attr ? attr->pszObjId : NULL);
2692 TRACE("returning %d\n", ret);
2696 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2697 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2698 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2702 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2703 pDecodePara, pvStructInfo, *pcbStructInfo);
2709 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2710 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2714 *pcbStructInfo = bytesNeeded;
2715 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2716 pvStructInfo, pcbStructInfo, bytesNeeded)))
2718 PCRYPT_ATTRIBUTE attr;
2720 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2721 pvStructInfo = *(BYTE **)pvStructInfo;
2722 attr = pvStructInfo;
2723 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2724 sizeof(CRYPT_ATTRIBUTE));
2725 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2726 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2733 SetLastError(STATUS_ACCESS_VIOLATION);
2736 TRACE("returning %d\n", ret);
2740 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2741 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2744 struct AsnArrayDescriptor arrayDesc = { 0,
2745 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2746 sizeof(CRYPT_ATTRIBUTES),
2747 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2748 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2751 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2752 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2756 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2757 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2758 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2762 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2763 pDecodePara, pvStructInfo, *pcbStructInfo);
2767 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2768 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2769 sizeof(CRYPT_ATTRIBUTES),
2770 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
2771 TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2773 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2774 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2778 SetLastError(STATUS_ACCESS_VIOLATION);
2781 TRACE("returning %d\n", ret);
2785 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2786 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2788 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2790 struct AsnDecodeSequenceItem items[] = {
2791 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2792 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2793 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2794 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2795 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2796 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2799 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2800 pvStructInfo, *pcbStructInfo, pcbDecoded);
2802 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2803 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2804 pcbDecoded, algo ? algo->pszObjId : NULL);
2805 if (ret && pvStructInfo)
2807 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2808 debugstr_a(algo->pszObjId));
2813 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2814 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2818 struct AsnDecodeSequenceItem items[] = {
2819 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2820 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2821 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2822 Algorithm.pszObjId) },
2823 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2824 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2825 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2827 PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2829 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2830 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2831 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2835 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2836 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2837 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2845 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2846 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2849 *pcbStructInfo = bytesNeeded;
2850 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2851 pvStructInfo, pcbStructInfo, bytesNeeded)))
2853 PCERT_PUBLIC_KEY_INFO info;
2855 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2856 pvStructInfo = *(BYTE **)pvStructInfo;
2857 info = pvStructInfo;
2858 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2859 sizeof(CERT_PUBLIC_KEY_INFO);
2860 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2861 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2862 &bytesNeeded, NULL);
2868 SetLastError(STATUS_ACCESS_VIOLATION);
2875 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2876 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2882 SetLastError(CRYPT_E_ASN1_CORRUPT);
2885 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2887 SetLastError(CRYPT_E_ASN1_CORRUPT);
2890 if (pbEncoded[1] > 1)
2892 SetLastError(CRYPT_E_ASN1_CORRUPT);
2899 *pcbStructInfo = sizeof(BOOL);
2902 else if (*pcbStructInfo < sizeof(BOOL))
2904 *pcbStructInfo = sizeof(BOOL);
2905 SetLastError(ERROR_MORE_DATA);
2910 *pcbStructInfo = sizeof(BOOL);
2911 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2914 TRACE("returning %d (%08x)\n", ret, GetLastError());
2918 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2919 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2921 PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2922 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2925 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2926 pvStructInfo, *pcbStructInfo);
2930 SetLastError(CRYPT_E_ASN1_CORRUPT);
2933 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2934 if (1 + lenBytes > cbEncoded)
2936 SetLastError(CRYPT_E_ASN1_CORRUPT);
2939 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2941 switch (pbEncoded[0] & ASN_TYPE_MASK)
2943 case 1: /* rfc822Name */
2944 case 2: /* dNSName */
2945 case 6: /* uniformResourceIdentifier */
2946 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2948 case 4: /* directoryName */
2949 case 7: /* iPAddress */
2950 bytesNeeded += dataLen;
2952 case 8: /* registeredID */
2953 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2957 /* FIXME: ugly, shouldn't need to know internals of OID decode
2958 * function to use it.
2960 bytesNeeded += dataLen - sizeof(LPSTR);
2963 case 0: /* otherName */
2964 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2965 SetLastError(CRYPT_E_ASN1_BADTAG);
2968 case 3: /* x400Address, unimplemented */
2969 case 5: /* ediPartyName, unimplemented */
2970 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2971 SetLastError(CRYPT_E_ASN1_BADTAG);
2975 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2976 SetLastError(CRYPT_E_ASN1_CORRUPT);
2982 *pcbDecoded = 1 + lenBytes + dataLen;
2984 *pcbStructInfo = bytesNeeded;
2985 else if (*pcbStructInfo < bytesNeeded)
2987 *pcbStructInfo = bytesNeeded;
2988 SetLastError(ERROR_MORE_DATA);
2993 *pcbStructInfo = bytesNeeded;
2994 /* MS used values one greater than the asn1 ones.. sigh */
2995 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
2996 switch (pbEncoded[0] & ASN_TYPE_MASK)
2998 case 1: /* rfc822Name */
2999 case 2: /* dNSName */
3000 case 6: /* uniformResourceIdentifier */
3004 for (i = 0; i < dataLen; i++)
3005 entry->u.pwszURL[i] =
3006 (WCHAR)pbEncoded[1 + lenBytes + i];
3007 entry->u.pwszURL[i] = 0;
3008 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3009 debugstr_w(entry->u.pwszURL));
3012 case 4: /* directoryName */
3013 /* The data are memory-equivalent with the IPAddress case,
3016 case 7: /* iPAddress */
3017 /* The next data pointer is in the pwszURL spot, that is,
3018 * the first 4 bytes. Need to move it to the next spot.
3020 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3021 entry->u.IPAddress.cbData = dataLen;
3022 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3025 case 8: /* registeredID */
3026 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
3027 &entry->u.pszRegisteredID, &dataLen, NULL);
3036 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
3037 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3041 struct AsnArrayDescriptor arrayDesc = { 0,
3042 offsetof(CERT_ALT_NAME_INFO, cAltEntry),
3043 offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
3044 sizeof(CERT_ALT_NAME_INFO),
3045 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3046 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3048 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3049 pvStructInfo, *pcbStructInfo, pcbDecoded);
3051 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3052 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3056 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
3057 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
3058 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3063 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3064 pvStructInfo, *pcbStructInfo, pcbDecoded);
3066 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
3069 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3070 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
3072 if (ret && pvStructInfo)
3074 CRYPT_DATA_BLOB *blob = pvStructInfo;
3081 for (i = 0; i < blob->cbData / 2; i++)
3083 temp = blob->pbData[i];
3084 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
3085 blob->pbData[blob->cbData - i - 1] = temp;
3089 TRACE("returning %d (%08x)\n", ret, GetLastError());
3093 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3094 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3095 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3101 struct AsnDecodeSequenceItem items[] = {
3102 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3103 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3104 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3105 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3106 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3107 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3108 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3109 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3110 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3111 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3112 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3115 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3116 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3117 pcbStructInfo, NULL, NULL);
3121 SetLastError(STATUS_ACCESS_VIOLATION);
3128 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3129 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3130 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3136 struct AsnDecodeSequenceItem items[] = {
3137 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3138 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3139 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3140 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3141 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3142 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3143 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3144 AuthorityCertIssuer.rgAltEntry), 0 },
3145 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3146 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3147 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3148 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3149 AuthorityCertSerialNumber.pbData), 0 },
3152 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3153 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3154 pcbStructInfo, NULL, NULL);
3158 SetLastError(STATUS_ACCESS_VIOLATION);
3165 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3166 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3169 struct AsnDecodeSequenceItem items[] = {
3170 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3171 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3172 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3173 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3174 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3175 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3177 CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3179 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3180 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3181 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3184 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3185 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3186 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3190 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3191 pDecodePara, pvStructInfo, *pcbStructInfo);
3195 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3196 offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr),
3197 offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr),
3198 sizeof(CERT_AUTHORITY_INFO_ACCESS),
3199 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3200 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3202 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3203 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3207 SetLastError(STATUS_ACCESS_VIOLATION);
3214 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3215 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3220 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3221 pvStructInfo, *pcbStructInfo, pcbDecoded);
3223 /* The caller has already checked the tag, no need to check it again.
3224 * Check the outer length is valid:
3226 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3228 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3231 pbEncoded += 1 + lenBytes;
3232 cbEncoded -= 1 + lenBytes;
3233 if (dataLen == CMSG_INDEFINITE_LENGTH)
3234 cbEncoded -= 2; /* space for 0 TLV */
3235 /* Check the inner length is valid: */
3236 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3240 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3241 pvStructInfo, pcbStructInfo, &decodedLen);
3242 if (dataLen == CMSG_INDEFINITE_LENGTH)
3244 if (*(pbEncoded + decodedLen) != 0 ||
3245 *(pbEncoded + decodedLen + 1) != 0)
3247 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3248 *(pbEncoded + decodedLen),
3249 *(pbEncoded + decodedLen + 1));
3250 SetLastError(CRYPT_E_ASN1_CORRUPT);
3256 if (ret && pcbDecoded)
3258 *pcbDecoded = 1 + lenBytes + decodedLen;
3259 TRACE("decoded %d bytes\n", *pcbDecoded);
3266 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3267 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3270 CRYPT_CONTENT_INFO *info = pvStructInfo;
3271 struct AsnDecodeSequenceItem items[] = {
3272 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3273 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3274 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3275 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3276 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3277 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3278 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3282 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3283 pvStructInfo, *pcbStructInfo, pcbDecoded);
3285 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3286 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3287 pcbDecoded, info ? info->pszObjId : NULL);
3291 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3292 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3293 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3297 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3298 pDecodePara, pvStructInfo, *pcbStructInfo);
3302 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3303 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3304 if (ret && pvStructInfo)
3306 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3307 pcbStructInfo, *pcbStructInfo);
3310 CRYPT_CONTENT_INFO *info;
3312 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3313 pvStructInfo = *(BYTE **)pvStructInfo;
3314 info = pvStructInfo;
3315 info->pszObjId = (LPSTR)((BYTE *)info +
3316 sizeof(CRYPT_CONTENT_INFO));
3317 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3318 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3319 pcbStructInfo, NULL);
3325 SetLastError(STATUS_ACCESS_VIOLATION);
3331 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3332 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3333 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3336 struct AsnDecodeSequenceItem items[] = {
3337 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3338 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3339 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3340 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3341 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3343 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3344 CRYPT_AsnDecodePKCSContentInfoInternal,
3345 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3346 ContentInfo.pszObjId), 0 },
3347 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3348 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3349 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3352 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3353 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3358 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3359 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3360 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3364 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3365 pDecodePara, pvStructInfo, *pcbStructInfo);
3371 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3372 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3375 *pcbStructInfo = bytesNeeded;
3376 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3377 pvStructInfo, pcbStructInfo, bytesNeeded)))
3379 CERT_ALT_NAME_INFO *name;
3381 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3382 pvStructInfo = *(BYTE **)pvStructInfo;
3383 name = pvStructInfo;
3384 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3385 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3386 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3387 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3388 &bytesNeeded, NULL);
3394 SetLastError(STATUS_ACCESS_VIOLATION);
3401 struct PATH_LEN_CONSTRAINT
3403 BOOL fPathLenConstraint;
3404 DWORD dwPathLenConstraint;
3407 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3408 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3412 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3414 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3415 pvStructInfo, *pcbStructInfo, pcbDecoded);
3419 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3421 *pcbStructInfo = bytesNeeded;
3423 else if (*pcbStructInfo < bytesNeeded)
3425 SetLastError(ERROR_MORE_DATA);
3426 *pcbStructInfo = bytesNeeded;
3431 struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3433 *pcbStructInfo = bytesNeeded;
3434 size = sizeof(constraint->dwPathLenConstraint);
3435 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3436 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3438 constraint->fPathLenConstraint = TRUE;
3439 TRACE("got an int, dwPathLenConstraint is %d\n",
3440 constraint->dwPathLenConstraint);
3442 TRACE("returning %d (%08x)\n", ret, GetLastError());
3446 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3447 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3451 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3452 offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3453 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
3454 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3455 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3456 offsetof(CERT_NAME_BLOB, pbData) };
3458 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3459 pvStructInfo, *pcbStructInfo, pcbDecoded);
3461 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3462 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3463 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3467 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3468 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3469 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3475 struct AsnDecodeSequenceItem items[] = {
3476 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3477 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3478 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3479 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3480 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3481 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3482 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3483 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3484 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3486 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3489 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3490 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3491 pcbStructInfo, NULL, NULL);
3495 SetLastError(STATUS_ACCESS_VIOLATION);
3502 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3503 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3504 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3510 struct AsnDecodeSequenceItem items[] = {
3511 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3512 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3513 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3514 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3515 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3518 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3519 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3520 pcbStructInfo, NULL, NULL);
3524 SetLastError(STATUS_ACCESS_VIOLATION);
3531 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
3532 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3535 struct AsnDecodeSequenceItem items[] = {
3536 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
3537 pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3538 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3540 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3541 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3542 offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3545 CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3547 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3548 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3550 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3551 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3552 pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3556 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
3557 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3561 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3562 offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3563 offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
3564 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
3565 CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
3566 offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3568 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3569 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3571 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3572 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3573 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3577 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
3578 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3580 struct AsnDecodeSequenceItem items[] = {
3581 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3582 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3583 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3584 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3585 CRYPT_AsnDecodePolicyQualifiers,
3586 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE,
3587 TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3589 CERT_POLICY_INFO *info = pvStructInfo;
3592 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3593 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3595 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3596 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3597 pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
3601 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
3602 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3603 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3607 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3608 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3612 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3613 offsetof(CERT_POLICIES_INFO, cPolicyInfo),
3614 offsetof(CERT_POLICIES_INFO, rgPolicyInfo),
3615 sizeof(CERT_POLICIES_INFO),
3616 CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
3617 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
3619 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3620 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3624 SetLastError(STATUS_ACCESS_VIOLATION);
3630 #define RSA1_MAGIC 0x31415352
3632 struct DECODED_RSA_PUB_KEY
3635 CRYPT_INTEGER_BLOB modulus;
3638 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3639 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3640 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3646 struct AsnDecodeSequenceItem items[] = {
3647 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3648 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3649 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3651 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3652 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3654 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3657 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3658 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3662 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3663 decodedKey->modulus.cbData;
3667 *pcbStructInfo = bytesNeeded;
3670 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3671 pvStructInfo, pcbStructInfo, bytesNeeded)))
3674 RSAPUBKEY *rsaPubKey;
3676 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3677 pvStructInfo = *(BYTE **)pvStructInfo;
3679 hdr->bType = PUBLICKEYBLOB;
3680 hdr->bVersion = CUR_BLOB_VERSION;
3682 hdr->aiKeyAlg = CALG_RSA_KEYX;
3683 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3684 sizeof(BLOBHEADER));
3685 rsaPubKey->magic = RSA1_MAGIC;
3686 rsaPubKey->pubexp = decodedKey->pubexp;
3687 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3688 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3689 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3690 decodedKey->modulus.cbData);
3692 LocalFree(decodedKey);
3697 SetLastError(STATUS_ACCESS_VIOLATION);
3704 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3705 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3709 DWORD bytesNeeded, dataLen;
3711 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3712 pvStructInfo, *pcbStructInfo, pcbDecoded);
3714 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3716 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3718 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3719 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3721 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3723 *pcbDecoded = 1 + lenBytes + dataLen;
3725 *pcbStructInfo = bytesNeeded;
3726 else if (*pcbStructInfo < bytesNeeded)
3728 SetLastError(ERROR_MORE_DATA);
3729 *pcbStructInfo = bytesNeeded;
3734 CRYPT_DATA_BLOB *blob;
3736 *pcbStructInfo = bytesNeeded;
3737 blob = pvStructInfo;
3738 blob->cbData = dataLen;
3739 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3740 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
3743 assert(blob->pbData);
3745 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
3753 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
3754 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3755 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3759 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3760 pDecodePara, pvStructInfo, *pcbStructInfo);
3768 SetLastError(CRYPT_E_ASN1_CORRUPT);
3771 else if (pbEncoded[0] != ASN_OCTETSTRING)
3773 SetLastError(CRYPT_E_ASN1_BADTAG);
3776 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3777 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3780 *pcbStructInfo = bytesNeeded;
3781 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3782 pvStructInfo, pcbStructInfo, bytesNeeded)))
3784 CRYPT_DATA_BLOB *blob;
3786 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3787 pvStructInfo = *(BYTE **)pvStructInfo;
3788 blob = pvStructInfo;
3789 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3790 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3791 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3792 &bytesNeeded, NULL);
3798 SetLastError(STATUS_ACCESS_VIOLATION);
3805 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3806 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3809 DWORD bytesNeeded, dataLen;
3810 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3812 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3813 pvStructInfo, *pcbStructInfo, pcbDecoded);
3815 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3817 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3818 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
3820 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
3822 *pcbDecoded = 1 + lenBytes + dataLen;
3824 *pcbStructInfo = bytesNeeded;
3825 else if (*pcbStructInfo < bytesNeeded)
3827 *pcbStructInfo = bytesNeeded;
3828 SetLastError(ERROR_MORE_DATA);
3833 CRYPT_BIT_BLOB *blob;
3835 *pcbStructInfo = bytesNeeded;
3836 blob = pvStructInfo;
3837 blob->cbData = dataLen - 1;
3838 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
3839 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3841 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
3845 assert(blob->pbData);
3848 BYTE mask = 0xff << blob->cUnusedBits;
3850 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
3852 blob->pbData[blob->cbData - 1] &= mask;
3860 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
3861 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3862 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3866 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
3867 pDecodePara, pvStructInfo, pcbStructInfo);
3875 SetLastError(CRYPT_E_ASN1_CORRUPT);
3878 else if (pbEncoded[0] != ASN_BITSTRING)
3880 SetLastError(CRYPT_E_ASN1_BADTAG);
3883 else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3884 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3887 *pcbStructInfo = bytesNeeded;
3888 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3889 pvStructInfo, pcbStructInfo, bytesNeeded)))
3891 CRYPT_BIT_BLOB *blob;
3893 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3894 pvStructInfo = *(BYTE **)pvStructInfo;
3895 blob = pvStructInfo;
3896 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
3897 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3898 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3899 &bytesNeeded, NULL);
3905 SetLastError(STATUS_ACCESS_VIOLATION);
3909 TRACE("returning %d (%08x)\n", ret, GetLastError());
3913 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3914 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3915 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3918 BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
3919 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
3920 DWORD size = sizeof(buf);
3922 blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
3923 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, buf,
3928 *pcbStructInfo = sizeof(int);
3929 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
3933 if (blob->pbData[blob->cbData - 1] & 0x80)
3935 /* initialize to a negative value to sign-extend */
3940 for (i = 0; i < blob->cbData; i++)
3943 val |= blob->pbData[blob->cbData - i - 1];
3945 memcpy(pvStructInfo, &val, sizeof(int));
3948 else if (GetLastError() == ERROR_MORE_DATA)
3949 SetLastError(CRYPT_E_ASN1_LARGE);
3953 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
3954 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3955 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3965 SetLastError(CRYPT_E_ASN1_EOD);
3968 else if (pbEncoded[0] != ASN_INTEGER)
3970 SetLastError(CRYPT_E_ASN1_BADTAG);
3974 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3975 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3979 *pcbStructInfo = bytesNeeded;
3980 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3981 pvStructInfo, pcbStructInfo, bytesNeeded)))
3983 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3984 pvStructInfo = *(BYTE **)pvStructInfo;
3985 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3986 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3987 &bytesNeeded, NULL);
3993 SetLastError(STATUS_ACCESS_VIOLATION);
4000 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
4001 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4005 DWORD bytesNeeded, dataLen;
4007 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4009 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4011 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4013 *pcbDecoded = 1 + lenBytes + dataLen;
4015 *pcbStructInfo = bytesNeeded;
4016 else if (*pcbStructInfo < bytesNeeded)
4018 *pcbStructInfo = bytesNeeded;
4019 SetLastError(ERROR_MORE_DATA);
4024 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4026 *pcbStructInfo = bytesNeeded;
4027 blob->cbData = dataLen;
4028 assert(blob->pbData);
4033 for (i = 0; i < blob->cbData; i++)
4035 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4044 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
4045 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4046 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4054 if (pbEncoded[0] != ASN_INTEGER)
4056 SetLastError(CRYPT_E_ASN1_BADTAG);
4060 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4061 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4065 *pcbStructInfo = bytesNeeded;
4066 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4067 pvStructInfo, pcbStructInfo, bytesNeeded)))
4069 CRYPT_INTEGER_BLOB *blob;
4071 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4072 pvStructInfo = *(BYTE **)pvStructInfo;
4073 blob = pvStructInfo;
4074 blob->pbData = (BYTE *)pvStructInfo +
4075 sizeof(CRYPT_INTEGER_BLOB);
4076 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4077 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4078 &bytesNeeded, NULL);
4084 SetLastError(STATUS_ACCESS_VIOLATION);
4091 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
4092 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4097 if (pbEncoded[0] == ASN_INTEGER)
4099 DWORD bytesNeeded, dataLen;
4101 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4103 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4106 *pcbDecoded = 1 + lenBytes + dataLen;
4107 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4109 *pcbStructInfo = bytesNeeded;
4110 else if (*pcbStructInfo < bytesNeeded)
4112 *pcbStructInfo = bytesNeeded;
4113 SetLastError(ERROR_MORE_DATA);
4118 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4120 *pcbStructInfo = bytesNeeded;
4121 blob->cbData = dataLen;
4122 assert(blob->pbData);
4123 /* remove leading zero byte if it exists */
4124 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
4133 for (i = 0; i < blob->cbData; i++)
4135 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4144 SetLastError(CRYPT_E_ASN1_BADTAG);
4150 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
4151 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4152 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4160 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
4161 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4164 *pcbStructInfo = bytesNeeded;
4165 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4166 pvStructInfo, pcbStructInfo, bytesNeeded)))
4168 CRYPT_INTEGER_BLOB *blob;
4170 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4171 pvStructInfo = *(BYTE **)pvStructInfo;
4172 blob = pvStructInfo;
4173 blob->pbData = (BYTE *)pvStructInfo +
4174 sizeof(CRYPT_INTEGER_BLOB);
4175 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
4176 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4177 &bytesNeeded, NULL);
4183 SetLastError(STATUS_ACCESS_VIOLATION);
4190 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
4191 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4192 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4198 *pcbStructInfo = sizeof(int);
4203 if (pbEncoded[0] == ASN_ENUMERATED)
4205 unsigned int val = 0, i;
4209 SetLastError(CRYPT_E_ASN1_EOD);
4212 else if (pbEncoded[1] == 0)
4214 SetLastError(CRYPT_E_ASN1_CORRUPT);
4219 /* A little strange looking, but we have to accept a sign byte:
4220 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4221 * assuming a small length is okay here, it has to be in short
4224 if (pbEncoded[1] > sizeof(unsigned int) + 1)
4226 SetLastError(CRYPT_E_ASN1_LARGE);
4229 for (i = 0; i < pbEncoded[1]; i++)
4232 val |= pbEncoded[2 + i];
4234 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4235 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
4237 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4238 pvStructInfo = *(BYTE **)pvStructInfo;
4239 memcpy(pvStructInfo, &val, sizeof(unsigned int));
4245 SetLastError(CRYPT_E_ASN1_BADTAG);
4251 SetLastError(STATUS_ACCESS_VIOLATION);
4258 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4261 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4266 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4268 if (!isdigit(*(pbEncoded))) \
4270 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4276 (word) += *(pbEncoded)++ - '0'; \
4281 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
4282 SYSTEMTIME *sysTime)
4286 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
4288 WORD hours, minutes = 0;
4289 BYTE sign = *pbEncoded++;
4292 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
4293 if (ret && hours >= 24)
4295 SetLastError(CRYPT_E_ASN1_CORRUPT);
4300 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
4301 if (ret && minutes >= 60)
4303 SetLastError(CRYPT_E_ASN1_CORRUPT);
4311 sysTime->wHour += hours;
4312 sysTime->wMinute += minutes;
4316 if (hours > sysTime->wHour)
4319 sysTime->wHour = 24 - (hours - sysTime->wHour);
4322 sysTime->wHour -= hours;
4323 if (minutes > sysTime->wMinute)
4326 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
4329 sysTime->wMinute -= minutes;
4336 #define MIN_ENCODED_TIME_LENGTH 10
4338 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
4339 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4344 if (pbEncoded[0] == ASN_UTCTIME)
4347 SetLastError(CRYPT_E_ASN1_EOD);
4348 else if (pbEncoded[1] > 0x7f)
4350 /* long-form date strings really can't be valid */
4351 SetLastError(CRYPT_E_ASN1_CORRUPT);
4355 SYSTEMTIME sysTime = { 0 };
4356 BYTE len = pbEncoded[1];
4358 if (len < MIN_ENCODED_TIME_LENGTH)
4359 SetLastError(CRYPT_E_ASN1_CORRUPT);
4364 *pcbDecoded = 2 + len;
4366 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
4367 if (sysTime.wYear >= 50)
4368 sysTime.wYear += 1900;
4370 sysTime.wYear += 2000;
4371 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4372 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4373 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4374 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
4377 if (len >= 2 && isdigit(*pbEncoded) &&
4378 isdigit(*(pbEncoded + 1)))
4379 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4381 else if (isdigit(*pbEncoded))
4382 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
4385 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4391 *pcbStructInfo = sizeof(FILETIME);
4392 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4394 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4400 SetLastError(CRYPT_E_ASN1_BADTAG);
4404 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
4405 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4406 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4414 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4415 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4419 *pcbStructInfo = bytesNeeded;
4420 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
4421 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
4423 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4424 pvStructInfo = *(BYTE **)pvStructInfo;
4425 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4426 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4427 &bytesNeeded, NULL);
4433 SetLastError(STATUS_ACCESS_VIOLATION);
4439 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
4440 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4445 if (pbEncoded[0] == ASN_GENERALTIME)
4448 SetLastError(CRYPT_E_ASN1_EOD);
4449 else if (pbEncoded[1] > 0x7f)
4451 /* long-form date strings really can't be valid */
4452 SetLastError(CRYPT_E_ASN1_CORRUPT);
4456 BYTE len = pbEncoded[1];
4458 if (len < MIN_ENCODED_TIME_LENGTH)
4459 SetLastError(CRYPT_E_ASN1_CORRUPT);
4462 SYSTEMTIME sysTime = { 0 };
4466 *pcbDecoded = 2 + len;
4468 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
4469 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4470 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4471 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4474 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4477 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4479 if (ret && len > 0 && (*pbEncoded == '.' ||
4486 /* workaround macro weirdness */
4487 digits = min(len, 3);
4488 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
4489 sysTime.wMilliseconds);
4492 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4498 *pcbStructInfo = sizeof(FILETIME);
4499 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4501 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4507 SetLastError(CRYPT_E_ASN1_BADTAG);
4511 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
4512 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4516 InternalDecodeFunc decode = NULL;
4518 if (pbEncoded[0] == ASN_UTCTIME)
4519 decode = CRYPT_AsnDecodeUtcTimeInternal;
4520 else if (pbEncoded[0] == ASN_GENERALTIME)
4521 decode = CRYPT_AsnDecodeGeneralizedTime;
4523 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
4524 pcbStructInfo, pcbDecoded);
4527 SetLastError(CRYPT_E_ASN1_BADTAG);
4533 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
4534 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4535 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4543 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4544 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4548 *pcbStructInfo = bytesNeeded;
4549 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4550 pvStructInfo, pcbStructInfo, bytesNeeded)))
4552 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4553 pvStructInfo = *(BYTE **)pvStructInfo;
4554 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4555 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4556 &bytesNeeded, NULL);
4562 SetLastError(STATUS_ACCESS_VIOLATION);
4569 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
4570 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4571 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4577 if (pbEncoded[0] == ASN_SEQUENCEOF)
4579 DWORD bytesNeeded, dataLen, remainingLen, cValue;
4581 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4586 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4587 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
4589 ptr = pbEncoded + 1 + lenBytes;
4590 remainingLen = dataLen;
4591 while (ret && remainingLen)
4595 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4598 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4600 remainingLen -= 1 + nextLenBytes + nextLen;
4601 ptr += 1 + nextLenBytes + nextLen;
4602 bytesNeeded += sizeof(CRYPT_DER_BLOB);
4603 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
4604 bytesNeeded += 1 + nextLenBytes + nextLen;
4610 CRYPT_SEQUENCE_OF_ANY *seq;
4615 *pcbStructInfo = bytesNeeded;
4616 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4617 pvStructInfo, pcbStructInfo, bytesNeeded)))
4619 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4620 pvStructInfo = *(BYTE **)pvStructInfo;
4622 seq->cValue = cValue;
4623 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
4625 nextPtr = (BYTE *)seq->rgValue +
4626 cValue * sizeof(CRYPT_DER_BLOB);
4627 ptr = pbEncoded + 1 + lenBytes;
4628 remainingLen = dataLen;
4630 while (ret && remainingLen)
4634 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4637 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4639 seq->rgValue[i].cbData = 1 + nextLenBytes +
4641 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4642 seq->rgValue[i].pbData = (BYTE *)ptr;
4645 seq->rgValue[i].pbData = nextPtr;
4646 memcpy(nextPtr, ptr, 1 + nextLenBytes +
4648 nextPtr += 1 + nextLenBytes + nextLen;
4650 remainingLen -= 1 + nextLenBytes + nextLen;
4651 ptr += 1 + nextLenBytes + nextLen;
4661 SetLastError(CRYPT_E_ASN1_BADTAG);
4667 SetLastError(STATUS_ACCESS_VIOLATION);
4674 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
4675 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4680 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
4682 DWORD bytesNeeded, dataLen;
4684 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4686 struct AsnArrayDescriptor arrayDesc = {
4687 ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4688 offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry),
4689 offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry),
4690 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u),
4691 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
4692 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
4693 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4698 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4699 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4700 dwFlags, NULL, NULL, &nameLen, NULL);
4701 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
4702 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u);
4705 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
4707 *pcbDecoded = 1 + lenBytes + dataLen;
4709 *pcbStructInfo = bytesNeeded;
4710 else if (*pcbStructInfo < bytesNeeded)
4712 *pcbStructInfo = bytesNeeded;
4713 SetLastError(ERROR_MORE_DATA);
4718 CRL_DIST_POINT_NAME *name = pvStructInfo;
4720 *pcbStructInfo = bytesNeeded;
4723 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
4724 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4725 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4726 dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen,
4730 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
4736 SetLastError(CRYPT_E_ASN1_BADTAG);
4742 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
4743 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4745 struct AsnDecodeSequenceItem items[] = {
4746 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
4747 DistPointName), CRYPT_AsnDecodeDistPointName,
4748 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
4749 DistPointName.u.FullName.rgAltEntry), 0 },
4750 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
4751 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
4752 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
4753 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
4754 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
4755 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
4757 CRL_DIST_POINT *point = pvStructInfo;
4760 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4761 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4762 pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
4766 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
4767 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4768 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4772 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4773 pDecodePara, pvStructInfo, *pcbStructInfo);
4777 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4778 offsetof(CRL_DIST_POINTS_INFO, cDistPoint),
4779 offsetof(CRL_DIST_POINTS_INFO, rgDistPoint),
4780 sizeof(CRL_DIST_POINTS_INFO),
4781 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
4782 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
4784 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
4785 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
4789 SetLastError(STATUS_ACCESS_VIOLATION);
4796 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
4797 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4798 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4802 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4803 pDecodePara, pvStructInfo, *pcbStructInfo);
4807 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4808 offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier),
4809 offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier),
4810 sizeof(CERT_ENHKEY_USAGE),
4811 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
4813 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
4814 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
4818 SetLastError(STATUS_ACCESS_VIOLATION);
4825 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
4826 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4827 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4831 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4832 pDecodePara, pvStructInfo, *pcbStructInfo);
4836 struct AsnDecodeSequenceItem items[] = {
4837 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
4838 DistPointName), CRYPT_AsnDecodeDistPointName,
4839 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
4840 offsetof(CRL_ISSUING_DIST_POINT,
4841 DistPointName.u.FullName.rgAltEntry), 0 },
4842 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
4843 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4845 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
4846 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4848 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
4849 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
4850 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
4851 OnlySomeReasonFlags.pbData), 0 },
4852 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
4853 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
4856 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4857 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4858 pcbStructInfo, NULL, NULL);
4862 SetLastError(STATUS_ACCESS_VIOLATION);
4869 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
4870 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4875 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4876 pvStructInfo, *pcbStructInfo, pcbDecoded);
4880 SetLastError(CRYPT_E_ASN1_EOD);
4883 if (pbEncoded[0] != (ASN_CONTEXT | 1))
4885 SetLastError(CRYPT_E_ASN1_BADTAG);
4888 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4889 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
4890 pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
4892 if (ret && pvStructInfo)
4893 *(BOOL *)pvStructInfo = TRUE;
4894 TRACE("returning %d\n", ret);
4898 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
4899 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4903 struct AsnDecodeSequenceItem items[] = {
4904 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
4905 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
4906 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
4907 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
4908 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
4909 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
4910 CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
4913 CERT_GENERAL_SUBTREE *subtree = pvStructInfo;
4915 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4916 pvStructInfo, *pcbStructInfo, pcbDecoded);
4918 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4919 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4920 pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
4923 TRACE("%d\n", *pcbDecoded);
4924 if (*pcbDecoded < cbEncoded)
4925 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
4926 *(pbEncoded + *pcbDecoded + 1));
4928 TRACE("returning %d\n", ret);
4932 static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded,
4933 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4937 struct AsnArrayDescriptor arrayDesc = { 0,
4938 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
4939 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree),
4940 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
4942 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
4943 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
4945 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4946 pvStructInfo, *pcbStructInfo, pcbDecoded);
4948 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
4949 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
4953 static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded,
4954 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4958 struct AsnArrayDescriptor arrayDesc = { 0,
4959 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4960 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree),
4961 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4962 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
4963 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
4965 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4966 pvStructInfo, *pcbStructInfo, pcbDecoded);
4968 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
4969 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
4973 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
4974 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4975 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4979 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4980 pDecodePara, pvStructInfo, *pcbStructInfo);
4984 struct AsnDecodeSequenceItem items[] = {
4985 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4986 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
4987 CRYPT_AsnDecodePermittedSubtree,
4988 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
4989 cExcludedSubtree), TRUE, TRUE,
4990 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
4991 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
4992 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4993 CRYPT_AsnDecodeExcludedSubtree,
4994 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4996 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
4999 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5000 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
5001 pcbStructInfo, NULL, NULL);
5005 SetLastError(STATUS_ACCESS_VIOLATION);
5011 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
5012 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5016 struct AsnDecodeSequenceItem items[] = {
5017 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
5018 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
5020 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
5021 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
5022 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
5024 CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;
5026 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5027 pvStructInfo, *pcbStructInfo, pcbDecoded);
5029 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5030 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5031 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
5032 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
5034 SetLastError(CRYPT_E_ASN1_CORRUPT);
5037 TRACE("returning %d\n", ret);
5041 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
5042 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5045 CMSG_SIGNER_INFO *info = pvStructInfo;
5046 struct AsnDecodeSequenceItem items[] = {
5047 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
5048 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5049 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
5050 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
5051 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
5052 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
5053 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5054 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5055 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5056 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
5057 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5058 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5059 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
5060 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5061 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
5062 HashEncryptionAlgorithm.pszObjId), 0 },
5063 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
5064 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5065 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
5066 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5067 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
5068 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5069 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5073 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5074 pvStructInfo, *pcbStructInfo);
5076 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5077 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5078 pcbDecoded, info ? info->Issuer.pbData : NULL);
5082 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
5083 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5084 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5088 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5089 pDecodePara, pvStructInfo, *pcbStructInfo);
5093 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
5094 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5095 if (ret && pvStructInfo)
5097 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5098 pcbStructInfo, *pcbStructInfo);
5101 CMSG_SIGNER_INFO *info;
5103 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5104 pvStructInfo = *(BYTE **)pvStructInfo;
5105 info = pvStructInfo;
5106 info->Issuer.pbData = ((BYTE *)info +
5107 sizeof(CMSG_SIGNER_INFO));
5108 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
5109 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5110 pcbStructInfo, NULL);
5116 SetLastError(STATUS_ACCESS_VIOLATION);
5119 TRACE("returning %d\n", ret);
5123 static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded,
5124 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5128 struct AsnArrayDescriptor arrayDesc = { 0,
5129 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
5130 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded),
5131 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded),
5132 CRYPT_AsnDecodeCopyBytes,
5133 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5135 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5136 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5138 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5139 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5143 static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded,
5144 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5148 struct AsnArrayDescriptor arrayDesc = { 0,
5149 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded),
5150 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded),
5151 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content),
5152 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB),
5153 TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5155 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5156 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5158 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5159 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5163 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
5164 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5167 CERT_ID *id = pvStructInfo;
5170 if (*pbEncoded == ASN_SEQUENCEOF)
5172 ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
5173 id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
5177 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5178 if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
5179 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5180 sizeof(CERT_ISSUER_SERIAL_NUMBER);
5182 *pcbStructInfo = sizeof(CERT_ID);
5185 else if (*pbEncoded == (ASN_CONTEXT | 0))
5187 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
5188 id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
5192 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5193 if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
5194 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5195 sizeof(CRYPT_DATA_BLOB);
5197 *pcbStructInfo = sizeof(CERT_ID);
5201 SetLastError(CRYPT_E_ASN1_BADTAG);
5205 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
5206 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5209 CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
5210 struct AsnDecodeSequenceItem items[] = {
5211 { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
5212 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5213 { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
5214 CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
5215 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
5216 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
5217 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5218 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5219 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5220 offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
5221 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5222 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5223 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
5224 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5225 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
5226 HashEncryptionAlgorithm.pszObjId), 0 },
5227 { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
5228 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5229 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
5230 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5231 offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
5232 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5233 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5237 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5238 pvStructInfo, *pcbStructInfo);
5240 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5241 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5242 pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
5246 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
5247 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5248 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5252 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5253 pDecodePara, pvStructInfo, *pcbStructInfo);
5257 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
5258 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5259 if (ret && pvStructInfo)
5261 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5262 pcbStructInfo, *pcbStructInfo);
5265 CMSG_CMS_SIGNER_INFO *info;
5267 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5268 pvStructInfo = *(BYTE **)pvStructInfo;
5269 info = pvStructInfo;
5270 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
5271 sizeof(CMSG_CMS_SIGNER_INFO));
5272 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
5273 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5274 pcbStructInfo, NULL);
5280 SetLastError(STATUS_ACCESS_VIOLATION);
5283 TRACE("returning %d\n", ret);
5287 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
5288 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5291 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5292 offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5293 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo),
5294 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo),
5295 CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
5296 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
5298 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5299 pvStructInfo, *pcbStructInfo, pcbDecoded);
5301 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5302 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5306 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5307 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5308 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
5311 struct AsnDecodeSequenceItem items[] = {
5312 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
5313 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5314 /* Placeholder for the hash algorithms - redundant with those in the
5315 * signers, so just ignore them.
5317 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5318 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
5319 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
5320 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
5321 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5322 offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded,
5323 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE,
5324 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
5325 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5326 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded,
5327 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE,
5328 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
5329 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5330 CRYPT_DecodeSignerArray,
5331 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE,
5332 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
5335 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5336 pDecodePara, signedInfo, *pcbSignedInfo);
5338 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5339 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
5341 TRACE("returning %d\n", ret);
5345 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
5346 LPCSTR lpszStructType)
5348 CryptDecodeObjectExFunc decodeFunc = NULL;
5350 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
5351 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
5353 SetLastError(ERROR_FILE_NOT_FOUND);
5356 if (!HIWORD(lpszStructType))
5358 switch (LOWORD(lpszStructType))
5360 case LOWORD(X509_CERT):
5361 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
5363 case LOWORD(X509_CERT_TO_BE_SIGNED):
5364 decodeFunc = CRYPT_AsnDecodeCert;
5366 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
5367 decodeFunc = CRYPT_AsnDecodeCRL;
5369 case LOWORD(X509_EXTENSIONS):
5370 decodeFunc = CRYPT_AsnDecodeExtensions;
5372 case LOWORD(X509_NAME_VALUE):
5373 decodeFunc = CRYPT_AsnDecodeNameValue;
5375 case LOWORD(X509_NAME):
5376 decodeFunc = CRYPT_AsnDecodeName;
5378 case LOWORD(X509_PUBLIC_KEY_INFO):
5379 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
5381 case LOWORD(X509_AUTHORITY_KEY_ID):
5382 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5384 case LOWORD(X509_ALTERNATE_NAME):
5385 decodeFunc = CRYPT_AsnDecodeAltName;
5387 case LOWORD(X509_BASIC_CONSTRAINTS):
5388 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5390 case LOWORD(X509_BASIC_CONSTRAINTS2):
5391 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5393 case LOWORD(X509_CERT_POLICIES):
5394 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5396 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
5397 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
5399 case LOWORD(X509_UNICODE_NAME):
5400 decodeFunc = CRYPT_AsnDecodeUnicodeName;
5402 case LOWORD(PKCS_ATTRIBUTE):
5403 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
5405 case LOWORD(X509_UNICODE_NAME_VALUE):
5406 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
5408 case LOWORD(X509_OCTET_STRING):
5409 decodeFunc = CRYPT_AsnDecodeOctets;
5411 case LOWORD(X509_BITS):
5412 case LOWORD(X509_KEY_USAGE):
5413 decodeFunc = CRYPT_AsnDecodeBits;
5415 case LOWORD(X509_INTEGER):
5416 decodeFunc = CRYPT_AsnDecodeInt;
5418 case LOWORD(X509_MULTI_BYTE_INTEGER):
5419 decodeFunc = CRYPT_AsnDecodeInteger;
5421 case LOWORD(X509_MULTI_BYTE_UINT):
5422 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
5424 case LOWORD(X509_ENUMERATED):
5425 decodeFunc = CRYPT_AsnDecodeEnumerated;
5427 case LOWORD(X509_CHOICE_OF_TIME):
5428 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
5430 case LOWORD(X509_AUTHORITY_KEY_ID2):
5431 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5433 case LOWORD(X509_AUTHORITY_INFO_ACCESS):
5434 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5436 case LOWORD(PKCS_CONTENT_INFO):
5437 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
5439 case LOWORD(X509_SEQUENCE_OF_ANY):
5440 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
5442 case LOWORD(PKCS_UTC_TIME):
5443 decodeFunc = CRYPT_AsnDecodeUtcTime;
5445 case LOWORD(X509_CRL_DIST_POINTS):
5446 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5448 case LOWORD(X509_ENHANCED_KEY_USAGE):
5449 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5451 case LOWORD(PKCS_CTL):
5452 decodeFunc = CRYPT_AsnDecodeCTL;
5454 case LOWORD(PKCS_SMIME_CAPABILITIES):
5455 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5457 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
5458 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5460 case LOWORD(PKCS_ATTRIBUTES):
5461 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
5463 case LOWORD(X509_ISSUING_DIST_POINT):
5464 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5466 case LOWORD(X509_NAME_CONSTRAINTS):
5467 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5469 case LOWORD(PKCS7_SIGNER_INFO):
5470 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
5472 case LOWORD(CMS_SIGNER_INFO):
5473 decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
5477 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
5478 decodeFunc = CRYPT_AsnDecodeExtensions;
5479 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
5480 decodeFunc = CRYPT_AsnDecodeUtcTime;
5481 else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
5482 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5483 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
5484 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5485 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
5486 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5487 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
5488 decodeFunc = CRYPT_AsnDecodeEnumerated;
5489 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
5490 decodeFunc = CRYPT_AsnDecodeBits;
5491 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
5492 decodeFunc = CRYPT_AsnDecodeOctets;
5493 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
5494 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5495 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
5496 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5497 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
5498 decodeFunc = CRYPT_AsnDecodeAltName;
5499 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
5500 decodeFunc = CRYPT_AsnDecodeAltName;
5501 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
5502 decodeFunc = CRYPT_AsnDecodeAltName;
5503 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
5504 decodeFunc = CRYPT_AsnDecodeAltName;
5505 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
5506 decodeFunc = CRYPT_AsnDecodeAltName;
5507 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
5508 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5509 else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
5510 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5511 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
5512 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5513 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
5514 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5515 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
5516 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5517 else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
5518 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5519 else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
5520 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5521 else if (!strcmp(lpszStructType, szOID_CTL))
5522 decodeFunc = CRYPT_AsnDecodeCTL;
5526 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
5527 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5529 static HCRYPTOIDFUNCSET set = NULL;
5530 CryptDecodeObjectFunc decodeFunc = NULL;
5533 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
5534 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5535 (void **)&decodeFunc, hFunc);
5539 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
5540 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5542 static HCRYPTOIDFUNCSET set = NULL;
5543 CryptDecodeObjectExFunc decodeFunc = NULL;
5546 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
5547 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5548 (void **)&decodeFunc, hFunc);
5552 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5553 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
5554 DWORD *pcbStructInfo)
5557 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
5558 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
5559 HCRYPTOIDFUNCADDR hFunc = NULL;
5561 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
5562 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
5563 pvStructInfo, pcbStructInfo);
5565 if (!pvStructInfo && !pcbStructInfo)
5567 SetLastError(ERROR_INVALID_PARAMETER);
5570 if (cbEncoded > MAX_ENCODED_LEN)
5572 SetLastError(CRYPT_E_ASN1_LARGE);
5576 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
5579 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5580 debugstr_a(lpszStructType));
5581 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
5582 lpszStructType, &hFunc);
5583 if (!pCryptDecodeObject)
5584 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
5585 lpszStructType, &hFunc);
5587 if (pCryptDecodeObject)
5588 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5589 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5590 else if (pCryptDecodeObjectEx)
5591 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
5592 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
5593 pvStructInfo, pcbStructInfo);
5595 CryptFreeOIDFunctionAddress(hFunc, 0);
5596 TRACE_(crypt)("returning %d\n", ret);
5600 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5601 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5602 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5605 CryptDecodeObjectExFunc decodeFunc;
5606 HCRYPTOIDFUNCADDR hFunc = NULL;
5608 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5609 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
5610 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5612 if (!pvStructInfo && !pcbStructInfo)
5614 SetLastError(ERROR_INVALID_PARAMETER);
5617 if (cbEncoded > MAX_ENCODED_LEN)
5619 SetLastError(CRYPT_E_ASN1_LARGE);
5623 SetLastError(NOERROR);
5624 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
5625 *(BYTE **)pvStructInfo = NULL;
5626 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
5629 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5630 debugstr_a(lpszStructType));
5631 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
5635 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
5636 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5639 CryptDecodeObjectFunc pCryptDecodeObject =
5640 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
5642 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5643 * directly, as that could cause an infinite loop.
5645 if (pCryptDecodeObject)
5647 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5649 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5650 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
5651 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
5652 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
5653 ret = pCryptDecodeObject(dwCertEncodingType,
5654 lpszStructType, pbEncoded, cbEncoded, dwFlags,
5655 *(BYTE **)pvStructInfo, pcbStructInfo);
5658 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5659 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5663 CryptFreeOIDFunctionAddress(hFunc, 0);
5664 TRACE_(crypt)("returning %d\n", ret);
5668 BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
5672 TRACE_(crypt)("(%p)\n", pPFX);
5674 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
5675 * version integer of length 1 (3 encoded byes) and at least one other
5676 * datum (two encoded bytes), plus at least two bytes for the outer
5677 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
5679 if (pPFX->cbData < 7)
5681 else if (pPFX->pbData[0] == ASN_SEQUENCE)
5685 if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
5687 BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);
5689 /* Need at least three bytes for the integer version */
5690 if (pPFX->cbData < 1 + lenLen + 3)
5692 else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
5693 pPFX->pbData[1 + lenLen + 1] != 1 || /* Definite length */
5694 pPFX->pbData[1 + lenLen + 2] != 3) /* PFX version */
5703 HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
5706 FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);