2 * Copyright 2005-2009 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
61 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
62 DWORD
, DWORD
, void *, DWORD
*);
63 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
64 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
66 /* Internal decoders don't do memory allocation or exception handling, and
67 * they report how many bytes they decoded.
69 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
70 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
72 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
73 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
75 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
76 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
78 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
80 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
81 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
82 /* Assumes algo->Parameters.pbData is set ahead of time. */
83 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
84 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
85 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
86 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
87 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
88 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
89 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
91 /* Doesn't check the tag, assumes the caller does so */
92 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
93 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
94 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
95 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
96 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
97 * member has been initialized, doesn't do exception handling, and doesn't do
98 * memory allocation. Also doesn't check tag, assumes the caller has checked
101 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
102 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
104 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
105 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
106 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
108 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
109 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
112 /* Gets the number of length bytes from the given (leading) length byte */
113 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
115 /* Helper function to get the encoded length of the data starting at pbEncoded,
116 * where pbEncoded[0] is the tag. If the data are too short to contain a
117 * length or if the length is too large for cbEncoded, sets an appropriate
118 * error code and returns FALSE. If the encoded length is unknown due to
119 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
121 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
128 SetLastError(CRYPT_E_ASN1_CORRUPT
);
131 else if (pbEncoded
[1] <= 0x7f)
133 if (pbEncoded
[1] + 1 > cbEncoded
)
135 SetLastError(CRYPT_E_ASN1_EOD
);
144 else if (pbEncoded
[1] == 0x80)
146 *len
= CMSG_INDEFINITE_LENGTH
;
151 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
153 if (lenLen
> sizeof(DWORD
) + 1)
155 SetLastError(CRYPT_E_ASN1_LARGE
);
158 else if (lenLen
+ 2 > cbEncoded
)
160 SetLastError(CRYPT_E_ASN1_CORRUPT
);
173 if (out
+ lenLen
+ 1 > cbEncoded
)
175 SetLastError(CRYPT_E_ASN1_EOD
);
188 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
189 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
193 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
194 *len
== CMSG_INDEFINITE_LENGTH
)
196 SetLastError(CRYPT_E_ASN1_CORRUPT
);
202 /* Helper function to check *pcbStructInfo, set it to the required size, and
203 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
204 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
205 * pointer to the newly allocated memory.
207 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
208 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
213 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
215 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
216 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
218 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
219 if (!*(BYTE
**)pvStructInfo
)
222 *pcbStructInfo
= bytesNeeded
;
224 else if (*pcbStructInfo
< bytesNeeded
)
226 *pcbStructInfo
= bytesNeeded
;
227 SetLastError(ERROR_MORE_DATA
);
231 *pcbStructInfo
= bytesNeeded
;
235 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara
, LPVOID pv
)
237 if (pDecodePara
&& pDecodePara
->pfnFree
)
238 pDecodePara
->pfnFree(pv
);
243 /* Helper function to check *pcbStructInfo and set it to the required size.
244 * Assumes pvStructInfo is not NULL.
246 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
250 if (*pcbStructInfo
< bytesNeeded
)
252 *pcbStructInfo
= bytesNeeded
;
253 SetLastError(ERROR_MORE_DATA
);
258 *pcbStructInfo
= bytesNeeded
;
265 * The expected tag of the item. If tag is 0, decodeFunc is called
266 * regardless of the tag value seen.
268 * A sequence is decoded into a struct. The offset member is the
269 * offset of this item within that struct.
271 * The decoder function to use. If this is NULL, then the member isn't
272 * decoded, but minSize space is reserved for it.
274 * The minimum amount of space occupied after decoding. You must set this.
276 * If true, and the tag doesn't match the expected tag for this item,
277 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
278 * filled with 0 for this member.
279 * hasPointer, pointerOffset:
280 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
281 * the offset within the struct of the data pointer (or to the
282 * first data pointer, if more than one exist).
284 * Used by CRYPT_AsnDecodeSequence, not for your use.
286 struct AsnDecodeSequenceItem
290 InternalDecodeFunc decodeFunc
;
298 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
299 #define MEMBERSIZE(s, member, nextmember) \
300 (offsetof(s, nextmember) - offsetof(s, member))
302 /* Decodes the items in a sequence, where the items are described in items,
303 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
304 * pvStructInfo. nextData is a pointer to the memory location at which the
305 * first decoded item with a dynamic pointer should point.
306 * Upon decoding, *cbDecoded is the total number of bytes decoded.
307 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
309 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
310 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
311 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
314 DWORD i
, decoded
= 0;
315 const BYTE
*ptr
= pbEncoded
;
317 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
318 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
320 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
322 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
326 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
327 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
329 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
331 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
333 DWORD itemEncodedLen
;
335 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
336 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
338 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
339 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
341 TRACE("Setting next pointer to %p\n",
343 *(BYTE
**)((BYTE
*)pvStructInfo
+
344 items
[i
].pointerOffset
) = nextData
;
346 if (items
[i
].decodeFunc
)
351 TRACE("decoding item %d\n", i
);
353 TRACE("sizing item %d\n", i
);
354 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
355 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
356 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
357 : NULL
, &items
[i
].size
, &itemDecoded
);
360 /* Account for alignment padding */
361 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
362 TRACE("item %d size: %d\n", i
, items
[i
].size
);
363 if (nextData
&& items
[i
].hasPointer
&&
364 items
[i
].size
> items
[i
].minSize
)
365 nextData
+= items
[i
].size
- items
[i
].minSize
;
366 if (itemDecoded
> itemEncodedLen
)
368 WARN("decoded length %d exceeds encoded %d\n",
369 itemDecoded
, itemEncodedLen
);
370 SetLastError(CRYPT_E_ASN1_CORRUPT
);
376 decoded
+= itemDecoded
;
377 TRACE("item %d: decoded %d bytes\n", i
,
381 else if (items
[i
].optional
&&
382 GetLastError() == CRYPT_E_ASN1_BADTAG
)
384 TRACE("skipping optional item %d\n", i
);
385 items
[i
].size
= items
[i
].minSize
;
386 SetLastError(NOERROR
);
390 TRACE("item %d failed: %08x\n", i
,
393 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
395 ERR("can't use indefinite length encoding without a decoder\n");
396 SetLastError(CRYPT_E_ASN1_CORRUPT
);
401 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
402 ptr
+= itemEncodedLen
;
403 decoded
+= itemEncodedLen
;
404 items
[i
].size
= items
[i
].minSize
;
407 else if (items
[i
].optional
)
409 TRACE("skipping optional item %d\n", i
);
410 items
[i
].size
= items
[i
].minSize
;
414 TRACE("item %d: tag %02x doesn't match expected %02x\n",
415 i
, ptr
[0], items
[i
].tag
);
416 SetLastError(CRYPT_E_ASN1_BADTAG
);
421 else if (items
[i
].optional
)
423 TRACE("missing optional item %d, skipping\n", i
);
424 items
[i
].size
= items
[i
].minSize
;
428 TRACE("not enough bytes for item %d, failing\n", i
);
429 SetLastError(CRYPT_E_ASN1_CORRUPT
);
434 *cbDecoded
= decoded
;
435 TRACE("returning %d\n", ret
);
439 /* This decodes an arbitrary sequence into a contiguous block of memory
440 * (basically, a struct.) Each element being decoded is described by a struct
441 * AsnDecodeSequenceItem, see above.
442 * startingPointer is an optional pointer to the first place where dynamic
443 * data will be stored. If you know the starting offset, you may pass it
444 * here. Otherwise, pass NULL, and one will be inferred from the items.
446 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
447 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
448 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
449 DWORD
*pcbDecoded
, void *startingPointer
)
453 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
454 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
459 SetLastError(CRYPT_E_ASN1_EOD
);
462 if (pbEncoded
[0] == ASN_SEQUENCE
)
466 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
468 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
469 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
470 BOOL indefinite
= FALSE
;
472 cbEncoded
-= 1 + lenBytes
;
473 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
478 else if (cbEncoded
< dataLen
)
480 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
482 SetLastError(CRYPT_E_ASN1_CORRUPT
);
487 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
488 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
489 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
491 if (cbDecoded
> cbEncoded
- 2)
493 /* Not enough space for 0 TLV */
494 SetLastError(CRYPT_E_ASN1_CORRUPT
);
497 else if (*(ptr
+ cbDecoded
) != 0 ||
498 *(ptr
+ cbDecoded
+ 1) != 0)
500 TRACE("expected 0 TLV\n");
501 SetLastError(CRYPT_E_ASN1_CORRUPT
);
508 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
510 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
512 SetLastError(CRYPT_E_ASN1_CORRUPT
);
517 DWORD i
, bytesNeeded
= 0, structSize
= 0;
519 for (i
= 0; i
< cItem
; i
++)
521 bytesNeeded
+= items
[i
].size
;
522 structSize
= max( structSize
, items
[i
].offset
+ items
[i
].minSize
);
525 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
527 *pcbStructInfo
= bytesNeeded
;
528 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
529 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
533 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
534 pvStructInfo
= *(BYTE
**)pvStructInfo
;
536 nextData
= startingPointer
;
538 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
539 memset(pvStructInfo
, 0, structSize
);
540 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
541 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
543 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
544 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
551 SetLastError(CRYPT_E_ASN1_BADTAG
);
554 TRACE("returning %d (%08x)\n", ret
, GetLastError());
559 * The expected tag of the entire encoded array (usually a variant
560 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
561 * regardless of the tag seen.
563 * The offset within the outer structure at which the count exists.
564 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
565 * while CRYPT_ATTRIBUTE has countOffset ==
566 * offsetof(CRYPT_ATTRIBUTE, cValue).
568 * The offset within the outer structure at which the array pointer exists.
569 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
570 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
572 * The minimum size of the decoded array. On WIN32, this is always 8:
573 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
576 * used to decode each item in the array
578 * is the minimum size of each decoded item
580 * indicates whether each item has a dynamic pointer
582 * indicates the offset within itemSize at which the pointer exists
584 struct AsnArrayDescriptor
590 InternalDecodeFunc decodeFunc
;
596 struct AsnArrayItemSize
602 /* Decodes an array of like types into a structure described by a struct
603 * AsnArrayDescriptor.
605 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
606 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
607 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
612 TRACE("%p, %p, %d, %p, %d\n", arrayDesc
, pbEncoded
,
613 cbEncoded
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
617 SetLastError(CRYPT_E_ASN1_EOD
);
620 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
624 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
626 DWORD bytesNeeded
= arrayDesc
->minArraySize
, cItems
= 0, decoded
;
627 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
628 /* There can be arbitrarily many items, but there is often only one.
630 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
632 decoded
= 1 + lenBytes
;
636 BOOL doneDecoding
= FALSE
;
638 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
640 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
647 SetLastError(CRYPT_E_ASN1_CORRUPT
);
654 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
658 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
660 /* Each item decoded may not tolerate extraneous bytes,
661 * so get the length of the next element if known.
663 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
664 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
666 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
667 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
669 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
673 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
674 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
679 if (itemSizes
!= &itemSize
)
680 itemSizes
= CryptMemRealloc(itemSizes
,
681 cItems
* sizeof(struct AsnArrayItemSize
));
686 cItems
* sizeof(struct AsnArrayItemSize
));
688 memcpy(itemSizes
, &itemSize
,
693 decoded
+= itemDecoded
;
694 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
695 itemSizes
[cItems
- 1].size
= size
;
708 *pcbDecoded
= decoded
;
710 *pcbStructInfo
= bytesNeeded
;
711 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
712 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
719 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
720 pvStructInfo
= *(void **)pvStructInfo
;
721 pcItems
= pvStructInfo
;
723 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
725 rgItems
= (BYTE
*)pvStructInfo
+
726 arrayDesc
->minArraySize
;
727 *(void **)((BYTE
*)pcItems
-
728 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
) =
732 rgItems
= *(void **)((BYTE
*)pcItems
-
733 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
);
734 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
735 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
736 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
741 if (arrayDesc
->hasPointer
)
742 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
743 + arrayDesc
->pointerOffset
) = nextData
;
744 ret
= arrayDesc
->decodeFunc(ptr
,
745 itemSizes
[i
].encodedLen
,
746 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
747 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
748 &itemSizes
[i
].size
, &itemDecoded
);
751 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
757 if (itemSizes
!= &itemSize
)
758 CryptMemFree(itemSizes
);
763 SetLastError(CRYPT_E_ASN1_BADTAG
);
769 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
770 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
771 * to CRYPT_E_ASN1_CORRUPT.
772 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
775 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
776 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
781 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
783 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
784 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
786 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
787 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
790 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
792 *pcbStructInfo
= bytesNeeded
;
793 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
795 CRYPT_DER_BLOB
*blob
;
797 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
798 pvStructInfo
= *(BYTE
**)pvStructInfo
;
800 blob
->cbData
= 1 + lenBytes
+ dataLen
;
803 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
804 blob
->pbData
= (BYTE
*)pbEncoded
;
807 assert(blob
->pbData
);
808 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
813 SetLastError(CRYPT_E_ASN1_CORRUPT
);
821 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
822 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
823 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
828 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
829 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
831 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
834 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
835 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
837 if (ret
&& pvStructInfo
)
839 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
846 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
848 temp
= blob
->pbData
[i
];
849 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
850 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
854 TRACE("returning %d (%08x)\n", ret
, GetLastError());
858 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
859 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
860 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
864 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
865 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
869 struct AsnDecodeSequenceItem items
[] = {
870 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
871 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
872 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
873 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
874 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
875 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
876 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
877 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
878 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
879 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
882 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
883 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
884 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
885 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
886 pcbStructInfo
, NULL
, NULL
);
890 SetLastError(STATUS_ACCESS_VIOLATION
);
895 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
899 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
900 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
905 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
907 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
909 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
910 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
912 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
917 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
918 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
922 struct AsnDecodeSequenceItem items
[] = {
923 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
924 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
925 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
926 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
929 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
930 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
935 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
936 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
940 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
941 offsetof(CERT_INFO
, cExtension
), offsetof(CERT_INFO
, rgExtension
),
942 FINALMEMBERSIZE(CERT_INFO
, cExtension
),
943 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
944 offsetof(CERT_EXTENSION
, pszObjId
) };
946 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
947 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
949 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
950 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
954 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
955 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
961 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
963 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
965 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
966 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
967 if (ret
&& pcbDecoded
)
968 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
973 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
974 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
975 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
978 struct AsnDecodeSequenceItem items
[] = {
979 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
980 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
981 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
982 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
983 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
984 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
985 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
986 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
987 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
988 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
990 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
991 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
993 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
994 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
996 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
997 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
998 FALSE
, TRUE
, offsetof(CERT_INFO
,
999 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
1000 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
1001 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1002 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
1003 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
1004 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1005 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
1006 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
1007 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
1008 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1011 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1012 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1014 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1015 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1017 if (ret
&& pvStructInfo
)
1021 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1022 info
= *(CERT_INFO
**)pvStructInfo
;
1024 info
= pvStructInfo
;
1025 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1026 !info
->Subject
.cbData
)
1028 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1029 /* Don't need to deallocate, because it should have failed on the
1030 * first pass (and no memory was allocated.)
1036 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1040 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1041 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1042 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1046 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1047 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1053 /* Unless told not to, first try to decode it as a signed cert. */
1054 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1056 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1058 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1059 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1060 &signedCert
, &size
);
1064 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1065 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1066 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1067 pvStructInfo
, pcbStructInfo
);
1068 LocalFree(signedCert
);
1071 /* Failing that, try it as an unsigned cert */
1075 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1076 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1077 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1082 SetLastError(STATUS_ACCESS_VIOLATION
);
1086 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1090 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1091 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1095 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1096 offsetof(CRL_ENTRY
, cExtension
), offsetof(CRL_ENTRY
, rgExtension
),
1097 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
),
1098 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1099 offsetof(CERT_EXTENSION
, pszObjId
) };
1101 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1102 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1104 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1105 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1109 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1110 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1113 struct AsnDecodeSequenceItem items
[] = {
1114 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1115 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1116 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1117 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1118 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1119 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1120 CRYPT_AsnDecodeCRLEntryExtensions
,
1121 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1122 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1124 PCRL_ENTRY entry
= pvStructInfo
;
1126 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1129 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1130 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1131 entry
? entry
->SerialNumber
.pbData
: NULL
);
1132 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1134 WARN("empty CRL entry serial number\n");
1135 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1141 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1142 * whose rgCRLEntry member has been set prior to calling.
1144 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1145 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1148 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1149 offsetof(CRL_INFO
, cCRLEntry
), offsetof(CRL_INFO
, rgCRLEntry
),
1150 MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1151 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1152 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1154 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1155 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1157 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1158 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1159 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1163 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1164 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1168 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1169 offsetof(CRL_INFO
, cExtension
), offsetof(CRL_INFO
, rgExtension
),
1170 FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1171 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1172 offsetof(CERT_EXTENSION
, pszObjId
) };
1174 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1175 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1177 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1178 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1182 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1183 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1189 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1191 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1193 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1194 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1195 if (ret
&& pcbDecoded
)
1196 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1201 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1202 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1203 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1205 struct AsnDecodeSequenceItem items
[] = {
1206 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1207 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1208 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1209 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1210 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1211 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1212 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1214 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1215 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1216 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1217 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1218 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1219 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1220 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1221 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1222 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1223 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1227 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1228 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1230 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1231 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1234 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1238 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1239 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1240 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1244 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1245 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1251 /* Unless told not to, first try to decode it as a signed crl. */
1252 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1254 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1256 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1257 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1262 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1263 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1264 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1265 pvStructInfo
, pcbStructInfo
);
1266 LocalFree(signedCrl
);
1269 /* Failing that, try it as an unsigned crl */
1273 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1274 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1275 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1280 SetLastError(STATUS_ACCESS_VIOLATION
);
1284 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1288 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1289 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1294 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1295 pvStructInfo
, *pcbStructInfo
);
1297 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1299 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1300 DWORD bytesNeeded
= sizeof(LPSTR
);
1304 /* The largest possible string for the first two components
1305 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1310 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1311 pbEncoded
[1 + lenBytes
] / 40,
1312 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1314 bytesNeeded
+= strlen(firstTwo
) + 1;
1315 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1316 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1318 /* large enough for ".4000000" */
1322 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1329 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1332 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1339 snprintf(str
, sizeof(str
), ".%d", val
);
1340 bytesNeeded
+= strlen(str
);
1345 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1347 *pcbStructInfo
= bytesNeeded
;
1348 else if (*pcbStructInfo
< bytesNeeded
)
1350 *pcbStructInfo
= bytesNeeded
;
1351 SetLastError(ERROR_MORE_DATA
);
1359 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1362 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1363 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1365 pszObjId
+= strlen(pszObjId
);
1366 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1367 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1371 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1380 sprintf(pszObjId
, ".%d", val
);
1381 pszObjId
+= strlen(pszObjId
);
1385 *(LPSTR
*)pvStructInfo
= NULL
;
1386 *pcbStructInfo
= bytesNeeded
;
1392 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1393 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1397 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1398 pvStructInfo
, *pcbStructInfo
);
1400 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1401 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1402 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1405 SetLastError(CRYPT_E_ASN1_BADTAG
);
1411 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1412 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1414 struct AsnDecodeSequenceItem items
[] = {
1415 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1416 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1417 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1418 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1419 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1420 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1421 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1422 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1425 PCERT_EXTENSION ext
= pvStructInfo
;
1427 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1431 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1432 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1433 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1434 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1436 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1437 debugstr_a(ext
->pszObjId
));
1438 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1442 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1443 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1444 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1448 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1449 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1453 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1454 offsetof(CERT_EXTENSIONS
, cExtension
),
1455 offsetof(CERT_EXTENSIONS
, rgExtension
),
1456 sizeof(CERT_EXTENSIONS
),
1457 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1458 offsetof(CERT_EXTENSION
, pszObjId
) };
1460 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1461 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1465 SetLastError(STATUS_ACCESS_VIOLATION
);
1472 /* Warning: this assumes the address of value->Value.pbData is already set, in
1473 * order to avoid overwriting memory. (In some cases, it may change it, if it
1474 * doesn't copy anything to memory.) Be sure to set it correctly!
1476 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1477 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1482 CERT_NAME_VALUE
*value
= pvStructInfo
;
1484 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1486 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1487 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1489 switch (pbEncoded
[0])
1491 case ASN_OCTETSTRING
:
1492 valueType
= CERT_RDN_OCTET_STRING
;
1493 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1494 bytesNeeded
+= dataLen
;
1496 case ASN_NUMERICSTRING
:
1497 valueType
= CERT_RDN_NUMERIC_STRING
;
1498 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1499 bytesNeeded
+= dataLen
;
1501 case ASN_PRINTABLESTRING
:
1502 valueType
= CERT_RDN_PRINTABLE_STRING
;
1503 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1504 bytesNeeded
+= dataLen
;
1507 valueType
= CERT_RDN_IA5_STRING
;
1508 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1509 bytesNeeded
+= dataLen
;
1512 valueType
= CERT_RDN_T61_STRING
;
1513 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1514 bytesNeeded
+= dataLen
;
1516 case ASN_VIDEOTEXSTRING
:
1517 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1518 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1519 bytesNeeded
+= dataLen
;
1521 case ASN_GRAPHICSTRING
:
1522 valueType
= CERT_RDN_GRAPHIC_STRING
;
1523 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1524 bytesNeeded
+= dataLen
;
1526 case ASN_VISIBLESTRING
:
1527 valueType
= CERT_RDN_VISIBLE_STRING
;
1528 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1529 bytesNeeded
+= dataLen
;
1531 case ASN_GENERALSTRING
:
1532 valueType
= CERT_RDN_GENERAL_STRING
;
1533 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1534 bytesNeeded
+= dataLen
;
1536 case ASN_UNIVERSALSTRING
:
1537 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1538 SetLastError(CRYPT_E_ASN1_BADTAG
);
1541 valueType
= CERT_RDN_BMP_STRING
;
1542 bytesNeeded
+= dataLen
;
1544 case ASN_UTF8STRING
:
1545 valueType
= CERT_RDN_UTF8_STRING
;
1546 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1547 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1550 SetLastError(CRYPT_E_ASN1_BADTAG
);
1555 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1557 *pcbStructInfo
= bytesNeeded
;
1558 else if (*pcbStructInfo
< bytesNeeded
)
1560 *pcbStructInfo
= bytesNeeded
;
1561 SetLastError(ERROR_MORE_DATA
);
1566 *pcbStructInfo
= bytesNeeded
;
1567 value
->dwValueType
= valueType
;
1572 assert(value
->Value
.pbData
);
1573 switch (pbEncoded
[0])
1575 case ASN_OCTETSTRING
:
1576 case ASN_NUMERICSTRING
:
1577 case ASN_PRINTABLESTRING
:
1580 case ASN_VIDEOTEXSTRING
:
1581 case ASN_GRAPHICSTRING
:
1582 case ASN_VISIBLESTRING
:
1583 case ASN_GENERALSTRING
:
1584 value
->Value
.cbData
= dataLen
;
1587 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1588 memcpy(value
->Value
.pbData
,
1589 pbEncoded
+ 1 + lenBytes
, dataLen
);
1591 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1597 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1599 value
->Value
.cbData
= dataLen
;
1600 for (i
= 0; i
< dataLen
/ 2; i
++)
1601 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1602 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1605 case ASN_UTF8STRING
:
1607 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1609 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1610 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1611 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1618 value
->Value
.cbData
= 0;
1619 value
->Value
.pbData
= NULL
;
1626 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1627 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1628 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1634 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1635 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1636 if (ret
&& pvStructInfo
)
1638 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1639 pcbStructInfo
, *pcbStructInfo
);
1642 CERT_NAME_VALUE
*value
;
1644 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1645 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1646 value
= pvStructInfo
;
1647 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1648 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1649 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1650 pcbStructInfo
, NULL
);
1656 SetLastError(STATUS_ACCESS_VIOLATION
);
1663 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1664 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1669 CERT_NAME_VALUE
*value
= pvStructInfo
;
1671 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1673 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1674 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1676 switch (pbEncoded
[0])
1678 case ASN_NUMERICSTRING
:
1679 valueType
= CERT_RDN_NUMERIC_STRING
;
1681 bytesNeeded
+= (dataLen
+ 1) * 2;
1683 case ASN_PRINTABLESTRING
:
1684 valueType
= CERT_RDN_PRINTABLE_STRING
;
1686 bytesNeeded
+= (dataLen
+ 1) * 2;
1689 valueType
= CERT_RDN_IA5_STRING
;
1691 bytesNeeded
+= (dataLen
+ 1) * 2;
1694 valueType
= CERT_RDN_T61_STRING
;
1696 bytesNeeded
+= (dataLen
+ 1) * 2;
1698 case ASN_VIDEOTEXSTRING
:
1699 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1701 bytesNeeded
+= (dataLen
+ 1) * 2;
1703 case ASN_GRAPHICSTRING
:
1704 valueType
= CERT_RDN_GRAPHIC_STRING
;
1706 bytesNeeded
+= (dataLen
+ 1) * 2;
1708 case ASN_VISIBLESTRING
:
1709 valueType
= CERT_RDN_VISIBLE_STRING
;
1711 bytesNeeded
+= (dataLen
+ 1) * 2;
1713 case ASN_GENERALSTRING
:
1714 valueType
= CERT_RDN_GENERAL_STRING
;
1716 bytesNeeded
+= (dataLen
+ 1) * 2;
1718 case ASN_UNIVERSALSTRING
:
1719 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1721 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1724 valueType
= CERT_RDN_BMP_STRING
;
1726 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1728 case ASN_UTF8STRING
:
1729 valueType
= CERT_RDN_UTF8_STRING
;
1731 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1732 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1735 SetLastError(CRYPT_E_ASN1_BADTAG
);
1740 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1742 *pcbStructInfo
= bytesNeeded
;
1743 else if (*pcbStructInfo
< bytesNeeded
)
1745 *pcbStructInfo
= bytesNeeded
;
1746 SetLastError(ERROR_MORE_DATA
);
1751 *pcbStructInfo
= bytesNeeded
;
1752 value
->dwValueType
= valueType
;
1756 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1758 assert(value
->Value
.pbData
);
1759 switch (pbEncoded
[0])
1761 case ASN_NUMERICSTRING
:
1762 case ASN_PRINTABLESTRING
:
1765 case ASN_VIDEOTEXSTRING
:
1766 case ASN_GRAPHICSTRING
:
1767 case ASN_VISIBLESTRING
:
1768 case ASN_GENERALSTRING
:
1769 value
->Value
.cbData
= dataLen
* 2;
1770 for (i
= 0; i
< dataLen
; i
++)
1771 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1774 case ASN_UNIVERSALSTRING
:
1775 value
->Value
.cbData
= dataLen
/ 2;
1776 for (i
= 0; i
< dataLen
/ 4; i
++)
1777 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1778 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1782 value
->Value
.cbData
= dataLen
;
1783 for (i
= 0; i
< dataLen
/ 2; i
++)
1784 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1785 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1788 case ASN_UTF8STRING
:
1789 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1790 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1791 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1792 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1793 value
->Value
.cbData
+= sizeof(WCHAR
);
1799 value
->Value
.cbData
= 0;
1800 value
->Value
.pbData
= NULL
;
1807 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1808 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1809 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1815 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1816 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1817 if (ret
&& pvStructInfo
)
1819 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1820 pcbStructInfo
, *pcbStructInfo
);
1823 CERT_NAME_VALUE
*value
;
1825 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1826 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1827 value
= pvStructInfo
;
1828 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1829 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1830 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1831 pcbStructInfo
, NULL
);
1837 SetLastError(STATUS_ACCESS_VIOLATION
);
1844 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1845 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1848 struct AsnDecodeSequenceItem items
[] = {
1849 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1850 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1851 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1852 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1853 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1854 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1856 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1858 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1859 pvStructInfo
, *pcbStructInfo
);
1862 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1863 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1864 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1865 attr
? attr
->pszObjId
: NULL
);
1868 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1869 debugstr_a(attr
->pszObjId
));
1870 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1872 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1876 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1877 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1880 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1881 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1883 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1884 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1886 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1887 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1891 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1892 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1893 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1899 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1900 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1901 sizeof(CERT_NAME_INFO
),
1902 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1903 offsetof(CERT_RDN
, rgRDNAttr
) };
1905 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1906 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1910 SetLastError(STATUS_ACCESS_VIOLATION
);
1917 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1918 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1922 struct AsnDecodeSequenceItem items
[] = {
1923 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1924 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1925 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1926 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1927 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1928 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1930 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1932 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1933 pvStructInfo
, *pcbStructInfo
);
1936 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1937 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1938 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1939 attr
? attr
->pszObjId
: NULL
);
1942 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1943 debugstr_a(attr
->pszObjId
));
1944 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1946 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1950 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1951 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1954 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1955 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1957 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1958 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1960 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1961 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1965 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1966 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1967 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1973 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1974 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1975 sizeof(CERT_NAME_INFO
),
1976 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1977 offsetof(CERT_RDN
, rgRDNAttr
) };
1979 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1980 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1984 SetLastError(STATUS_ACCESS_VIOLATION
);
1991 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1994 BOOL ret
= TRUE
, done
= FALSE
;
1995 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
1997 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2004 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2007 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2009 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2011 indefiniteNestingLevels
++;
2012 pbEncoded
+= 1 + lenBytes
;
2013 cbEncoded
-= 1 + lenBytes
;
2014 decoded
+= 1 + lenBytes
;
2015 TRACE("indefiniteNestingLevels = %d\n",
2016 indefiniteNestingLevels
);
2020 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2021 indefiniteNestingLevels
)
2023 indefiniteNestingLevels
--;
2024 TRACE("indefiniteNestingLevels = %d\n",
2025 indefiniteNestingLevels
);
2027 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2028 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2029 decoded
+= 1 + lenBytes
+ dataLen
;
2030 if (!indefiniteNestingLevels
)
2034 } while (ret
&& !done
);
2035 /* If we haven't found all 0 TLVs, we haven't found the end */
2036 if (ret
&& indefiniteNestingLevels
)
2038 SetLastError(CRYPT_E_ASN1_EOD
);
2042 *pcbDecoded
= decoded
;
2043 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2047 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2048 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2052 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2054 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2055 pvStructInfo
, *pcbStructInfo
);
2057 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2059 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2060 bytesNeeded
+= encodedLen
;
2062 *pcbStructInfo
= bytesNeeded
;
2063 else if (*pcbStructInfo
< bytesNeeded
)
2065 SetLastError(ERROR_MORE_DATA
);
2066 *pcbStructInfo
= bytesNeeded
;
2071 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2073 *pcbStructInfo
= bytesNeeded
;
2074 blob
->cbData
= encodedLen
;
2077 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2078 blob
->pbData
= (LPBYTE
)pbEncoded
;
2081 assert(blob
->pbData
);
2082 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2086 blob
->pbData
= NULL
;
2089 *pcbDecoded
= encodedLen
;
2094 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2095 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2098 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2099 offsetof(CTL_USAGE
, cUsageIdentifier
),
2100 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2102 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2104 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2105 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2109 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2110 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2113 struct AsnArrayDescriptor arrayDesc
= { 0,
2114 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2115 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2116 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2117 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2120 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2121 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2125 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2126 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2128 struct AsnDecodeSequenceItem items
[] = {
2129 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2130 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2131 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2132 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2133 CRYPT_AsnDecodeCTLEntryAttributes
,
2134 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2135 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2138 CTL_ENTRY
*entry
= pvStructInfo
;
2140 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2143 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2144 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2145 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2149 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2150 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2153 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2154 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2155 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2156 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2157 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2159 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2160 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2162 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2163 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2167 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2168 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2172 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2173 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2174 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2175 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2176 offsetof(CERT_EXTENSION
, pszObjId
) };
2178 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2179 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2181 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2182 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2186 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2187 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2193 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2195 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2197 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2198 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2199 if (ret
&& pcbDecoded
)
2200 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2205 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2206 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2207 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2211 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2212 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2216 struct AsnDecodeSequenceItem items
[] = {
2217 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2218 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2219 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2220 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2221 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2222 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2223 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2224 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2225 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2226 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2227 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2228 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2229 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2231 { 0, offsetof(CTL_INFO
, NextUpdate
),
2232 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2234 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2235 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2236 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2237 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2238 CRYPT_AsnDecodeCTLEntries
,
2239 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2240 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2241 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2242 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2243 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2246 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2247 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2248 pcbStructInfo
, NULL
, NULL
);
2252 SetLastError(STATUS_ACCESS_VIOLATION
);
2258 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2259 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2263 struct AsnDecodeSequenceItem items
[] = {
2264 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2265 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2266 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2267 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2268 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2269 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2271 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2273 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2274 pvStructInfo
, *pcbStructInfo
);
2276 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2277 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2278 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2279 TRACE("returning %d\n", ret
);
2283 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2284 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2285 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2289 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2290 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2294 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2295 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2296 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2297 sizeof(CRYPT_SMIME_CAPABILITIES
),
2298 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2299 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2301 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2302 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2306 SetLastError(STATUS_ACCESS_VIOLATION
);
2309 TRACE("returning %d\n", ret
);
2313 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2314 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2319 LPSTR
*pStr
= pvStructInfo
;
2321 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2323 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2324 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2326 if (pbEncoded
[0] != ASN_IA5STRING
)
2328 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2333 bytesNeeded
+= dataLen
;
2335 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2337 *pcbStructInfo
= bytesNeeded
;
2338 else if (*pcbStructInfo
< bytesNeeded
)
2340 *pcbStructInfo
= bytesNeeded
;
2341 SetLastError(ERROR_MORE_DATA
);
2346 *pcbStructInfo
= bytesNeeded
;
2352 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2363 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2364 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2367 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2368 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2369 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2370 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2371 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2374 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2375 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2377 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2378 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2379 TRACE("returning %d\n", ret
);
2383 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2384 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2388 struct AsnDecodeSequenceItem items
[] = {
2389 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2390 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2391 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2392 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2393 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2394 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2395 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2396 rgNoticeNumbers
), 0 },
2400 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2401 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2403 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2404 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2408 /* The caller is expecting a pointer to a
2409 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2410 * CRYPT_AsnDecodeSequence is decoding a
2411 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2412 * needed, and decode again if the requisite space is available.
2414 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2416 *pcbStructInfo
= bytesNeeded
;
2417 else if (*pcbStructInfo
< bytesNeeded
)
2419 *pcbStructInfo
= bytesNeeded
;
2420 SetLastError(ERROR_MORE_DATA
);
2425 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2427 *pcbStructInfo
= bytesNeeded
;
2428 /* The pointer (pvStructInfo) passed in points to the first dynamic
2429 * pointer, so use it as the pointer to the
2430 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2431 * appropriate offset for the first dynamic pointer within the
2432 * notice reference by pointing to the first memory location past
2433 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2436 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2437 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2438 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2439 ret
= CRYPT_AsnDecodeSequence(items
,
2440 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2441 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2442 noticeRef
->pszOrganization
);
2445 TRACE("returning %d\n", ret
);
2449 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2450 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2456 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2458 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2459 DWORD bytesNeeded
= sizeof(LPWSTR
);
2461 switch (pbEncoded
[0])
2463 case ASN_NUMERICSTRING
:
2465 bytesNeeded
+= (dataLen
+ 1) * 2;
2467 case ASN_PRINTABLESTRING
:
2469 bytesNeeded
+= (dataLen
+ 1) * 2;
2473 bytesNeeded
+= (dataLen
+ 1) * 2;
2477 bytesNeeded
+= (dataLen
+ 1) * 2;
2479 case ASN_VIDEOTEXSTRING
:
2481 bytesNeeded
+= (dataLen
+ 1) * 2;
2483 case ASN_GRAPHICSTRING
:
2485 bytesNeeded
+= (dataLen
+ 1) * 2;
2487 case ASN_VISIBLESTRING
:
2489 bytesNeeded
+= (dataLen
+ 1) * 2;
2491 case ASN_GENERALSTRING
:
2493 bytesNeeded
+= (dataLen
+ 1) * 2;
2495 case ASN_UNIVERSALSTRING
:
2497 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2501 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2503 case ASN_UTF8STRING
:
2505 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2506 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2509 SetLastError(CRYPT_E_ASN1_BADTAG
);
2514 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2516 *pcbStructInfo
= bytesNeeded
;
2517 else if (*pcbStructInfo
< bytesNeeded
)
2519 *pcbStructInfo
= bytesNeeded
;
2520 SetLastError(ERROR_MORE_DATA
);
2525 LPWSTR
*pStr
= pvStructInfo
;
2527 *pcbStructInfo
= bytesNeeded
;
2531 LPWSTR str
= *(LPWSTR
*)pStr
;
2534 switch (pbEncoded
[0])
2536 case ASN_NUMERICSTRING
:
2537 case ASN_PRINTABLESTRING
:
2540 case ASN_VIDEOTEXSTRING
:
2541 case ASN_GRAPHICSTRING
:
2542 case ASN_VISIBLESTRING
:
2543 case ASN_GENERALSTRING
:
2544 for (i
= 0; i
< dataLen
; i
++)
2545 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2548 case ASN_UNIVERSALSTRING
:
2549 for (i
= 0; i
< dataLen
/ 4; i
++)
2550 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2551 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2555 for (i
= 0; i
< dataLen
/ 2; i
++)
2556 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2557 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2560 case ASN_UTF8STRING
:
2562 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2563 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2564 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2577 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2578 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2579 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2582 struct AsnDecodeSequenceItem items
[] = {
2583 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2584 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2585 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2586 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2587 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2588 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2589 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2591 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2593 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2594 pvStructInfo
, *pcbStructInfo
);
2596 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2597 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2598 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2599 TRACE("returning %d\n", ret
);
2603 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2604 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2605 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2606 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2610 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2611 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2617 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2618 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2623 *pcbStructInfo
= bytesNeeded
;
2624 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2625 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2627 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2629 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2630 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2631 notice
= pvStructInfo
;
2632 notice
->pNoticeReference
=
2633 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2634 ((BYTE
*)pvStructInfo
+
2635 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2636 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2637 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2638 pvStructInfo
, &bytesNeeded
, NULL
);
2644 SetLastError(STATUS_ACCESS_VIOLATION
);
2647 TRACE("returning %d\n", ret
);
2651 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2652 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2656 struct AsnArrayDescriptor arrayDesc
= { 0,
2657 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2658 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2659 CRYPT_AsnDecodeCopyBytes
,
2660 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2662 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2663 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2665 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2666 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2670 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2671 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2675 struct AsnDecodeSequenceItem items
[] = {
2676 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2677 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2678 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2679 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2680 CRYPT_AsnDecodePKCSAttributeValue
,
2681 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2682 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2684 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2686 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2687 pvStructInfo
, *pcbStructInfo
);
2689 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2690 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2691 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2692 TRACE("returning %d\n", ret
);
2696 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2697 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2698 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2702 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2703 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2709 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2710 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2714 *pcbStructInfo
= bytesNeeded
;
2715 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2716 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2718 PCRYPT_ATTRIBUTE attr
;
2720 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2721 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2722 attr
= pvStructInfo
;
2723 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2724 sizeof(CRYPT_ATTRIBUTE
));
2725 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2726 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2733 SetLastError(STATUS_ACCESS_VIOLATION
);
2736 TRACE("returning %d\n", ret
);
2740 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2741 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2744 struct AsnArrayDescriptor arrayDesc
= { 0,
2745 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2746 sizeof(CRYPT_ATTRIBUTES
),
2747 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2748 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2751 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2752 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2756 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2757 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2758 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2762 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2763 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2767 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2768 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2769 sizeof(CRYPT_ATTRIBUTES
),
2770 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2771 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2773 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2774 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2778 SetLastError(STATUS_ACCESS_VIOLATION
);
2781 TRACE("returning %d\n", ret
);
2785 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2786 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2788 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2790 struct AsnDecodeSequenceItem items
[] = {
2791 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2792 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2793 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2794 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2795 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2796 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2799 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2800 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2802 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2803 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2804 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2805 if (ret
&& pvStructInfo
)
2807 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2808 debugstr_a(algo
->pszObjId
));
2813 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2814 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2818 struct AsnDecodeSequenceItem items
[] = {
2819 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2820 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2821 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2822 Algorithm
.pszObjId
) },
2823 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2824 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2825 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2827 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2829 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2830 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2831 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2835 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2836 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2837 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2845 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2846 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2849 *pcbStructInfo
= bytesNeeded
;
2850 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2851 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2853 PCERT_PUBLIC_KEY_INFO info
;
2855 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2856 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2857 info
= pvStructInfo
;
2858 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2859 sizeof(CERT_PUBLIC_KEY_INFO
);
2860 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2861 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2862 &bytesNeeded
, NULL
);
2868 SetLastError(STATUS_ACCESS_VIOLATION
);
2875 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2876 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2882 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2885 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2887 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2890 if (pbEncoded
[1] > 1)
2892 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2899 *pcbStructInfo
= sizeof(BOOL
);
2902 else if (*pcbStructInfo
< sizeof(BOOL
))
2904 *pcbStructInfo
= sizeof(BOOL
);
2905 SetLastError(ERROR_MORE_DATA
);
2910 *pcbStructInfo
= sizeof(BOOL
);
2911 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2914 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2918 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2919 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2921 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2922 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2925 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2926 pvStructInfo
, *pcbStructInfo
);
2930 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2933 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2934 if (1 + lenBytes
> cbEncoded
)
2936 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2939 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2941 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2943 case 1: /* rfc822Name */
2944 case 2: /* dNSName */
2945 case 6: /* uniformResourceIdentifier */
2946 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2948 case 4: /* directoryName */
2949 case 7: /* iPAddress */
2950 bytesNeeded
+= dataLen
;
2952 case 8: /* registeredID */
2953 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
2957 /* FIXME: ugly, shouldn't need to know internals of OID decode
2958 * function to use it.
2960 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
2963 case 0: /* otherName */
2964 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2965 SetLastError(CRYPT_E_ASN1_BADTAG
);
2968 case 3: /* x400Address, unimplemented */
2969 case 5: /* ediPartyName, unimplemented */
2970 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2971 SetLastError(CRYPT_E_ASN1_BADTAG
);
2975 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2976 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2982 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2984 *pcbStructInfo
= bytesNeeded
;
2985 else if (*pcbStructInfo
< bytesNeeded
)
2987 *pcbStructInfo
= bytesNeeded
;
2988 SetLastError(ERROR_MORE_DATA
);
2993 *pcbStructInfo
= bytesNeeded
;
2994 /* MS used values one greater than the asn1 ones.. sigh */
2995 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
2996 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2998 case 1: /* rfc822Name */
2999 case 2: /* dNSName */
3000 case 6: /* uniformResourceIdentifier */
3004 for (i
= 0; i
< dataLen
; i
++)
3005 entry
->u
.pwszURL
[i
] =
3006 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3007 entry
->u
.pwszURL
[i
] = 0;
3008 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3009 debugstr_w(entry
->u
.pwszURL
));
3012 case 4: /* directoryName */
3013 /* The data are memory-equivalent with the IPAddress case,
3016 case 7: /* iPAddress */
3017 /* The next data pointer is in the pwszURL spot, that is,
3018 * the first 4 bytes. Need to move it to the next spot.
3020 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3021 entry
->u
.IPAddress
.cbData
= dataLen
;
3022 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3025 case 8: /* registeredID */
3026 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3027 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3036 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3037 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3041 struct AsnArrayDescriptor arrayDesc
= { 0,
3042 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3043 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3044 sizeof(CERT_ALT_NAME_INFO
),
3045 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3046 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3048 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3049 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3051 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3052 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3056 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
3057 static BOOL
CRYPT_AsnDecodeIntegerSwapBytes(const BYTE
*pbEncoded
,
3058 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3063 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3064 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3066 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
3069 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
3070 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
3072 if (ret
&& pvStructInfo
)
3074 CRYPT_DATA_BLOB
*blob
= pvStructInfo
;
3081 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
3083 temp
= blob
->pbData
[i
];
3084 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
3085 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
3089 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3093 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3094 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3095 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3101 struct AsnDecodeSequenceItem items
[] = {
3102 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3103 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
3104 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3105 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3106 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3107 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3108 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3109 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3110 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3111 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3112 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3115 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3116 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3117 pcbStructInfo
, NULL
, NULL
);
3121 SetLastError(STATUS_ACCESS_VIOLATION
);
3128 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3129 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3130 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3136 struct AsnDecodeSequenceItem items
[] = {
3137 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3138 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
3139 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3140 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3141 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3142 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3143 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3144 AuthorityCertIssuer
.rgAltEntry
), 0 },
3145 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3146 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3147 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3148 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3149 AuthorityCertSerialNumber
.pbData
), 0 },
3152 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3153 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3154 pcbStructInfo
, NULL
, NULL
);
3158 SetLastError(STATUS_ACCESS_VIOLATION
);
3165 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3166 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3169 struct AsnDecodeSequenceItem items
[] = {
3170 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3171 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3172 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3173 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3174 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3175 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3177 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3179 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3180 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3181 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3184 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3185 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3186 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3190 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3191 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3195 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3196 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3197 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3198 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3199 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3200 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3202 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3203 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3207 SetLastError(STATUS_ACCESS_VIOLATION
);
3214 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3215 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3220 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3221 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3223 /* The caller has already checked the tag, no need to check it again.
3224 * Check the outer length is valid:
3226 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3228 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3231 pbEncoded
+= 1 + lenBytes
;
3232 cbEncoded
-= 1 + lenBytes
;
3233 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3234 cbEncoded
-= 2; /* space for 0 TLV */
3235 /* Check the inner length is valid: */
3236 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3240 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3241 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3242 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3244 if (*(pbEncoded
+ decodedLen
) != 0 ||
3245 *(pbEncoded
+ decodedLen
+ 1) != 0)
3247 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3248 *(pbEncoded
+ decodedLen
),
3249 *(pbEncoded
+ decodedLen
+ 1));
3250 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3256 if (ret
&& pcbDecoded
)
3258 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3259 TRACE("decoded %d bytes\n", *pcbDecoded
);
3266 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3267 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3270 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3271 struct AsnDecodeSequenceItem items
[] = {
3272 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3273 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3274 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3275 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3276 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3277 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3278 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3282 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3283 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3285 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3286 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3287 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3291 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3292 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3293 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3297 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3298 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3302 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3303 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3304 if (ret
&& pvStructInfo
)
3306 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3307 pcbStructInfo
, *pcbStructInfo
);
3310 CRYPT_CONTENT_INFO
*info
;
3312 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3313 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3314 info
= pvStructInfo
;
3315 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3316 sizeof(CRYPT_CONTENT_INFO
));
3317 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3318 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3319 pcbStructInfo
, NULL
);
3325 SetLastError(STATUS_ACCESS_VIOLATION
);
3331 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3332 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3333 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3336 struct AsnDecodeSequenceItem items
[] = {
3337 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3338 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3339 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3340 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3341 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3343 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3344 CRYPT_AsnDecodePKCSContentInfoInternal
,
3345 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3346 ContentInfo
.pszObjId
), 0 },
3347 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3348 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3349 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3352 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3353 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3358 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3359 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3360 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3364 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3365 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3371 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3372 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3375 *pcbStructInfo
= bytesNeeded
;
3376 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3377 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3379 CERT_ALT_NAME_INFO
*name
;
3381 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3382 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3383 name
= pvStructInfo
;
3384 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3385 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3386 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3387 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3388 &bytesNeeded
, NULL
);
3394 SetLastError(STATUS_ACCESS_VIOLATION
);
3401 struct PATH_LEN_CONSTRAINT
3403 BOOL fPathLenConstraint
;
3404 DWORD dwPathLenConstraint
;
3407 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3408 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3412 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3414 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3415 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3419 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3421 *pcbStructInfo
= bytesNeeded
;
3423 else if (*pcbStructInfo
< bytesNeeded
)
3425 SetLastError(ERROR_MORE_DATA
);
3426 *pcbStructInfo
= bytesNeeded
;
3431 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3433 *pcbStructInfo
= bytesNeeded
;
3434 size
= sizeof(constraint
->dwPathLenConstraint
);
3435 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3436 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3438 constraint
->fPathLenConstraint
= TRUE
;
3439 TRACE("got an int, dwPathLenConstraint is %d\n",
3440 constraint
->dwPathLenConstraint
);
3442 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3446 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3447 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3451 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3452 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3453 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3454 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3455 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3456 offsetof(CERT_NAME_BLOB
, pbData
) };
3458 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3459 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3461 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3462 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3463 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3467 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3468 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3469 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3475 struct AsnDecodeSequenceItem items
[] = {
3476 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3477 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3478 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3479 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3480 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3481 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3482 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3483 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3484 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3486 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3489 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3490 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3491 pcbStructInfo
, NULL
, NULL
);
3495 SetLastError(STATUS_ACCESS_VIOLATION
);
3502 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3503 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3504 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3510 struct AsnDecodeSequenceItem items
[] = {
3511 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3512 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3513 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3514 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3515 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3518 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3519 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3520 pcbStructInfo
, NULL
, NULL
);
3524 SetLastError(STATUS_ACCESS_VIOLATION
);
3531 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3532 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3535 struct AsnDecodeSequenceItem items
[] = {
3536 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3537 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3538 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3540 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3541 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3542 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3545 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3547 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3548 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3550 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3551 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3552 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3556 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3557 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3561 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3562 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3563 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3564 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3565 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3566 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3568 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3569 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3571 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3572 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3573 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3577 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3578 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3580 struct AsnDecodeSequenceItem items
[] = {
3581 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3582 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3583 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3584 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3585 CRYPT_AsnDecodePolicyQualifiers
,
3586 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3587 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3589 CERT_POLICY_INFO
*info
= pvStructInfo
;
3592 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3593 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3595 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3596 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3597 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3601 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3602 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3603 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3607 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3608 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3612 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3613 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3614 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3615 sizeof(CERT_POLICIES_INFO
),
3616 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3617 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3619 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3620 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3624 SetLastError(STATUS_ACCESS_VIOLATION
);
3630 #define RSA1_MAGIC 0x31415352
3632 struct DECODED_RSA_PUB_KEY
3635 CRYPT_INTEGER_BLOB modulus
;
3638 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3639 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3640 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3646 struct AsnDecodeSequenceItem items
[] = {
3647 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3648 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3649 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3651 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3652 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3654 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3657 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3658 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3662 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3663 decodedKey
->modulus
.cbData
;
3667 *pcbStructInfo
= bytesNeeded
;
3670 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3671 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3674 RSAPUBKEY
*rsaPubKey
;
3676 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3677 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3679 hdr
->bType
= PUBLICKEYBLOB
;
3680 hdr
->bVersion
= CUR_BLOB_VERSION
;
3682 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3683 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3684 sizeof(BLOBHEADER
));
3685 rsaPubKey
->magic
= RSA1_MAGIC
;
3686 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3687 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3688 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3689 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3690 decodedKey
->modulus
.cbData
);
3692 LocalFree(decodedKey
);
3697 SetLastError(STATUS_ACCESS_VIOLATION
);
3704 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3705 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3709 DWORD bytesNeeded
, dataLen
;
3711 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3712 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3714 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3716 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3718 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3719 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3721 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3723 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3725 *pcbStructInfo
= bytesNeeded
;
3726 else if (*pcbStructInfo
< bytesNeeded
)
3728 SetLastError(ERROR_MORE_DATA
);
3729 *pcbStructInfo
= bytesNeeded
;
3734 CRYPT_DATA_BLOB
*blob
;
3736 *pcbStructInfo
= bytesNeeded
;
3737 blob
= pvStructInfo
;
3738 blob
->cbData
= dataLen
;
3739 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3740 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3743 assert(blob
->pbData
);
3745 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3753 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3754 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3755 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3759 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3760 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3768 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3771 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
3773 SetLastError(CRYPT_E_ASN1_BADTAG
);
3776 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3777 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3780 *pcbStructInfo
= bytesNeeded
;
3781 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3782 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3784 CRYPT_DATA_BLOB
*blob
;
3786 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3787 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3788 blob
= pvStructInfo
;
3789 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
3790 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3791 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3792 &bytesNeeded
, NULL
);
3798 SetLastError(STATUS_ACCESS_VIOLATION
);
3805 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3806 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3809 DWORD bytesNeeded
, dataLen
;
3810 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3812 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3813 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3815 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3817 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3818 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
3820 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
3822 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3824 *pcbStructInfo
= bytesNeeded
;
3825 else if (*pcbStructInfo
< bytesNeeded
)
3827 *pcbStructInfo
= bytesNeeded
;
3828 SetLastError(ERROR_MORE_DATA
);
3833 CRYPT_BIT_BLOB
*blob
;
3835 *pcbStructInfo
= bytesNeeded
;
3836 blob
= pvStructInfo
;
3837 blob
->cbData
= dataLen
- 1;
3838 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
3839 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3841 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
3845 assert(blob
->pbData
);
3848 BYTE mask
= 0xff << blob
->cUnusedBits
;
3850 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
3852 blob
->pbData
[blob
->cbData
- 1] &= mask
;
3860 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
3861 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3862 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3866 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3867 pDecodePara
, pvStructInfo
, pcbStructInfo
);
3875 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3878 else if (pbEncoded
[0] != ASN_BITSTRING
)
3880 SetLastError(CRYPT_E_ASN1_BADTAG
);
3883 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3884 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3887 *pcbStructInfo
= bytesNeeded
;
3888 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3889 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3891 CRYPT_BIT_BLOB
*blob
;
3893 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3894 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3895 blob
= pvStructInfo
;
3896 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
3897 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
3898 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3899 &bytesNeeded
, NULL
);
3905 SetLastError(STATUS_ACCESS_VIOLATION
);
3909 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3913 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
3914 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3915 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3920 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3922 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3925 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3926 if (dataLen
> sizeof(int))
3928 SetLastError(CRYPT_E_ASN1_LARGE
);
3931 else if (!pvStructInfo
)
3932 *pcbStructInfo
= sizeof(int);
3933 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
3937 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
3939 /* initialize to a negative value to sign-extend */
3944 for (i
= 0; i
< dataLen
; i
++)
3947 val
|= pbEncoded
[1 + lenBytes
+ i
];
3949 memcpy(pvStructInfo
, &val
, sizeof(int));
3955 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
3956 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3957 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3967 SetLastError(CRYPT_E_ASN1_EOD
);
3970 else if (pbEncoded
[0] != ASN_INTEGER
)
3972 SetLastError(CRYPT_E_ASN1_BADTAG
);
3976 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3977 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3981 *pcbStructInfo
= bytesNeeded
;
3982 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3983 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3985 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3986 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3987 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
3988 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3989 &bytesNeeded
, NULL
);
3995 SetLastError(STATUS_ACCESS_VIOLATION
);
4002 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4003 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4007 DWORD bytesNeeded
, dataLen
;
4009 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4011 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4013 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4015 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4017 *pcbStructInfo
= bytesNeeded
;
4018 else if (*pcbStructInfo
< bytesNeeded
)
4020 *pcbStructInfo
= bytesNeeded
;
4021 SetLastError(ERROR_MORE_DATA
);
4026 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4028 *pcbStructInfo
= bytesNeeded
;
4029 blob
->cbData
= dataLen
;
4030 assert(blob
->pbData
);
4035 for (i
= 0; i
< blob
->cbData
; i
++)
4037 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4046 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4047 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4048 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4056 if (pbEncoded
[0] != ASN_INTEGER
)
4058 SetLastError(CRYPT_E_ASN1_BADTAG
);
4062 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4063 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4067 *pcbStructInfo
= bytesNeeded
;
4068 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4069 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4071 CRYPT_INTEGER_BLOB
*blob
;
4073 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4074 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4075 blob
= pvStructInfo
;
4076 blob
->pbData
= (BYTE
*)pvStructInfo
+
4077 sizeof(CRYPT_INTEGER_BLOB
);
4078 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4079 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4080 &bytesNeeded
, NULL
);
4086 SetLastError(STATUS_ACCESS_VIOLATION
);
4093 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4094 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4099 if (pbEncoded
[0] == ASN_INTEGER
)
4101 DWORD bytesNeeded
, dataLen
;
4103 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4105 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4108 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4109 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4111 *pcbStructInfo
= bytesNeeded
;
4112 else if (*pcbStructInfo
< bytesNeeded
)
4114 *pcbStructInfo
= bytesNeeded
;
4115 SetLastError(ERROR_MORE_DATA
);
4120 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4122 *pcbStructInfo
= bytesNeeded
;
4123 blob
->cbData
= dataLen
;
4124 assert(blob
->pbData
);
4125 /* remove leading zero byte if it exists */
4126 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4135 for (i
= 0; i
< blob
->cbData
; i
++)
4137 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4146 SetLastError(CRYPT_E_ASN1_BADTAG
);
4152 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4153 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4154 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4162 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4163 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4166 *pcbStructInfo
= bytesNeeded
;
4167 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4168 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4170 CRYPT_INTEGER_BLOB
*blob
;
4172 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4173 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4174 blob
= pvStructInfo
;
4175 blob
->pbData
= (BYTE
*)pvStructInfo
+
4176 sizeof(CRYPT_INTEGER_BLOB
);
4177 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4178 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4179 &bytesNeeded
, NULL
);
4185 SetLastError(STATUS_ACCESS_VIOLATION
);
4192 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4193 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4194 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4200 *pcbStructInfo
= sizeof(int);
4205 if (pbEncoded
[0] == ASN_ENUMERATED
)
4207 unsigned int val
= 0, i
;
4211 SetLastError(CRYPT_E_ASN1_EOD
);
4214 else if (pbEncoded
[1] == 0)
4216 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4221 /* A little strange looking, but we have to accept a sign byte:
4222 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4223 * assuming a small length is okay here, it has to be in short
4226 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4228 SetLastError(CRYPT_E_ASN1_LARGE
);
4231 for (i
= 0; i
< pbEncoded
[1]; i
++)
4234 val
|= pbEncoded
[2 + i
];
4236 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4237 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4239 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4240 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4241 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4247 SetLastError(CRYPT_E_ASN1_BADTAG
);
4253 SetLastError(STATUS_ACCESS_VIOLATION
);
4260 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4263 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4268 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4270 if (!isdigit(*(pbEncoded))) \
4272 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4278 (word) += *(pbEncoded)++ - '0'; \
4283 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4284 SYSTEMTIME
*sysTime
)
4288 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4290 WORD hours
, minutes
= 0;
4291 BYTE sign
= *pbEncoded
++;
4294 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4295 if (ret
&& hours
>= 24)
4297 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4302 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4303 if (ret
&& minutes
>= 60)
4305 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4313 sysTime
->wHour
+= hours
;
4314 sysTime
->wMinute
+= minutes
;
4318 if (hours
> sysTime
->wHour
)
4321 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4324 sysTime
->wHour
-= hours
;
4325 if (minutes
> sysTime
->wMinute
)
4328 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4331 sysTime
->wMinute
-= minutes
;
4338 #define MIN_ENCODED_TIME_LENGTH 10
4340 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4341 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4346 if (pbEncoded
[0] == ASN_UTCTIME
)
4349 SetLastError(CRYPT_E_ASN1_EOD
);
4350 else if (pbEncoded
[1] > 0x7f)
4352 /* long-form date strings really can't be valid */
4353 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4357 SYSTEMTIME sysTime
= { 0 };
4358 BYTE len
= pbEncoded
[1];
4360 if (len
< MIN_ENCODED_TIME_LENGTH
)
4361 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4366 *pcbDecoded
= 2 + len
;
4368 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4369 if (sysTime
.wYear
>= 50)
4370 sysTime
.wYear
+= 1900;
4372 sysTime
.wYear
+= 2000;
4373 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4374 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4375 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4376 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4379 if (len
>= 2 && isdigit(*pbEncoded
) &&
4380 isdigit(*(pbEncoded
+ 1)))
4381 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4383 else if (isdigit(*pbEncoded
))
4384 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4387 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4393 *pcbStructInfo
= sizeof(FILETIME
);
4394 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4396 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4402 SetLastError(CRYPT_E_ASN1_BADTAG
);
4406 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4407 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4408 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4416 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4417 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4421 *pcbStructInfo
= bytesNeeded
;
4422 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4423 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4425 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4426 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4427 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4428 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4429 &bytesNeeded
, NULL
);
4435 SetLastError(STATUS_ACCESS_VIOLATION
);
4441 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4442 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4447 if (pbEncoded
[0] == ASN_GENERALTIME
)
4450 SetLastError(CRYPT_E_ASN1_EOD
);
4451 else if (pbEncoded
[1] > 0x7f)
4453 /* long-form date strings really can't be valid */
4454 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4458 BYTE len
= pbEncoded
[1];
4460 if (len
< MIN_ENCODED_TIME_LENGTH
)
4461 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4464 SYSTEMTIME sysTime
= { 0 };
4468 *pcbDecoded
= 2 + len
;
4470 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4471 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4472 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4473 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4476 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4479 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4481 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4488 /* workaround macro weirdness */
4489 digits
= min(len
, 3);
4490 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4491 sysTime
.wMilliseconds
);
4494 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4500 *pcbStructInfo
= sizeof(FILETIME
);
4501 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4503 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4509 SetLastError(CRYPT_E_ASN1_BADTAG
);
4513 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4514 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4518 InternalDecodeFunc decode
= NULL
;
4520 if (pbEncoded
[0] == ASN_UTCTIME
)
4521 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4522 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4523 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4525 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4526 pcbStructInfo
, pcbDecoded
);
4529 SetLastError(CRYPT_E_ASN1_BADTAG
);
4535 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4536 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4537 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4545 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4546 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4550 *pcbStructInfo
= bytesNeeded
;
4551 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4552 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4554 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4555 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4556 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4557 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4558 &bytesNeeded
, NULL
);
4564 SetLastError(STATUS_ACCESS_VIOLATION
);
4571 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4572 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4573 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4579 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4581 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4583 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4588 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4589 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4591 ptr
= pbEncoded
+ 1 + lenBytes
;
4592 remainingLen
= dataLen
;
4593 while (ret
&& remainingLen
)
4597 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4600 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4602 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4603 ptr
+= 1 + nextLenBytes
+ nextLen
;
4604 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4605 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4606 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4612 CRYPT_SEQUENCE_OF_ANY
*seq
;
4617 *pcbStructInfo
= bytesNeeded
;
4618 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4619 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4621 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4622 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4624 seq
->cValue
= cValue
;
4625 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4627 nextPtr
= (BYTE
*)seq
->rgValue
+
4628 cValue
* sizeof(CRYPT_DER_BLOB
);
4629 ptr
= pbEncoded
+ 1 + lenBytes
;
4630 remainingLen
= dataLen
;
4632 while (ret
&& remainingLen
)
4636 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4639 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4641 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4643 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4644 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4647 seq
->rgValue
[i
].pbData
= nextPtr
;
4648 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4650 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4652 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4653 ptr
+= 1 + nextLenBytes
+ nextLen
;
4663 SetLastError(CRYPT_E_ASN1_BADTAG
);
4669 SetLastError(STATUS_ACCESS_VIOLATION
);
4676 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4677 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4682 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4684 DWORD bytesNeeded
, dataLen
;
4686 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4688 struct AsnArrayDescriptor arrayDesc
= {
4689 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4690 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
4691 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
4692 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
4693 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4694 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4695 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4700 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4701 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4702 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
4703 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4704 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
4707 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4709 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4711 *pcbStructInfo
= bytesNeeded
;
4712 else if (*pcbStructInfo
< bytesNeeded
)
4714 *pcbStructInfo
= bytesNeeded
;
4715 SetLastError(ERROR_MORE_DATA
);
4720 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
4722 *pcbStructInfo
= bytesNeeded
;
4725 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4726 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4727 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4728 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
4732 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4738 SetLastError(CRYPT_E_ASN1_BADTAG
);
4744 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4745 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4747 struct AsnDecodeSequenceItem items
[] = {
4748 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4749 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4750 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4751 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4752 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4753 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4754 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4755 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4756 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4757 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4759 CRL_DIST_POINT
*point
= pvStructInfo
;
4762 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4763 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4764 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
4768 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
4769 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4770 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4774 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4775 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4779 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4780 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
4781 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
4782 sizeof(CRL_DIST_POINTS_INFO
),
4783 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
4784 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
4786 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
4787 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
4791 SetLastError(STATUS_ACCESS_VIOLATION
);
4798 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
4799 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4800 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4804 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4805 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4809 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4810 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
4811 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
4812 sizeof(CERT_ENHKEY_USAGE
),
4813 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
4815 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
4816 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
4820 SetLastError(STATUS_ACCESS_VIOLATION
);
4827 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
4828 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4829 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4833 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4834 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4838 struct AsnDecodeSequenceItem items
[] = {
4839 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
4840 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4841 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
4842 offsetof(CRL_ISSUING_DIST_POINT
,
4843 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4844 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
4845 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4847 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
4848 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4850 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
4851 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
4852 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
4853 OnlySomeReasonFlags
.pbData
), 0 },
4854 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
4855 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
4858 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4859 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
4860 pcbStructInfo
, NULL
, NULL
);
4864 SetLastError(STATUS_ACCESS_VIOLATION
);
4871 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
4872 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4876 DWORD max
, size
= sizeof(max
);
4878 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4879 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4883 SetLastError(CRYPT_E_ASN1_EOD
);
4886 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
4888 SetLastError(CRYPT_E_ASN1_BADTAG
);
4891 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
4892 &max
, &size
, pcbDecoded
)))
4894 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
4897 *pcbStructInfo
= bytesNeeded
;
4898 else if (*pcbStructInfo
< bytesNeeded
)
4900 *pcbStructInfo
= bytesNeeded
;
4901 SetLastError(ERROR_MORE_DATA
);
4906 CERT_GENERAL_SUBTREE
*subtree
= (CERT_GENERAL_SUBTREE
*)
4907 ((BYTE
*)pvStructInfo
- offsetof(CERT_GENERAL_SUBTREE
, fMaximum
));
4909 *pcbStructInfo
= bytesNeeded
;
4910 /* The BOOL is implicit: if the integer is present, then it's
4913 subtree
->fMaximum
= TRUE
;
4914 subtree
->dwMaximum
= max
;
4917 TRACE("returning %d\n", ret
);
4921 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
4922 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4926 struct AsnDecodeSequenceItem items
[] = {
4927 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
4928 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
4929 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
4930 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
4931 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
4932 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
4933 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
4934 TRUE
, FALSE
, 0, 0 },
4936 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
4938 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4939 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4941 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4942 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4943 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
4946 TRACE("%d\n", *pcbDecoded
);
4947 if (*pcbDecoded
< cbEncoded
)
4948 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
4949 *(pbEncoded
+ *pcbDecoded
+ 1));
4951 TRACE("returning %d\n", ret
);
4955 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
4956 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4960 struct AsnArrayDescriptor arrayDesc
= { 0,
4961 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
4962 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
4963 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
4965 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
4966 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
4968 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4969 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4971 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
4972 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
4976 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
4977 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4981 struct AsnArrayDescriptor arrayDesc
= { 0,
4982 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
4983 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
4984 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
4985 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
4986 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
4988 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4989 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4991 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
4992 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
4996 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
4997 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4998 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5002 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5003 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5007 struct AsnDecodeSequenceItem items
[] = {
5008 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5009 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5010 CRYPT_AsnDecodePermittedSubtree
,
5011 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5012 cExcludedSubtree
), TRUE
, TRUE
,
5013 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5014 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5015 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5016 CRYPT_AsnDecodeExcludedSubtree
,
5017 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5019 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5022 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5023 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5024 pcbStructInfo
, NULL
, NULL
);
5028 SetLastError(STATUS_ACCESS_VIOLATION
);
5034 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5035 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5039 struct AsnDecodeSequenceItem items
[] = {
5040 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5041 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5043 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5044 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5045 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5047 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5049 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5050 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5052 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5053 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5054 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5055 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5057 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5060 TRACE("returning %d\n", ret
);
5064 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5065 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5068 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5069 struct AsnDecodeSequenceItem items
[] = {
5070 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5071 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5072 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5073 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5074 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5075 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5076 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5077 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5078 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5079 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5080 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5081 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5082 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5083 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5084 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5085 HashEncryptionAlgorithm
.pszObjId
), 0 },
5086 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5087 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5088 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5089 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5090 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5091 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5092 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5096 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5097 pvStructInfo
, *pcbStructInfo
);
5099 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5100 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5101 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5105 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5106 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5107 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5111 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5112 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5116 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5117 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5118 if (ret
&& pvStructInfo
)
5120 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5121 pcbStructInfo
, *pcbStructInfo
);
5124 CMSG_SIGNER_INFO
*info
;
5126 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5127 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5128 info
= pvStructInfo
;
5129 info
->Issuer
.pbData
= ((BYTE
*)info
+
5130 sizeof(CMSG_SIGNER_INFO
));
5131 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5132 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5133 pcbStructInfo
, NULL
);
5139 SetLastError(STATUS_ACCESS_VIOLATION
);
5142 TRACE("returning %d\n", ret
);
5146 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5147 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5151 struct AsnArrayDescriptor arrayDesc
= { 0,
5152 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5153 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5154 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5155 CRYPT_AsnDecodeCopyBytes
,
5156 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5158 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5159 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5161 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5162 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5166 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5167 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5171 struct AsnArrayDescriptor arrayDesc
= { 0,
5172 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5173 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5174 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5175 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5176 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5178 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5179 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5181 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5182 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5186 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5187 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5190 CERT_ID
*id
= pvStructInfo
;
5193 if (*pbEncoded
== ASN_SEQUENCEOF
)
5195 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5196 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5200 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5201 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5202 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5203 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5205 *pcbStructInfo
= sizeof(CERT_ID
);
5208 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5210 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5211 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5215 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5216 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5217 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5218 sizeof(CRYPT_DATA_BLOB
);
5220 *pcbStructInfo
= sizeof(CERT_ID
);
5224 SetLastError(CRYPT_E_ASN1_BADTAG
);
5228 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5229 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5232 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5233 struct AsnDecodeSequenceItem items
[] = {
5234 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5235 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5236 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5237 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5238 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5239 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5240 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5241 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5242 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5243 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5244 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5245 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5246 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5247 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5248 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5249 HashEncryptionAlgorithm
.pszObjId
), 0 },
5250 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5251 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5252 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5253 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5254 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5255 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5256 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5260 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5261 pvStructInfo
, *pcbStructInfo
);
5263 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5264 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5265 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5269 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5270 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5271 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5275 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5276 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5280 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5281 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5282 if (ret
&& pvStructInfo
)
5284 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5285 pcbStructInfo
, *pcbStructInfo
);
5288 CMSG_CMS_SIGNER_INFO
*info
;
5290 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5291 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5292 info
= pvStructInfo
;
5293 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5294 sizeof(CMSG_CMS_SIGNER_INFO
));
5295 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5296 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5297 pcbStructInfo
, NULL
);
5303 SetLastError(STATUS_ACCESS_VIOLATION
);
5306 TRACE("returning %d\n", ret
);
5310 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5311 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5314 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5315 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5316 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5317 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5318 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5319 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5321 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5322 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5324 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5325 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5329 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5330 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5331 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5334 struct AsnDecodeSequenceItem items
[] = {
5335 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5336 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5337 /* Placeholder for the hash algorithms - redundant with those in the
5338 * signers, so just ignore them.
5340 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5341 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5342 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5343 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5344 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5345 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5346 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5347 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5348 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5349 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5350 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5351 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5352 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5353 CRYPT_DecodeSignerArray
,
5354 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5355 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5358 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5359 pDecodePara
, signedInfo
, *pcbSignedInfo
);
5361 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5362 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5364 TRACE("returning %d\n", ret
);
5368 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5369 LPCSTR lpszStructType
)
5371 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5373 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5374 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5376 SetLastError(ERROR_FILE_NOT_FOUND
);
5379 if (!HIWORD(lpszStructType
))
5381 switch (LOWORD(lpszStructType
))
5383 case LOWORD(X509_CERT
):
5384 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5386 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5387 decodeFunc
= CRYPT_AsnDecodeCert
;
5389 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5390 decodeFunc
= CRYPT_AsnDecodeCRL
;
5392 case LOWORD(X509_EXTENSIONS
):
5393 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5395 case LOWORD(X509_NAME_VALUE
):
5396 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5398 case LOWORD(X509_NAME
):
5399 decodeFunc
= CRYPT_AsnDecodeName
;
5401 case LOWORD(X509_PUBLIC_KEY_INFO
):
5402 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5404 case LOWORD(X509_AUTHORITY_KEY_ID
):
5405 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5407 case LOWORD(X509_ALTERNATE_NAME
):
5408 decodeFunc
= CRYPT_AsnDecodeAltName
;
5410 case LOWORD(X509_BASIC_CONSTRAINTS
):
5411 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5413 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5414 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5416 case LOWORD(X509_CERT_POLICIES
):
5417 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5419 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5420 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5422 case LOWORD(X509_UNICODE_NAME
):
5423 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5425 case LOWORD(PKCS_ATTRIBUTE
):
5426 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5428 case LOWORD(X509_UNICODE_NAME_VALUE
):
5429 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5431 case LOWORD(X509_OCTET_STRING
):
5432 decodeFunc
= CRYPT_AsnDecodeOctets
;
5434 case LOWORD(X509_BITS
):
5435 case LOWORD(X509_KEY_USAGE
):
5436 decodeFunc
= CRYPT_AsnDecodeBits
;
5438 case LOWORD(X509_INTEGER
):
5439 decodeFunc
= CRYPT_AsnDecodeInt
;
5441 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5442 decodeFunc
= CRYPT_AsnDecodeInteger
;
5444 case LOWORD(X509_MULTI_BYTE_UINT
):
5445 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5447 case LOWORD(X509_ENUMERATED
):
5448 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5450 case LOWORD(X509_CHOICE_OF_TIME
):
5451 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5453 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5454 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5456 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5457 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5459 case LOWORD(PKCS_CONTENT_INFO
):
5460 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5462 case LOWORD(X509_SEQUENCE_OF_ANY
):
5463 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5465 case LOWORD(PKCS_UTC_TIME
):
5466 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5468 case LOWORD(X509_CRL_DIST_POINTS
):
5469 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5471 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5472 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5474 case LOWORD(PKCS_CTL
):
5475 decodeFunc
= CRYPT_AsnDecodeCTL
;
5477 case LOWORD(PKCS_SMIME_CAPABILITIES
):
5478 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5480 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
5481 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5483 case LOWORD(PKCS_ATTRIBUTES
):
5484 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
5486 case LOWORD(X509_ISSUING_DIST_POINT
):
5487 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5489 case LOWORD(X509_NAME_CONSTRAINTS
):
5490 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5492 case LOWORD(PKCS7_SIGNER_INFO
):
5493 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
5495 case LOWORD(CMS_SIGNER_INFO
):
5496 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
5500 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
5501 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5502 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
5503 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5504 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
5505 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5506 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
5507 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5508 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
5509 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5510 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
5511 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5512 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
5513 decodeFunc
= CRYPT_AsnDecodeBits
;
5514 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
5515 decodeFunc
= CRYPT_AsnDecodeOctets
;
5516 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
5517 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5518 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
5519 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5520 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
5521 decodeFunc
= CRYPT_AsnDecodeAltName
;
5522 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
5523 decodeFunc
= CRYPT_AsnDecodeAltName
;
5524 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
5525 decodeFunc
= CRYPT_AsnDecodeAltName
;
5526 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
5527 decodeFunc
= CRYPT_AsnDecodeAltName
;
5528 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
5529 decodeFunc
= CRYPT_AsnDecodeAltName
;
5530 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
5531 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5532 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
5533 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5534 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
5535 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5536 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
5537 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5538 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
5539 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5540 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
5541 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5542 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
5543 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5544 else if (!strcmp(lpszStructType
, szOID_CTL
))
5545 decodeFunc
= CRYPT_AsnDecodeCTL
;
5549 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
5550 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5552 static HCRYPTOIDFUNCSET set
= NULL
;
5553 CryptDecodeObjectFunc decodeFunc
= NULL
;
5556 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
5557 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5558 (void **)&decodeFunc
, hFunc
);
5562 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
5563 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5565 static HCRYPTOIDFUNCSET set
= NULL
;
5566 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5569 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
5570 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5571 (void **)&decodeFunc
, hFunc
);
5575 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5576 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
5577 DWORD
*pcbStructInfo
)
5580 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
5581 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
5582 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5584 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
5585 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
5586 pvStructInfo
, pcbStructInfo
);
5588 if (!pvStructInfo
&& !pcbStructInfo
)
5590 SetLastError(ERROR_INVALID_PARAMETER
);
5593 if (cbEncoded
> MAX_ENCODED_LEN
)
5595 SetLastError(CRYPT_E_ASN1_LARGE
);
5599 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
5602 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5603 debugstr_a(lpszStructType
));
5604 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
5605 lpszStructType
, &hFunc
);
5606 if (!pCryptDecodeObject
)
5607 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
5608 lpszStructType
, &hFunc
);
5610 if (pCryptDecodeObject
)
5611 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5612 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5613 else if (pCryptDecodeObjectEx
)
5614 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
5615 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5616 pvStructInfo
, pcbStructInfo
);
5618 CryptFreeOIDFunctionAddress(hFunc
, 0);
5619 TRACE_(crypt
)("returning %d\n", ret
);
5623 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5624 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5625 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5628 CryptDecodeObjectExFunc decodeFunc
;
5629 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5631 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5632 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
5633 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5635 if (!pvStructInfo
&& !pcbStructInfo
)
5637 SetLastError(ERROR_INVALID_PARAMETER
);
5640 if (cbEncoded
> MAX_ENCODED_LEN
)
5642 SetLastError(CRYPT_E_ASN1_LARGE
);
5646 SetLastError(NOERROR
);
5647 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
5648 *(BYTE
**)pvStructInfo
= NULL
;
5649 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
5652 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5653 debugstr_a(lpszStructType
));
5654 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
5658 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
5659 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5662 CryptDecodeObjectFunc pCryptDecodeObject
=
5663 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
5665 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5666 * directly, as that could cause an infinite loop.
5668 if (pCryptDecodeObject
)
5670 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5672 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5673 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
5674 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5675 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
5676 ret
= pCryptDecodeObject(dwCertEncodingType
,
5677 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
5678 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
5681 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5682 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5686 CryptFreeOIDFunctionAddress(hFunc
, 0);
5687 TRACE_(crypt
)("returning %d\n", ret
);
5691 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
5695 TRACE_(crypt
)("(%p)\n", pPFX
);
5697 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
5698 * version integer of length 1 (3 encoded byes) and at least one other
5699 * datum (two encoded bytes), plus at least two bytes for the outer
5700 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
5702 if (pPFX
->cbData
< 7)
5704 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
5708 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
5710 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
5712 /* Need at least three bytes for the integer version */
5713 if (pPFX
->cbData
< 1 + lenLen
+ 3)
5715 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
5716 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
5717 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
5726 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
5729 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);