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, NULL, &size, &itemDecoded);
678 if (itemSizes != &itemSize)
679 itemSizes = CryptMemRealloc(itemSizes,
680 cItems * sizeof(struct AsnArrayItemSize));
685 cItems * sizeof(struct AsnArrayItemSize));
687 memcpy(itemSizes, &itemSize,
692 decoded += itemDecoded;
693 itemSizes[cItems - 1].encodedLen = itemEncoded;
694 itemSizes[cItems - 1].size = size;
707 *pcbDecoded = decoded;
709 *pcbStructInfo = bytesNeeded;
710 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
711 pvStructInfo, pcbStructInfo, bytesNeeded)))
718 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
719 pvStructInfo = *(void **)pvStructInfo;
720 pcItems = pvStructInfo;
722 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
724 rgItems = (BYTE *)pvStructInfo +
725 arrayDesc->minArraySize;
726 *(void **)((BYTE *)pcItems -
727 arrayDesc->countOffset + arrayDesc->arrayOffset) =
731 rgItems = *(void **)((BYTE *)pcItems -
732 arrayDesc->countOffset + arrayDesc->arrayOffset);
733 nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize;
734 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret &&
735 i < cItems && ptr - pbEncoded - 1 - lenBytes <
740 if (arrayDesc->hasPointer)
741 *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize
742 + arrayDesc->pointerOffset) = nextData;
743 ret = arrayDesc->decodeFunc(ptr,
744 itemSizes[i].encodedLen, 0,
745 (BYTE *)rgItems + i * arrayDesc->itemSize,
746 &itemSizes[i].size, &itemDecoded);
749 nextData += itemSizes[i].size - arrayDesc->itemSize;
755 if (itemSizes != &itemSize)
756 CryptMemFree(itemSizes);
761 SetLastError(CRYPT_E_ASN1_BADTAG);
767 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
768 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
769 * to CRYPT_E_ASN1_CORRUPT.
770 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
773 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded,
774 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
779 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
781 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
782 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB);
784 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
785 bytesNeeded += 1 + lenBytes + dataLen;
788 *pcbDecoded = 1 + lenBytes + dataLen;
790 *pcbStructInfo = bytesNeeded;
791 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded)))
793 CRYPT_DER_BLOB *blob;
795 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
796 pvStructInfo = *(BYTE **)pvStructInfo;
798 blob->cbData = 1 + lenBytes + dataLen;
801 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
802 blob->pbData = (BYTE *)pbEncoded;
805 assert(blob->pbData);
806 memcpy(blob->pbData, pbEncoded, blob->cbData);
811 SetLastError(CRYPT_E_ASN1_CORRUPT);
819 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
820 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded,
821 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
826 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
827 pvStructInfo, *pcbStructInfo, pcbDecoded);
829 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
832 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
833 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
835 if (ret && pvStructInfo)
837 CRYPT_BIT_BLOB *blob = pvStructInfo;
844 for (i = 0; i < blob->cbData / 2; i++)
846 temp = blob->pbData[i];
847 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
848 blob->pbData[blob->cbData - i - 1] = temp;
852 TRACE("returning %d (%08x)\n", ret, GetLastError());
856 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
857 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
858 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
862 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
863 pDecodePara, pvStructInfo, *pcbStructInfo);
867 struct AsnDecodeSequenceItem items[] = {
868 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned),
869 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE,
870 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 },
871 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO,
872 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId,
873 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE,
874 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 },
875 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature),
876 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
877 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 },
880 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
881 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
882 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
883 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
884 pcbStructInfo, NULL, NULL);
888 SetLastError(STATUS_ACCESS_VIOLATION);
893 TRACE("Returning %d (%08x)\n", ret, GetLastError());
897 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded,
898 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
903 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
905 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
907 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen,
908 dwFlags, pvStructInfo, pcbStructInfo, NULL);
910 *pcbDecoded = 1 + lenBytes + dataLen;
915 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
916 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
920 struct AsnDecodeSequenceItem items[] = {
921 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore),
922 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
923 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter),
924 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
927 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
928 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
933 static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded,
934 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
938 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
939 offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension),
940 FINALMEMBERSIZE(CERT_INFO, cExtension),
941 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
942 offsetof(CERT_EXTENSION, pszObjId) };
944 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
945 pvStructInfo, *pcbStructInfo, pcbDecoded);
947 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
948 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
952 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded,
953 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
959 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
961 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
963 ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes,
964 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
965 if (ret && pcbDecoded)
966 *pcbDecoded = 1 + lenBytes + dataLen;
971 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
972 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
973 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
976 struct AsnDecodeSequenceItem items[] = {
977 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion),
978 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 },
979 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber),
980 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
981 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 },
982 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm),
983 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
984 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 },
985 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
986 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
988 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore),
989 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE,
991 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob,
992 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO,
994 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo),
995 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO),
996 FALSE, TRUE, offsetof(CERT_INFO,
997 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 },
998 { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId),
999 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1000 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 },
1001 { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId),
1002 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
1003 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 },
1004 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension),
1005 CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension),
1006 TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 },
1009 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1010 pDecodePara, pvStructInfo, *pcbStructInfo);
1012 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1013 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1015 if (ret && pvStructInfo)
1019 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1020 info = *(CERT_INFO **)pvStructInfo;
1022 info = pvStructInfo;
1023 if (!info->SerialNumber.cbData || !info->Issuer.cbData ||
1024 !info->Subject.cbData)
1026 SetLastError(CRYPT_E_ASN1_CORRUPT);
1027 /* Don't need to deallocate, because it should have failed on the
1028 * first pass (and no memory was allocated.)
1034 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1038 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType,
1039 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1040 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1044 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1045 pDecodePara, pvStructInfo, *pcbStructInfo);
1051 /* Unless told not to, first try to decode it as a signed cert. */
1052 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1054 PCERT_SIGNED_CONTENT_INFO signedCert = NULL;
1056 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1057 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1058 &signedCert, &size);
1062 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1063 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData,
1064 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara,
1065 pvStructInfo, pcbStructInfo);
1066 LocalFree(signedCert);
1069 /* Failing that, try it as an unsigned cert */
1073 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType,
1074 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags,
1075 pDecodePara, pvStructInfo, pcbStructInfo);
1080 SetLastError(STATUS_ACCESS_VIOLATION);
1084 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1088 static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded,
1089 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1093 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1094 offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension),
1095 FINALMEMBERSIZE(CRL_ENTRY, cExtension),
1096 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1097 offsetof(CERT_EXTENSION, pszObjId) };
1099 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1100 pvStructInfo, *pcbStructInfo, pcbDecoded);
1102 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1103 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1107 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
1108 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1111 struct AsnDecodeSequenceItem items[] = {
1112 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber),
1113 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE,
1114 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 },
1115 { 0, offsetof(CRL_ENTRY, RevocationDate),
1116 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
1117 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension),
1118 CRYPT_AsnDecodeCRLEntryExtensions,
1119 FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE,
1120 offsetof(CRL_ENTRY, rgExtension), 0 },
1122 PCRL_ENTRY entry = pvStructInfo;
1124 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
1127 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1128 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
1129 entry ? entry->SerialNumber.pbData : NULL);
1130 if (ret && entry && !entry->SerialNumber.cbData)
1132 WARN("empty CRL entry serial number\n");
1133 SetLastError(CRYPT_E_ASN1_CORRUPT);
1139 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1140 * whose rgCRLEntry member has been set prior to calling.
1142 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
1143 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1146 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1147 offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry),
1148 MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1149 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE,
1150 offsetof(CRL_ENTRY, SerialNumber.pbData) };
1152 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1153 pvStructInfo, *pcbStructInfo, pcbDecoded);
1155 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1156 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1157 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1161 static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded,
1162 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1166 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1167 offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension),
1168 FINALMEMBERSIZE(CRL_INFO, cExtension),
1169 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1170 offsetof(CERT_EXTENSION, pszObjId) };
1172 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
1173 pvStructInfo, *pcbStructInfo, pcbDecoded);
1175 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1176 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1180 static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded,
1181 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1187 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1189 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1191 ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes,
1192 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
1193 if (ret && pcbDecoded)
1194 *pcbDecoded = 1 + lenBytes + dataLen;
1199 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
1200 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1201 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1203 struct AsnDecodeSequenceItem items[] = {
1204 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion),
1205 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
1206 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm),
1207 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
1208 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 },
1209 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob,
1210 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO,
1212 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1213 sizeof(FILETIME), FALSE, FALSE, 0 },
1214 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal,
1215 sizeof(FILETIME), TRUE, FALSE, 0 },
1216 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry),
1217 CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension),
1218 TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 },
1219 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension),
1220 CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension),
1221 TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 },
1225 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1226 pDecodePara, pvStructInfo, *pcbStructInfo);
1228 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1229 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
1232 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1236 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType,
1237 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1238 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1242 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1243 pDecodePara, pvStructInfo, *pcbStructInfo);
1249 /* Unless told not to, first try to decode it as a signed crl. */
1250 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG))
1252 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL;
1254 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType,
1255 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL,
1260 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1261 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData,
1262 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara,
1263 pvStructInfo, pcbStructInfo);
1264 LocalFree(signedCrl);
1267 /* Failing that, try it as an unsigned crl */
1271 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType,
1272 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded,
1273 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
1278 SetLastError(STATUS_ACCESS_VIOLATION);
1282 TRACE("Returning %d (%08x)\n", ret, GetLastError());
1286 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded,
1287 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1292 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1293 pvStructInfo, *pcbStructInfo);
1295 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1297 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1298 DWORD bytesNeeded = sizeof(LPSTR);
1302 /* The largest possible string for the first two components
1303 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1308 snprintf(firstTwo, sizeof(firstTwo), "%d.%d",
1309 pbEncoded[1 + lenBytes] / 40,
1310 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40)
1312 bytesNeeded += strlen(firstTwo) + 1;
1313 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1314 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1316 /* large enough for ".4000000" */
1320 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1327 if (ptr - pbEncoded - 1 - lenBytes >= dataLen ||
1330 SetLastError(CRYPT_E_ASN1_CORRUPT);
1337 snprintf(str, sizeof(str), ".%d", val);
1338 bytesNeeded += strlen(str);
1343 *pcbDecoded = 1 + lenBytes + dataLen;
1345 *pcbStructInfo = bytesNeeded;
1346 else if (*pcbStructInfo < bytesNeeded)
1348 *pcbStructInfo = bytesNeeded;
1349 SetLastError(ERROR_MORE_DATA);
1357 LPSTR pszObjId = *(LPSTR *)pvStructInfo;
1360 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40,
1361 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] /
1363 pszObjId += strlen(pszObjId);
1364 for (ptr = pbEncoded + 2 + lenBytes; ret &&
1365 ptr - pbEncoded - 1 - lenBytes < dataLen; )
1369 while (ptr - pbEncoded - 1 - lenBytes < dataLen &&
1378 sprintf(pszObjId, ".%d", val);
1379 pszObjId += strlen(pszObjId);
1383 *(LPSTR *)pvStructInfo = NULL;
1384 *pcbStructInfo = bytesNeeded;
1390 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded,
1391 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1395 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1396 pvStructInfo, *pcbStructInfo);
1398 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER)
1399 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags,
1400 pvStructInfo, pcbStructInfo, pcbDecoded);
1403 SetLastError(CRYPT_E_ASN1_BADTAG);
1409 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
1410 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1412 struct AsnDecodeSequenceItem items[] = {
1413 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId),
1414 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1415 offsetof(CERT_EXTENSION, pszObjId), 0 },
1416 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool,
1417 sizeof(BOOL), TRUE, FALSE, 0, 0 },
1418 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value),
1419 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE,
1420 offsetof(CERT_EXTENSION, Value.pbData) },
1423 PCERT_EXTENSION ext = pvStructInfo;
1425 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext,
1429 TRACE("ext->pszObjId is %p\n", ext->pszObjId);
1430 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1431 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
1432 pcbDecoded, ext ? ext->pszObjId : NULL);
1434 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId,
1435 debugstr_a(ext->pszObjId));
1436 TRACE("returning %d (%08x)\n", ret, GetLastError());
1440 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType,
1441 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1442 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1446 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1447 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
1451 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1452 offsetof(CERT_EXTENSIONS, cExtension),
1453 offsetof(CERT_EXTENSIONS, rgExtension),
1454 sizeof(CERT_EXTENSIONS),
1455 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
1456 offsetof(CERT_EXTENSION, pszObjId) };
1458 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1459 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1463 SetLastError(STATUS_ACCESS_VIOLATION);
1470 /* Warning: this assumes the address of value->Value.pbData is already set, in
1471 * order to avoid overwriting memory. (In some cases, it may change it, if it
1472 * doesn't copy anything to memory.) Be sure to set it correctly!
1474 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded,
1475 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1480 CERT_NAME_VALUE *value = pvStructInfo;
1482 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1484 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1485 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1487 switch (pbEncoded[0])
1489 case ASN_OCTETSTRING:
1490 valueType = CERT_RDN_OCTET_STRING;
1491 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1492 bytesNeeded += dataLen;
1494 case ASN_NUMERICSTRING:
1495 valueType = CERT_RDN_NUMERIC_STRING;
1496 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1497 bytesNeeded += dataLen;
1499 case ASN_PRINTABLESTRING:
1500 valueType = CERT_RDN_PRINTABLE_STRING;
1501 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1502 bytesNeeded += dataLen;
1505 valueType = CERT_RDN_IA5_STRING;
1506 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1507 bytesNeeded += dataLen;
1510 valueType = CERT_RDN_T61_STRING;
1511 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1512 bytesNeeded += dataLen;
1514 case ASN_VIDEOTEXSTRING:
1515 valueType = CERT_RDN_VIDEOTEX_STRING;
1516 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1517 bytesNeeded += dataLen;
1519 case ASN_GRAPHICSTRING:
1520 valueType = CERT_RDN_GRAPHIC_STRING;
1521 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1522 bytesNeeded += dataLen;
1524 case ASN_VISIBLESTRING:
1525 valueType = CERT_RDN_VISIBLE_STRING;
1526 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1527 bytesNeeded += dataLen;
1529 case ASN_GENERALSTRING:
1530 valueType = CERT_RDN_GENERAL_STRING;
1531 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1532 bytesNeeded += dataLen;
1534 case ASN_UNIVERSALSTRING:
1535 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1536 SetLastError(CRYPT_E_ASN1_BADTAG);
1539 valueType = CERT_RDN_BMP_STRING;
1540 bytesNeeded += dataLen;
1542 case ASN_UTF8STRING:
1543 valueType = CERT_RDN_UTF8_STRING;
1544 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0,
1545 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2;
1548 SetLastError(CRYPT_E_ASN1_BADTAG);
1553 *pcbDecoded = 1 + lenBytes + dataLen;
1555 *pcbStructInfo = bytesNeeded;
1556 else if (*pcbStructInfo < bytesNeeded)
1558 *pcbStructInfo = bytesNeeded;
1559 SetLastError(ERROR_MORE_DATA);
1564 *pcbStructInfo = bytesNeeded;
1565 value->dwValueType = valueType;
1570 assert(value->Value.pbData);
1571 switch (pbEncoded[0])
1573 case ASN_OCTETSTRING:
1574 case ASN_NUMERICSTRING:
1575 case ASN_PRINTABLESTRING:
1578 case ASN_VIDEOTEXSTRING:
1579 case ASN_GRAPHICSTRING:
1580 case ASN_VISIBLESTRING:
1581 case ASN_GENERALSTRING:
1582 value->Value.cbData = dataLen;
1585 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
1586 memcpy(value->Value.pbData,
1587 pbEncoded + 1 + lenBytes, dataLen);
1589 value->Value.pbData = (LPBYTE)pbEncoded + 1 +
1595 LPWSTR str = (LPWSTR)value->Value.pbData;
1597 value->Value.cbData = dataLen;
1598 for (i = 0; i < dataLen / 2; i++)
1599 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1600 pbEncoded[1 + lenBytes + 2 * i + 1];
1603 case ASN_UTF8STRING:
1605 LPWSTR str = (LPWSTR)value->Value.pbData;
1607 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1608 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1609 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
1616 value->Value.cbData = 0;
1617 value->Value.pbData = NULL;
1624 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType,
1625 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1626 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1632 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded,
1633 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1634 if (ret && pvStructInfo)
1636 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1637 pcbStructInfo, *pcbStructInfo);
1640 CERT_NAME_VALUE *value;
1642 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1643 pvStructInfo = *(BYTE **)pvStructInfo;
1644 value = pvStructInfo;
1645 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1646 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded,
1647 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1648 pcbStructInfo, NULL);
1654 SetLastError(STATUS_ACCESS_VIOLATION);
1661 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded,
1662 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1667 CERT_NAME_VALUE *value = pvStructInfo;
1669 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
1671 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
1672 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType;
1674 switch (pbEncoded[0])
1676 case ASN_NUMERICSTRING:
1677 valueType = CERT_RDN_NUMERIC_STRING;
1679 bytesNeeded += (dataLen + 1) * 2;
1681 case ASN_PRINTABLESTRING:
1682 valueType = CERT_RDN_PRINTABLE_STRING;
1684 bytesNeeded += (dataLen + 1) * 2;
1687 valueType = CERT_RDN_IA5_STRING;
1689 bytesNeeded += (dataLen + 1) * 2;
1692 valueType = CERT_RDN_T61_STRING;
1694 bytesNeeded += (dataLen + 1) * 2;
1696 case ASN_VIDEOTEXSTRING:
1697 valueType = CERT_RDN_VIDEOTEX_STRING;
1699 bytesNeeded += (dataLen + 1) * 2;
1701 case ASN_GRAPHICSTRING:
1702 valueType = CERT_RDN_GRAPHIC_STRING;
1704 bytesNeeded += (dataLen + 1) * 2;
1706 case ASN_VISIBLESTRING:
1707 valueType = CERT_RDN_VISIBLE_STRING;
1709 bytesNeeded += (dataLen + 1) * 2;
1711 case ASN_GENERALSTRING:
1712 valueType = CERT_RDN_GENERAL_STRING;
1714 bytesNeeded += (dataLen + 1) * 2;
1716 case ASN_UNIVERSALSTRING:
1717 valueType = CERT_RDN_UNIVERSAL_STRING;
1719 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
1722 valueType = CERT_RDN_BMP_STRING;
1724 bytesNeeded += dataLen + sizeof(WCHAR);
1726 case ASN_UTF8STRING:
1727 valueType = CERT_RDN_UTF8_STRING;
1729 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
1730 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
1733 SetLastError(CRYPT_E_ASN1_BADTAG);
1738 *pcbDecoded = 1 + lenBytes + dataLen;
1740 *pcbStructInfo = bytesNeeded;
1741 else if (*pcbStructInfo < bytesNeeded)
1743 *pcbStructInfo = bytesNeeded;
1744 SetLastError(ERROR_MORE_DATA);
1749 *pcbStructInfo = bytesNeeded;
1750 value->dwValueType = valueType;
1754 LPWSTR str = (LPWSTR)value->Value.pbData;
1756 assert(value->Value.pbData);
1757 switch (pbEncoded[0])
1759 case ASN_NUMERICSTRING:
1760 case ASN_PRINTABLESTRING:
1763 case ASN_VIDEOTEXSTRING:
1764 case ASN_GRAPHICSTRING:
1765 case ASN_VISIBLESTRING:
1766 case ASN_GENERALSTRING:
1767 value->Value.cbData = dataLen * 2;
1768 for (i = 0; i < dataLen; i++)
1769 str[i] = pbEncoded[1 + lenBytes + i];
1772 case ASN_UNIVERSALSTRING:
1773 value->Value.cbData = dataLen / 2;
1774 for (i = 0; i < dataLen / 4; i++)
1775 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
1776 | pbEncoded[1 + lenBytes + 2 * i + 3];
1780 value->Value.cbData = dataLen;
1781 for (i = 0; i < dataLen / 2; i++)
1782 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
1783 pbEncoded[1 + lenBytes + 2 * i + 1];
1786 case ASN_UTF8STRING:
1787 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
1788 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
1789 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
1790 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
1791 value->Value.cbData += sizeof(WCHAR);
1797 value->Value.cbData = 0;
1798 value->Value.pbData = NULL;
1805 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType,
1806 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1807 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1813 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded,
1814 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
1815 if (ret && pvStructInfo)
1817 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
1818 pcbStructInfo, *pcbStructInfo);
1821 CERT_NAME_VALUE *value;
1823 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
1824 pvStructInfo = *(BYTE **)pvStructInfo;
1825 value = pvStructInfo;
1826 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE));
1827 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded,
1828 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
1829 pcbStructInfo, NULL);
1835 SetLastError(STATUS_ACCESS_VIOLATION);
1842 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
1843 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1846 struct AsnDecodeSequenceItem items[] = {
1847 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1848 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1849 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1850 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1851 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1852 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1854 CERT_RDN_ATTR *attr = pvStructInfo;
1856 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1857 pvStructInfo, *pcbStructInfo);
1860 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1861 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1862 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1863 attr ? attr->pszObjId : NULL);
1866 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1867 debugstr_a(attr->pszObjId));
1868 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1870 TRACE("returning %d (%08x)\n", ret, GetLastError());
1874 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1875 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1878 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1879 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1881 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1882 offsetof(CERT_RDN_ATTR, pszObjId) };
1884 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1885 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1889 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType,
1890 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1891 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1897 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1898 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
1899 sizeof(CERT_NAME_INFO),
1900 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE,
1901 offsetof(CERT_RDN, rgRDNAttr) };
1903 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1904 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1908 SetLastError(STATUS_ACCESS_VIOLATION);
1915 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
1916 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
1920 struct AsnDecodeSequenceItem items[] = {
1921 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId),
1922 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
1923 offsetof(CERT_RDN_ATTR, pszObjId), 0 },
1924 { 0, offsetof(CERT_RDN_ATTR, dwValueType),
1925 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE),
1926 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 },
1928 CERT_RDN_ATTR *attr = pvStructInfo;
1930 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
1931 pvStructInfo, *pcbStructInfo);
1934 TRACE("attr->pszObjId is %p\n", attr->pszObjId);
1935 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
1936 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
1937 attr ? attr->pszObjId : NULL);
1940 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId,
1941 debugstr_a(attr->pszObjId));
1942 TRACE("attr->dwValueType is %d\n", attr->dwValueType);
1944 TRACE("returning %d (%08x)\n", ret, GetLastError());
1948 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded,
1949 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
1952 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
1953 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr),
1955 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE,
1956 offsetof(CERT_RDN_ATTR, pszObjId) };
1958 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
1959 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
1963 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType,
1964 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
1965 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
1971 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
1972 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN),
1973 sizeof(CERT_NAME_INFO),
1974 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE,
1975 offsetof(CERT_RDN, rgRDNAttr) };
1977 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
1978 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
1982 SetLastError(STATUS_ACCESS_VIOLATION);
1989 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded,
1992 BOOL ret = TRUE, done = FALSE;
1993 DWORD indefiniteNestingLevels = 0, decoded = 0;
1995 TRACE("(%p, %d)\n", pbEncoded, cbEncoded);
2002 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded,
2005 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2007 if (dataLen == CMSG_INDEFINITE_LENGTH)
2009 indefiniteNestingLevels++;
2010 pbEncoded += 1 + lenBytes;
2011 cbEncoded -= 1 + lenBytes;
2012 decoded += 1 + lenBytes;
2013 TRACE("indefiniteNestingLevels = %d\n",
2014 indefiniteNestingLevels);
2018 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 &&
2019 indefiniteNestingLevels)
2021 indefiniteNestingLevels--;
2022 TRACE("indefiniteNestingLevels = %d\n",
2023 indefiniteNestingLevels);
2025 pbEncoded += 1 + lenBytes + dataLen;
2026 cbEncoded -= 1 + lenBytes + dataLen;
2027 decoded += 1 + lenBytes + dataLen;
2028 if (!indefiniteNestingLevels)
2032 } while (ret && !done);
2033 /* If we haven't found all 0 TLVs, we haven't found the end */
2034 if (ret && indefiniteNestingLevels)
2036 SetLastError(CRYPT_E_ASN1_EOD);
2040 *pcbDecoded = decoded;
2041 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0);
2045 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded,
2046 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2050 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0;
2052 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2053 pvStructInfo, *pcbStructInfo);
2055 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen)))
2057 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
2058 bytesNeeded += encodedLen;
2060 *pcbStructInfo = bytesNeeded;
2061 else if (*pcbStructInfo < bytesNeeded)
2063 SetLastError(ERROR_MORE_DATA);
2064 *pcbStructInfo = bytesNeeded;
2069 PCRYPT_OBJID_BLOB blob = pvStructInfo;
2071 *pcbStructInfo = bytesNeeded;
2072 blob->cbData = encodedLen;
2075 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
2076 blob->pbData = (LPBYTE)pbEncoded;
2079 assert(blob->pbData);
2080 memcpy(blob->pbData, pbEncoded, blob->cbData);
2084 blob->pbData = NULL;
2087 *pcbDecoded = encodedLen;
2092 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded,
2093 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2096 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2097 offsetof(CTL_USAGE, cUsageIdentifier),
2098 offsetof(CTL_USAGE, rgpszUsageIdentifier),
2100 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
2102 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2103 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2107 static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded,
2108 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2111 struct AsnArrayDescriptor arrayDesc = { 0,
2112 offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute),
2113 FINALMEMBERSIZE(CTL_ENTRY, cAttribute),
2114 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2115 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2118 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2119 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2123 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2124 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2126 struct AsnDecodeSequenceItem items[] = {
2127 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier),
2128 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE,
2129 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 },
2130 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute),
2131 CRYPT_AsnDecodeCTLEntryAttributes,
2132 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE,
2133 offsetof(CTL_ENTRY, rgAttribute), 0 },
2136 CTL_ENTRY *entry = pvStructInfo;
2138 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
2141 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2142 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
2143 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
2147 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded,
2148 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2151 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2152 offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry),
2153 FINALMEMBERSIZE(CTL_INFO, cExtension),
2154 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE,
2155 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) };
2157 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2158 pvStructInfo, *pcbStructInfo, pcbDecoded);
2160 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2161 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2165 static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded,
2166 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2170 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2171 offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension),
2172 FINALMEMBERSIZE(CTL_INFO, cExtension),
2173 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE,
2174 offsetof(CERT_EXTENSION, pszObjId) };
2176 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2177 pvStructInfo, *pcbStructInfo, pcbDecoded);
2179 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2180 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2184 static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded,
2185 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2191 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2193 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2195 ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes,
2196 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL);
2197 if (ret && pcbDecoded)
2198 *pcbDecoded = 1 + lenBytes + dataLen;
2203 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
2204 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2205 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2209 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2210 pDecodePara, pvStructInfo, *pcbStructInfo);
2214 struct AsnDecodeSequenceItem items[] = {
2215 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion),
2216 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
2217 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage),
2218 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE,
2219 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 },
2220 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier),
2221 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE,
2222 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 },
2223 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber),
2224 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
2225 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 },
2226 { 0, offsetof(CTL_INFO, ThisUpdate),
2227 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE,
2229 { 0, offsetof(CTL_INFO, NextUpdate),
2230 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE,
2232 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm),
2233 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2234 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 },
2235 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry),
2236 CRYPT_AsnDecodeCTLEntries,
2237 MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension),
2238 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 },
2239 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension),
2240 CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension),
2241 TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
2244 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2245 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
2246 pcbStructInfo, NULL, NULL);
2250 SetLastError(STATUS_ACCESS_VIOLATION);
2256 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
2257 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2261 struct AsnDecodeSequenceItem items[] = {
2262 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId),
2263 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2264 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 },
2265 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters),
2266 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2267 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 },
2269 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo;
2271 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2272 pvStructInfo, *pcbStructInfo);
2274 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2275 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2276 pcbDecoded, capability ? capability->pszObjId : NULL);
2277 TRACE("returning %d\n", ret);
2281 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType,
2282 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2283 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2287 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2288 pDecodePara, pvStructInfo, *pcbStructInfo);
2292 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2293 offsetof(CRYPT_SMIME_CAPABILITIES, cCapability),
2294 offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability),
2295 sizeof(CRYPT_SMIME_CAPABILITIES),
2296 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE,
2297 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) };
2299 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2300 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2304 SetLastError(STATUS_ACCESS_VIOLATION);
2307 TRACE("returning %d\n", ret);
2311 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded,
2312 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2317 LPSTR *pStr = pvStructInfo;
2319 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2321 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2322 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char);
2324 if (pbEncoded[0] != ASN_IA5STRING)
2326 SetLastError(CRYPT_E_ASN1_CORRUPT);
2331 bytesNeeded += dataLen;
2333 *pcbDecoded = 1 + lenBytes + dataLen;
2335 *pcbStructInfo = bytesNeeded;
2336 else if (*pcbStructInfo < bytesNeeded)
2338 *pcbStructInfo = bytesNeeded;
2339 SetLastError(ERROR_MORE_DATA);
2344 *pcbStructInfo = bytesNeeded;
2350 memcpy(str, pbEncoded + 1 + lenBytes, dataLen);
2361 static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded,
2362 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2365 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
2366 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2367 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers),
2368 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2369 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 };
2372 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags,
2373 pvStructInfo, pvStructInfo ? *pcbDecoded : 0);
2375 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2376 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2377 TRACE("returning %d\n", ret);
2381 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
2382 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2386 struct AsnDecodeSequenceItem items[] = {
2387 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2388 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE,
2389 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 },
2390 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2391 cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers,
2392 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers),
2393 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE,
2394 rgNoticeNumbers), 0 },
2398 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2399 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
2401 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2402 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
2406 /* The caller is expecting a pointer to a
2407 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2408 * CRYPT_AsnDecodeSequence is decoding a
2409 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2410 * needed, and decode again if the requisite space is available.
2412 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE);
2414 *pcbStructInfo = bytesNeeded;
2415 else if (*pcbStructInfo < bytesNeeded)
2417 *pcbStructInfo = bytesNeeded;
2418 SetLastError(ERROR_MORE_DATA);
2423 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef;
2425 *pcbStructInfo = bytesNeeded;
2426 /* The pointer (pvStructInfo) passed in points to the first dynamic
2427 * pointer, so use it as the pointer to the
2428 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2429 * appropriate offset for the first dynamic pointer within the
2430 * notice reference by pointing to the first memory location past
2431 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2434 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
2435 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
2436 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
2437 ret = CRYPT_AsnDecodeSequence(items,
2438 sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
2439 NULL, noticeRef, &bytesNeeded, pcbDecoded,
2440 noticeRef->pszOrganization);
2443 TRACE("returning %d\n", ret);
2447 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded,
2448 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2454 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2456 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2457 DWORD bytesNeeded = sizeof(LPWSTR);
2459 switch (pbEncoded[0])
2461 case ASN_NUMERICSTRING:
2463 bytesNeeded += (dataLen + 1) * 2;
2465 case ASN_PRINTABLESTRING:
2467 bytesNeeded += (dataLen + 1) * 2;
2471 bytesNeeded += (dataLen + 1) * 2;
2475 bytesNeeded += (dataLen + 1) * 2;
2477 case ASN_VIDEOTEXSTRING:
2479 bytesNeeded += (dataLen + 1) * 2;
2481 case ASN_GRAPHICSTRING:
2483 bytesNeeded += (dataLen + 1) * 2;
2485 case ASN_VISIBLESTRING:
2487 bytesNeeded += (dataLen + 1) * 2;
2489 case ASN_GENERALSTRING:
2491 bytesNeeded += (dataLen + 1) * 2;
2493 case ASN_UNIVERSALSTRING:
2495 bytesNeeded += dataLen / 2 + sizeof(WCHAR);
2499 bytesNeeded += dataLen + sizeof(WCHAR);
2501 case ASN_UTF8STRING:
2503 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0,
2504 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2;
2507 SetLastError(CRYPT_E_ASN1_BADTAG);
2512 *pcbDecoded = 1 + lenBytes + dataLen;
2514 *pcbStructInfo = bytesNeeded;
2515 else if (*pcbStructInfo < bytesNeeded)
2517 *pcbStructInfo = bytesNeeded;
2518 SetLastError(ERROR_MORE_DATA);
2523 LPWSTR *pStr = pvStructInfo;
2525 *pcbStructInfo = bytesNeeded;
2529 LPWSTR str = *(LPWSTR *)pStr;
2532 switch (pbEncoded[0])
2534 case ASN_NUMERICSTRING:
2535 case ASN_PRINTABLESTRING:
2538 case ASN_VIDEOTEXSTRING:
2539 case ASN_GRAPHICSTRING:
2540 case ASN_VISIBLESTRING:
2541 case ASN_GENERALSTRING:
2542 for (i = 0; i < dataLen; i++)
2543 str[i] = pbEncoded[1 + lenBytes + i];
2546 case ASN_UNIVERSALSTRING:
2547 for (i = 0; i < dataLen / 4; i++)
2548 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8)
2549 | pbEncoded[1 + lenBytes + 2 * i + 3];
2553 for (i = 0; i < dataLen / 2; i++)
2554 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) |
2555 pbEncoded[1 + lenBytes + 2 * i + 1];
2558 case ASN_UTF8STRING:
2560 int len = MultiByteToWideChar(CP_UTF8, 0,
2561 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
2562 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
2575 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2576 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
2577 DWORD *pcbStructInfo, DWORD *pcbDecoded)
2580 struct AsnDecodeSequenceItem items[] = {
2581 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE,
2582 pNoticeReference), CRYPT_AsnDecodeNoticeReference,
2583 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE,
2584 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 },
2585 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText),
2586 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE,
2587 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 },
2589 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo;
2591 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2592 pvStructInfo, *pcbStructInfo);
2594 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2595 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2596 pcbDecoded, notice ? notice->pNoticeReference : NULL);
2597 TRACE("returning %d\n", ret);
2601 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice(
2602 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded,
2603 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
2604 void *pvStructInfo, DWORD *pcbStructInfo)
2608 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2609 pDecodePara, pvStructInfo, *pcbStructInfo);
2615 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded,
2616 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded,
2621 *pcbStructInfo = bytesNeeded;
2622 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2623 pvStructInfo, pcbStructInfo, bytesNeeded)))
2625 PCERT_POLICY_QUALIFIER_USER_NOTICE notice;
2627 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2628 pvStructInfo = *(BYTE **)pvStructInfo;
2629 notice = pvStructInfo;
2630 notice->pNoticeReference =
2631 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE)
2632 ((BYTE *)pvStructInfo +
2633 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE));
2634 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2635 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
2636 pvStructInfo, &bytesNeeded, NULL);
2642 SetLastError(STATUS_ACCESS_VIOLATION);
2645 TRACE("returning %d\n", ret);
2649 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded,
2650 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2654 struct AsnArrayDescriptor arrayDesc = { 0,
2655 offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue),
2656 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue),
2657 CRYPT_AsnDecodeCopyBytes,
2658 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
2660 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2661 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
2663 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2664 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2668 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
2669 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2673 struct AsnDecodeSequenceItem items[] = {
2674 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId),
2675 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2676 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 },
2677 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue),
2678 CRYPT_AsnDecodePKCSAttributeValue,
2679 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE,
2680 TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 },
2682 PCRYPT_ATTRIBUTE attr = pvStructInfo;
2684 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2685 pvStructInfo, *pcbStructInfo);
2687 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2688 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2689 pcbDecoded, attr ? attr->pszObjId : NULL);
2690 TRACE("returning %d\n", ret);
2694 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType,
2695 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2696 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2700 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2701 pDecodePara, pvStructInfo, *pcbStructInfo);
2707 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2708 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
2712 *pcbStructInfo = bytesNeeded;
2713 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2714 pvStructInfo, pcbStructInfo, bytesNeeded)))
2716 PCRYPT_ATTRIBUTE attr;
2718 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2719 pvStructInfo = *(BYTE **)pvStructInfo;
2720 attr = pvStructInfo;
2721 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo +
2722 sizeof(CRYPT_ATTRIBUTE));
2723 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded,
2724 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded,
2731 SetLastError(STATUS_ACCESS_VIOLATION);
2734 TRACE("returning %d\n", ret);
2738 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded,
2739 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2742 struct AsnArrayDescriptor arrayDesc = { 0,
2743 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2744 sizeof(CRYPT_ATTRIBUTES),
2745 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE,
2746 offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2749 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
2750 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
2754 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType,
2755 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2756 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2760 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2761 pDecodePara, pvStructInfo, *pcbStructInfo);
2765 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
2766 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr),
2767 sizeof(CRYPT_ATTRIBUTES),
2768 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE),
2769 TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) };
2771 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
2772 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
2776 SetLastError(STATUS_ACCESS_VIOLATION);
2779 TRACE("returning %d\n", ret);
2783 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
2784 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2786 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo;
2788 struct AsnDecodeSequenceItem items[] = {
2789 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId),
2790 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
2791 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 },
2792 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters),
2793 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
2794 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 },
2797 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
2798 pvStructInfo, *pcbStructInfo, pcbDecoded);
2800 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2801 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2802 pcbDecoded, algo ? algo->pszObjId : NULL);
2803 if (ret && pvStructInfo)
2805 TRACE("pszObjId is %p (%s)\n", algo->pszObjId,
2806 debugstr_a(algo->pszObjId));
2811 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
2812 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
2816 struct AsnDecodeSequenceItem items[] = {
2817 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm),
2818 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
2819 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO,
2820 Algorithm.pszObjId) },
2821 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey),
2822 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
2823 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) },
2825 PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
2827 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
2828 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
2829 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
2833 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType,
2834 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
2835 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
2843 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2844 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
2847 *pcbStructInfo = bytesNeeded;
2848 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
2849 pvStructInfo, pcbStructInfo, bytesNeeded)))
2851 PCERT_PUBLIC_KEY_INFO info;
2853 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
2854 pvStructInfo = *(BYTE **)pvStructInfo;
2855 info = pvStructInfo;
2856 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo +
2857 sizeof(CERT_PUBLIC_KEY_INFO);
2858 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded,
2859 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
2860 &bytesNeeded, NULL);
2866 SetLastError(STATUS_ACCESS_VIOLATION);
2873 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded,
2874 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2880 SetLastError(CRYPT_E_ASN1_CORRUPT);
2883 if (GET_LEN_BYTES(pbEncoded[1]) > 1)
2885 SetLastError(CRYPT_E_ASN1_CORRUPT);
2888 if (pbEncoded[1] > 1)
2890 SetLastError(CRYPT_E_ASN1_CORRUPT);
2897 *pcbStructInfo = sizeof(BOOL);
2900 else if (*pcbStructInfo < sizeof(BOOL))
2902 *pcbStructInfo = sizeof(BOOL);
2903 SetLastError(ERROR_MORE_DATA);
2908 *pcbStructInfo = sizeof(BOOL);
2909 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE;
2912 TRACE("returning %d (%08x)\n", ret, GetLastError());
2916 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded,
2917 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
2919 PCERT_ALT_NAME_ENTRY entry = pvStructInfo;
2920 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY);
2923 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
2924 pvStructInfo, *pcbStructInfo);
2928 SetLastError(CRYPT_E_ASN1_CORRUPT);
2931 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
2932 if (1 + lenBytes > cbEncoded)
2934 SetLastError(CRYPT_E_ASN1_CORRUPT);
2937 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
2939 switch (pbEncoded[0] & ASN_TYPE_MASK)
2941 case 1: /* rfc822Name */
2942 case 2: /* dNSName */
2943 case 6: /* uniformResourceIdentifier */
2944 bytesNeeded += (dataLen + 1) * sizeof(WCHAR);
2946 case 4: /* directoryName */
2947 case 7: /* iPAddress */
2948 bytesNeeded += dataLen;
2950 case 8: /* registeredID */
2951 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL,
2955 /* FIXME: ugly, shouldn't need to know internals of OID decode
2956 * function to use it.
2958 bytesNeeded += dataLen - sizeof(LPSTR);
2961 case 0: /* otherName */
2962 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK);
2963 SetLastError(CRYPT_E_ASN1_BADTAG);
2966 case 3: /* x400Address, unimplemented */
2967 case 5: /* ediPartyName, unimplemented */
2968 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK);
2969 SetLastError(CRYPT_E_ASN1_BADTAG);
2973 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK);
2974 SetLastError(CRYPT_E_ASN1_CORRUPT);
2980 *pcbDecoded = 1 + lenBytes + dataLen;
2982 *pcbStructInfo = bytesNeeded;
2983 else if (*pcbStructInfo < bytesNeeded)
2985 *pcbStructInfo = bytesNeeded;
2986 SetLastError(ERROR_MORE_DATA);
2991 *pcbStructInfo = bytesNeeded;
2992 /* MS used values one greater than the asn1 ones.. sigh */
2993 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1;
2994 switch (pbEncoded[0] & ASN_TYPE_MASK)
2996 case 1: /* rfc822Name */
2997 case 2: /* dNSName */
2998 case 6: /* uniformResourceIdentifier */
3002 for (i = 0; i < dataLen; i++)
3003 entry->u.pwszURL[i] =
3004 (WCHAR)pbEncoded[1 + lenBytes + i];
3005 entry->u.pwszURL[i] = 0;
3006 TRACE("URL is %p (%s)\n", entry->u.pwszURL,
3007 debugstr_w(entry->u.pwszURL));
3010 case 4: /* directoryName */
3011 /* The data are memory-equivalent with the IPAddress case,
3014 case 7: /* iPAddress */
3015 /* The next data pointer is in the pwszURL spot, that is,
3016 * the first 4 bytes. Need to move it to the next spot.
3018 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL;
3019 entry->u.IPAddress.cbData = dataLen;
3020 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes,
3023 case 8: /* registeredID */
3024 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0,
3025 &entry->u.pszRegisteredID, &dataLen, NULL);
3034 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded,
3035 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3039 struct AsnArrayDescriptor arrayDesc = { 0,
3040 offsetof(CERT_ALT_NAME_INFO, cAltEntry),
3041 offsetof(CERT_ALT_NAME_INFO, rgAltEntry),
3042 sizeof(CERT_ALT_NAME_INFO),
3043 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
3044 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
3046 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3047 pvStructInfo, *pcbStructInfo, pcbDecoded);
3049 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags,
3050 NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3054 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
3055 static BOOL CRYPT_AsnDecodeIntegerSwapBytes(const BYTE *pbEncoded,
3056 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3061 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3062 pvStructInfo, *pcbStructInfo, pcbDecoded);
3064 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
3067 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
3068 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo,
3070 if (ret && pvStructInfo)
3072 CRYPT_DATA_BLOB *blob = pvStructInfo;
3079 for (i = 0; i < blob->cbData / 2; i++)
3081 temp = blob->pbData[i];
3082 blob->pbData[i] = blob->pbData[blob->cbData - i - 1];
3083 blob->pbData[blob->cbData - i - 1] = temp;
3087 TRACE("returning %d (%08x)\n", ret, GetLastError());
3091 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
3092 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3093 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3099 struct AsnDecodeSequenceItem items[] = {
3100 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId),
3101 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3102 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 },
3103 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3104 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer),
3105 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE,
3106 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 },
3107 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO,
3108 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3109 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3110 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
3113 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3114 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3115 pcbStructInfo, NULL, NULL);
3119 SetLastError(STATUS_ACCESS_VIOLATION);
3126 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
3127 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3128 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3134 struct AsnDecodeSequenceItem items[] = {
3135 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId),
3136 CRYPT_AsnDecodeIntegerSwapBytes, sizeof(CRYPT_DATA_BLOB),
3137 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 },
3138 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1,
3139 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer),
3140 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE,
3141 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3142 AuthorityCertIssuer.rgAltEntry), 0 },
3143 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3144 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal,
3145 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE,
3146 offsetof(CERT_AUTHORITY_KEY_ID2_INFO,
3147 AuthorityCertSerialNumber.pbData), 0 },
3150 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3151 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3152 pcbStructInfo, NULL, NULL);
3156 SetLastError(STATUS_ACCESS_VIOLATION);
3163 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
3164 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3167 struct AsnDecodeSequenceItem items[] = {
3168 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod),
3169 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3170 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 },
3171 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation),
3172 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE,
3173 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 },
3175 CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
3177 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3178 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3179 pcbDecoded, descr ? descr->pszAccessMethod : NULL);
3182 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType,
3183 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3184 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3188 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3189 pDecodePara, pvStructInfo, *pcbStructInfo);
3193 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3194 offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr),
3195 offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr),
3196 sizeof(CERT_AUTHORITY_INFO_ACCESS),
3197 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION),
3198 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) };
3200 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3201 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3205 SetLastError(STATUS_ACCESS_VIOLATION);
3212 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded,
3213 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3218 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3219 pvStructInfo, *pcbStructInfo, pcbDecoded);
3221 /* The caller has already checked the tag, no need to check it again.
3222 * Check the outer length is valid:
3224 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen)))
3226 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3229 pbEncoded += 1 + lenBytes;
3230 cbEncoded -= 1 + lenBytes;
3231 if (dataLen == CMSG_INDEFINITE_LENGTH)
3232 cbEncoded -= 2; /* space for 0 TLV */
3233 /* Check the inner length is valid: */
3234 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen)))
3238 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags,
3239 pvStructInfo, pcbStructInfo, &decodedLen);
3240 if (dataLen == CMSG_INDEFINITE_LENGTH)
3242 if (*(pbEncoded + decodedLen) != 0 ||
3243 *(pbEncoded + decodedLen + 1) != 0)
3245 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3246 *(pbEncoded + decodedLen),
3247 *(pbEncoded + decodedLen + 1));
3248 SetLastError(CRYPT_E_ASN1_CORRUPT);
3254 if (ret && pcbDecoded)
3256 *pcbDecoded = 1 + lenBytes + decodedLen;
3257 TRACE("decoded %d bytes\n", *pcbDecoded);
3264 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
3265 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3268 CRYPT_CONTENT_INFO *info = pvStructInfo;
3269 struct AsnDecodeSequenceItem items[] = {
3270 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId),
3271 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE,
3272 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 },
3273 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
3274 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent,
3275 sizeof(CRYPT_DER_BLOB), TRUE, TRUE,
3276 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 },
3280 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3281 pvStructInfo, *pcbStructInfo, pcbDecoded);
3283 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3284 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3285 pcbDecoded, info ? info->pszObjId : NULL);
3289 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType,
3290 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3291 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3295 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3296 pDecodePara, pvStructInfo, *pcbStructInfo);
3300 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded,
3301 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
3302 if (ret && pvStructInfo)
3304 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
3305 pcbStructInfo, *pcbStructInfo);
3308 CRYPT_CONTENT_INFO *info;
3310 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3311 pvStructInfo = *(BYTE **)pvStructInfo;
3312 info = pvStructInfo;
3313 info->pszObjId = (LPSTR)((BYTE *)info +
3314 sizeof(CRYPT_CONTENT_INFO));
3315 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded,
3316 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3317 pcbStructInfo, NULL);
3323 SetLastError(STATUS_ACCESS_VIOLATION);
3329 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
3330 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
3331 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData)
3334 struct AsnDecodeSequenceItem items[] = {
3335 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version),
3336 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3337 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm),
3338 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
3339 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId),
3341 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo),
3342 CRYPT_AsnDecodePKCSContentInfoInternal,
3343 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA,
3344 ContentInfo.pszObjId), 0 },
3345 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash),
3346 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE,
3347 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
3350 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3351 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
3356 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType,
3357 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3358 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3362 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3363 pDecodePara, pvStructInfo, *pcbStructInfo);
3369 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3370 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3373 *pcbStructInfo = bytesNeeded;
3374 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3375 pvStructInfo, pcbStructInfo, bytesNeeded)))
3377 CERT_ALT_NAME_INFO *name;
3379 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3380 pvStructInfo = *(BYTE **)pvStructInfo;
3381 name = pvStructInfo;
3382 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY)
3383 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO));
3384 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded,
3385 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3386 &bytesNeeded, NULL);
3392 SetLastError(STATUS_ACCESS_VIOLATION);
3399 struct PATH_LEN_CONSTRAINT
3401 BOOL fPathLenConstraint;
3402 DWORD dwPathLenConstraint;
3405 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded,
3406 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3410 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size;
3412 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3413 pvStructInfo, *pcbStructInfo, pcbDecoded);
3417 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL,
3419 *pcbStructInfo = bytesNeeded;
3421 else if (*pcbStructInfo < bytesNeeded)
3423 SetLastError(ERROR_MORE_DATA);
3424 *pcbStructInfo = bytesNeeded;
3429 struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo;
3431 *pcbStructInfo = bytesNeeded;
3432 size = sizeof(constraint->dwPathLenConstraint);
3433 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
3434 &constraint->dwPathLenConstraint, &size, pcbDecoded);
3436 constraint->fPathLenConstraint = TRUE;
3437 TRACE("got an int, dwPathLenConstraint is %d\n",
3438 constraint->dwPathLenConstraint);
3440 TRACE("returning %d (%08x)\n", ret, GetLastError());
3444 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded,
3445 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3449 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3450 offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3451 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint),
3452 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3453 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE,
3454 offsetof(CERT_NAME_BLOB, pbData) };
3456 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3457 pvStructInfo, *pcbStructInfo, pcbDecoded);
3459 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3460 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3461 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3465 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
3466 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3467 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3473 struct AsnDecodeSequenceItem items[] = {
3474 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType),
3475 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE,
3476 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 },
3477 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3478 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3479 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3480 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO,
3481 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints,
3482 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint),
3484 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
3487 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3488 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3489 pcbStructInfo, NULL, NULL);
3493 SetLastError(STATUS_ACCESS_VIOLATION);
3500 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
3501 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3502 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3508 struct AsnDecodeSequenceItem items[] = {
3509 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA),
3510 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 },
3511 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO,
3512 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint,
3513 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
3516 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3517 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
3518 pcbStructInfo, NULL, NULL);
3522 SetLastError(STATUS_ACCESS_VIOLATION);
3529 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
3530 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3533 struct AsnDecodeSequenceItem items[] = {
3534 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO,
3535 pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR),
3536 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId),
3538 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier),
3539 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE,
3540 offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 },
3543 CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo;
3545 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3546 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3548 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3549 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3550 pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
3554 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded,
3555 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3559 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3560 offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3561 offsetof(CERT_POLICY_INFO, rgPolicyQualifier),
3562 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier),
3563 CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE,
3564 offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) };
3566 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3567 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3569 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3570 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
3571 TRACE("Returning %d (%08x)\n", ret, GetLastError());
3575 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
3576 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3578 struct AsnDecodeSequenceItem items[] = {
3579 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier),
3580 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE,
3581 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 },
3582 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier),
3583 CRYPT_AsnDecodePolicyQualifiers,
3584 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE,
3585 TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 },
3587 CERT_POLICY_INFO *info = pvStructInfo;
3590 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3591 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3593 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3594 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
3595 pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
3599 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType,
3600 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3601 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3605 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3606 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
3610 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
3611 offsetof(CERT_POLICIES_INFO, cPolicyInfo),
3612 offsetof(CERT_POLICIES_INFO, rgPolicyInfo),
3613 sizeof(CERT_POLICIES_INFO),
3614 CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE,
3615 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) };
3617 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
3618 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
3622 SetLastError(STATUS_ACCESS_VIOLATION);
3628 #define RSA1_MAGIC 0x31415352
3630 struct DECODED_RSA_PUB_KEY
3633 CRYPT_INTEGER_BLOB modulus;
3636 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
3637 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3638 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3644 struct AsnDecodeSequenceItem items[] = {
3645 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus),
3646 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB),
3647 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData),
3649 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp),
3650 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
3652 struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
3655 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
3656 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
3660 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
3661 decodedKey->modulus.cbData;
3665 *pcbStructInfo = bytesNeeded;
3668 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3669 pvStructInfo, pcbStructInfo, bytesNeeded)))
3672 RSAPUBKEY *rsaPubKey;
3674 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3675 pvStructInfo = *(BYTE **)pvStructInfo;
3677 hdr->bType = PUBLICKEYBLOB;
3678 hdr->bVersion = CUR_BLOB_VERSION;
3680 hdr->aiKeyAlg = CALG_RSA_KEYX;
3681 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo +
3682 sizeof(BLOBHEADER));
3683 rsaPubKey->magic = RSA1_MAGIC;
3684 rsaPubKey->pubexp = decodedKey->pubexp;
3685 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8;
3686 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) +
3687 sizeof(RSAPUBKEY), decodedKey->modulus.pbData,
3688 decodedKey->modulus.cbData);
3690 LocalFree(decodedKey);
3695 SetLastError(STATUS_ACCESS_VIOLATION);
3702 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded,
3703 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
3707 DWORD bytesNeeded, dataLen;
3709 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
3710 pvStructInfo, *pcbStructInfo, pcbDecoded);
3712 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3714 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3716 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3717 bytesNeeded = sizeof(CRYPT_DATA_BLOB);
3719 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB);
3721 *pcbDecoded = 1 + lenBytes + dataLen;
3723 *pcbStructInfo = bytesNeeded;
3724 else if (*pcbStructInfo < bytesNeeded)
3726 SetLastError(ERROR_MORE_DATA);
3727 *pcbStructInfo = bytesNeeded;
3732 CRYPT_DATA_BLOB *blob;
3734 *pcbStructInfo = bytesNeeded;
3735 blob = pvStructInfo;
3736 blob->cbData = dataLen;
3737 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3738 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes;
3741 assert(blob->pbData);
3743 memcpy(blob->pbData, pbEncoded + 1 + lenBytes,
3751 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType,
3752 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3753 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3757 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
3758 pDecodePara, pvStructInfo, *pcbStructInfo);
3766 SetLastError(CRYPT_E_ASN1_CORRUPT);
3769 else if (pbEncoded[0] != ASN_OCTETSTRING)
3771 SetLastError(CRYPT_E_ASN1_BADTAG);
3774 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3775 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3778 *pcbStructInfo = bytesNeeded;
3779 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3780 pvStructInfo, pcbStructInfo, bytesNeeded)))
3782 CRYPT_DATA_BLOB *blob;
3784 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3785 pvStructInfo = *(BYTE **)pvStructInfo;
3786 blob = pvStructInfo;
3787 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB);
3788 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded,
3789 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3790 &bytesNeeded, NULL);
3796 SetLastError(STATUS_ACCESS_VIOLATION);
3803 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3804 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3807 DWORD bytesNeeded, dataLen;
3808 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
3810 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags,
3811 pvStructInfo, *pcbStructInfo, pcbDecoded);
3813 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
3815 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3816 bytesNeeded = sizeof(CRYPT_BIT_BLOB);
3818 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB);
3820 *pcbDecoded = 1 + lenBytes + dataLen;
3822 *pcbStructInfo = bytesNeeded;
3823 else if (*pcbStructInfo < bytesNeeded)
3825 *pcbStructInfo = bytesNeeded;
3826 SetLastError(ERROR_MORE_DATA);
3831 CRYPT_BIT_BLOB *blob;
3833 *pcbStructInfo = bytesNeeded;
3834 blob = pvStructInfo;
3835 blob->cbData = dataLen - 1;
3836 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes);
3837 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
3839 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes;
3843 assert(blob->pbData);
3846 BYTE mask = 0xff << blob->cUnusedBits;
3848 memcpy(blob->pbData, pbEncoded + 2 + lenBytes,
3850 blob->pbData[blob->cbData - 1] &= mask;
3858 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType,
3859 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3860 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3864 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags,
3865 pDecodePara, pvStructInfo, pcbStructInfo);
3873 SetLastError(CRYPT_E_ASN1_CORRUPT);
3876 else if (pbEncoded[0] != ASN_BITSTRING)
3878 SetLastError(CRYPT_E_ASN1_BADTAG);
3881 else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3882 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
3885 *pcbStructInfo = bytesNeeded;
3886 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3887 pvStructInfo, pcbStructInfo, bytesNeeded)))
3889 CRYPT_BIT_BLOB *blob;
3891 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3892 pvStructInfo = *(BYTE **)pvStructInfo;
3893 blob = pvStructInfo;
3894 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB);
3895 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded,
3896 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3897 &bytesNeeded, NULL);
3903 SetLastError(STATUS_ACCESS_VIOLATION);
3907 TRACE("returning %d (%08x)\n", ret, GetLastError());
3911 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3912 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded,
3913 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
3916 BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)];
3917 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
3918 DWORD size = sizeof(buf);
3920 blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB);
3921 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, buf,
3926 *pcbStructInfo = sizeof(int);
3927 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int))))
3931 if (blob->pbData[blob->cbData - 1] & 0x80)
3933 /* initialize to a negative value to sign-extend */
3938 for (i = 0; i < blob->cbData; i++)
3941 val |= blob->pbData[blob->cbData - i - 1];
3943 memcpy(pvStructInfo, &val, sizeof(int));
3946 else if (GetLastError() == ERROR_MORE_DATA)
3947 SetLastError(CRYPT_E_ASN1_LARGE);
3951 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType,
3952 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
3953 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
3963 SetLastError(CRYPT_E_ASN1_EOD);
3966 else if (pbEncoded[0] != ASN_INTEGER)
3968 SetLastError(CRYPT_E_ASN1_BADTAG);
3972 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3973 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
3977 *pcbStructInfo = bytesNeeded;
3978 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
3979 pvStructInfo, pcbStructInfo, bytesNeeded)))
3981 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
3982 pvStructInfo = *(BYTE **)pvStructInfo;
3983 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded,
3984 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
3985 &bytesNeeded, NULL);
3991 SetLastError(STATUS_ACCESS_VIOLATION);
3998 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded,
3999 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4003 DWORD bytesNeeded, dataLen;
4005 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4007 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4009 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4011 *pcbDecoded = 1 + lenBytes + dataLen;
4013 *pcbStructInfo = bytesNeeded;
4014 else if (*pcbStructInfo < bytesNeeded)
4016 *pcbStructInfo = bytesNeeded;
4017 SetLastError(ERROR_MORE_DATA);
4022 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4024 *pcbStructInfo = bytesNeeded;
4025 blob->cbData = dataLen;
4026 assert(blob->pbData);
4031 for (i = 0; i < blob->cbData; i++)
4033 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4042 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType,
4043 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4044 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4052 if (pbEncoded[0] != ASN_INTEGER)
4054 SetLastError(CRYPT_E_ASN1_BADTAG);
4058 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4059 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4063 *pcbStructInfo = bytesNeeded;
4064 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4065 pvStructInfo, pcbStructInfo, bytesNeeded)))
4067 CRYPT_INTEGER_BLOB *blob;
4069 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4070 pvStructInfo = *(BYTE **)pvStructInfo;
4071 blob = pvStructInfo;
4072 blob->pbData = (BYTE *)pvStructInfo +
4073 sizeof(CRYPT_INTEGER_BLOB);
4074 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded,
4075 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4076 &bytesNeeded, NULL);
4082 SetLastError(STATUS_ACCESS_VIOLATION);
4089 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded,
4090 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4095 if (pbEncoded[0] == ASN_INTEGER)
4097 DWORD bytesNeeded, dataLen;
4099 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4101 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4104 *pcbDecoded = 1 + lenBytes + dataLen;
4105 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB);
4107 *pcbStructInfo = bytesNeeded;
4108 else if (*pcbStructInfo < bytesNeeded)
4110 *pcbStructInfo = bytesNeeded;
4111 SetLastError(ERROR_MORE_DATA);
4116 CRYPT_INTEGER_BLOB *blob = pvStructInfo;
4118 *pcbStructInfo = bytesNeeded;
4119 blob->cbData = dataLen;
4120 assert(blob->pbData);
4121 /* remove leading zero byte if it exists */
4122 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0)
4131 for (i = 0; i < blob->cbData; i++)
4133 blob->pbData[i] = *(pbEncoded + 1 + lenBytes +
4142 SetLastError(CRYPT_E_ASN1_BADTAG);
4148 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType,
4149 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4150 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4158 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded,
4159 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL)))
4162 *pcbStructInfo = bytesNeeded;
4163 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4164 pvStructInfo, pcbStructInfo, bytesNeeded)))
4166 CRYPT_INTEGER_BLOB *blob;
4168 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4169 pvStructInfo = *(BYTE **)pvStructInfo;
4170 blob = pvStructInfo;
4171 blob->pbData = (BYTE *)pvStructInfo +
4172 sizeof(CRYPT_INTEGER_BLOB);
4173 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded,
4174 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo,
4175 &bytesNeeded, NULL);
4181 SetLastError(STATUS_ACCESS_VIOLATION);
4188 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType,
4189 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4190 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4196 *pcbStructInfo = sizeof(int);
4201 if (pbEncoded[0] == ASN_ENUMERATED)
4203 unsigned int val = 0, i;
4207 SetLastError(CRYPT_E_ASN1_EOD);
4210 else if (pbEncoded[1] == 0)
4212 SetLastError(CRYPT_E_ASN1_CORRUPT);
4217 /* A little strange looking, but we have to accept a sign byte:
4218 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4219 * assuming a small length is okay here, it has to be in short
4222 if (pbEncoded[1] > sizeof(unsigned int) + 1)
4224 SetLastError(CRYPT_E_ASN1_LARGE);
4227 for (i = 0; i < pbEncoded[1]; i++)
4230 val |= pbEncoded[2 + i];
4232 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4233 pvStructInfo, pcbStructInfo, sizeof(unsigned int))))
4235 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4236 pvStructInfo = *(BYTE **)pvStructInfo;
4237 memcpy(pvStructInfo, &val, sizeof(unsigned int));
4243 SetLastError(CRYPT_E_ASN1_BADTAG);
4249 SetLastError(STATUS_ACCESS_VIOLATION);
4256 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4259 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4264 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4266 if (!isdigit(*(pbEncoded))) \
4268 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4274 (word) += *(pbEncoded)++ - '0'; \
4279 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len,
4280 SYSTEMTIME *sysTime)
4284 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-'))
4286 WORD hours, minutes = 0;
4287 BYTE sign = *pbEncoded++;
4290 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours);
4291 if (ret && hours >= 24)
4293 SetLastError(CRYPT_E_ASN1_CORRUPT);
4298 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes);
4299 if (ret && minutes >= 60)
4301 SetLastError(CRYPT_E_ASN1_CORRUPT);
4309 sysTime->wHour += hours;
4310 sysTime->wMinute += minutes;
4314 if (hours > sysTime->wHour)
4317 sysTime->wHour = 24 - (hours - sysTime->wHour);
4320 sysTime->wHour -= hours;
4321 if (minutes > sysTime->wMinute)
4324 sysTime->wMinute = 60 - (minutes - sysTime->wMinute);
4327 sysTime->wMinute -= minutes;
4334 #define MIN_ENCODED_TIME_LENGTH 10
4336 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded,
4337 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4342 if (pbEncoded[0] == ASN_UTCTIME)
4345 SetLastError(CRYPT_E_ASN1_EOD);
4346 else if (pbEncoded[1] > 0x7f)
4348 /* long-form date strings really can't be valid */
4349 SetLastError(CRYPT_E_ASN1_CORRUPT);
4353 SYSTEMTIME sysTime = { 0 };
4354 BYTE len = pbEncoded[1];
4356 if (len < MIN_ENCODED_TIME_LENGTH)
4357 SetLastError(CRYPT_E_ASN1_CORRUPT);
4362 *pcbDecoded = 2 + len;
4364 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear);
4365 if (sysTime.wYear >= 50)
4366 sysTime.wYear += 1900;
4368 sysTime.wYear += 2000;
4369 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4370 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4371 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4372 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute);
4375 if (len >= 2 && isdigit(*pbEncoded) &&
4376 isdigit(*(pbEncoded + 1)))
4377 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4379 else if (isdigit(*pbEncoded))
4380 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1,
4383 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4389 *pcbStructInfo = sizeof(FILETIME);
4390 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4392 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4398 SetLastError(CRYPT_E_ASN1_BADTAG);
4402 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType,
4403 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4404 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4412 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4413 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4417 *pcbStructInfo = bytesNeeded;
4418 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
4419 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
4421 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4422 pvStructInfo = *(BYTE **)pvStructInfo;
4423 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded,
4424 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4425 &bytesNeeded, NULL);
4431 SetLastError(STATUS_ACCESS_VIOLATION);
4437 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded,
4438 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4443 if (pbEncoded[0] == ASN_GENERALTIME)
4446 SetLastError(CRYPT_E_ASN1_EOD);
4447 else if (pbEncoded[1] > 0x7f)
4449 /* long-form date strings really can't be valid */
4450 SetLastError(CRYPT_E_ASN1_CORRUPT);
4454 BYTE len = pbEncoded[1];
4456 if (len < MIN_ENCODED_TIME_LENGTH)
4457 SetLastError(CRYPT_E_ASN1_CORRUPT);
4460 SYSTEMTIME sysTime = { 0 };
4464 *pcbDecoded = 2 + len;
4466 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear);
4467 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth);
4468 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay);
4469 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour);
4472 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4475 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2,
4477 if (ret && len > 0 && (*pbEncoded == '.' ||
4484 /* workaround macro weirdness */
4485 digits = min(len, 3);
4486 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits,
4487 sysTime.wMilliseconds);
4490 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len,
4496 *pcbStructInfo = sizeof(FILETIME);
4497 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo,
4499 ret = SystemTimeToFileTime(&sysTime, pvStructInfo);
4505 SetLastError(CRYPT_E_ASN1_BADTAG);
4509 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded,
4510 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4514 InternalDecodeFunc decode = NULL;
4516 if (pbEncoded[0] == ASN_UTCTIME)
4517 decode = CRYPT_AsnDecodeUtcTimeInternal;
4518 else if (pbEncoded[0] == ASN_GENERALTIME)
4519 decode = CRYPT_AsnDecodeGeneralizedTime;
4521 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo,
4522 pcbStructInfo, pcbDecoded);
4525 SetLastError(CRYPT_E_ASN1_BADTAG);
4531 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType,
4532 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4533 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4541 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4542 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL);
4546 *pcbStructInfo = bytesNeeded;
4547 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4548 pvStructInfo, pcbStructInfo, bytesNeeded)))
4550 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4551 pvStructInfo = *(BYTE **)pvStructInfo;
4552 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded,
4553 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
4554 &bytesNeeded, NULL);
4560 SetLastError(STATUS_ACCESS_VIOLATION);
4567 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType,
4568 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4569 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4575 if (pbEncoded[0] == ASN_SEQUENCEOF)
4577 DWORD bytesNeeded, dataLen, remainingLen, cValue;
4579 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4584 lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4585 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY);
4587 ptr = pbEncoded + 1 + lenBytes;
4588 remainingLen = dataLen;
4589 while (ret && remainingLen)
4593 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4596 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4598 remainingLen -= 1 + nextLenBytes + nextLen;
4599 ptr += 1 + nextLenBytes + nextLen;
4600 bytesNeeded += sizeof(CRYPT_DER_BLOB);
4601 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG))
4602 bytesNeeded += 1 + nextLenBytes + nextLen;
4608 CRYPT_SEQUENCE_OF_ANY *seq;
4613 *pcbStructInfo = bytesNeeded;
4614 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
4615 pvStructInfo, pcbStructInfo, bytesNeeded)))
4617 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
4618 pvStructInfo = *(BYTE **)pvStructInfo;
4620 seq->cValue = cValue;
4621 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq +
4623 nextPtr = (BYTE *)seq->rgValue +
4624 cValue * sizeof(CRYPT_DER_BLOB);
4625 ptr = pbEncoded + 1 + lenBytes;
4626 remainingLen = dataLen;
4628 while (ret && remainingLen)
4632 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen);
4635 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]);
4637 seq->rgValue[i].cbData = 1 + nextLenBytes +
4639 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG)
4640 seq->rgValue[i].pbData = (BYTE *)ptr;
4643 seq->rgValue[i].pbData = nextPtr;
4644 memcpy(nextPtr, ptr, 1 + nextLenBytes +
4646 nextPtr += 1 + nextLenBytes + nextLen;
4648 remainingLen -= 1 + nextLenBytes + nextLen;
4649 ptr += 1 + nextLenBytes + nextLen;
4659 SetLastError(CRYPT_E_ASN1_BADTAG);
4665 SetLastError(STATUS_ACCESS_VIOLATION);
4672 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded,
4673 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4678 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0))
4680 DWORD bytesNeeded, dataLen;
4682 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
4684 struct AsnArrayDescriptor arrayDesc = {
4685 ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4686 offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry),
4687 offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry),
4688 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u),
4689 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE,
4690 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) };
4691 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
4696 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4697 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4698 dwFlags, NULL, NULL, &nameLen, NULL);
4699 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen -
4700 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u);
4703 bytesNeeded = sizeof(CRL_DIST_POINT_NAME);
4705 *pcbDecoded = 1 + lenBytes + dataLen;
4707 *pcbStructInfo = bytesNeeded;
4708 else if (*pcbStructInfo < bytesNeeded)
4710 *pcbStructInfo = bytesNeeded;
4711 SetLastError(ERROR_MORE_DATA);
4716 CRL_DIST_POINT_NAME *name = pvStructInfo;
4718 *pcbStructInfo = bytesNeeded;
4721 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
4722 ret = CRYPT_AsnDecodeArray(&arrayDesc,
4723 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes,
4724 dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen,
4728 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
4734 SetLastError(CRYPT_E_ASN1_BADTAG);
4740 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
4741 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
4743 struct AsnDecodeSequenceItem items[] = {
4744 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT,
4745 DistPointName), CRYPT_AsnDecodeDistPointName,
4746 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT,
4747 DistPointName.u.FullName.rgAltEntry), 0 },
4748 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags),
4749 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE,
4750 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 },
4751 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer),
4752 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE,
4753 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 },
4755 CRL_DIST_POINT *point = pvStructInfo;
4758 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4759 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4760 pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
4764 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType,
4765 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4766 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4770 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4771 pDecodePara, pvStructInfo, *pcbStructInfo);
4775 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4776 offsetof(CRL_DIST_POINTS_INFO, cDistPoint),
4777 offsetof(CRL_DIST_POINTS_INFO, rgDistPoint),
4778 sizeof(CRL_DIST_POINTS_INFO),
4779 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE,
4780 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) };
4782 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
4783 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
4787 SetLastError(STATUS_ACCESS_VIOLATION);
4794 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType,
4795 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4796 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4800 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4801 pDecodePara, pvStructInfo, *pcbStructInfo);
4805 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF,
4806 offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier),
4807 offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier),
4808 sizeof(CERT_ENHKEY_USAGE),
4809 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 };
4811 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
4812 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL);
4816 SetLastError(STATUS_ACCESS_VIOLATION);
4823 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
4824 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4825 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4829 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4830 pDecodePara, pvStructInfo, *pcbStructInfo);
4834 struct AsnDecodeSequenceItem items[] = {
4835 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT,
4836 DistPointName), CRYPT_AsnDecodeDistPointName,
4837 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE,
4838 offsetof(CRL_ISSUING_DIST_POINT,
4839 DistPointName.u.FullName.rgAltEntry), 0 },
4840 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT,
4841 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4843 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT,
4844 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE,
4846 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT,
4847 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal,
4848 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT,
4849 OnlySomeReasonFlags.pbData), 0 },
4850 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT,
4851 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
4854 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4855 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4856 pcbStructInfo, NULL, NULL);
4860 SetLastError(STATUS_ACCESS_VIOLATION);
4867 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded,
4868 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4873 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4874 pvStructInfo, *pcbStructInfo, pcbDecoded);
4878 SetLastError(CRYPT_E_ASN1_EOD);
4881 if (pbEncoded[0] != (ASN_CONTEXT | 1))
4883 SetLastError(CRYPT_E_ASN1_BADTAG);
4886 /* The BOOL is implicit: if the integer is present, then it's TRUE */
4887 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags,
4888 pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo,
4890 if (ret && pvStructInfo)
4891 *(BOOL *)pvStructInfo = TRUE;
4892 TRACE("returning %d\n", ret);
4896 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
4897 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4901 struct AsnDecodeSequenceItem items[] = {
4902 { 0, offsetof(CERT_GENERAL_SUBTREE, Base),
4903 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE,
4904 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 },
4905 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum),
4906 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 },
4907 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum),
4908 CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0,
4911 CERT_GENERAL_SUBTREE *subtree = pvStructInfo;
4913 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4914 pvStructInfo, *pcbStructInfo, pcbDecoded);
4916 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4917 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
4918 pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
4921 TRACE("%d\n", *pcbDecoded);
4922 if (*pcbDecoded < cbEncoded)
4923 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded),
4924 *(pbEncoded + *pcbDecoded + 1));
4926 TRACE("returning %d\n", ret);
4930 static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded,
4931 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4935 struct AsnArrayDescriptor arrayDesc = { 0,
4936 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
4937 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree),
4938 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
4940 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
4941 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
4943 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4944 pvStructInfo, *pcbStructInfo, pcbDecoded);
4946 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
4947 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
4951 static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded,
4952 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
4956 struct AsnArrayDescriptor arrayDesc = { 0,
4957 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4958 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree),
4959 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4960 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE,
4961 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) };
4963 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
4964 pvStructInfo, *pcbStructInfo, pcbDecoded);
4966 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
4967 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
4971 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
4972 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
4973 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
4977 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
4978 pDecodePara, pvStructInfo, *pcbStructInfo);
4982 struct AsnDecodeSequenceItem items[] = {
4983 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0,
4984 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree),
4985 CRYPT_AsnDecodePermittedSubtree,
4986 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree,
4987 cExcludedSubtree), TRUE, TRUE,
4988 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 },
4989 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1,
4990 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4991 CRYPT_AsnDecodeExcludedSubtree,
4992 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree),
4994 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
4997 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
4998 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
4999 pcbStructInfo, NULL, NULL);
5003 SetLastError(STATUS_ACCESS_VIOLATION);
5009 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
5010 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5014 struct AsnDecodeSequenceItem items[] = {
5015 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob,
5016 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER,
5018 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber),
5019 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE,
5020 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 },
5022 CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo;
5024 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5025 pvStructInfo, *pcbStructInfo, pcbDecoded);
5027 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5028 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5029 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
5030 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
5032 SetLastError(CRYPT_E_ASN1_CORRUPT);
5035 TRACE("returning %d\n", ret);
5039 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
5040 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5043 CMSG_SIGNER_INFO *info = pvStructInfo;
5044 struct AsnDecodeSequenceItem items[] = {
5045 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion),
5046 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5047 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer),
5048 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER),
5049 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 },
5050 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm),
5051 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5052 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5053 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5054 offsetof(CMSG_SIGNER_INFO, AuthAttrs),
5055 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5056 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5057 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm),
5058 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5059 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO,
5060 HashEncryptionAlgorithm.pszObjId), 0 },
5061 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash),
5062 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5063 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 },
5064 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5065 offsetof(CMSG_SIGNER_INFO, UnauthAttrs),
5066 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5067 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5071 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5072 pvStructInfo, *pcbStructInfo);
5074 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5075 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5076 pcbDecoded, info ? info->Issuer.pbData : NULL);
5080 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType,
5081 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5082 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5086 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5087 pDecodePara, pvStructInfo, *pcbStructInfo);
5091 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded,
5092 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5093 if (ret && pvStructInfo)
5095 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5096 pcbStructInfo, *pcbStructInfo);
5099 CMSG_SIGNER_INFO *info;
5101 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5102 pvStructInfo = *(BYTE **)pvStructInfo;
5103 info = pvStructInfo;
5104 info->Issuer.pbData = ((BYTE *)info +
5105 sizeof(CMSG_SIGNER_INFO));
5106 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded,
5107 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5108 pcbStructInfo, NULL);
5114 SetLastError(STATUS_ACCESS_VIOLATION);
5117 TRACE("returning %d\n", ret);
5121 static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded,
5122 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5126 struct AsnArrayDescriptor arrayDesc = { 0,
5127 offsetof(CRYPT_SIGNED_INFO, cCertEncoded),
5128 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded),
5129 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded),
5130 CRYPT_AsnDecodeCopyBytes,
5131 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5133 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5134 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5136 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5137 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5141 static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded,
5142 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5146 struct AsnArrayDescriptor arrayDesc = { 0,
5147 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded),
5148 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded),
5149 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content),
5150 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB),
5151 TRUE, offsetof(CRYPT_DER_BLOB, pbData) };
5153 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5154 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded);
5156 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5157 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5161 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded,
5162 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5165 CERT_ID *id = pvStructInfo;
5168 if (*pbEncoded == ASN_SEQUENCEOF)
5170 ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags,
5171 id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded);
5175 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5176 if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER))
5177 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5178 sizeof(CERT_ISSUER_SERIAL_NUMBER);
5180 *pcbStructInfo = sizeof(CERT_ID);
5183 else if (*pbEncoded == (ASN_CONTEXT | 0))
5185 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags,
5186 id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded);
5190 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5191 if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB))
5192 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo -
5193 sizeof(CRYPT_DATA_BLOB);
5195 *pcbStructInfo = sizeof(CERT_ID);
5199 SetLastError(CRYPT_E_ASN1_BADTAG);
5203 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
5204 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo,
5207 CMSG_CMS_SIGNER_INFO *info = pvStructInfo;
5208 struct AsnDecodeSequenceItem items[] = {
5209 { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion),
5210 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5211 { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId),
5212 CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE,
5213 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 },
5214 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm),
5215 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5216 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 },
5217 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5218 offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs),
5219 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5220 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 },
5221 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm),
5222 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER),
5223 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO,
5224 HashEncryptionAlgorithm.pszObjId), 0 },
5225 { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash),
5226 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB),
5227 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 },
5228 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5229 offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs),
5230 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES),
5231 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 },
5235 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5236 pvStructInfo, *pcbStructInfo);
5238 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5239 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
5240 pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
5244 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType,
5245 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5246 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5250 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5251 pDecodePara, pvStructInfo, *pcbStructInfo);
5255 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded,
5256 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL);
5257 if (ret && pvStructInfo)
5259 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo,
5260 pcbStructInfo, *pcbStructInfo);
5263 CMSG_CMS_SIGNER_INFO *info;
5265 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5266 pvStructInfo = *(BYTE **)pvStructInfo;
5267 info = pvStructInfo;
5268 info->SignerId.u.KeyId.pbData = ((BYTE *)info +
5269 sizeof(CMSG_CMS_SIGNER_INFO));
5270 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded,
5271 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo,
5272 pcbStructInfo, NULL);
5278 SetLastError(STATUS_ACCESS_VIOLATION);
5281 TRACE("returning %d\n", ret);
5285 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded,
5286 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded)
5289 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF,
5290 offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5291 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo),
5292 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo),
5293 CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE,
5294 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) };
5296 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
5297 pvStructInfo, *pcbStructInfo, pcbDecoded);
5299 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded,
5300 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded);
5304 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
5305 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
5306 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo)
5309 struct AsnDecodeSequenceItem items[] = {
5310 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version),
5311 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 },
5312 /* Placeholder for the hash algorithms - redundant with those in the
5313 * signers, so just ignore them.
5315 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 },
5316 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content),
5317 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO),
5318 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 },
5319 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0,
5320 offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded,
5321 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE,
5322 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 },
5323 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1,
5324 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded,
5325 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE,
5326 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 },
5327 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo),
5328 CRYPT_DecodeSignerArray,
5329 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE,
5330 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 },
5333 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
5334 pDecodePara, signedInfo, *pcbSignedInfo);
5336 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
5337 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
5339 TRACE("returning %d\n", ret);
5343 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
5344 LPCSTR lpszStructType)
5346 CryptDecodeObjectExFunc decodeFunc = NULL;
5348 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING
5349 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING)
5351 SetLastError(ERROR_FILE_NOT_FOUND);
5354 if (!HIWORD(lpszStructType))
5356 switch (LOWORD(lpszStructType))
5358 case LOWORD(X509_CERT):
5359 decodeFunc = CRYPT_AsnDecodeCertSignedContent;
5361 case LOWORD(X509_CERT_TO_BE_SIGNED):
5362 decodeFunc = CRYPT_AsnDecodeCert;
5364 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED):
5365 decodeFunc = CRYPT_AsnDecodeCRL;
5367 case LOWORD(X509_EXTENSIONS):
5368 decodeFunc = CRYPT_AsnDecodeExtensions;
5370 case LOWORD(X509_NAME_VALUE):
5371 decodeFunc = CRYPT_AsnDecodeNameValue;
5373 case LOWORD(X509_NAME):
5374 decodeFunc = CRYPT_AsnDecodeName;
5376 case LOWORD(X509_PUBLIC_KEY_INFO):
5377 decodeFunc = CRYPT_AsnDecodePubKeyInfo;
5379 case LOWORD(X509_AUTHORITY_KEY_ID):
5380 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5382 case LOWORD(X509_ALTERNATE_NAME):
5383 decodeFunc = CRYPT_AsnDecodeAltName;
5385 case LOWORD(X509_BASIC_CONSTRAINTS):
5386 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5388 case LOWORD(X509_BASIC_CONSTRAINTS2):
5389 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5391 case LOWORD(X509_CERT_POLICIES):
5392 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5394 case LOWORD(RSA_CSP_PUBLICKEYBLOB):
5395 decodeFunc = CRYPT_AsnDecodeRsaPubKey;
5397 case LOWORD(X509_UNICODE_NAME):
5398 decodeFunc = CRYPT_AsnDecodeUnicodeName;
5400 case LOWORD(PKCS_ATTRIBUTE):
5401 decodeFunc = CRYPT_AsnDecodePKCSAttribute;
5403 case LOWORD(X509_UNICODE_NAME_VALUE):
5404 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue;
5406 case LOWORD(X509_OCTET_STRING):
5407 decodeFunc = CRYPT_AsnDecodeOctets;
5409 case LOWORD(X509_BITS):
5410 case LOWORD(X509_KEY_USAGE):
5411 decodeFunc = CRYPT_AsnDecodeBits;
5413 case LOWORD(X509_INTEGER):
5414 decodeFunc = CRYPT_AsnDecodeInt;
5416 case LOWORD(X509_MULTI_BYTE_INTEGER):
5417 decodeFunc = CRYPT_AsnDecodeInteger;
5419 case LOWORD(X509_MULTI_BYTE_UINT):
5420 decodeFunc = CRYPT_AsnDecodeUnsignedInteger;
5422 case LOWORD(X509_ENUMERATED):
5423 decodeFunc = CRYPT_AsnDecodeEnumerated;
5425 case LOWORD(X509_CHOICE_OF_TIME):
5426 decodeFunc = CRYPT_AsnDecodeChoiceOfTime;
5428 case LOWORD(X509_AUTHORITY_KEY_ID2):
5429 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5431 case LOWORD(X509_AUTHORITY_INFO_ACCESS):
5432 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5434 case LOWORD(PKCS_CONTENT_INFO):
5435 decodeFunc = CRYPT_AsnDecodePKCSContentInfo;
5437 case LOWORD(X509_SEQUENCE_OF_ANY):
5438 decodeFunc = CRYPT_AsnDecodeSequenceOfAny;
5440 case LOWORD(PKCS_UTC_TIME):
5441 decodeFunc = CRYPT_AsnDecodeUtcTime;
5443 case LOWORD(X509_CRL_DIST_POINTS):
5444 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5446 case LOWORD(X509_ENHANCED_KEY_USAGE):
5447 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5449 case LOWORD(PKCS_CTL):
5450 decodeFunc = CRYPT_AsnDecodeCTL;
5452 case LOWORD(PKCS_SMIME_CAPABILITIES):
5453 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5455 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE):
5456 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5458 case LOWORD(PKCS_ATTRIBUTES):
5459 decodeFunc = CRYPT_AsnDecodePKCSAttributes;
5461 case LOWORD(X509_ISSUING_DIST_POINT):
5462 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5464 case LOWORD(X509_NAME_CONSTRAINTS):
5465 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5467 case LOWORD(PKCS7_SIGNER_INFO):
5468 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo;
5470 case LOWORD(CMS_SIGNER_INFO):
5471 decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
5475 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
5476 decodeFunc = CRYPT_AsnDecodeExtensions;
5477 else if (!strcmp(lpszStructType, szOID_RSA_signingTime))
5478 decodeFunc = CRYPT_AsnDecodeUtcTime;
5479 else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities))
5480 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities;
5481 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER))
5482 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId;
5483 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
5484 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2;
5485 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE))
5486 decodeFunc = CRYPT_AsnDecodeEnumerated;
5487 else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
5488 decodeFunc = CRYPT_AsnDecodeBits;
5489 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER))
5490 decodeFunc = CRYPT_AsnDecodeOctets;
5491 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS))
5492 decodeFunc = CRYPT_AsnDecodeBasicConstraints;
5493 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
5494 decodeFunc = CRYPT_AsnDecodeBasicConstraints2;
5495 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
5496 decodeFunc = CRYPT_AsnDecodeAltName;
5497 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
5498 decodeFunc = CRYPT_AsnDecodeAltName;
5499 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION))
5500 decodeFunc = CRYPT_AsnDecodeAltName;
5501 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
5502 decodeFunc = CRYPT_AsnDecodeAltName;
5503 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
5504 decodeFunc = CRYPT_AsnDecodeAltName;
5505 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
5506 decodeFunc = CRYPT_AsnDecodeCRLDistPoints;
5507 else if (!strcmp(lpszStructType, szOID_CERT_POLICIES))
5508 decodeFunc = CRYPT_AsnDecodeCertPolicies;
5509 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
5510 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage;
5511 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT))
5512 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint;
5513 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS))
5514 decodeFunc = CRYPT_AsnDecodeNameConstraints;
5515 else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
5516 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess;
5517 else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
5518 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
5519 else if (!strcmp(lpszStructType, szOID_CTL))
5520 decodeFunc = CRYPT_AsnDecodeCTL;
5524 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType,
5525 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5527 static HCRYPTOIDFUNCSET set = NULL;
5528 CryptDecodeObjectFunc decodeFunc = NULL;
5531 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
5532 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5533 (void **)&decodeFunc, hFunc);
5537 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType,
5538 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc)
5540 static HCRYPTOIDFUNCSET set = NULL;
5541 CryptDecodeObjectExFunc decodeFunc = NULL;
5544 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
5545 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
5546 (void **)&decodeFunc, hFunc);
5550 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5551 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
5552 DWORD *pcbStructInfo)
5555 CryptDecodeObjectFunc pCryptDecodeObject = NULL;
5556 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL;
5557 HCRYPTOIDFUNCADDR hFunc = NULL;
5559 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType,
5560 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
5561 pvStructInfo, pcbStructInfo);
5563 if (!pvStructInfo && !pcbStructInfo)
5565 SetLastError(ERROR_INVALID_PARAMETER);
5568 if (cbEncoded > MAX_ENCODED_LEN)
5570 SetLastError(CRYPT_E_ASN1_LARGE);
5574 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType,
5577 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5578 debugstr_a(lpszStructType));
5579 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType,
5580 lpszStructType, &hFunc);
5581 if (!pCryptDecodeObject)
5582 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType,
5583 lpszStructType, &hFunc);
5585 if (pCryptDecodeObject)
5586 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5587 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5588 else if (pCryptDecodeObjectEx)
5589 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType,
5590 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
5591 pvStructInfo, pcbStructInfo);
5593 CryptFreeOIDFunctionAddress(hFunc, 0);
5594 TRACE_(crypt)("returning %d\n", ret);
5598 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
5599 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
5600 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
5603 CryptDecodeObjectExFunc decodeFunc;
5604 HCRYPTOIDFUNCADDR hFunc = NULL;
5606 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5607 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
5608 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5610 if (!pvStructInfo && !pcbStructInfo)
5612 SetLastError(ERROR_INVALID_PARAMETER);
5615 if (cbEncoded > MAX_ENCODED_LEN)
5617 SetLastError(CRYPT_E_ASN1_LARGE);
5621 SetLastError(NOERROR);
5622 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG && pvStructInfo)
5623 *(BYTE **)pvStructInfo = NULL;
5624 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType);
5627 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n",
5628 debugstr_a(lpszStructType));
5629 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType,
5633 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
5634 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
5637 CryptDecodeObjectFunc pCryptDecodeObject =
5638 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc);
5640 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5641 * directly, as that could cause an infinite loop.
5643 if (pCryptDecodeObject)
5645 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
5647 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5648 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo);
5649 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara,
5650 pvStructInfo, pcbStructInfo, *pcbStructInfo)))
5651 ret = pCryptDecodeObject(dwCertEncodingType,
5652 lpszStructType, pbEncoded, cbEncoded, dwFlags,
5653 *(BYTE **)pvStructInfo, pcbStructInfo);
5656 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
5657 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
5661 CryptFreeOIDFunctionAddress(hFunc, 0);
5662 TRACE_(crypt)("returning %d\n", ret);
5666 BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX)
5670 TRACE_(crypt)("(%p)\n", pPFX);
5672 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
5673 * version integer of length 1 (3 encoded byes) and at least one other
5674 * datum (two encoded bytes), plus at least two bytes for the outer
5675 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
5677 if (pPFX->cbData < 7)
5679 else if (pPFX->pbData[0] == ASN_SEQUENCE)
5683 if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len)))
5685 BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]);
5687 /* Need at least three bytes for the integer version */
5688 if (pPFX->cbData < 1 + lenLen + 3)
5690 else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */
5691 pPFX->pbData[1 + lenLen + 1] != 1 || /* Definite length */
5692 pPFX->pbData[1 + lenLen + 2] != 3) /* PFX version */
5701 HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword,
5704 FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags);