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"
38 #define NONAMELESSUNION
45 #include "wine/debug.h"
46 #include "wine/exception.h"
47 #include "crypt32_private.h"
49 /* This is a bit arbitrary, but to set some limit: */
50 #define MAX_ENCODED_LEN 0x04000000
52 #define ASN_FLAGS_MASK 0xe0
53 #define ASN_TYPE_MASK 0x1f
55 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
56 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
58 void CRYPT_CopyReversed(BYTE
*dst
, const BYTE
*src
, size_t len
)
61 for (i
= 0; i
< len
; i
++) {
62 dst
[len
- i
- 1] = src
[i
];
66 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
67 DWORD
, DWORD
, void *, DWORD
*);
68 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
69 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
71 /* Internal decoders don't do memory allocation or exception handling, and
72 * they report how many bytes they decoded.
74 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
75 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
77 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
78 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
80 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
81 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
83 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
85 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
86 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
87 /* Assumes algo->Parameters.pbData is set ahead of time. */
88 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
89 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
90 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
91 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
92 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
93 static BOOL
CRYPT_AsnDecodeOctets(const BYTE
*pbEncoded
,
94 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
96 /* Doesn't check the tag, assumes the caller does so */
97 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
98 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
99 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
100 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
101 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
102 * member has been initialized, doesn't do exception handling, and doesn't do
103 * memory allocation. Also doesn't check tag, assumes the caller has checked
106 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
107 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
109 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
110 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
111 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
113 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
114 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
117 /* Gets the number of length bytes from the given (leading) length byte */
118 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
120 /* Helper function to get the encoded length of the data starting at pbEncoded,
121 * where pbEncoded[0] is the tag. If the data are too short to contain a
122 * length or if the length is too large for cbEncoded, sets an appropriate
123 * error code and returns FALSE. If the encoded length is unknown due to
124 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
126 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
133 SetLastError(CRYPT_E_ASN1_CORRUPT
);
136 else if (pbEncoded
[1] <= 0x7f)
138 if (pbEncoded
[1] + 1 > cbEncoded
)
140 SetLastError(CRYPT_E_ASN1_EOD
);
149 else if (pbEncoded
[1] == 0x80)
151 *len
= CMSG_INDEFINITE_LENGTH
;
156 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
158 if (lenLen
> sizeof(DWORD
) + 1)
160 SetLastError(CRYPT_E_ASN1_LARGE
);
163 else if (lenLen
+ 2 > cbEncoded
)
165 SetLastError(CRYPT_E_ASN1_CORRUPT
);
178 if (out
+ lenLen
+ 1 > cbEncoded
)
180 SetLastError(CRYPT_E_ASN1_EOD
);
193 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
194 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
198 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
199 *len
== CMSG_INDEFINITE_LENGTH
)
201 SetLastError(CRYPT_E_ASN1_CORRUPT
);
207 /* Helper function to check *pcbStructInfo, set it to the required size, and
208 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
209 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
210 * pointer to the newly allocated memory.
212 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
213 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
218 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
220 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
221 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
223 *(BYTE
**)pvStructInfo
= LocalAlloc(LPTR
, bytesNeeded
);
224 if (!*(BYTE
**)pvStructInfo
)
227 *pcbStructInfo
= bytesNeeded
;
229 else if (*pcbStructInfo
< bytesNeeded
)
231 *pcbStructInfo
= bytesNeeded
;
232 SetLastError(ERROR_MORE_DATA
);
236 *pcbStructInfo
= bytesNeeded
;
240 static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA
*pDecodePara
, LPVOID pv
)
242 if (pDecodePara
&& pDecodePara
->pfnFree
)
243 pDecodePara
->pfnFree(pv
);
248 /* Helper function to check *pcbStructInfo and set it to the required size.
249 * Assumes pvStructInfo is not NULL.
251 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
255 if (*pcbStructInfo
< bytesNeeded
)
257 *pcbStructInfo
= bytesNeeded
;
258 SetLastError(ERROR_MORE_DATA
);
263 *pcbStructInfo
= bytesNeeded
;
270 * The expected tag of the item. If tag is 0, decodeFunc is called
271 * regardless of the tag value seen.
273 * A sequence is decoded into a struct. The offset member is the
274 * offset of this item within that struct.
276 * The decoder function to use. If this is NULL, then the member isn't
277 * decoded, but minSize space is reserved for it.
279 * The minimum amount of space occupied after decoding. You must set this.
281 * If true, and the tag doesn't match the expected tag for this item,
282 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
283 * filled with 0 for this member.
284 * hasPointer, pointerOffset:
285 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
286 * the offset within the struct of the data pointer (or to the
287 * first data pointer, if more than one exist).
289 * Used by CRYPT_AsnDecodeSequence, not for your use.
291 struct AsnDecodeSequenceItem
295 InternalDecodeFunc decodeFunc
;
303 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
304 #define MEMBERSIZE(s, member, nextmember) \
305 (offsetof(s, nextmember) - offsetof(s, member))
307 /* Decodes the items in a sequence, where the items are described in items,
308 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
309 * pvStructInfo. nextData is a pointer to the memory location at which the
310 * first decoded item with a dynamic pointer should point.
311 * Upon decoding, *cbDecoded is the total number of bytes decoded.
312 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
314 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
315 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
316 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
319 DWORD i
, decoded
= 0;
320 const BYTE
*ptr
= pbEncoded
;
322 TRACE("%p, %ld, %p, %ld, %08lx, %p, %p, %p\n", items
, cItem
, pbEncoded
,
323 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
325 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
327 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
331 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
332 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
334 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
336 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
338 DWORD itemEncodedLen
;
340 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
341 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
343 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
344 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
346 TRACE("Setting next pointer to %p\n",
348 *(BYTE
**)((BYTE
*)pvStructInfo
+
349 items
[i
].pointerOffset
) = nextData
;
351 if (items
[i
].decodeFunc
)
356 TRACE("decoding item %ld\n", i
);
358 TRACE("sizing item %ld\n", i
);
359 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
360 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
361 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
362 : NULL
, &items
[i
].size
, &itemDecoded
);
365 if (items
[i
].size
< items
[i
].minSize
)
366 items
[i
].size
= items
[i
].minSize
;
367 else if (items
[i
].size
> items
[i
].minSize
)
369 /* Account for alignment padding */
370 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
372 TRACE("item %ld size: %ld\n", i
, items
[i
].size
);
373 if (nextData
&& items
[i
].hasPointer
&&
374 items
[i
].size
> items
[i
].minSize
)
375 nextData
+= items
[i
].size
- items
[i
].minSize
;
376 if (itemDecoded
> itemEncodedLen
)
378 WARN("decoded length %ld exceeds encoded %ld\n",
379 itemDecoded
, itemEncodedLen
);
380 SetLastError(CRYPT_E_ASN1_CORRUPT
);
386 decoded
+= itemDecoded
;
387 TRACE("item %ld: decoded %ld bytes\n", i
,
391 else if (items
[i
].optional
&&
392 GetLastError() == CRYPT_E_ASN1_BADTAG
)
394 TRACE("skipping optional item %ld\n", i
);
395 items
[i
].size
= items
[i
].minSize
;
396 SetLastError(NOERROR
);
400 TRACE("item %ld failed: %08lx\n", i
,
403 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
405 ERR("can't use indefinite length encoding without a decoder\n");
406 SetLastError(CRYPT_E_ASN1_CORRUPT
);
411 TRACE("item %ld: decoded %ld bytes\n", i
, itemEncodedLen
);
412 ptr
+= itemEncodedLen
;
413 decoded
+= itemEncodedLen
;
414 items
[i
].size
= items
[i
].minSize
;
417 else if (items
[i
].optional
)
419 TRACE("skipping optional item %ld\n", i
);
420 items
[i
].size
= items
[i
].minSize
;
424 TRACE("item %ld: tag %02x doesn't match expected %02x\n",
425 i
, ptr
[0], items
[i
].tag
);
426 SetLastError(CRYPT_E_ASN1_BADTAG
);
431 else if (items
[i
].optional
)
433 TRACE("missing optional item %ld, skipping\n", i
);
434 items
[i
].size
= items
[i
].minSize
;
438 TRACE("not enough bytes for item %ld, failing\n", i
);
439 SetLastError(CRYPT_E_ASN1_CORRUPT
);
444 *cbDecoded
= decoded
;
445 TRACE("returning %d\n", ret
);
449 /* This decodes an arbitrary sequence into a contiguous block of memory
450 * (basically, a struct.) Each element being decoded is described by a struct
451 * AsnDecodeSequenceItem, see above.
452 * startingPointer is an optional pointer to the first place where dynamic
453 * data will be stored. If you know the starting offset, you may pass it
454 * here. Otherwise, pass NULL, and one will be inferred from the items.
456 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
457 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
458 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
459 DWORD
*pcbDecoded
, void *startingPointer
)
463 TRACE("%p, %ld, %p, %ld, %08lx, %p, %p, %ld, %p\n", items
, cItem
, pbEncoded
,
464 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
469 SetLastError(CRYPT_E_ASN1_EOD
);
472 if (pbEncoded
[0] == ASN_SEQUENCE
)
476 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
478 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
479 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
480 BOOL indefinite
= FALSE
;
482 cbEncoded
-= 1 + lenBytes
;
483 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
489 else if (cbEncoded
< dataLen
)
491 TRACE("dataLen %ld exceeds cbEncoded %ld, failing\n", dataLen
,
493 SetLastError(CRYPT_E_ASN1_CORRUPT
);
498 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
499 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
500 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
502 if (cbDecoded
> cbEncoded
- 2)
504 /* Not enough space for 0 TLV */
505 SetLastError(CRYPT_E_ASN1_CORRUPT
);
508 else if (*(ptr
+ cbDecoded
) != 0 ||
509 *(ptr
+ cbDecoded
+ 1) != 0)
511 TRACE("expected 0 TLV\n");
512 SetLastError(CRYPT_E_ASN1_CORRUPT
);
519 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
521 TRACE("expected %ld decoded, got %ld, failing\n", dataLen
,
523 SetLastError(CRYPT_E_ASN1_CORRUPT
);
528 DWORD i
, bytesNeeded
= 0, structSize
= 0;
530 for (i
= 0; i
< cItem
; i
++)
532 if (items
[i
].size
> items
[i
].minSize
)
533 bytesNeeded
+= items
[i
].size
- items
[i
].minSize
;
534 structSize
= max( structSize
, items
[i
].offset
+ items
[i
].minSize
);
536 bytesNeeded
+= structSize
;
538 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
540 *pcbStructInfo
= bytesNeeded
;
541 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
542 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
546 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
547 pvStructInfo
= *(BYTE
**)pvStructInfo
;
549 nextData
= startingPointer
;
551 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
552 memset(pvStructInfo
, 0, structSize
);
553 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
554 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
556 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
557 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
564 SetLastError(CRYPT_E_ASN1_BADTAG
);
567 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
572 * The expected tag of the entire encoded array (usually a variant
573 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
574 * regardless of the tag seen.
576 * The offset within the outer structure at which the count exists.
577 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
578 * while CRYPT_ATTRIBUTE has countOffset ==
579 * offsetof(CRYPT_ATTRIBUTE, cValue).
581 * The offset within the outer structure at which the array pointer exists.
582 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
583 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
585 * The minimum size of the decoded array. On WIN32, this is always 8:
586 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
589 * used to decode each item in the array
591 * is the minimum size of each decoded item
593 * indicates whether each item has a dynamic pointer
595 * indicates the offset within itemSize at which the pointer exists
597 struct AsnArrayDescriptor
603 InternalDecodeFunc decodeFunc
;
609 struct AsnArrayItemSize
615 /* Decodes an array of like types into a structure described by a struct
616 * AsnArrayDescriptor.
618 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
619 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
620 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
625 TRACE("%p, %p, %ld, %p, %ld\n", arrayDesc
, pbEncoded
,
626 cbEncoded
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
630 SetLastError(CRYPT_E_ASN1_EOD
);
633 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
637 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
639 DWORD bytesNeeded
= arrayDesc
->minArraySize
, cItems
= 0, capacity
= 0, decoded
;
640 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
641 /* There can be arbitrarily many items, but there is often only one.
643 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
645 decoded
= 1 + lenBytes
;
649 BOOL doneDecoding
= FALSE
;
651 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
653 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
660 SetLastError(CRYPT_E_ASN1_CORRUPT
);
667 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
671 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
673 /* Each item decoded may not tolerate extraneous bytes,
674 * so get the length of the next element if known.
676 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
677 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
679 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
680 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
682 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
686 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
687 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
691 /* Ignore an item that failed to decode but the decoder doesn't want to fail the whole process */
699 itemSizes
= &itemSize
;
700 else if (itemSizes
== &itemSize
)
703 itemSizes
= CryptMemAlloc(capacity
* sizeof(struct AsnArrayItemSize
));
704 if (itemSizes
) *itemSizes
= itemSize
;
706 else if (cItems
> capacity
)
708 capacity
= capacity
* 3 / 2;
709 itemSizes
= CryptMemRealloc(itemSizes
, capacity
* sizeof(struct AsnArrayItemSize
));
713 decoded
+= itemDecoded
;
714 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
715 itemSizes
[cItems
- 1].size
= size
;
728 *pcbDecoded
= decoded
;
730 *pcbStructInfo
= bytesNeeded
;
731 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
732 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
739 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
740 pvStructInfo
= *(void **)pvStructInfo
;
741 pcItems
= pvStructInfo
;
743 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
745 rgItems
= (BYTE
*)pvStructInfo
+
746 arrayDesc
->minArraySize
;
747 *(void **)((BYTE
*)pcItems
-
748 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
) =
752 rgItems
= *(void **)((BYTE
*)pcItems
-
753 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
);
754 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
755 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
756 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
761 if (arrayDesc
->hasPointer
)
762 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
763 + arrayDesc
->pointerOffset
) = nextData
;
764 ret
= arrayDesc
->decodeFunc(ptr
,
765 itemSizes
[i
].encodedLen
,
766 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
767 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
768 &itemSizes
[i
].size
, &itemDecoded
);
771 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
775 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
776 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
779 if (itemSizes
!= &itemSize
)
780 CryptMemFree(itemSizes
);
785 SetLastError(CRYPT_E_ASN1_BADTAG
);
791 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
792 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
793 * to CRYPT_E_ASN1_CORRUPT.
794 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
797 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
798 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
803 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
805 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
806 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
808 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
809 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
812 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
814 *pcbStructInfo
= bytesNeeded
;
815 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
817 CRYPT_DER_BLOB
*blob
;
819 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
820 pvStructInfo
= *(BYTE
**)pvStructInfo
;
822 blob
->cbData
= 1 + lenBytes
+ dataLen
;
825 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
826 blob
->pbData
= (BYTE
*)pbEncoded
;
829 assert(blob
->pbData
);
830 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
835 SetLastError(CRYPT_E_ASN1_CORRUPT
);
843 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
844 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
845 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
850 TRACE("(%p, %ld, 0x%08lx, %p, %ld, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
851 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
853 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
856 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
857 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
859 if (ret
&& pvStructInfo
)
861 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
868 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
870 temp
= blob
->pbData
[i
];
871 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
872 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
876 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
880 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
881 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
882 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
886 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
887 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
891 struct AsnDecodeSequenceItem items
[] = {
892 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
893 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
894 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
895 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
896 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
897 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
898 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
899 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
900 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
901 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
904 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
905 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
906 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
907 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
908 pcbStructInfo
, NULL
, NULL
);
912 SetLastError(STATUS_ACCESS_VIOLATION
);
917 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
921 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
922 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
927 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
929 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
931 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
932 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
934 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
939 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
940 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
944 struct AsnDecodeSequenceItem items
[] = {
945 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
946 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
947 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
948 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
951 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
952 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
957 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
958 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
962 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
963 offsetof(CERT_INFO
, cExtension
), offsetof(CERT_INFO
, rgExtension
),
964 FINALMEMBERSIZE(CERT_INFO
, cExtension
),
965 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
966 offsetof(CERT_EXTENSION
, pszObjId
) };
968 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
969 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
971 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
972 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
976 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
977 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
983 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
985 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
987 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
988 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
989 if (ret
&& pcbDecoded
)
990 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
995 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
996 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
997 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1000 struct AsnDecodeSequenceItem items
[] = {
1001 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
1002 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1003 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
1004 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
1005 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
1006 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
1007 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1008 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1009 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1010 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1012 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
1013 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
1015 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
1016 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1018 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
1019 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
1020 FALSE
, TRUE
, offsetof(CERT_INFO
,
1021 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
1022 { ASN_CONTEXT
| 1, offsetof(CERT_INFO
, IssuerUniqueId
),
1023 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1024 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
1025 { ASN_CONTEXT
| 2, offsetof(CERT_INFO
, SubjectUniqueId
),
1026 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1027 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
1028 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
1029 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
1030 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1033 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1034 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1036 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1037 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1039 if (ret
&& pvStructInfo
)
1043 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1044 info
= *(CERT_INFO
**)pvStructInfo
;
1046 info
= pvStructInfo
;
1047 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1048 !info
->Subject
.cbData
)
1050 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1051 /* Don't need to deallocate, because it should have failed on the
1052 * first pass (and no memory was allocated.)
1058 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1062 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1063 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1064 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1068 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1069 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1075 /* Unless told not to, first try to decode it as a signed cert. */
1076 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1078 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1080 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1081 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1082 &signedCert
, &size
);
1086 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1087 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1088 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1089 pvStructInfo
, pcbStructInfo
);
1090 LocalFree(signedCert
);
1093 /* Failing that, try it as an unsigned cert */
1097 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1098 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1099 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1104 SetLastError(STATUS_ACCESS_VIOLATION
);
1108 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1112 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1113 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1117 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1118 offsetof(CRL_ENTRY
, cExtension
), offsetof(CRL_ENTRY
, rgExtension
),
1119 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
),
1120 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1121 offsetof(CERT_EXTENSION
, pszObjId
) };
1123 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1124 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1126 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1127 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1131 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1132 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1135 struct AsnDecodeSequenceItem items
[] = {
1136 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1137 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1138 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1139 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1140 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1141 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1142 CRYPT_AsnDecodeCRLEntryExtensions
,
1143 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1144 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1146 PCRL_ENTRY entry
= pvStructInfo
;
1148 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1151 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1152 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1153 entry
? entry
->SerialNumber
.pbData
: NULL
);
1154 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1156 WARN("empty CRL entry serial number\n");
1157 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1163 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1164 * whose rgCRLEntry member has been set prior to calling.
1166 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1167 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1170 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1171 offsetof(CRL_INFO
, cCRLEntry
), offsetof(CRL_INFO
, rgCRLEntry
),
1172 MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1173 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1174 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1176 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1177 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1179 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1180 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1181 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1185 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1186 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1190 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1191 offsetof(CRL_INFO
, cExtension
), offsetof(CRL_INFO
, rgExtension
),
1192 FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1193 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1194 offsetof(CERT_EXTENSION
, pszObjId
) };
1196 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1197 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1199 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1200 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1204 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1205 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1211 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1213 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1215 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1216 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1217 if (ret
&& pcbDecoded
)
1218 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1223 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1224 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1225 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1227 struct AsnDecodeSequenceItem items
[] = {
1228 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1229 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1230 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1231 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1232 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1233 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1234 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1236 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1237 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1238 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1239 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1240 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1241 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1242 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1243 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1244 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1245 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1249 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1250 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1252 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
), pbEncoded
, cbEncoded
, dwFlags
,
1253 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1255 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1259 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1260 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1261 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1265 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1266 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1272 /* Unless told not to, first try to decode it as a signed crl. */
1273 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1275 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1277 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1278 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1283 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1284 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1285 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1286 pvStructInfo
, pcbStructInfo
);
1287 LocalFree(signedCrl
);
1290 /* Failing that, try it as an unsigned crl */
1294 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1295 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1296 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1301 SetLastError(STATUS_ACCESS_VIOLATION
);
1305 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1309 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1310 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1315 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1316 pvStructInfo
, *pcbStructInfo
);
1318 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1320 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1321 DWORD bytesNeeded
= sizeof(LPSTR
);
1328 snprintf(str
, sizeof(str
), "%d.%d",
1329 pbEncoded
[1 + lenBytes
] / 40,
1330 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1332 bytesNeeded
+= strlen(str
) + 1;
1333 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1334 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1338 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1345 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1348 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1355 snprintf(str
, sizeof(str
), ".%d", val
);
1356 bytesNeeded
+= strlen(str
);
1361 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1363 *pcbStructInfo
= bytesNeeded
;
1364 else if (*pcbStructInfo
< bytesNeeded
)
1366 *pcbStructInfo
= bytesNeeded
;
1367 SetLastError(ERROR_MORE_DATA
);
1375 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1378 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1379 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1381 pszObjId
+= strlen(pszObjId
);
1382 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1383 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1387 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1396 sprintf(pszObjId
, ".%d", val
);
1397 pszObjId
+= strlen(pszObjId
);
1401 *(LPSTR
*)pvStructInfo
= NULL
;
1402 *pcbStructInfo
= bytesNeeded
;
1408 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1409 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1413 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1414 pvStructInfo
, *pcbStructInfo
);
1416 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1417 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1418 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1421 SetLastError(CRYPT_E_ASN1_BADTAG
);
1427 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1428 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1430 struct AsnDecodeSequenceItem items
[] = {
1431 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1432 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1433 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1434 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1435 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1436 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1437 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1438 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1441 PCERT_EXTENSION ext
= pvStructInfo
;
1443 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1447 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1448 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1449 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1450 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1452 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1453 debugstr_a(ext
->pszObjId
));
1454 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1458 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1459 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1460 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1464 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1465 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1469 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1470 offsetof(CERT_EXTENSIONS
, cExtension
),
1471 offsetof(CERT_EXTENSIONS
, rgExtension
),
1472 sizeof(CERT_EXTENSIONS
),
1473 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1474 offsetof(CERT_EXTENSION
, pszObjId
) };
1475 CERT_EXTENSIONS
*exts
= pvStructInfo
;
1477 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1478 exts
->rgExtension
= (CERT_EXTENSION
*)(exts
+ 1);
1479 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1480 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1484 SetLastError(STATUS_ACCESS_VIOLATION
);
1491 /* Warning: this assumes the address of value->Value.pbData is already set, in
1492 * order to avoid overwriting memory. (In some cases, it may change it, if it
1493 * doesn't copy anything to memory.) Be sure to set it correctly!
1495 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1496 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1501 CERT_NAME_VALUE
*value
= pvStructInfo
;
1503 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1505 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1506 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1508 switch (pbEncoded
[0])
1510 case ASN_OCTETSTRING
:
1511 valueType
= CERT_RDN_OCTET_STRING
;
1512 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1513 bytesNeeded
+= dataLen
;
1515 case ASN_NUMERICSTRING
:
1516 valueType
= CERT_RDN_NUMERIC_STRING
;
1517 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1518 bytesNeeded
+= dataLen
;
1520 case ASN_PRINTABLESTRING
:
1521 valueType
= CERT_RDN_PRINTABLE_STRING
;
1522 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1523 bytesNeeded
+= dataLen
;
1526 valueType
= CERT_RDN_IA5_STRING
;
1527 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1528 bytesNeeded
+= dataLen
;
1531 valueType
= CERT_RDN_T61_STRING
;
1532 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1533 bytesNeeded
+= dataLen
;
1535 case ASN_VIDEOTEXSTRING
:
1536 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1537 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1538 bytesNeeded
+= dataLen
;
1540 case ASN_GRAPHICSTRING
:
1541 valueType
= CERT_RDN_GRAPHIC_STRING
;
1542 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1543 bytesNeeded
+= dataLen
;
1545 case ASN_VISIBLESTRING
:
1546 valueType
= CERT_RDN_VISIBLE_STRING
;
1547 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1548 bytesNeeded
+= dataLen
;
1550 case ASN_GENERALSTRING
:
1551 valueType
= CERT_RDN_GENERAL_STRING
;
1552 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1553 bytesNeeded
+= dataLen
;
1555 case ASN_UNIVERSALSTRING
:
1556 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1557 SetLastError(CRYPT_E_ASN1_BADTAG
);
1560 valueType
= CERT_RDN_BMP_STRING
;
1561 bytesNeeded
+= dataLen
;
1563 case ASN_UTF8STRING
:
1564 valueType
= CERT_RDN_UTF8_STRING
;
1565 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1566 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * sizeof(WCHAR
);
1569 SetLastError(CRYPT_E_ASN1_BADTAG
);
1574 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1576 *pcbStructInfo
= bytesNeeded
;
1577 else if (*pcbStructInfo
< bytesNeeded
)
1579 *pcbStructInfo
= bytesNeeded
;
1580 SetLastError(ERROR_MORE_DATA
);
1585 *pcbStructInfo
= bytesNeeded
;
1586 value
->dwValueType
= valueType
;
1591 assert(value
->Value
.pbData
);
1592 switch (pbEncoded
[0])
1594 case ASN_OCTETSTRING
:
1595 case ASN_NUMERICSTRING
:
1596 case ASN_PRINTABLESTRING
:
1599 case ASN_VIDEOTEXSTRING
:
1600 case ASN_GRAPHICSTRING
:
1601 case ASN_VISIBLESTRING
:
1602 case ASN_GENERALSTRING
:
1603 value
->Value
.cbData
= dataLen
;
1604 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1605 memcpy(value
->Value
.pbData
,
1606 pbEncoded
+ 1 + lenBytes
, dataLen
);
1608 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1613 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1615 value
->Value
.cbData
= dataLen
;
1616 for (i
= 0; i
< dataLen
/ 2; i
++)
1617 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1618 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1621 case ASN_UTF8STRING
:
1623 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1625 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1626 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1627 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1634 value
->Value
.cbData
= 0;
1635 value
->Value
.pbData
= NULL
;
1642 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1643 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1644 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1650 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1651 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1652 if (ret
&& pvStructInfo
)
1654 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1655 pcbStructInfo
, *pcbStructInfo
);
1658 CERT_NAME_VALUE
*value
;
1660 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1661 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1662 value
= pvStructInfo
;
1663 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1664 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1665 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1666 pcbStructInfo
, NULL
);
1667 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1668 CRYPT_FreeSpace(pDecodePara
, value
);
1674 SetLastError(STATUS_ACCESS_VIOLATION
);
1681 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1682 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1687 CERT_NAME_VALUE
*value
= pvStructInfo
;
1689 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1691 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1692 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1694 switch (pbEncoded
[0])
1696 case ASN_NUMERICSTRING
:
1697 valueType
= CERT_RDN_NUMERIC_STRING
;
1699 bytesNeeded
+= (dataLen
+ 1) * 2;
1701 case ASN_PRINTABLESTRING
:
1702 valueType
= CERT_RDN_PRINTABLE_STRING
;
1704 bytesNeeded
+= (dataLen
+ 1) * 2;
1707 valueType
= CERT_RDN_IA5_STRING
;
1709 bytesNeeded
+= (dataLen
+ 1) * 2;
1712 valueType
= CERT_RDN_T61_STRING
;
1714 bytesNeeded
+= (dataLen
+ 1) * 2;
1716 case ASN_VIDEOTEXSTRING
:
1717 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1719 bytesNeeded
+= (dataLen
+ 1) * 2;
1721 case ASN_GRAPHICSTRING
:
1722 valueType
= CERT_RDN_GRAPHIC_STRING
;
1724 bytesNeeded
+= (dataLen
+ 1) * 2;
1726 case ASN_VISIBLESTRING
:
1727 valueType
= CERT_RDN_VISIBLE_STRING
;
1729 bytesNeeded
+= (dataLen
+ 1) * 2;
1731 case ASN_GENERALSTRING
:
1732 valueType
= CERT_RDN_GENERAL_STRING
;
1734 bytesNeeded
+= (dataLen
+ 1) * 2;
1736 case ASN_UNIVERSALSTRING
:
1737 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1739 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1742 valueType
= CERT_RDN_BMP_STRING
;
1744 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1746 case ASN_UTF8STRING
:
1747 valueType
= CERT_RDN_UTF8_STRING
;
1749 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1750 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1753 SetLastError(CRYPT_E_ASN1_BADTAG
);
1758 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1760 *pcbStructInfo
= bytesNeeded
;
1761 else if (*pcbStructInfo
< bytesNeeded
)
1763 *pcbStructInfo
= bytesNeeded
;
1764 SetLastError(ERROR_MORE_DATA
);
1769 *pcbStructInfo
= bytesNeeded
;
1770 value
->dwValueType
= valueType
;
1774 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1776 assert(value
->Value
.pbData
);
1777 switch (pbEncoded
[0])
1779 case ASN_NUMERICSTRING
:
1780 case ASN_PRINTABLESTRING
:
1783 case ASN_VIDEOTEXSTRING
:
1784 case ASN_GRAPHICSTRING
:
1785 case ASN_VISIBLESTRING
:
1786 case ASN_GENERALSTRING
:
1787 value
->Value
.cbData
= dataLen
* 2;
1788 for (i
= 0; i
< dataLen
; i
++)
1789 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1792 case ASN_UNIVERSALSTRING
:
1793 value
->Value
.cbData
= dataLen
/ 2;
1794 for (i
= 0; i
< dataLen
/ 4; i
++)
1795 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1796 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1800 value
->Value
.cbData
= dataLen
;
1801 for (i
= 0; i
< dataLen
/ 2; i
++)
1802 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1803 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1806 case ASN_UTF8STRING
:
1807 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1808 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1809 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1810 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1811 value
->Value
.cbData
+= sizeof(WCHAR
);
1817 value
->Value
.cbData
= 0;
1818 value
->Value
.pbData
= NULL
;
1825 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1826 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1827 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1833 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1834 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1835 if (ret
&& pvStructInfo
)
1837 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1838 pcbStructInfo
, *pcbStructInfo
);
1841 CERT_NAME_VALUE
*value
;
1843 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1844 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1845 value
= pvStructInfo
;
1846 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1847 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1848 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1849 pcbStructInfo
, NULL
);
1850 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1851 CRYPT_FreeSpace(pDecodePara
, value
);
1857 SetLastError(STATUS_ACCESS_VIOLATION
);
1864 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1865 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1868 struct AsnDecodeSequenceItem items
[] = {
1869 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1870 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1871 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1872 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1873 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1874 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1876 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1878 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1879 pvStructInfo
, *pcbStructInfo
);
1882 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1883 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1884 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1885 attr
? attr
->pszObjId
: NULL
);
1888 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1889 debugstr_a(attr
->pszObjId
));
1890 TRACE("attr->dwValueType is %ld\n", attr
->dwValueType
);
1892 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1896 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1897 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1900 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1901 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1903 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1904 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1906 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1907 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1911 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1912 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1913 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1919 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1920 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1921 sizeof(CERT_NAME_INFO
),
1922 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1923 offsetof(CERT_RDN
, rgRDNAttr
) };
1924 DWORD bytesNeeded
= 0;
1926 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1927 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1932 *pcbStructInfo
= bytesNeeded
;
1933 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1934 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1936 CERT_NAME_INFO
*info
;
1938 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1939 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1940 info
= pvStructInfo
;
1941 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1942 sizeof(CERT_NAME_INFO
));
1943 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1944 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1945 &bytesNeeded
, NULL
);
1946 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1947 CRYPT_FreeSpace(pDecodePara
, info
);
1953 SetLastError(STATUS_ACCESS_VIOLATION
);
1960 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1961 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1965 struct AsnDecodeSequenceItem items
[] = {
1966 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1967 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1968 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1969 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1970 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1971 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1973 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1975 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1976 pvStructInfo
, *pcbStructInfo
);
1979 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1980 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1981 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1982 attr
? attr
->pszObjId
: NULL
);
1985 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1986 debugstr_a(attr
->pszObjId
));
1987 TRACE("attr->dwValueType is %ld\n", attr
->dwValueType
);
1989 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1993 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1994 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1997 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1998 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
2000 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
2001 offsetof(CERT_RDN_ATTR
, pszObjId
) };
2003 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2004 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2008 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
2009 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2010 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2016 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2017 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2018 sizeof(CERT_NAME_INFO
),
2019 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2020 offsetof(CERT_RDN
, rgRDNAttr
) };
2021 DWORD bytesNeeded
= 0;
2023 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2024 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2029 *pcbStructInfo
= bytesNeeded
;
2030 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2031 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2033 CERT_NAME_INFO
*info
;
2035 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2036 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2037 info
= pvStructInfo
;
2038 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2039 sizeof(CERT_NAME_INFO
));
2040 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2041 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2042 &bytesNeeded
, NULL
);
2043 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2044 CRYPT_FreeSpace(pDecodePara
, info
);
2050 SetLastError(STATUS_ACCESS_VIOLATION
);
2057 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2060 BOOL ret
= TRUE
, done
= FALSE
;
2061 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2063 TRACE("(%p, %ld)\n", pbEncoded
, cbEncoded
);
2070 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2073 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2075 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2077 indefiniteNestingLevels
++;
2078 pbEncoded
+= 1 + lenBytes
;
2079 cbEncoded
-= 1 + lenBytes
;
2080 decoded
+= 1 + lenBytes
;
2081 TRACE("indefiniteNestingLevels = %ld\n",
2082 indefiniteNestingLevels
);
2086 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2087 indefiniteNestingLevels
)
2089 indefiniteNestingLevels
--;
2090 TRACE("indefiniteNestingLevels = %ld\n",
2091 indefiniteNestingLevels
);
2093 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2094 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2095 decoded
+= 1 + lenBytes
+ dataLen
;
2096 if (!indefiniteNestingLevels
)
2100 } while (ret
&& !done
);
2101 /* If we haven't found all 0 TLVs, we haven't found the end */
2102 if (ret
&& indefiniteNestingLevels
)
2104 SetLastError(CRYPT_E_ASN1_EOD
);
2108 *pcbDecoded
= decoded
;
2109 TRACE("returning %d (%ld)\n", ret
, ret
? *pcbDecoded
: 0);
2113 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2114 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2118 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2120 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2121 pvStructInfo
, *pcbStructInfo
);
2123 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2125 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2126 bytesNeeded
+= encodedLen
;
2128 *pcbStructInfo
= bytesNeeded
;
2129 else if (*pcbStructInfo
< bytesNeeded
)
2131 SetLastError(ERROR_MORE_DATA
);
2132 *pcbStructInfo
= bytesNeeded
;
2137 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2139 *pcbStructInfo
= bytesNeeded
;
2140 blob
->cbData
= encodedLen
;
2143 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2144 blob
->pbData
= (LPBYTE
)pbEncoded
;
2147 assert(blob
->pbData
);
2148 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2152 blob
->pbData
= NULL
;
2155 *pcbDecoded
= encodedLen
;
2160 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2161 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2164 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2165 offsetof(CTL_USAGE
, cUsageIdentifier
),
2166 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2168 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2170 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2171 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2175 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2176 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2179 struct AsnArrayDescriptor arrayDesc
= { 0,
2180 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2181 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2182 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2183 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2186 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2187 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2191 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2192 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2194 struct AsnDecodeSequenceItem items
[] = {
2195 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2196 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2197 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2198 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2199 CRYPT_AsnDecodeCTLEntryAttributes
,
2200 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2201 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2204 CTL_ENTRY
*entry
= pvStructInfo
;
2206 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2209 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2210 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2211 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2215 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2216 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2219 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2220 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2221 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2222 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2223 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2225 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2226 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2228 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2229 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2233 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2234 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2238 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2239 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2240 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2241 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2242 offsetof(CERT_EXTENSION
, pszObjId
) };
2244 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2245 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2247 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2248 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2252 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2253 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2259 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2261 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2263 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2264 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2265 if (ret
&& pcbDecoded
)
2266 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2271 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2272 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2273 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2277 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2278 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2282 struct AsnDecodeSequenceItem items
[] = {
2283 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2284 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2285 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2286 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2287 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2288 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2289 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2290 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2291 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2292 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2293 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2294 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2295 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2297 { 0, offsetof(CTL_INFO
, NextUpdate
),
2298 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2300 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2301 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2302 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2303 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2304 CRYPT_AsnDecodeCTLEntries
,
2305 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2306 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2307 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2308 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2309 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2312 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2313 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2314 pcbStructInfo
, NULL
, NULL
);
2318 SetLastError(STATUS_ACCESS_VIOLATION
);
2324 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2325 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2329 struct AsnDecodeSequenceItem items
[] = {
2330 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2331 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2332 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2333 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2334 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2335 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2337 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2339 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2340 pvStructInfo
, *pcbStructInfo
);
2342 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2343 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2344 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2345 TRACE("returning %d\n", ret
);
2349 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2350 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2351 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2355 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2356 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2360 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2361 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2362 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2363 sizeof(CRYPT_SMIME_CAPABILITIES
),
2364 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2365 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2366 CRYPT_SMIME_CAPABILITIES
*capabilities
= pvStructInfo
;
2368 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2369 capabilities
->rgCapability
= (CRYPT_SMIME_CAPABILITY
*)(capabilities
+ 1);
2370 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2371 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2375 SetLastError(STATUS_ACCESS_VIOLATION
);
2378 TRACE("returning %d\n", ret
);
2382 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2383 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2388 LPSTR
*pStr
= pvStructInfo
;
2390 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2392 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2393 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2395 if (pbEncoded
[0] != ASN_IA5STRING
)
2397 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2402 bytesNeeded
+= dataLen
;
2404 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2406 *pcbStructInfo
= bytesNeeded
;
2407 else if (*pcbStructInfo
< bytesNeeded
)
2409 *pcbStructInfo
= bytesNeeded
;
2410 SetLastError(ERROR_MORE_DATA
);
2415 *pcbStructInfo
= bytesNeeded
;
2421 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2432 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2433 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2436 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2437 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2438 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2439 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2440 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2443 TRACE("(%p, %ld, %08lx, %p, %ld)\n", pbEncoded
, cbEncoded
, dwFlags
,
2444 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2446 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2447 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2448 TRACE("returning %d\n", ret
);
2452 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2453 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2457 struct AsnDecodeSequenceItem items
[] = {
2458 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2459 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2460 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2461 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2462 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2463 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2464 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2465 rgNoticeNumbers
), 0 },
2467 DWORD bytesNeeded
= 0;
2469 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2470 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2472 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2473 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2477 /* The caller is expecting a pointer to a
2478 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2479 * CRYPT_AsnDecodeSequence is decoding a
2480 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2481 * needed, and decode again if the requisite space is available.
2483 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2485 *pcbStructInfo
= bytesNeeded
;
2486 else if (*pcbStructInfo
< bytesNeeded
)
2488 *pcbStructInfo
= bytesNeeded
;
2489 SetLastError(ERROR_MORE_DATA
);
2494 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2496 *pcbStructInfo
= bytesNeeded
;
2497 /* The pointer (pvStructInfo) passed in points to the first dynamic
2498 * pointer, so use it as the pointer to the
2499 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2500 * appropriate offset for the first dynamic pointer within the
2501 * notice reference by pointing to the first memory location past
2502 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2505 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2506 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2507 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2508 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
), pbEncoded
, cbEncoded
, dwFlags
,
2509 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
, noticeRef
->pszOrganization
);
2512 TRACE("returning %d\n", ret
);
2516 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2517 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2523 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2525 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2526 DWORD bytesNeeded
= sizeof(LPWSTR
);
2528 switch (pbEncoded
[0])
2530 case ASN_NUMERICSTRING
:
2532 bytesNeeded
+= (dataLen
+ 1) * 2;
2534 case ASN_PRINTABLESTRING
:
2536 bytesNeeded
+= (dataLen
+ 1) * 2;
2540 bytesNeeded
+= (dataLen
+ 1) * 2;
2544 bytesNeeded
+= (dataLen
+ 1) * 2;
2546 case ASN_VIDEOTEXSTRING
:
2548 bytesNeeded
+= (dataLen
+ 1) * 2;
2550 case ASN_GRAPHICSTRING
:
2552 bytesNeeded
+= (dataLen
+ 1) * 2;
2554 case ASN_VISIBLESTRING
:
2556 bytesNeeded
+= (dataLen
+ 1) * 2;
2558 case ASN_GENERALSTRING
:
2560 bytesNeeded
+= (dataLen
+ 1) * 2;
2562 case ASN_UNIVERSALSTRING
:
2564 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2568 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2570 case ASN_UTF8STRING
:
2572 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2573 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2576 SetLastError(CRYPT_E_ASN1_BADTAG
);
2581 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2583 *pcbStructInfo
= bytesNeeded
;
2584 else if (*pcbStructInfo
< bytesNeeded
)
2586 *pcbStructInfo
= bytesNeeded
;
2587 SetLastError(ERROR_MORE_DATA
);
2592 LPWSTR
*pStr
= pvStructInfo
;
2594 *pcbStructInfo
= bytesNeeded
;
2601 switch (pbEncoded
[0])
2603 case ASN_NUMERICSTRING
:
2604 case ASN_PRINTABLESTRING
:
2607 case ASN_VIDEOTEXSTRING
:
2608 case ASN_GRAPHICSTRING
:
2609 case ASN_VISIBLESTRING
:
2610 case ASN_GENERALSTRING
:
2611 for (i
= 0; i
< dataLen
; i
++)
2612 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2615 case ASN_UNIVERSALSTRING
:
2616 for (i
= 0; i
< dataLen
/ 4; i
++)
2617 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2618 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2622 for (i
= 0; i
< dataLen
/ 2; i
++)
2623 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2624 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2627 case ASN_UTF8STRING
:
2629 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2630 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2631 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2644 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2645 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2646 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2649 struct AsnDecodeSequenceItem items
[] = {
2650 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2651 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2652 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2653 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2654 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2655 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2656 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2658 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2660 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2661 pvStructInfo
, *pcbStructInfo
);
2663 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2664 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2665 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2666 TRACE("returning %d\n", ret
);
2670 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2671 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2672 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2673 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2677 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2678 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2682 DWORD bytesNeeded
= 0;
2684 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2685 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2690 *pcbStructInfo
= bytesNeeded
;
2691 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2692 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2694 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2696 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2697 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2698 notice
= pvStructInfo
;
2699 notice
->pNoticeReference
=
2700 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2701 ((BYTE
*)pvStructInfo
+
2702 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2703 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2704 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2705 pvStructInfo
, &bytesNeeded
, NULL
);
2706 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2707 CRYPT_FreeSpace(pDecodePara
, notice
);
2713 SetLastError(STATUS_ACCESS_VIOLATION
);
2716 TRACE("returning %d\n", ret
);
2720 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2721 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2725 struct AsnArrayDescriptor arrayDesc
= { 0,
2726 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2727 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2728 CRYPT_AsnDecodeCopyBytes
,
2729 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2731 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2732 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2734 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2735 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2739 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2740 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2744 struct AsnDecodeSequenceItem items
[] = {
2745 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2746 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2747 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2748 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2749 CRYPT_AsnDecodePKCSAttributeValue
,
2750 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2751 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2753 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2755 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2756 pvStructInfo
, *pcbStructInfo
);
2758 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2759 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2760 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2761 TRACE("returning %d\n", ret
);
2765 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2766 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2767 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2771 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2772 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2776 DWORD bytesNeeded
= 0;
2778 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2779 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2783 *pcbStructInfo
= bytesNeeded
;
2784 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2785 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2787 PCRYPT_ATTRIBUTE attr
;
2789 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2790 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2791 attr
= pvStructInfo
;
2792 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2793 sizeof(CRYPT_ATTRIBUTE
));
2794 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2795 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2797 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2798 CRYPT_FreeSpace(pDecodePara
, attr
);
2804 SetLastError(STATUS_ACCESS_VIOLATION
);
2807 TRACE("returning %d\n", ret
);
2811 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2812 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2815 struct AsnArrayDescriptor arrayDesc
= { 0,
2816 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2817 sizeof(CRYPT_ATTRIBUTES
),
2818 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2819 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2822 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2823 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2827 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2828 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2829 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2833 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2834 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2838 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2839 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2840 sizeof(CRYPT_ATTRIBUTES
),
2841 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2842 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2843 CRYPT_ATTRIBUTES
*attrs
= pvStructInfo
;
2845 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2846 attrs
->rgAttr
= (CRYPT_ATTRIBUTE
*)(attrs
+ 1);
2847 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2848 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2852 SetLastError(STATUS_ACCESS_VIOLATION
);
2855 TRACE("returning %d\n", ret
);
2859 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2860 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2862 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2864 struct AsnDecodeSequenceItem items
[] = {
2865 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2866 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2867 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2868 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2869 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2870 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2873 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2874 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2876 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2877 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2878 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2879 if (ret
&& pvStructInfo
)
2881 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2882 debugstr_a(algo
->pszObjId
));
2887 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2888 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2892 struct AsnDecodeSequenceItem items
[] = {
2893 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2894 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2895 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2896 Algorithm
.pszObjId
) },
2897 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2898 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2899 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2901 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2903 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2904 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2905 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2909 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2910 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2911 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2917 DWORD bytesNeeded
= 0;
2919 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2920 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2923 *pcbStructInfo
= bytesNeeded
;
2924 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2925 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2927 PCERT_PUBLIC_KEY_INFO info
;
2929 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2930 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2931 info
= pvStructInfo
;
2932 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2933 sizeof(CERT_PUBLIC_KEY_INFO
);
2934 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2935 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2936 &bytesNeeded
, NULL
);
2937 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2938 CRYPT_FreeSpace(pDecodePara
, info
);
2944 SetLastError(STATUS_ACCESS_VIOLATION
);
2951 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2952 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2958 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2961 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2963 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2966 if (pbEncoded
[1] > 1)
2968 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2975 *pcbStructInfo
= sizeof(BOOL
);
2978 else if (*pcbStructInfo
< sizeof(BOOL
))
2980 *pcbStructInfo
= sizeof(BOOL
);
2981 SetLastError(ERROR_MORE_DATA
);
2986 *pcbStructInfo
= sizeof(BOOL
);
2987 *(BOOL
*)pvStructInfo
= pbEncoded
[2] != 0;
2990 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
2994 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2995 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2997 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2998 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
3001 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3002 pvStructInfo
, *pcbStructInfo
);
3006 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3009 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3010 if (1 + lenBytes
> cbEncoded
)
3012 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3015 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3017 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3019 case 1: /* rfc822Name */
3020 case 2: /* dNSName */
3021 case 6: /* uniformResourceIdentifier */
3022 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
3024 SetLastError(CRYPT_E_ASN1_RULE
);
3028 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3030 case 4: /* directoryName */
3031 case 7: /* iPAddress */
3032 bytesNeeded
+= dataLen
;
3034 case 8: /* registeredID */
3035 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3039 /* FIXME: ugly, shouldn't need to know internals of OID decode
3040 * function to use it.
3042 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3045 case 0: /* otherName */
3046 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3047 SetLastError(CRYPT_E_ASN1_BADTAG
);
3050 case 3: /* x400Address, unimplemented */
3051 case 5: /* ediPartyName, unimplemented */
3052 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3053 SetLastError(CRYPT_E_ASN1_BADTAG
);
3057 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3058 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3064 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3066 *pcbStructInfo
= bytesNeeded
;
3067 else if (*pcbStructInfo
< bytesNeeded
)
3069 *pcbStructInfo
= bytesNeeded
;
3070 SetLastError(ERROR_MORE_DATA
);
3075 *pcbStructInfo
= bytesNeeded
;
3076 /* MS used values one greater than the asn1 ones.. sigh */
3077 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3078 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3080 case 1: /* rfc822Name */
3081 case 2: /* dNSName */
3082 case 6: /* uniformResourceIdentifier */
3086 for (i
= 0; i
< dataLen
; i
++)
3087 entry
->u
.pwszURL
[i
] =
3088 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3089 entry
->u
.pwszURL
[i
] = 0;
3090 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3091 debugstr_w(entry
->u
.pwszURL
));
3094 case 4: /* directoryName */
3095 /* The data are memory-equivalent with the IPAddress case,
3098 case 7: /* iPAddress */
3099 /* The next data pointer is in the pwszURL spot, that is,
3100 * the first 4 bytes. Need to move it to the next spot.
3102 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3103 entry
->u
.IPAddress
.cbData
= dataLen
;
3104 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3107 case 8: /* registeredID */
3108 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3109 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3118 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3119 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3123 struct AsnArrayDescriptor arrayDesc
= { 0,
3124 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3125 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3126 sizeof(CERT_ALT_NAME_INFO
),
3127 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3128 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3130 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3131 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3133 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3134 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3138 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3139 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3140 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3146 struct AsnDecodeSequenceItem items
[] = {
3147 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3148 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3149 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3150 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3151 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3152 CRYPT_AsnDecodeOctets
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3153 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3154 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3155 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3156 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3157 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3160 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3161 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3162 pcbStructInfo
, NULL
, NULL
);
3166 SetLastError(STATUS_ACCESS_VIOLATION
);
3173 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3174 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3175 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3181 struct AsnDecodeSequenceItem items
[] = {
3182 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3183 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3184 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3185 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3186 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3187 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3188 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3189 AuthorityCertIssuer
.rgAltEntry
), 0 },
3190 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3191 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3192 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3193 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3194 AuthorityCertSerialNumber
.pbData
), 0 },
3197 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3198 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3199 pcbStructInfo
, NULL
, NULL
);
3203 SetLastError(STATUS_ACCESS_VIOLATION
);
3210 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3211 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3214 struct AsnDecodeSequenceItem items
[] = {
3215 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3216 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3217 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3218 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3219 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3220 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3222 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3224 return CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3225 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3226 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3229 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3230 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3231 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3235 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3236 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3240 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3241 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3242 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3243 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3244 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3245 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3246 CERT_AUTHORITY_INFO_ACCESS
*info
= pvStructInfo
;
3248 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3249 info
->rgAccDescr
= (CERT_ACCESS_DESCRIPTION
*)(info
+ 1);
3250 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3251 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3255 SetLastError(STATUS_ACCESS_VIOLATION
);
3262 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3263 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3268 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3269 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3271 /* The caller has already checked the tag, no need to check it again.
3272 * Check the outer length is valid:
3274 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3276 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3279 pbEncoded
+= 1 + lenBytes
;
3280 cbEncoded
-= 1 + lenBytes
;
3281 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3282 cbEncoded
-= 2; /* space for 0 TLV */
3283 /* Check the inner length is valid: */
3284 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3288 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3289 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3290 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3292 if (*(pbEncoded
+ decodedLen
) != 0 ||
3293 *(pbEncoded
+ decodedLen
+ 1) != 0)
3295 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3296 *(pbEncoded
+ decodedLen
),
3297 *(pbEncoded
+ decodedLen
+ 1));
3298 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3304 if (ret
&& pcbDecoded
)
3306 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3307 TRACE("decoded %ld bytes\n", *pcbDecoded
);
3314 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3315 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3318 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3319 struct AsnDecodeSequenceItem items
[] = {
3320 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3321 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3322 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3323 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3324 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3325 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3326 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3330 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3331 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3333 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3334 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3335 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3339 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3340 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3341 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3345 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3346 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3350 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3351 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3352 if (ret
&& pvStructInfo
)
3354 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3355 pcbStructInfo
, *pcbStructInfo
);
3358 CRYPT_CONTENT_INFO
*info
;
3360 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3361 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3362 info
= pvStructInfo
;
3363 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3364 sizeof(CRYPT_CONTENT_INFO
));
3365 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3366 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3367 pcbStructInfo
, NULL
);
3368 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3369 CRYPT_FreeSpace(pDecodePara
, info
);
3375 SetLastError(STATUS_ACCESS_VIOLATION
);
3381 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3382 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3383 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3386 struct AsnDecodeSequenceItem items
[] = {
3387 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3388 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3389 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3390 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3391 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3393 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3394 CRYPT_AsnDecodePKCSContentInfoInternal
,
3395 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3396 ContentInfo
.pszObjId
), 0 },
3397 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3398 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3399 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3402 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3403 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3408 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3409 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3410 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3414 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3415 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3419 DWORD bytesNeeded
= 0;
3421 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3422 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3425 *pcbStructInfo
= bytesNeeded
;
3426 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3427 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3429 CERT_ALT_NAME_INFO
*name
;
3431 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3432 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3433 name
= pvStructInfo
;
3434 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3435 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3436 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3437 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3438 &bytesNeeded
, NULL
);
3439 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3440 CRYPT_FreeSpace(pDecodePara
, name
);
3446 SetLastError(STATUS_ACCESS_VIOLATION
);
3453 struct PATH_LEN_CONSTRAINT
3455 BOOL fPathLenConstraint
;
3456 DWORD dwPathLenConstraint
;
3459 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3460 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3464 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3466 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3467 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3471 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3473 *pcbStructInfo
= bytesNeeded
;
3475 else if (*pcbStructInfo
< bytesNeeded
)
3477 SetLastError(ERROR_MORE_DATA
);
3478 *pcbStructInfo
= bytesNeeded
;
3483 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3485 *pcbStructInfo
= bytesNeeded
;
3486 size
= sizeof(constraint
->dwPathLenConstraint
);
3487 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3488 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3490 constraint
->fPathLenConstraint
= TRUE
;
3491 TRACE("got an int, dwPathLenConstraint is %ld\n",
3492 constraint
->dwPathLenConstraint
);
3494 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
3498 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3499 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3503 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3504 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3505 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3506 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3507 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3508 offsetof(CERT_NAME_BLOB
, pbData
) };
3510 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3511 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3513 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3514 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3515 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
3519 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3520 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3521 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3527 struct AsnDecodeSequenceItem items
[] = {
3528 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3529 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3530 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3531 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3532 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3533 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3534 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3535 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3536 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3538 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3541 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3542 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3543 pcbStructInfo
, NULL
, NULL
);
3547 SetLastError(STATUS_ACCESS_VIOLATION
);
3554 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3555 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3556 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3562 struct AsnDecodeSequenceItem items
[] = {
3563 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3564 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3565 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3566 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3567 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3570 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3571 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3572 pcbStructInfo
, NULL
, NULL
);
3576 SetLastError(STATUS_ACCESS_VIOLATION
);
3583 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3584 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3587 struct AsnDecodeSequenceItem items
[] = {
3588 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3589 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3590 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3592 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3593 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3594 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3597 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3599 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3600 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3602 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3603 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3604 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3608 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3609 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3613 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3614 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3615 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3616 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3617 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3618 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3620 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3621 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3623 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3624 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3625 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
3629 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3630 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3632 struct AsnDecodeSequenceItem items
[] = {
3633 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3634 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3635 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3636 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3637 CRYPT_AsnDecodePolicyQualifiers
,
3638 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3639 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3641 CERT_POLICY_INFO
*info
= pvStructInfo
;
3644 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3645 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3647 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3648 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3649 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3653 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3654 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3655 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3659 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3660 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3664 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3665 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3666 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3667 sizeof(CERT_POLICIES_INFO
),
3668 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3669 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3670 CERT_POLICIES_INFO
*info
= pvStructInfo
;
3672 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3673 info
->rgPolicyInfo
= (CERT_POLICY_INFO
*)(info
+ 1);
3675 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3676 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3680 SetLastError(STATUS_ACCESS_VIOLATION
);
3686 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3687 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3690 struct AsnDecodeSequenceItem items
[] = {
3691 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3692 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3693 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3694 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3695 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3696 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3698 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3701 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3702 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3704 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3705 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3706 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3710 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3711 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3712 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3716 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3717 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3721 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3722 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3723 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3724 sizeof(CERT_POLICY_MAPPING
),
3725 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3726 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3727 CERT_POLICY_MAPPINGS_INFO
*info
= pvStructInfo
;
3729 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3730 info
->rgPolicyMapping
= (CERT_POLICY_MAPPING
*)(info
+ 1);
3731 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3732 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3736 SetLastError(STATUS_ACCESS_VIOLATION
);
3742 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3743 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3747 DWORD skip
, size
= sizeof(skip
);
3751 SetLastError(CRYPT_E_ASN1_EOD
);
3754 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3756 SetLastError(CRYPT_E_ASN1_BADTAG
);
3759 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3760 &skip
, &size
, pcbDecoded
)))
3762 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3763 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3766 *pcbStructInfo
= bytesNeeded
;
3767 else if (*pcbStructInfo
< bytesNeeded
)
3769 *pcbStructInfo
= bytesNeeded
;
3770 SetLastError(ERROR_MORE_DATA
);
3775 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3776 CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
);
3778 *pcbStructInfo
= bytesNeeded
;
3779 /* The BOOL is implicit: if the integer is present, then it's
3782 info
->fRequireExplicitPolicy
= TRUE
;
3783 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3789 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3790 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3794 DWORD skip
, size
= sizeof(skip
);
3798 SetLastError(CRYPT_E_ASN1_EOD
);
3801 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3803 SetLastError(CRYPT_E_ASN1_BADTAG
);
3806 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3807 &skip
, &size
, pcbDecoded
)))
3809 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3810 fInhibitPolicyMapping
);
3813 *pcbStructInfo
= bytesNeeded
;
3814 else if (*pcbStructInfo
< bytesNeeded
)
3816 *pcbStructInfo
= bytesNeeded
;
3817 SetLastError(ERROR_MORE_DATA
);
3822 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3823 CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
);
3825 *pcbStructInfo
= bytesNeeded
;
3826 /* The BOOL is implicit: if the integer is present, then it's
3829 info
->fInhibitPolicyMapping
= TRUE
;
3830 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3836 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3837 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3838 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3839 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3843 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3844 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3848 struct AsnDecodeSequenceItem items
[] = {
3850 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3851 CRYPT_AsnDecodeRequireExplicit
,
3852 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3853 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3855 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3856 CRYPT_AsnDecodeInhibitMapping
,
3857 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3858 TRUE
, FALSE
, 0, 0 },
3861 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3862 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3863 pcbStructInfo
, NULL
, NULL
);
3867 SetLastError(STATUS_ACCESS_VIOLATION
);
3873 #define RSA1_MAGIC 0x31415352
3875 struct DECODED_RSA_PUB_KEY
3877 CRYPT_INTEGER_BLOB pubexp
;
3878 CRYPT_INTEGER_BLOB modulus
;
3881 /* Helper function to decode an ASN.1 DER encoded RSA public key, writing the decoded
3882 * key into 'decodedKey', and the length into 'size'. The memory
3883 * for 'decodedKey' is allocated with 'CRYPT_DECODE_ALLOC_FLAG'
3885 static BOOL
CRYPT_raw_decode_rsa_pub_key(struct DECODED_RSA_PUB_KEY
**decodedKey
,
3886 DWORD
*size
, const BYTE
*pbEncoded
, DWORD cbEncoded
)
3890 struct AsnDecodeSequenceItem items
[] = {
3891 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3892 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3893 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3895 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3896 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3897 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
.pbData
),
3901 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3902 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, decodedKey
,
3905 if (ret
&& (*decodedKey
)->pubexp
.cbData
> sizeof(DWORD
))
3907 WARN("Unexpected exponent length %lu.\n", (*decodedKey
)->pubexp
.cbData
);
3908 LocalFree(*decodedKey
);
3909 SetLastError(CRYPT_E_ASN1_LARGE
);
3916 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey_Bcrypt(DWORD dwCertEncodingType
,
3917 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3918 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3924 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3927 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3928 pvStructInfo
, *pcbStructInfo
);
3930 ret
= CRYPT_raw_decode_rsa_pub_key(&decodedKey
, &size
, pbEncoded
, cbEncoded
);
3933 /* Header, exponent, and modulus */
3934 DWORD bytesNeeded
= sizeof(BCRYPT_RSAKEY_BLOB
) + decodedKey
->pubexp
.cbData
+
3935 decodedKey
->modulus
.cbData
;
3939 *pcbStructInfo
= bytesNeeded
;
3942 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3943 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3945 BCRYPT_RSAKEY_BLOB
*hdr
;
3947 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3948 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3951 hdr
->Magic
= BCRYPT_RSAPUBLIC_MAGIC
;
3952 hdr
->BitLength
= decodedKey
->modulus
.cbData
* 8;
3953 hdr
->cbPublicExp
= decodedKey
->pubexp
.cbData
;
3954 hdr
->cbModulus
= decodedKey
->modulus
.cbData
;
3957 /* CNG_RSA_PUBLIC_KEY_BLOB always stores the exponent and modulus
3958 * in big-endian format, so we need to convert from little-endian
3960 CRYPT_CopyReversed((BYTE
*)pvStructInfo
+ sizeof(BCRYPT_RSAKEY_BLOB
),
3961 decodedKey
->pubexp
.pbData
, hdr
->cbPublicExp
);
3962 CRYPT_CopyReversed((BYTE
*)pvStructInfo
+ sizeof(BCRYPT_RSAKEY_BLOB
) +
3963 hdr
->cbPublicExp
, decodedKey
->modulus
.pbData
,
3964 decodedKey
->modulus
.cbData
);
3966 LocalFree(decodedKey
);
3971 SetLastError(STATUS_ACCESS_VIOLATION
);
3979 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3980 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3981 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3987 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3989 ret
= CRYPT_raw_decode_rsa_pub_key(&decodedKey
, &size
, pbEncoded
, cbEncoded
);
3992 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3993 decodedKey
->modulus
.cbData
;
3997 *pcbStructInfo
= bytesNeeded
;
3999 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4000 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4003 RSAPUBKEY
*rsaPubKey
;
4006 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4007 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4009 hdr
->bType
= PUBLICKEYBLOB
;
4010 hdr
->bVersion
= CUR_BLOB_VERSION
;
4012 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
4013 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
4014 sizeof(BLOBHEADER
));
4015 rsaPubKey
->magic
= RSA1_MAGIC
;
4016 rsaPubKey
->pubexp
= 0;
4017 assert(decodedKey
->pubexp
.cbData
<= sizeof(rsaPubKey
->pubexp
));
4018 for (i
= 0; i
< decodedKey
->pubexp
.cbData
; ++i
)
4019 rsaPubKey
->pubexp
|= decodedKey
->pubexp
.pbData
[i
] << (i
* 8);
4021 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
4022 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
4023 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
4024 decodedKey
->modulus
.cbData
);
4026 LocalFree(decodedKey
);
4031 SetLastError(STATUS_ACCESS_VIOLATION
);
4038 #define RSA2_MAGIC 0x32415352
4040 struct DECODED_RSA_PRIV_KEY
4044 CRYPT_INTEGER_BLOB modulus
;
4045 CRYPT_INTEGER_BLOB privexp
;
4046 CRYPT_INTEGER_BLOB prime1
;
4047 CRYPT_INTEGER_BLOB prime2
;
4048 CRYPT_INTEGER_BLOB exponent1
;
4049 CRYPT_INTEGER_BLOB exponent2
;
4050 CRYPT_INTEGER_BLOB coefficient
;
4053 static BOOL WINAPI
CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType
,
4054 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4055 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4062 struct AsnDecodeSequenceItem items
[] = {
4063 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, version
),
4064 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4065 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
),
4066 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4067 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
.pbData
),
4069 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, pubexp
),
4070 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4071 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
),
4072 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4073 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
.pbData
),
4075 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
),
4076 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4077 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
.pbData
),
4079 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
),
4080 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4081 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
.pbData
),
4083 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
),
4084 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4085 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
.pbData
),
4087 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
),
4088 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4089 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
.pbData
),
4091 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
),
4092 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4093 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
.pbData
),
4096 struct DECODED_RSA_PRIV_KEY
*decodedKey
= NULL
;
4099 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
4100 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
4104 halflen
= decodedKey
->prime1
.cbData
;
4105 if (halflen
< decodedKey
->prime2
.cbData
)
4106 halflen
= decodedKey
->prime2
.cbData
;
4107 if (halflen
< decodedKey
->exponent1
.cbData
)
4108 halflen
= decodedKey
->exponent1
.cbData
;
4109 if (halflen
< decodedKey
->exponent2
.cbData
)
4110 halflen
= decodedKey
->exponent2
.cbData
;
4111 if (halflen
< decodedKey
->coefficient
.cbData
)
4112 halflen
= decodedKey
->coefficient
.cbData
;
4113 if (halflen
* 2 < decodedKey
->modulus
.cbData
)
4114 halflen
= decodedKey
->modulus
.cbData
/ 2 + decodedKey
->modulus
.cbData
% 2;
4115 if (halflen
* 2 < decodedKey
->privexp
.cbData
)
4116 halflen
= decodedKey
->privexp
.cbData
/ 2 + decodedKey
->privexp
.cbData
% 2;
4120 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
4125 *pcbStructInfo
= bytesNeeded
;
4128 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4129 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4132 RSAPUBKEY
*rsaPubKey
;
4135 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4136 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4139 hdr
->bType
= PRIVATEKEYBLOB
;
4140 hdr
->bVersion
= CUR_BLOB_VERSION
;
4142 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
4144 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
4145 sizeof(BLOBHEADER
));
4146 rsaPubKey
->magic
= RSA2_MAGIC
;
4147 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
4148 rsaPubKey
->bitlen
= halflen
* 16;
4150 vardata
= (BYTE
*)(rsaPubKey
+ 1);
4151 memset(vardata
, 0, halflen
* 9);
4153 decodedKey
->modulus
.pbData
, decodedKey
->modulus
.cbData
);
4154 memcpy(vardata
+ halflen
* 2,
4155 decodedKey
->prime1
.pbData
, decodedKey
->prime1
.cbData
);
4156 memcpy(vardata
+ halflen
* 3,
4157 decodedKey
->prime2
.pbData
, decodedKey
->prime2
.cbData
);
4158 memcpy(vardata
+ halflen
* 4,
4159 decodedKey
->exponent1
.pbData
, decodedKey
->exponent1
.cbData
);
4160 memcpy(vardata
+ halflen
* 5,
4161 decodedKey
->exponent2
.pbData
, decodedKey
->exponent2
.cbData
);
4162 memcpy(vardata
+ halflen
* 6,
4163 decodedKey
->coefficient
.pbData
, decodedKey
->coefficient
.cbData
);
4164 memcpy(vardata
+ halflen
* 7,
4165 decodedKey
->privexp
.pbData
, decodedKey
->privexp
.cbData
);
4169 LocalFree(decodedKey
);
4174 SetLastError(STATUS_ACCESS_VIOLATION
);
4181 static BOOL
CRYPT_AsnDecodeOctets(const BYTE
*pbEncoded
,
4182 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4186 DWORD bytesNeeded
, dataLen
;
4188 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4189 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4191 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4193 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4195 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4196 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
4198 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
4200 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4202 *pcbStructInfo
= bytesNeeded
;
4203 else if (*pcbStructInfo
< bytesNeeded
)
4205 SetLastError(ERROR_MORE_DATA
);
4206 *pcbStructInfo
= bytesNeeded
;
4211 CRYPT_DATA_BLOB
*blob
;
4213 *pcbStructInfo
= bytesNeeded
;
4214 blob
= pvStructInfo
;
4215 blob
->cbData
= dataLen
;
4216 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4217 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
4220 assert(blob
->pbData
);
4222 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
4230 static BOOL
CRYPT_AsnDecodeOctetStringInternal(const BYTE
*encoded
, DWORD encoded_size
,
4231 DWORD flags
, void *buf
, DWORD
*buf_size
, DWORD
*ret_decoded
)
4233 DWORD decoded
= 0, indefinite_len_depth
= 0, len_size
, len
, bytes_needed
;
4234 CRYPT_DATA_BLOB
*blob
;
4237 while (encoded
[0] == (ASN_CONSTRUCTOR
| ASN_OCTETSTRING
))
4239 if (!CRYPT_GetLengthIndefinite(encoded
, encoded_size
, &len
))
4242 len_size
= GET_LEN_BYTES(encoded
[1]);
4243 encoded
+= 1 + len_size
;
4244 encoded_size
-= 1 + len_size
;
4245 decoded
+= 1 + len_size
;
4247 if (len
== CMSG_INDEFINITE_LENGTH
)
4249 indefinite_len_depth
++;
4250 if (encoded_size
< 2)
4252 SetLastError(CRYPT_E_ASN1_EOD
);
4260 if (encoded
[0] != ASN_OCTETSTRING
)
4262 WARN("Unexpected tag %02x\n", encoded
[0]);
4263 SetLastError(CRYPT_E_ASN1_BADTAG
);
4267 if (!CRYPT_GetLen(encoded
, encoded_size
, &len
))
4269 len_size
= GET_LEN_BYTES(encoded
[1]);
4270 decoded
+= 1 + len_size
+ len
;
4271 encoded_size
-= 1 + len_size
;
4273 if (len
> encoded_size
)
4275 SetLastError(CRYPT_E_ASN1_EOD
);
4279 *ret_decoded
= decoded
;
4281 encoded
+= 1 + len_size
;
4285 while (indefinite_len_depth
--)
4287 if (encoded
[0] || encoded
[1])
4289 TRACE("expected 0 TLV, got %02x %02x\n", encoded
[0], encoded
[1]);
4290 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4295 bytes_needed
= sizeof(*blob
);
4296 if (!(flags
& CRYPT_DECODE_NOCOPY_FLAG
)) bytes_needed
+= len
;
4299 *buf_size
= bytes_needed
;
4302 if (*buf_size
< bytes_needed
)
4304 SetLastError(ERROR_MORE_DATA
);
4305 *buf_size
= bytes_needed
;
4309 *buf_size
= bytes_needed
;
4312 if (flags
& CRYPT_DECODE_NOCOPY_FLAG
)
4313 blob
->pbData
= (BYTE
*)string
;
4314 else if (blob
->cbData
)
4315 memcpy(blob
->pbData
, string
, blob
->cbData
);
4318 *ret_decoded
= decoded
;
4322 static BOOL WINAPI
CRYPT_AsnDecodeOctetString(DWORD dwCertEncodingType
,
4323 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4324 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4328 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
4329 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4333 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4339 DWORD bytesNeeded
= 0;
4341 if ((ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4342 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4345 *pcbStructInfo
= bytesNeeded
;
4346 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4347 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4349 CRYPT_DATA_BLOB
*blob
;
4351 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4352 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4353 blob
= pvStructInfo
;
4354 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4355 ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4356 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4357 &bytesNeeded
, NULL
);
4358 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4359 CRYPT_FreeSpace(pDecodePara
, blob
);
4365 SetLastError(STATUS_ACCESS_VIOLATION
);
4372 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4373 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4376 DWORD bytesNeeded
, dataLen
;
4377 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4379 TRACE("(%p, %ld, 0x%08lx, %p, %ld, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4380 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4382 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4384 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4385 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4387 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4389 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4391 *pcbStructInfo
= bytesNeeded
;
4392 else if (*pcbStructInfo
< bytesNeeded
)
4394 *pcbStructInfo
= bytesNeeded
;
4395 SetLastError(ERROR_MORE_DATA
);
4400 CRYPT_BIT_BLOB
*blob
;
4402 *pcbStructInfo
= bytesNeeded
;
4403 blob
= pvStructInfo
;
4404 blob
->cbData
= dataLen
- 1;
4405 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4406 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4408 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4412 assert(blob
->pbData
);
4415 BYTE mask
= 0xff << blob
->cUnusedBits
;
4417 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4419 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4427 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4428 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4429 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4433 TRACE("(%p, %ld, 0x%08lx, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4434 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4438 DWORD bytesNeeded
= 0;
4442 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4445 else if (pbEncoded
[0] != ASN_BITSTRING
)
4447 SetLastError(CRYPT_E_ASN1_BADTAG
);
4450 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4451 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4454 *pcbStructInfo
= bytesNeeded
;
4455 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4456 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4458 CRYPT_BIT_BLOB
*blob
;
4460 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4461 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4462 blob
= pvStructInfo
;
4463 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4464 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4465 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4466 &bytesNeeded
, NULL
);
4467 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4468 CRYPT_FreeSpace(pDecodePara
, blob
);
4474 SetLastError(STATUS_ACCESS_VIOLATION
);
4478 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
4482 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4483 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4484 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4489 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4491 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4494 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4495 if (dataLen
> sizeof(int))
4497 SetLastError(CRYPT_E_ASN1_LARGE
);
4500 else if (!pvStructInfo
)
4501 *pcbStructInfo
= sizeof(int);
4502 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4506 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4508 /* initialize to a negative value to sign-extend */
4513 for (i
= 0; i
< dataLen
; i
++)
4516 val
|= pbEncoded
[1 + lenBytes
+ i
];
4518 memcpy(pvStructInfo
, &val
, sizeof(int));
4524 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4525 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4526 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4532 DWORD bytesNeeded
= 0;
4536 SetLastError(CRYPT_E_ASN1_EOD
);
4539 else if (pbEncoded
[0] != ASN_INTEGER
)
4541 SetLastError(CRYPT_E_ASN1_BADTAG
);
4545 ret
= CRYPT_AsnDecodeIntInternal(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_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4557 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4558 &bytesNeeded
, NULL
);
4559 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4560 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4566 SetLastError(STATUS_ACCESS_VIOLATION
);
4573 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4574 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4578 DWORD bytesNeeded
, dataLen
;
4580 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4582 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4584 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4586 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4588 *pcbStructInfo
= bytesNeeded
;
4589 else if (*pcbStructInfo
< bytesNeeded
)
4591 *pcbStructInfo
= bytesNeeded
;
4592 SetLastError(ERROR_MORE_DATA
);
4597 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4599 *pcbStructInfo
= bytesNeeded
;
4600 blob
->cbData
= dataLen
;
4601 assert(blob
->pbData
);
4606 for (i
= 0; i
< blob
->cbData
; i
++)
4608 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4617 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4618 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4619 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4625 DWORD bytesNeeded
= 0;
4627 if (pbEncoded
[0] != ASN_INTEGER
)
4629 SetLastError(CRYPT_E_ASN1_BADTAG
);
4633 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4634 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4638 *pcbStructInfo
= bytesNeeded
;
4639 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4640 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4642 CRYPT_INTEGER_BLOB
*blob
;
4644 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4645 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4646 blob
= pvStructInfo
;
4647 blob
->pbData
= (BYTE
*)pvStructInfo
+
4648 sizeof(CRYPT_INTEGER_BLOB
);
4649 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4650 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4651 &bytesNeeded
, NULL
);
4652 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4653 CRYPT_FreeSpace(pDecodePara
, blob
);
4659 SetLastError(STATUS_ACCESS_VIOLATION
);
4666 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4667 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4672 if (pbEncoded
[0] == ASN_INTEGER
)
4674 DWORD bytesNeeded
, dataLen
;
4676 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4678 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4681 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4682 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4684 *pcbStructInfo
= bytesNeeded
;
4685 else if (*pcbStructInfo
< bytesNeeded
)
4687 *pcbStructInfo
= bytesNeeded
;
4688 SetLastError(ERROR_MORE_DATA
);
4693 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4695 *pcbStructInfo
= bytesNeeded
;
4696 blob
->cbData
= dataLen
;
4697 assert(blob
->pbData
);
4698 /* remove leading zero byte if it exists */
4699 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4708 for (i
= 0; i
< blob
->cbData
; i
++)
4710 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4719 SetLastError(CRYPT_E_ASN1_BADTAG
);
4725 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4726 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4727 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4733 DWORD bytesNeeded
= 0;
4735 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4736 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4739 *pcbStructInfo
= bytesNeeded
;
4740 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4741 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4743 CRYPT_INTEGER_BLOB
*blob
;
4745 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4746 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4747 blob
= pvStructInfo
;
4748 blob
->pbData
= (BYTE
*)pvStructInfo
+
4749 sizeof(CRYPT_INTEGER_BLOB
);
4750 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4751 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4752 &bytesNeeded
, NULL
);
4753 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4754 CRYPT_FreeSpace(pDecodePara
, blob
);
4760 SetLastError(STATUS_ACCESS_VIOLATION
);
4767 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4768 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4769 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4775 *pcbStructInfo
= sizeof(int);
4780 if (pbEncoded
[0] == ASN_ENUMERATED
)
4782 unsigned int val
= 0, i
;
4786 SetLastError(CRYPT_E_ASN1_EOD
);
4789 else if (pbEncoded
[1] == 0)
4791 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4796 /* A little strange looking, but we have to accept a sign byte:
4797 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4798 * assuming a small length is okay here, it has to be in short
4801 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4803 SetLastError(CRYPT_E_ASN1_LARGE
);
4806 for (i
= 0; i
< pbEncoded
[1]; i
++)
4809 val
|= pbEncoded
[2 + i
];
4811 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4812 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4814 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4815 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4816 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4822 SetLastError(CRYPT_E_ASN1_BADTAG
);
4828 SetLastError(STATUS_ACCESS_VIOLATION
);
4835 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4838 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4843 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4845 if (!isdigit(*(pbEncoded))) \
4847 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4853 (word) += *(pbEncoded)++ - '0'; \
4858 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4859 SYSTEMTIME
*sysTime
)
4863 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4865 WORD hours
, minutes
= 0;
4866 BYTE sign
= *pbEncoded
++;
4869 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4870 if (ret
&& hours
>= 24)
4872 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4877 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4878 if (ret
&& minutes
>= 60)
4880 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4888 sysTime
->wHour
+= hours
;
4889 sysTime
->wMinute
+= minutes
;
4893 if (hours
> sysTime
->wHour
)
4896 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4899 sysTime
->wHour
-= hours
;
4900 if (minutes
> sysTime
->wMinute
)
4903 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4906 sysTime
->wMinute
-= minutes
;
4913 #define MIN_ENCODED_TIME_LENGTH 10
4915 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4916 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4921 if (pbEncoded
[0] == ASN_UTCTIME
)
4924 SetLastError(CRYPT_E_ASN1_EOD
);
4925 else if (pbEncoded
[1] > 0x7f)
4927 /* long-form date strings really can't be valid */
4928 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4932 SYSTEMTIME sysTime
= { 0 };
4933 BYTE len
= pbEncoded
[1];
4935 if (len
< MIN_ENCODED_TIME_LENGTH
)
4936 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4941 *pcbDecoded
= 2 + len
;
4943 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4944 if (sysTime
.wYear
>= 50)
4945 sysTime
.wYear
+= 1900;
4947 sysTime
.wYear
+= 2000;
4948 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4949 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4950 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4951 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4954 if (len
>= 2 && isdigit(*pbEncoded
) &&
4955 isdigit(*(pbEncoded
+ 1)))
4956 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4958 else if (isdigit(*pbEncoded
))
4959 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4962 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4968 *pcbStructInfo
= sizeof(FILETIME
);
4969 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4971 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4977 SetLastError(CRYPT_E_ASN1_BADTAG
);
4981 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4982 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4983 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4989 DWORD bytesNeeded
= 0;
4991 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4992 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4996 *pcbStructInfo
= bytesNeeded
;
4997 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4998 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5000 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5001 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5002 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
5003 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5004 &bytesNeeded
, NULL
);
5005 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5006 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
5012 SetLastError(STATUS_ACCESS_VIOLATION
);
5018 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
5019 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5024 if (pbEncoded
[0] == ASN_GENERALTIME
)
5027 SetLastError(CRYPT_E_ASN1_EOD
);
5028 else if (pbEncoded
[1] > 0x7f)
5030 /* long-form date strings really can't be valid */
5031 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5035 BYTE len
= pbEncoded
[1];
5037 if (len
< MIN_ENCODED_TIME_LENGTH
)
5038 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5041 SYSTEMTIME sysTime
= { 0 };
5045 *pcbDecoded
= 2 + len
;
5047 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
5048 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
5049 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
5050 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
5053 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
5056 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
5058 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
5065 /* workaround macro weirdness */
5066 digits
= min(len
, 3);
5067 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
5068 sysTime
.wMilliseconds
);
5071 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
5077 *pcbStructInfo
= sizeof(FILETIME
);
5078 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
5080 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
5086 SetLastError(CRYPT_E_ASN1_BADTAG
);
5090 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
5091 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5095 InternalDecodeFunc decode
= NULL
;
5097 if (pbEncoded
[0] == ASN_UTCTIME
)
5098 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
5099 else if (pbEncoded
[0] == ASN_GENERALTIME
)
5100 decode
= CRYPT_AsnDecodeGeneralizedTime
;
5102 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
5103 pcbStructInfo
, pcbDecoded
);
5106 SetLastError(CRYPT_E_ASN1_BADTAG
);
5112 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
5113 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5114 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5120 DWORD bytesNeeded
= 0;
5122 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5123 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
5127 *pcbStructInfo
= bytesNeeded
;
5128 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5129 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5131 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5132 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5133 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5134 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5135 &bytesNeeded
, NULL
);
5136 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5137 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
5143 SetLastError(STATUS_ACCESS_VIOLATION
);
5150 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
5151 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5152 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5158 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
5160 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
5162 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5167 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5168 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
5170 ptr
= pbEncoded
+ 1 + lenBytes
;
5171 remainingLen
= dataLen
;
5172 while (ret
&& remainingLen
)
5176 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5179 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5181 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5182 ptr
+= 1 + nextLenBytes
+ nextLen
;
5183 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
5184 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
5185 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
5191 CRYPT_SEQUENCE_OF_ANY
*seq
;
5196 *pcbStructInfo
= bytesNeeded
;
5197 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5198 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5200 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5201 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5203 seq
->cValue
= cValue
;
5204 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
5206 nextPtr
= (BYTE
*)seq
->rgValue
+
5207 cValue
* sizeof(CRYPT_DER_BLOB
);
5208 ptr
= pbEncoded
+ 1 + lenBytes
;
5209 remainingLen
= dataLen
;
5211 while (ret
&& remainingLen
)
5215 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5218 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5220 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
5222 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
5223 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
5226 seq
->rgValue
[i
].pbData
= nextPtr
;
5227 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
5229 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
5231 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5232 ptr
+= 1 + nextLenBytes
+ nextLen
;
5236 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5237 CRYPT_FreeSpace(pDecodePara
, seq
);
5244 SetLastError(CRYPT_E_ASN1_BADTAG
);
5250 SetLastError(STATUS_ACCESS_VIOLATION
);
5257 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
5258 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5263 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
5265 DWORD bytesNeeded
= 0, dataLen
;
5267 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5269 struct AsnArrayDescriptor arrayDesc
= {
5270 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5271 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
5272 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
5273 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
5274 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
5275 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
5276 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5281 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5282 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5283 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
5284 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
5285 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
5288 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
5290 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
5292 *pcbStructInfo
= bytesNeeded
;
5293 else if (*pcbStructInfo
< bytesNeeded
)
5295 *pcbStructInfo
= bytesNeeded
;
5296 SetLastError(ERROR_MORE_DATA
);
5301 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
5303 *pcbStructInfo
= bytesNeeded
;
5306 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
5307 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5308 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5309 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
5313 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
5319 SetLastError(CRYPT_E_ASN1_BADTAG
);
5325 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5326 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5328 struct AsnDecodeSequenceItem items
[] = {
5329 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
5330 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5331 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
5332 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5333 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
5334 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
5335 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
5336 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
5337 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
5338 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
5340 CRL_DIST_POINT
*point
= pvStructInfo
;
5343 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5344 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5345 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5349 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5350 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5351 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5355 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5356 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5360 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5361 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
5362 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
5363 sizeof(CRL_DIST_POINTS_INFO
),
5364 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5365 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5366 CRL_DIST_POINTS_INFO
*info
= pvStructInfo
;
5368 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5369 info
->rgDistPoint
= (CRL_DIST_POINT
*)(info
+ 1);
5370 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5371 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5375 SetLastError(STATUS_ACCESS_VIOLATION
);
5382 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5383 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5384 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5388 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5389 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5393 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5394 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5395 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5396 sizeof(CERT_ENHKEY_USAGE
),
5397 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5398 CERT_ENHKEY_USAGE
*usage
= pvStructInfo
;
5400 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5401 usage
->rgpszUsageIdentifier
= (LPSTR
*)(usage
+ 1);
5402 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5403 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5407 SetLastError(STATUS_ACCESS_VIOLATION
);
5414 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5415 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5416 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5420 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5421 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5425 struct AsnDecodeSequenceItem items
[] = {
5426 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5427 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5428 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5429 offsetof(CRL_ISSUING_DIST_POINT
,
5430 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5431 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5432 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5434 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5435 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5437 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5438 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5439 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5440 OnlySomeReasonFlags
.pbData
), 0 },
5441 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5442 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5445 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5446 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5447 pcbStructInfo
, NULL
, NULL
);
5451 SetLastError(STATUS_ACCESS_VIOLATION
);
5458 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5459 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5463 DWORD max
, size
= sizeof(max
);
5465 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5466 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5470 SetLastError(CRYPT_E_ASN1_EOD
);
5473 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5475 SetLastError(CRYPT_E_ASN1_BADTAG
);
5478 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5479 &max
, &size
, pcbDecoded
)))
5481 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5484 *pcbStructInfo
= bytesNeeded
;
5485 else if (*pcbStructInfo
< bytesNeeded
)
5487 *pcbStructInfo
= bytesNeeded
;
5488 SetLastError(ERROR_MORE_DATA
);
5493 CERT_GENERAL_SUBTREE
*subtree
= CONTAINING_RECORD(pvStructInfo
,
5494 CERT_GENERAL_SUBTREE
, fMaximum
);
5496 *pcbStructInfo
= bytesNeeded
;
5497 /* The BOOL is implicit: if the integer is present, then it's
5500 subtree
->fMaximum
= TRUE
;
5501 subtree
->dwMaximum
= max
;
5504 TRACE("returning %d\n", ret
);
5508 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5509 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5513 struct AsnDecodeSequenceItem items
[] = {
5514 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5515 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5516 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5517 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5518 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5519 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5520 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5521 TRUE
, FALSE
, 0, 0 },
5523 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5525 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5526 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5528 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5529 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5530 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5533 TRACE("%ld\n", *pcbDecoded
);
5534 if (*pcbDecoded
< cbEncoded
)
5535 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5536 *(pbEncoded
+ *pcbDecoded
+ 1));
5538 TRACE("returning %d\n", ret
);
5542 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5543 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5547 struct AsnArrayDescriptor arrayDesc
= { 0,
5548 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5549 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5550 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5552 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5553 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5555 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5556 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5558 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5559 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5563 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5564 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5568 struct AsnArrayDescriptor arrayDesc
= { 0,
5569 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5570 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5571 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5572 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5573 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5575 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5576 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5578 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5579 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5583 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5584 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5585 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5589 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5590 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5594 struct AsnDecodeSequenceItem items
[] = {
5595 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5596 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5597 CRYPT_AsnDecodePermittedSubtree
,
5598 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5599 cExcludedSubtree
), TRUE
, TRUE
,
5600 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5601 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5602 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5603 CRYPT_AsnDecodeExcludedSubtree
,
5604 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5606 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5609 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5610 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5611 pcbStructInfo
, NULL
, NULL
);
5615 SetLastError(STATUS_ACCESS_VIOLATION
);
5621 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5622 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5626 struct AsnDecodeSequenceItem items
[] = {
5627 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5628 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5630 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5631 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5632 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5634 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5636 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5637 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5639 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5640 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5641 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5642 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5644 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5647 TRACE("returning %d\n", ret
);
5651 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5652 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5655 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5656 struct AsnDecodeSequenceItem items
[] = {
5657 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5658 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5659 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5660 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5661 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5662 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5663 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5664 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5665 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5666 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5667 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5668 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5669 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5670 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5671 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5672 HashEncryptionAlgorithm
.pszObjId
), 0 },
5673 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5674 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5675 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5676 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5677 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5678 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5679 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5683 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5684 pvStructInfo
, *pcbStructInfo
);
5686 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5687 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5688 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5692 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5693 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5694 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5698 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5699 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5703 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5704 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5705 if (ret
&& pvStructInfo
)
5707 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5708 pcbStructInfo
, *pcbStructInfo
);
5711 CMSG_SIGNER_INFO
*info
;
5713 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5714 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5715 info
= pvStructInfo
;
5716 info
->Issuer
.pbData
= ((BYTE
*)info
+
5717 sizeof(CMSG_SIGNER_INFO
));
5718 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5719 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5720 pcbStructInfo
, NULL
);
5721 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5722 CRYPT_FreeSpace(pDecodePara
, info
);
5728 SetLastError(STATUS_ACCESS_VIOLATION
);
5731 TRACE("returning %d\n", ret
);
5735 static BOOL
verify_and_copy_certificate(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5736 void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5738 PCCERT_CONTEXT cert
;
5740 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, pbEncoded
, cbEncoded
);
5743 WARN("CertCreateCertificateContext error %#lx\n", GetLastError());
5749 CertFreeCertificateContext(cert
);
5751 return CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5754 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5755 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5759 struct AsnArrayDescriptor arrayDesc
= { 0,
5760 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5761 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5762 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5763 verify_and_copy_certificate
,
5764 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5766 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5767 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5769 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5770 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5774 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5775 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5779 struct AsnArrayDescriptor arrayDesc
= { 0,
5780 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5781 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5782 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5783 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5784 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5786 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5787 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5789 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5790 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5794 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5795 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5798 CERT_ID
*id
= pvStructInfo
;
5801 if (*pbEncoded
== ASN_SEQUENCEOF
)
5803 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5804 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5808 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5809 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5810 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5811 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5813 *pcbStructInfo
= sizeof(CERT_ID
);
5816 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5818 ret
= CRYPT_AsnDecodeOctets(pbEncoded
, cbEncoded
, dwFlags
,
5819 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5823 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5824 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5825 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5826 sizeof(CRYPT_DATA_BLOB
);
5828 *pcbStructInfo
= sizeof(CERT_ID
);
5832 SetLastError(CRYPT_E_ASN1_BADTAG
);
5836 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5837 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5840 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5841 struct AsnDecodeSequenceItem items
[] = {
5842 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5843 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5844 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5845 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5846 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5847 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5848 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5849 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5850 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5851 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5852 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5853 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5854 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5855 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5856 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5857 HashEncryptionAlgorithm
.pszObjId
), 0 },
5858 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5859 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5860 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5861 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5862 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5863 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5864 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5868 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5869 pvStructInfo
, *pcbStructInfo
);
5871 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5872 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5873 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5877 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5878 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5879 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5883 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5884 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5888 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5889 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5890 if (ret
&& pvStructInfo
)
5892 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5893 pcbStructInfo
, *pcbStructInfo
);
5896 CMSG_CMS_SIGNER_INFO
*info
;
5898 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5899 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5900 info
= pvStructInfo
;
5901 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5902 sizeof(CMSG_CMS_SIGNER_INFO
));
5903 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5904 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5905 pcbStructInfo
, NULL
);
5906 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5907 CRYPT_FreeSpace(pDecodePara
, info
);
5913 SetLastError(STATUS_ACCESS_VIOLATION
);
5916 TRACE("returning %d\n", ret
);
5920 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5921 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5924 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5925 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5926 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5927 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5928 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5929 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5931 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5932 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5934 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5935 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5939 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5940 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5941 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5944 struct AsnDecodeSequenceItem items
[] = {
5945 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5946 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5947 /* Placeholder for the hash algorithms - redundant with those in the
5948 * signers, so just ignore them.
5950 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5951 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5952 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5953 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5954 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5955 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5956 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5957 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5958 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5959 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5960 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5961 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5962 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5963 CRYPT_DecodeSignerArray
,
5964 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5965 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5968 TRACE("%p, %ld, %08lx, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5969 pDecodePara
, signedInfo
, pcbSignedInfo
);
5971 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5972 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5974 TRACE("returning %d\n", ret
);
5978 static BOOL
CRYPT_AsnDecodeRecipientInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5979 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5982 CMSG_KEY_TRANS_RECIPIENT_INFO
*info
= pvStructInfo
;
5983 struct AsnDecodeSequenceItem items
[] = {
5984 { ASN_INTEGER
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, dwVersion
),
5985 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5986 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5987 RecipientId
.u
.IssuerSerialNumber
), CRYPT_AsnDecodeIssuerSerialNumber
,
5988 sizeof(CERT_ISSUER_SERIAL_NUMBER
), FALSE
, TRUE
,
5989 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5990 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
), 0 },
5991 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5992 KeyEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5993 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5994 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5995 KeyEncryptionAlgorithm
.pszObjId
), 0 },
5996 { ASN_OCTETSTRING
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
),
5997 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
5998 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
.pbData
), 0 },
6001 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
6002 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
6004 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6005 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
6006 pcbDecoded
, info
? info
->RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
:
6009 info
->RecipientId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
6010 TRACE("returning %d\n", ret
);
6014 static BOOL
CRYPT_DecodeRecipientInfoArray(const BYTE
*pbEncoded
,
6015 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6019 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
6020 offsetof(CRYPT_ENVELOPED_DATA
, cRecipientInfo
),
6021 offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
),
6022 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
6023 CRYPT_AsnDecodeRecipientInfo
, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO
), TRUE
,
6024 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
6025 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
) };
6027 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
6028 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
6030 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
6031 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
6032 TRACE("returning %d\n", ret
);
6036 static BOOL
CRYPT_AsnDecodeEncryptedContentInfo(const BYTE
*pbEncoded
,
6037 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6041 CRYPT_ENCRYPTED_CONTENT_INFO
*info
= pvStructInfo
;
6042 struct AsnDecodeSequenceItem items
[] = {
6043 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
6044 contentType
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
6045 FALSE
, TRUE
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
6047 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
6048 contentEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
6049 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
6050 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
6051 contentEncryptionAlgorithm
.pszObjId
), 0 },
6052 { ASN_CONTEXT
| 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
6053 encryptedContent
), CRYPT_AsnDecodeOctets
,
6054 sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
6055 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
, encryptedContent
.pbData
) },
6058 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
6059 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
6061 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6062 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
6063 pcbDecoded
, info
? info
->contentType
: NULL
);
6064 TRACE("returning %d\n", ret
);
6068 BOOL
CRYPT_AsnDecodePKCSEnvelopedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
6069 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
6070 CRYPT_ENVELOPED_DATA
*envelopedData
, DWORD
*pcbEnvelopedData
)
6073 struct AsnDecodeSequenceItem items
[] = {
6074 { ASN_INTEGER
, offsetof(CRYPT_ENVELOPED_DATA
, version
),
6075 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
6076 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ENVELOPED_DATA
,
6077 cRecipientInfo
), CRYPT_DecodeRecipientInfoArray
,
6078 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
6079 FALSE
, TRUE
, offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
), 0 },
6080 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
),
6081 CRYPT_AsnDecodeEncryptedContentInfo
,
6082 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO
), FALSE
, TRUE
,
6083 offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
.contentType
), 0 },
6086 TRACE("%p, %ld, %08lx, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
6087 pDecodePara
, envelopedData
, pcbEnvelopedData
);
6089 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6090 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, envelopedData
,
6091 pcbEnvelopedData
, NULL
, NULL
);
6092 TRACE("returning %d\n", ret
);
6096 static BOOL WINAPI
CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType
,
6097 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6098 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6100 DWORD bytesNeeded
= 0;
6105 ret
= CRYPT_AsnDecodeOidInternal(pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
6106 NULL
, &bytesNeeded
, NULL
);
6110 *pcbStructInfo
= bytesNeeded
;
6111 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
6115 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6116 pvStructInfo
= *(BYTE
**)pvStructInfo
;
6118 info
= pvStructInfo
;
6119 *info
= (void *)((BYTE
*)info
+ sizeof(*info
));
6120 ret
= CRYPT_AsnDecodeOidInternal(pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
6121 pvStructInfo
, &bytesNeeded
, NULL
);
6122 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
6123 CRYPT_FreeSpace(pDecodePara
, info
);
6129 SetLastError(STATUS_ACCESS_VIOLATION
);
6136 static BOOL WINAPI
CRYPT_AsnDecodeEccSignature(DWORD dwCertEncodingType
,
6137 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6138 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6141 struct AsnDecodeSequenceItem items
[] = {
6142 { ASN_INTEGER
, offsetof(CERT_ECC_SIGNATURE
, r
),
6143 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_UINT_BLOB
), FALSE
,
6144 TRUE
, offsetof(CERT_ECC_SIGNATURE
, r
.pbData
), 0 },
6145 { ASN_INTEGER
, offsetof(CERT_ECC_SIGNATURE
, s
),
6146 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_UINT_BLOB
), FALSE
,
6147 TRUE
, offsetof(CERT_ECC_SIGNATURE
, s
.pbData
), 0 },
6152 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6153 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
6154 pcbStructInfo
, NULL
, NULL
);
6158 SetLastError(STATUS_ACCESS_VIOLATION
);
6165 static BOOL
CRYPT_AsnDecodeOCSPResponseStatus(const BYTE
*pbEncoded
,
6166 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6171 SetLastError(CRYPT_E_ASN1_EOD
);
6174 if (pbEncoded
[0] != ASN_ENUMERATED
)
6176 SetLastError(CRYPT_E_ASN1_BADTAG
);
6180 return CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
6181 pcbStructInfo
, pcbDecoded
);
6184 static BOOL
CRYPT_AsnDecodeOCSPResponseBytes(const BYTE
*pbEncoded
,
6185 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6193 SetLastError(CRYPT_E_ASN1_EOD
);
6196 if (pbEncoded
[0] != (ASN_CONTEXT
| ASN_CONSTRUCTOR
))
6198 SetLastError(CRYPT_E_ASN1_BADTAG
);
6202 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
6204 struct AsnDecodeSequenceItem items
[] = {
6205 { ASN_OBJECTIDENTIFIER
, 0,
6206 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
6208 { ASN_OCTETSTRING
, sizeof(LPSTR
),
6209 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
6210 sizeof(LPSTR
) + offsetof(CRYPT_OBJID_BLOB
, pbData
), 0 },
6212 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6217 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6218 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
, dwFlags
, NULL
,
6219 pvStructInfo
, pcbStructInfo
, &bytesNeeded
, NULL
);
6220 if (ret
) *pcbDecoded
= bytesNeeded
+ lenBytes
+ 1;
6226 static BOOL WINAPI
CRYPT_AsnDecodeOCSPResponse(DWORD dwCertEncodingType
,
6227 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6228 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6231 struct AsnDecodeSequenceItem items
[] = {
6232 { ASN_ENUMERATED
, offsetof(OCSP_RESPONSE_INFO
, dwStatus
),
6233 CRYPT_AsnDecodeOCSPResponseStatus
, sizeof(DWORD
), FALSE
, FALSE
,
6235 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(OCSP_RESPONSE_INFO
, pszObjId
),
6236 CRYPT_AsnDecodeOCSPResponseBytes
, sizeof(LPSTR
) + sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
6237 offsetof(OCSP_RESPONSE_INFO
, pszObjId
), 0 },
6242 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6243 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
6244 pcbStructInfo
, NULL
, NULL
);
6248 SetLastError(STATUS_ACCESS_VIOLATION
);
6255 static BOOL
CRYPT_AsnDecodeOCSPSignatureInfoCertEncoded(const BYTE
*pbEncoded
,
6256 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6260 struct AsnArrayDescriptor arrayDesc
= { 0,
6261 offsetof(OCSP_SIGNATURE_INFO
, cCertEncoded
), offsetof(OCSP_SIGNATURE_INFO
, rgCertEncoded
),
6262 FINALMEMBERSIZE(OCSP_SIGNATURE_INFO
, cCertEncoded
), verify_and_copy_certificate
,
6263 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
6265 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
6266 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
6270 static BOOL WINAPI
CRYPT_AsnDecodeOCSPBasicSignedResponse(DWORD dwCertEncodingType
,
6271 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6272 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6275 struct AsnDecodeSequenceItem items
[] = {
6276 { 0, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, ToBeSigned
),
6277 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
6278 offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, ToBeSigned
.pbData
), 0 },
6279 { ASN_SEQUENCEOF
, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.SignatureAlgorithm
),
6280 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
6281 offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.SignatureAlgorithm
.pszObjId
), 0 },
6282 { ASN_BITSTRING
, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.Signature
),
6283 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
6284 offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.Signature
.pbData
) },
6285 { 0, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.cCertEncoded
),
6286 CRYPT_AsnDecodeOCSPSignatureInfoCertEncoded
, FINALMEMBERSIZE(OCSP_SIGNATURE_INFO
, cCertEncoded
),
6287 TRUE
, TRUE
, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.rgCertEncoded
) },
6292 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6293 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
6294 pcbStructInfo
, NULL
, NULL
);
6298 SetLastError(STATUS_ACCESS_VIOLATION
);
6305 static BOOL
CRYPT_AsnDecodeOCSPHashAlgorithm(const BYTE
*pbEncoded
,
6306 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6314 SetLastError(CRYPT_E_ASN1_EOD
);
6317 if (pbEncoded
[0] != ASN_SEQUENCEOF
)
6319 SetLastError(CRYPT_E_ASN1_BADTAG
);
6323 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
6325 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6329 ret
= CRYPT_AsnDecodeAlgorithmId(pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
, dwFlags
,
6330 pvStructInfo
, pcbStructInfo
, &bytesDecoded
);
6331 if (ret
) *pcbDecoded
= bytesDecoded
+ lenBytes
+ 1;
6337 static BOOL
CRYPT_AsnDecodeOCSPNextUpdate(const BYTE
*pbEncoded
,
6338 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6346 SetLastError(CRYPT_E_ASN1_EOD
);
6349 if (pbEncoded
[0] != (ASN_CONTEXT
| ASN_CONSTRUCTOR
))
6351 SetLastError(CRYPT_E_ASN1_BADTAG
);
6355 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
6357 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6361 ret
= CRYPT_AsnDecodeGeneralizedTime(pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
, dwFlags
,
6362 pvStructInfo
, pcbStructInfo
, &bytesDecoded
);
6363 if (ret
) *pcbDecoded
= bytesDecoded
+ lenBytes
+ 1;
6369 static BOOL
CRYPT_AsnDecodeCertStatus(const BYTE
*pbEncoded
,
6370 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6374 BYTE tag
= pbEncoded
[0] & ~3, status
= pbEncoded
[0] & 3;
6375 DWORD bytesNeeded
= FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, ThisUpdate
) -
6376 FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, dwCertStatus
);
6380 SetLastError(CRYPT_E_ASN1_EOD
);
6387 if (tag
!= ASN_CONTEXT
)
6389 WARN("Unexpected tag %02x\n", tag
);
6390 SetLastError(CRYPT_E_ASN1_BADTAG
);
6393 if (cbEncoded
< 2 || pbEncoded
[1])
6395 SetLastError(CRYPT_E_ASN1_CORRUPT
);
6399 *pcbStructInfo
= bytesNeeded
;
6400 else if (*pcbStructInfo
< bytesNeeded
)
6402 *pcbStructInfo
= bytesNeeded
;
6403 SetLastError(ERROR_MORE_DATA
);
6408 *(DWORD
*)pvStructInfo
= 0;
6409 *(OCSP_BASIC_REVOKED_INFO
**)((char *)pvStructInfo
6410 + FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, u
.pRevokedInfo
)
6411 - FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, dwCertStatus
)) = NULL
;
6413 *pcbStructInfo
= bytesNeeded
;
6421 if (tag
!= (ASN_CONTEXT
| ASN_CONSTRUCTOR
))
6423 WARN("Unexpected tag %02x\n", tag
);
6424 SetLastError(CRYPT_E_ASN1_BADTAG
);
6427 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
6429 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6430 DWORD bytesDecoded
, size
;
6435 size
= sizeof(date
);
6436 ret
= CRYPT_AsnDecodeGeneralizedTime(pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
6437 dwFlags
, &date
, &size
, &bytesDecoded
);
6440 OCSP_BASIC_REVOKED_INFO
*info
;
6442 bytesNeeded
+= sizeof(*info
);
6444 *pcbStructInfo
= bytesNeeded
;
6445 else if (*pcbStructInfo
< bytesNeeded
)
6447 *pcbStructInfo
= bytesNeeded
;
6448 SetLastError(ERROR_MORE_DATA
);
6453 *(DWORD
*)pvStructInfo
= 1;
6454 info
= *(OCSP_BASIC_REVOKED_INFO
**)((char *)pvStructInfo
6455 + FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, u
.pRevokedInfo
)
6456 - FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, dwCertStatus
));
6457 info
->RevocationDate
= date
;
6459 *pcbStructInfo
= bytesNeeded
;
6460 *pcbDecoded
= 1 + lenBytes
+ bytesDecoded
;
6467 FIXME("Unhandled status %u\n", status
);
6468 SetLastError(CRYPT_E_ASN1_BADTAG
);
6475 static BOOL
CRYPT_AsnDecodeOCSPBasicResponseEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
6476 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
6478 struct AsnDecodeSequenceItem items
[] = {
6479 { ASN_SEQUENCEOF
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.HashAlgorithm
.pszObjId
),
6480 CRYPT_AsnDecodeOCSPHashAlgorithm
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
6481 offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.HashAlgorithm
.pszObjId
), 0 },
6482 { ASN_OCTETSTRING
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.IssuerNameHash
),
6483 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
6484 offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.IssuerNameHash
.pbData
), 0 },
6485 { ASN_OCTETSTRING
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.IssuerKeyHash
),
6486 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
6487 offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.IssuerKeyHash
.pbData
), 0 },
6488 { ASN_INTEGER
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.SerialNumber
),
6489 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
6490 offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.SerialNumber
.pbData
), 0 },
6491 { 0, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, dwCertStatus
),
6492 CRYPT_AsnDecodeCertStatus
, sizeof(DWORD
), FALSE
, TRUE
,
6493 offsetof(OCSP_BASIC_RESPONSE_ENTRY
, u
.pRevokedInfo
), 0 },
6494 { ASN_GENERALTIME
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, ThisUpdate
),
6495 CRYPT_AsnDecodeGeneralizedTime
, sizeof(FILETIME
), FALSE
, FALSE
,
6497 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, NextUpdate
),
6498 CRYPT_AsnDecodeOCSPNextUpdate
, sizeof(FILETIME
), TRUE
, FALSE
,
6500 { ASN_CONTEXT
| ASN_CONSTRUCTOR
/* FIXME */, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, cExtension
),
6501 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(OCSP_BASIC_RESPONSE_ENTRY
, cExtension
),
6502 TRUE
, TRUE
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, rgExtension
), 0 },
6505 return CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6506 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
,
6507 pcbStructInfo
, pcbDecoded
, NULL
);
6510 static BOOL
CRYPT_AsnDecodeOCSPBasicResponseEntriesArray(const BYTE
*pbEncoded
,
6511 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6514 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
6515 offsetof(OCSP_BASIC_RESPONSE_INFO
, cResponseEntry
), offsetof(OCSP_BASIC_RESPONSE_INFO
, rgResponseEntry
),
6516 MEMBERSIZE(OCSP_BASIC_RESPONSE_INFO
, cResponseEntry
, cExtension
),
6517 CRYPT_AsnDecodeOCSPBasicResponseEntry
, sizeof(OCSP_BASIC_RESPONSE_ENTRY
),
6520 return CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
6521 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
6524 static BOOL
CRYPT_AsnDecodeResponderIDByName(const BYTE
*pbEncoded
,
6525 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6528 OCSP_BASIC_RESPONSE_INFO
*info
= pvStructInfo
;
6529 DWORD dataLen
, decodedLen
, lenBytes
, bytesNeeded
= sizeof(*info
);
6530 BYTE tag
= pbEncoded
[0] & ~3;
6531 CERT_NAME_BLOB
*blob
;
6533 if (tag
!= (ASN_CONTEXT
| ASN_CONSTRUCTOR
))
6535 WARN("Unexpected tag %02x\n", tag
);
6536 SetLastError(CRYPT_E_ASN1_BADTAG
);
6540 if (!CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
))
6542 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6543 cbEncoded
-= 1 + lenBytes
;
6545 if (dataLen
> cbEncoded
)
6547 SetLastError(CRYPT_E_ASN1_EOD
);
6550 pbEncoded
+= 1 + lenBytes
;
6551 decodedLen
= 1 + lenBytes
+ dataLen
;
6553 if (pbEncoded
[0] != ASN_SEQUENCE
)
6555 WARN("Unexpected tag %02x %02x\n", pbEncoded
[0], pbEncoded
[1]);
6556 SetLastError(CRYPT_E_ASN1_BADTAG
);
6560 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)) bytesNeeded
+= dataLen
;
6561 if (pvStructInfo
&& *pcbStructInfo
>= bytesNeeded
)
6563 info
->dwResponderIdChoice
= 1;
6565 blob
= &info
->u
.ByNameResponderId
;
6566 blob
->cbData
= dataLen
;
6567 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
6568 blob
->pbData
= (BYTE
*)pbEncoded
;
6569 else if (blob
->cbData
)
6571 blob
->pbData
= (BYTE
*)(info
+ 1);
6572 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
6577 *pcbDecoded
= decodedLen
;
6581 *pcbStructInfo
= bytesNeeded
;
6585 if (*pcbStructInfo
< bytesNeeded
)
6587 SetLastError(ERROR_MORE_DATA
);
6588 *pcbStructInfo
= bytesNeeded
;
6592 *pcbStructInfo
= bytesNeeded
;
6596 static BOOL
CRYPT_AsnDecodeResponderIDByKey(const BYTE
*pbEncoded
,
6597 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6600 OCSP_BASIC_RESPONSE_INFO
*info
= pvStructInfo
;
6601 DWORD dataLen
, decodedLen
, lenBytes
, bytesNeeded
= sizeof(*info
), len
;
6602 BYTE tag
= pbEncoded
[0] & ~3;
6603 CRYPT_HASH_BLOB
*blob
;
6605 if (tag
!= (ASN_CONTEXT
| ASN_CONSTRUCTOR
))
6607 WARN("Unexpected tag %02x\n", tag
);
6608 SetLastError(CRYPT_E_ASN1_BADTAG
);
6612 if (!CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
))
6614 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6615 cbEncoded
-= 1 + lenBytes
;
6616 decodedLen
= 1 + lenBytes
;
6618 if (dataLen
> cbEncoded
)
6620 SetLastError(CRYPT_E_ASN1_EOD
);
6623 pbEncoded
+= 1 + lenBytes
;
6624 if (pbEncoded
[0] != ASN_OCTETSTRING
)
6626 WARN("Unexpected tag %02x\n", pbEncoded
[0]);
6627 SetLastError(CRYPT_E_ASN1_BADTAG
);
6631 if (!CRYPT_GetLen(pbEncoded
, cbEncoded
, &len
))
6633 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6634 decodedLen
+= 1 + lenBytes
+ len
;
6635 cbEncoded
-= 1 + lenBytes
;
6637 if (len
> cbEncoded
)
6639 SetLastError(CRYPT_E_ASN1_EOD
);
6642 pbEncoded
+= 1 + lenBytes
;
6644 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)) bytesNeeded
+= len
;
6645 if (pvStructInfo
&& *pcbStructInfo
>= bytesNeeded
)
6647 info
->dwResponderIdChoice
= 2;
6648 blob
= &info
->u
.ByKeyResponderId
;
6650 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
6651 blob
->pbData
= (BYTE
*)pbEncoded
;
6652 else if (blob
->cbData
)
6654 blob
->pbData
= (BYTE
*)(info
+ 1);
6655 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
6660 *pcbDecoded
= decodedLen
;
6664 *pcbStructInfo
= bytesNeeded
;
6668 if (*pcbStructInfo
< bytesNeeded
)
6670 SetLastError(ERROR_MORE_DATA
);
6671 *pcbStructInfo
= bytesNeeded
;
6675 *pcbStructInfo
= bytesNeeded
;
6679 static BOOL
CRYPT_AsnDecodeResponderID(const BYTE
*pbEncoded
,
6680 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6683 BYTE choice
= pbEncoded
[0] & 3;
6685 TRACE("choice %02x\n", choice
);
6689 return CRYPT_AsnDecodeResponderIDByName(pbEncoded
, cbEncoded
, dwFlags
,
6690 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
6692 return CRYPT_AsnDecodeResponderIDByKey(pbEncoded
, cbEncoded
, dwFlags
,
6693 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
6695 WARN("Unexpected choice %02x\n", choice
);
6696 SetLastError(CRYPT_E_ASN1_CORRUPT
);
6701 static BOOL WINAPI
CRYPT_AsnDecodeOCSPBasicResponse(DWORD dwCertEncodingType
,
6702 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6703 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6705 struct AsnDecodeSequenceItem items
[] = {
6707 CRYPT_AsnDecodeResponderID
, offsetof(OCSP_BASIC_RESPONSE_INFO
, ProducedAt
), FALSE
, TRUE
,
6708 offsetof(OCSP_BASIC_RESPONSE_INFO
, u
.ByNameResponderId
.pbData
), 0 },
6709 { ASN_GENERALTIME
, offsetof(OCSP_BASIC_RESPONSE_INFO
, ProducedAt
),
6710 CRYPT_AsnDecodeGeneralizedTime
, sizeof(FILETIME
), FALSE
, FALSE
,
6712 { ASN_SEQUENCEOF
, offsetof(OCSP_BASIC_RESPONSE_INFO
, cResponseEntry
),
6713 CRYPT_AsnDecodeOCSPBasicResponseEntriesArray
, MEMBERSIZE(OCSP_BASIC_RESPONSE_INFO
, cResponseEntry
, cExtension
),
6714 TRUE
, TRUE
, offsetof(OCSP_BASIC_RESPONSE_INFO
, rgResponseEntry
) },
6715 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(OCSP_BASIC_RESPONSE_INFO
, cExtension
),
6716 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(OCSP_BASIC_RESPONSE_INFO
, cExtension
),
6717 TRUE
, TRUE
, offsetof(OCSP_BASIC_RESPONSE_INFO
, rgExtension
), 0 },
6723 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6724 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
6725 pcbStructInfo
, NULL
, NULL
);
6729 SetLastError(STATUS_ACCESS_VIOLATION
);
6736 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
6737 LPCSTR lpszStructType
)
6739 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6741 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
6742 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
6744 SetLastError(ERROR_FILE_NOT_FOUND
);
6747 if (IS_INTOID(lpszStructType
))
6749 switch (LOWORD(lpszStructType
))
6751 case LOWORD(X509_CERT
):
6752 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
6754 case LOWORD(X509_CERT_TO_BE_SIGNED
):
6755 decodeFunc
= CRYPT_AsnDecodeCert
;
6757 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
6758 decodeFunc
= CRYPT_AsnDecodeCRL
;
6760 case LOWORD(X509_EXTENSIONS
):
6761 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6763 case LOWORD(X509_NAME_VALUE
):
6764 decodeFunc
= CRYPT_AsnDecodeNameValue
;
6766 case LOWORD(X509_NAME
):
6767 decodeFunc
= CRYPT_AsnDecodeName
;
6769 case LOWORD(X509_PUBLIC_KEY_INFO
):
6770 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
6772 case LOWORD(X509_AUTHORITY_KEY_ID
):
6773 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6775 case LOWORD(X509_ALTERNATE_NAME
):
6776 decodeFunc
= CRYPT_AsnDecodeAltName
;
6778 case LOWORD(X509_BASIC_CONSTRAINTS
):
6779 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6781 case LOWORD(X509_BASIC_CONSTRAINTS2
):
6782 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6784 case LOWORD(X509_CERT_POLICIES
):
6785 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6787 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
6788 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
6790 case LOWORD(PKCS_RSA_PRIVATE_KEY
):
6791 decodeFunc
= CRYPT_AsnDecodeRsaPrivKey
;
6793 case LOWORD(X509_UNICODE_NAME
):
6794 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
6796 case LOWORD(PKCS_ATTRIBUTE
):
6797 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
6799 case LOWORD(X509_UNICODE_NAME_VALUE
):
6800 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
6802 case LOWORD(X509_OCTET_STRING
):
6803 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6805 case LOWORD(X509_BITS
):
6806 case LOWORD(X509_KEY_USAGE
):
6807 decodeFunc
= CRYPT_AsnDecodeBits
;
6809 case LOWORD(X509_INTEGER
):
6810 decodeFunc
= CRYPT_AsnDecodeInt
;
6812 case LOWORD(X509_MULTI_BYTE_INTEGER
):
6813 decodeFunc
= CRYPT_AsnDecodeInteger
;
6815 case LOWORD(X509_MULTI_BYTE_UINT
):
6816 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
6818 case LOWORD(X509_ENUMERATED
):
6819 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6821 case LOWORD(X509_CHOICE_OF_TIME
):
6822 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
6824 case LOWORD(X509_AUTHORITY_KEY_ID2
):
6825 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6827 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
6828 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6830 case LOWORD(PKCS_CONTENT_INFO
):
6831 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
6833 case LOWORD(X509_SEQUENCE_OF_ANY
):
6834 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
6836 case LOWORD(PKCS_UTC_TIME
):
6837 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6839 case LOWORD(X509_CRL_DIST_POINTS
):
6840 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6842 case LOWORD(X509_ENHANCED_KEY_USAGE
):
6843 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6845 case LOWORD(PKCS_CTL
):
6846 decodeFunc
= CRYPT_AsnDecodeCTL
;
6848 case LOWORD(PKCS_SMIME_CAPABILITIES
):
6849 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6851 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
6852 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6854 case LOWORD(PKCS_ATTRIBUTES
):
6855 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
6857 case LOWORD(X509_ISSUING_DIST_POINT
):
6858 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6860 case LOWORD(X509_NAME_CONSTRAINTS
):
6861 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6863 case LOWORD(X509_POLICY_MAPPINGS
):
6864 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6866 case LOWORD(X509_POLICY_CONSTRAINTS
):
6867 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6869 case LOWORD(PKCS7_SIGNER_INFO
):
6870 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
6872 case LOWORD(CMS_SIGNER_INFO
):
6873 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
6875 case LOWORD(X509_OBJECT_IDENTIFIER
):
6876 decodeFunc
= CRYPT_AsnDecodeObjectIdentifier
;
6878 case LOWORD(X509_ECC_SIGNATURE
):
6879 decodeFunc
= CRYPT_AsnDecodeEccSignature
;
6881 case LOWORD(CNG_RSA_PUBLIC_KEY_BLOB
):
6882 decodeFunc
= CRYPT_AsnDecodeRsaPubKey_Bcrypt
;
6884 case LOWORD(OCSP_RESPONSE
):
6885 decodeFunc
= CRYPT_AsnDecodeOCSPResponse
;
6887 case LOWORD(OCSP_BASIC_SIGNED_RESPONSE
):
6888 decodeFunc
= CRYPT_AsnDecodeOCSPBasicSignedResponse
;
6890 case LOWORD(OCSP_BASIC_RESPONSE
):
6891 decodeFunc
= CRYPT_AsnDecodeOCSPBasicResponse
;
6897 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
6898 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6899 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
6900 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6901 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
6902 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6903 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
6904 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6905 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
6906 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6907 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
6908 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6909 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
6910 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6911 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
6912 decodeFunc
= CRYPT_AsnDecodeBits
;
6913 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
6914 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6915 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
6916 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6917 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
6918 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6919 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
6920 decodeFunc
= CRYPT_AsnDecodeAltName
;
6921 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
6922 decodeFunc
= CRYPT_AsnDecodeAltName
;
6923 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
6924 decodeFunc
= CRYPT_AsnDecodeAltName
;
6925 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
6926 decodeFunc
= CRYPT_AsnDecodeAltName
;
6927 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
6928 decodeFunc
= CRYPT_AsnDecodeAltName
;
6929 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
6930 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6931 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
6932 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6933 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
6934 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6935 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
6936 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6937 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
6938 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6939 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
6940 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6941 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
6942 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6943 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
6944 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6945 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
6946 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6947 else if (!strcmp(lpszStructType
, szOID_CTL
))
6948 decodeFunc
= CRYPT_AsnDecodeCTL
;
6949 else if (!strcmp(lpszStructType
, szOID_ECC_PUBLIC_KEY
))
6950 decodeFunc
= CRYPT_AsnDecodeObjectIdentifier
;
6954 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
6955 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6957 static HCRYPTOIDFUNCSET set
= NULL
;
6958 CryptDecodeObjectFunc decodeFunc
= NULL
;
6961 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
6962 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6963 (void **)&decodeFunc
, hFunc
);
6967 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
6968 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6970 static HCRYPTOIDFUNCSET set
= NULL
;
6971 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6974 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
6975 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6976 (void **)&decodeFunc
, hFunc
);
6980 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6981 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
6982 DWORD
*pcbStructInfo
)
6984 return CryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
6985 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
);
6988 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6989 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6990 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6993 CryptDecodeObjectExFunc decodeFunc
;
6994 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6996 TRACE_(crypt
)("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p)\n",
6997 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
6998 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
7000 if (!pvStructInfo
&& !pcbStructInfo
)
7002 SetLastError(ERROR_INVALID_PARAMETER
);
7005 if (cbEncoded
> MAX_ENCODED_LEN
)
7007 FIXME_(crypt
)("Returning CRYPT_E_ASN1_LARGE, cbEncoded %lu.\n", cbEncoded
);
7008 SetLastError(CRYPT_E_ASN1_LARGE
);
7012 SetLastError(NOERROR
);
7013 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
7017 SetLastError(ERROR_INVALID_PARAMETER
);
7020 *(BYTE
**)pvStructInfo
= NULL
;
7022 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
7025 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
7026 debugstr_a(lpszStructType
));
7027 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
7031 if (IS_INTOID(lpszStructType
))
7032 FIXME("Unimplemented decoder for lpszStructType OID %d\n", LOWORD(lpszStructType
));
7034 FIXME("Unsupported decoder for lpszStructType %s\n", lpszStructType
);
7038 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
7039 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
7042 CryptDecodeObjectFunc pCryptDecodeObject
=
7043 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
7045 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
7046 * directly, as that could cause an infinite loop.
7048 if (pCryptDecodeObject
)
7050 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
7052 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
7053 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
7054 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
7055 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
7057 ret
= pCryptDecodeObject(dwCertEncodingType
,
7058 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
7059 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
7061 CRYPT_FreeSpace(pDecodePara
, *(BYTE
**)pvStructInfo
);
7065 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
7066 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
7070 CryptFreeOIDFunctionAddress(hFunc
, 0);
7071 TRACE_(crypt
)("returning %d\n", ret
);
7075 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
7079 TRACE_(crypt
)("(%p)\n", pPFX
);
7081 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
7082 * version integer of length 1 (3 encoded byes) and at least one other
7083 * datum (two encoded bytes), plus at least two bytes for the outer
7084 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
7086 if (pPFX
->cbData
< 7)
7088 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
7092 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
7094 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
7096 /* Need at least three bytes for the integer version */
7097 if (pPFX
->cbData
< 1 + lenLen
+ 3)
7099 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
7100 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
7101 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */