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 0x02000000
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 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
59 DWORD
, DWORD
, void *, DWORD
*);
60 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
61 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
63 /* Internal decoders don't do memory allocation or exception handling, and
64 * they report how many bytes they decoded.
66 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
67 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
69 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
70 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
72 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
73 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
75 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
77 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
78 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
79 /* Assumes algo->Parameters.pbData is set ahead of time. */
80 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
81 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
82 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
83 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
84 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
85 static BOOL
CRYPT_AsnDecodeOctets(const BYTE
*pbEncoded
,
86 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
88 /* Doesn't check the tag, assumes the caller does so */
89 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
90 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
91 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
92 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
93 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
94 * member has been initialized, doesn't do exception handling, and doesn't do
95 * memory allocation. Also doesn't check tag, assumes the caller has checked
98 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
99 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
101 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
102 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
103 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
105 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
106 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
109 /* Gets the number of length bytes from the given (leading) length byte */
110 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
112 /* Helper function to get the encoded length of the data starting at pbEncoded,
113 * where pbEncoded[0] is the tag. If the data are too short to contain a
114 * length or if the length is too large for cbEncoded, sets an appropriate
115 * error code and returns FALSE. If the encoded length is unknown due to
116 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
118 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
125 SetLastError(CRYPT_E_ASN1_CORRUPT
);
128 else if (pbEncoded
[1] <= 0x7f)
130 if (pbEncoded
[1] + 1 > cbEncoded
)
132 SetLastError(CRYPT_E_ASN1_EOD
);
141 else if (pbEncoded
[1] == 0x80)
143 *len
= CMSG_INDEFINITE_LENGTH
;
148 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
150 if (lenLen
> sizeof(DWORD
) + 1)
152 SetLastError(CRYPT_E_ASN1_LARGE
);
155 else if (lenLen
+ 2 > cbEncoded
)
157 SetLastError(CRYPT_E_ASN1_CORRUPT
);
170 if (out
+ lenLen
+ 1 > cbEncoded
)
172 SetLastError(CRYPT_E_ASN1_EOD
);
185 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
186 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
190 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
191 *len
== CMSG_INDEFINITE_LENGTH
)
193 SetLastError(CRYPT_E_ASN1_CORRUPT
);
199 /* Helper function to check *pcbStructInfo, set it to the required size, and
200 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
201 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
202 * pointer to the newly allocated memory.
204 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
205 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
210 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
212 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
213 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
215 *(BYTE
**)pvStructInfo
= LocalAlloc(LPTR
, bytesNeeded
);
216 if (!*(BYTE
**)pvStructInfo
)
219 *pcbStructInfo
= bytesNeeded
;
221 else if (*pcbStructInfo
< bytesNeeded
)
223 *pcbStructInfo
= bytesNeeded
;
224 SetLastError(ERROR_MORE_DATA
);
228 *pcbStructInfo
= bytesNeeded
;
232 static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA
*pDecodePara
, LPVOID pv
)
234 if (pDecodePara
&& pDecodePara
->pfnFree
)
235 pDecodePara
->pfnFree(pv
);
240 /* Helper function to check *pcbStructInfo and set it to the required size.
241 * Assumes pvStructInfo is not NULL.
243 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
247 if (*pcbStructInfo
< bytesNeeded
)
249 *pcbStructInfo
= bytesNeeded
;
250 SetLastError(ERROR_MORE_DATA
);
255 *pcbStructInfo
= bytesNeeded
;
262 * The expected tag of the item. If tag is 0, decodeFunc is called
263 * regardless of the tag value seen.
265 * A sequence is decoded into a struct. The offset member is the
266 * offset of this item within that struct.
268 * The decoder function to use. If this is NULL, then the member isn't
269 * decoded, but minSize space is reserved for it.
271 * The minimum amount of space occupied after decoding. You must set this.
273 * If true, and the tag doesn't match the expected tag for this item,
274 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
275 * filled with 0 for this member.
276 * hasPointer, pointerOffset:
277 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
278 * the offset within the struct of the data pointer (or to the
279 * first data pointer, if more than one exist).
281 * Used by CRYPT_AsnDecodeSequence, not for your use.
283 struct AsnDecodeSequenceItem
287 InternalDecodeFunc decodeFunc
;
295 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
296 #define MEMBERSIZE(s, member, nextmember) \
297 (offsetof(s, nextmember) - offsetof(s, member))
299 /* Decodes the items in a sequence, where the items are described in items,
300 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
301 * pvStructInfo. nextData is a pointer to the memory location at which the
302 * first decoded item with a dynamic pointer should point.
303 * Upon decoding, *cbDecoded is the total number of bytes decoded.
304 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
306 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
307 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
308 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
311 DWORD i
, decoded
= 0;
312 const BYTE
*ptr
= pbEncoded
;
314 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
315 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
317 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
319 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
323 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
324 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
326 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
328 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
330 DWORD itemEncodedLen
;
332 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
333 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
335 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
336 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
338 TRACE("Setting next pointer to %p\n",
340 *(BYTE
**)((BYTE
*)pvStructInfo
+
341 items
[i
].pointerOffset
) = nextData
;
343 if (items
[i
].decodeFunc
)
348 TRACE("decoding item %d\n", i
);
350 TRACE("sizing item %d\n", i
);
351 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
352 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
353 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
354 : NULL
, &items
[i
].size
, &itemDecoded
);
357 if (items
[i
].size
< items
[i
].minSize
)
358 items
[i
].size
= items
[i
].minSize
;
359 else if (items
[i
].size
> items
[i
].minSize
)
361 /* Account for alignment padding */
362 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
364 TRACE("item %d size: %d\n", i
, items
[i
].size
);
365 if (nextData
&& items
[i
].hasPointer
&&
366 items
[i
].size
> items
[i
].minSize
)
367 nextData
+= items
[i
].size
- items
[i
].minSize
;
368 if (itemDecoded
> itemEncodedLen
)
370 WARN("decoded length %d exceeds encoded %d\n",
371 itemDecoded
, itemEncodedLen
);
372 SetLastError(CRYPT_E_ASN1_CORRUPT
);
378 decoded
+= itemDecoded
;
379 TRACE("item %d: decoded %d bytes\n", i
,
383 else if (items
[i
].optional
&&
384 GetLastError() == CRYPT_E_ASN1_BADTAG
)
386 TRACE("skipping optional item %d\n", i
);
387 items
[i
].size
= items
[i
].minSize
;
388 SetLastError(NOERROR
);
392 TRACE("item %d failed: %08x\n", i
,
395 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
397 ERR("can't use indefinite length encoding without a decoder\n");
398 SetLastError(CRYPT_E_ASN1_CORRUPT
);
403 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
404 ptr
+= itemEncodedLen
;
405 decoded
+= itemEncodedLen
;
406 items
[i
].size
= items
[i
].minSize
;
409 else if (items
[i
].optional
)
411 TRACE("skipping optional item %d\n", i
);
412 items
[i
].size
= items
[i
].minSize
;
416 TRACE("item %d: tag %02x doesn't match expected %02x\n",
417 i
, ptr
[0], items
[i
].tag
);
418 SetLastError(CRYPT_E_ASN1_BADTAG
);
423 else if (items
[i
].optional
)
425 TRACE("missing optional item %d, skipping\n", i
);
426 items
[i
].size
= items
[i
].minSize
;
430 TRACE("not enough bytes for item %d, failing\n", i
);
431 SetLastError(CRYPT_E_ASN1_CORRUPT
);
436 *cbDecoded
= decoded
;
437 TRACE("returning %d\n", ret
);
441 /* This decodes an arbitrary sequence into a contiguous block of memory
442 * (basically, a struct.) Each element being decoded is described by a struct
443 * AsnDecodeSequenceItem, see above.
444 * startingPointer is an optional pointer to the first place where dynamic
445 * data will be stored. If you know the starting offset, you may pass it
446 * here. Otherwise, pass NULL, and one will be inferred from the items.
448 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
449 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
450 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
451 DWORD
*pcbDecoded
, void *startingPointer
)
455 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
456 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
461 SetLastError(CRYPT_E_ASN1_EOD
);
464 if (pbEncoded
[0] == ASN_SEQUENCE
)
468 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
470 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
471 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
472 BOOL indefinite
= FALSE
;
474 cbEncoded
-= 1 + lenBytes
;
475 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
481 else if (cbEncoded
< dataLen
)
483 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
485 SetLastError(CRYPT_E_ASN1_CORRUPT
);
490 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
491 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
492 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
494 if (cbDecoded
> cbEncoded
- 2)
496 /* Not enough space for 0 TLV */
497 SetLastError(CRYPT_E_ASN1_CORRUPT
);
500 else if (*(ptr
+ cbDecoded
) != 0 ||
501 *(ptr
+ cbDecoded
+ 1) != 0)
503 TRACE("expected 0 TLV\n");
504 SetLastError(CRYPT_E_ASN1_CORRUPT
);
511 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
513 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
515 SetLastError(CRYPT_E_ASN1_CORRUPT
);
520 DWORD i
, bytesNeeded
= 0, structSize
= 0;
522 for (i
= 0; i
< cItem
; i
++)
524 if (items
[i
].size
> items
[i
].minSize
)
525 bytesNeeded
+= items
[i
].size
- items
[i
].minSize
;
526 structSize
= max( structSize
, items
[i
].offset
+ items
[i
].minSize
);
528 bytesNeeded
+= structSize
;
530 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
532 *pcbStructInfo
= bytesNeeded
;
533 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
534 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
538 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
539 pvStructInfo
= *(BYTE
**)pvStructInfo
;
541 nextData
= startingPointer
;
543 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
544 memset(pvStructInfo
, 0, structSize
);
545 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
546 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
548 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
549 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
556 SetLastError(CRYPT_E_ASN1_BADTAG
);
559 TRACE("returning %d (%08x)\n", ret
, GetLastError());
564 * The expected tag of the entire encoded array (usually a variant
565 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
566 * regardless of the tag seen.
568 * The offset within the outer structure at which the count exists.
569 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
570 * while CRYPT_ATTRIBUTE has countOffset ==
571 * offsetof(CRYPT_ATTRIBUTE, cValue).
573 * The offset within the outer structure at which the array pointer exists.
574 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
575 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
577 * The minimum size of the decoded array. On WIN32, this is always 8:
578 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
581 * used to decode each item in the array
583 * is the minimum size of each decoded item
585 * indicates whether each item has a dynamic pointer
587 * indicates the offset within itemSize at which the pointer exists
589 struct AsnArrayDescriptor
595 InternalDecodeFunc decodeFunc
;
601 struct AsnArrayItemSize
607 /* Decodes an array of like types into a structure described by a struct
608 * AsnArrayDescriptor.
610 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
611 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
612 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
617 TRACE("%p, %p, %d, %p, %d\n", arrayDesc
, pbEncoded
,
618 cbEncoded
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
622 SetLastError(CRYPT_E_ASN1_EOD
);
625 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
629 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
631 DWORD bytesNeeded
= arrayDesc
->minArraySize
, cItems
= 0, decoded
;
632 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
633 /* There can be arbitrarily many items, but there is often only one.
635 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
637 decoded
= 1 + lenBytes
;
641 BOOL doneDecoding
= FALSE
;
643 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
645 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
652 SetLastError(CRYPT_E_ASN1_CORRUPT
);
659 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
663 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
665 /* Each item decoded may not tolerate extraneous bytes,
666 * so get the length of the next element if known.
668 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
669 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
671 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
672 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
674 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
678 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
679 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
683 /* Ignore an item that failed to decode but the decoder doesn't want to fail the whole process */
691 if (itemSizes
!= &itemSize
)
692 itemSizes
= CryptMemRealloc(itemSizes
,
693 cItems
* sizeof(struct AsnArrayItemSize
));
698 cItems
* sizeof(struct AsnArrayItemSize
));
700 *itemSizes
= itemSize
;
704 decoded
+= itemDecoded
;
705 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
706 itemSizes
[cItems
- 1].size
= size
;
719 *pcbDecoded
= decoded
;
721 *pcbStructInfo
= bytesNeeded
;
722 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
723 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
730 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
731 pvStructInfo
= *(void **)pvStructInfo
;
732 pcItems
= pvStructInfo
;
734 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
736 rgItems
= (BYTE
*)pvStructInfo
+
737 arrayDesc
->minArraySize
;
738 *(void **)((BYTE
*)pcItems
-
739 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
) =
743 rgItems
= *(void **)((BYTE
*)pcItems
-
744 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
);
745 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
746 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
747 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
752 if (arrayDesc
->hasPointer
)
753 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
754 + arrayDesc
->pointerOffset
) = nextData
;
755 ret
= arrayDesc
->decodeFunc(ptr
,
756 itemSizes
[i
].encodedLen
,
757 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
758 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
759 &itemSizes
[i
].size
, &itemDecoded
);
762 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
766 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
767 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
770 if (itemSizes
!= &itemSize
)
771 CryptMemFree(itemSizes
);
776 SetLastError(CRYPT_E_ASN1_BADTAG
);
782 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
783 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
784 * to CRYPT_E_ASN1_CORRUPT.
785 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
788 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
789 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
794 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
796 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
797 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
799 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
800 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
803 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
805 *pcbStructInfo
= bytesNeeded
;
806 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
808 CRYPT_DER_BLOB
*blob
;
810 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
811 pvStructInfo
= *(BYTE
**)pvStructInfo
;
813 blob
->cbData
= 1 + lenBytes
+ dataLen
;
816 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
817 blob
->pbData
= (BYTE
*)pbEncoded
;
820 assert(blob
->pbData
);
821 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
826 SetLastError(CRYPT_E_ASN1_CORRUPT
);
834 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
835 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
836 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
841 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
842 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
844 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
847 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
848 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
850 if (ret
&& pvStructInfo
)
852 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
859 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
861 temp
= blob
->pbData
[i
];
862 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
863 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
867 TRACE("returning %d (%08x)\n", ret
, GetLastError());
871 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
872 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
873 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
877 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
878 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
882 struct AsnDecodeSequenceItem items
[] = {
883 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
884 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
885 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
886 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
887 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
888 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
889 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
890 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
891 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
892 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
895 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
896 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
897 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
898 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
899 pcbStructInfo
, NULL
, NULL
);
903 SetLastError(STATUS_ACCESS_VIOLATION
);
908 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
912 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
913 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
918 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
920 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
922 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
923 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
925 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
930 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
931 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
935 struct AsnDecodeSequenceItem items
[] = {
936 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
937 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
938 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
939 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
942 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
943 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
948 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
949 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
953 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
954 offsetof(CERT_INFO
, cExtension
), offsetof(CERT_INFO
, rgExtension
),
955 FINALMEMBERSIZE(CERT_INFO
, cExtension
),
956 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
957 offsetof(CERT_EXTENSION
, pszObjId
) };
959 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
960 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
962 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
963 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
967 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
968 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
974 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
976 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
978 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
979 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
980 if (ret
&& pcbDecoded
)
981 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
986 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
987 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
988 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
991 struct AsnDecodeSequenceItem items
[] = {
992 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
993 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
994 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
995 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
996 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
997 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
998 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
999 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1000 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1001 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1003 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
1004 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
1006 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
1007 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1009 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
1010 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
1011 FALSE
, TRUE
, offsetof(CERT_INFO
,
1012 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
1013 { ASN_CONTEXT
| 1, offsetof(CERT_INFO
, IssuerUniqueId
),
1014 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1015 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
1016 { ASN_CONTEXT
| 2, offsetof(CERT_INFO
, SubjectUniqueId
),
1017 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1018 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
1019 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
1020 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
1021 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1024 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1025 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1027 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1028 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1030 if (ret
&& pvStructInfo
)
1034 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1035 info
= *(CERT_INFO
**)pvStructInfo
;
1037 info
= pvStructInfo
;
1038 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1039 !info
->Subject
.cbData
)
1041 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1042 /* Don't need to deallocate, because it should have failed on the
1043 * first pass (and no memory was allocated.)
1049 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1053 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1054 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1055 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1059 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1060 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1066 /* Unless told not to, first try to decode it as a signed cert. */
1067 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1069 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1071 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1072 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1073 &signedCert
, &size
);
1077 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1078 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1079 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1080 pvStructInfo
, pcbStructInfo
);
1081 LocalFree(signedCert
);
1084 /* Failing that, try it as an unsigned cert */
1088 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1089 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1090 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1095 SetLastError(STATUS_ACCESS_VIOLATION
);
1099 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1103 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1104 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1108 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1109 offsetof(CRL_ENTRY
, cExtension
), offsetof(CRL_ENTRY
, rgExtension
),
1110 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
),
1111 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1112 offsetof(CERT_EXTENSION
, pszObjId
) };
1114 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1115 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1117 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1118 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1122 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1123 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1126 struct AsnDecodeSequenceItem items
[] = {
1127 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1128 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1129 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1130 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1131 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1132 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1133 CRYPT_AsnDecodeCRLEntryExtensions
,
1134 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1135 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1137 PCRL_ENTRY entry
= pvStructInfo
;
1139 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1142 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1143 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1144 entry
? entry
->SerialNumber
.pbData
: NULL
);
1145 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1147 WARN("empty CRL entry serial number\n");
1148 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1154 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1155 * whose rgCRLEntry member has been set prior to calling.
1157 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1158 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1161 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1162 offsetof(CRL_INFO
, cCRLEntry
), offsetof(CRL_INFO
, rgCRLEntry
),
1163 MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1164 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1165 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1167 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1168 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1170 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1171 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1172 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1176 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1177 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1181 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1182 offsetof(CRL_INFO
, cExtension
), offsetof(CRL_INFO
, rgExtension
),
1183 FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1184 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1185 offsetof(CERT_EXTENSION
, pszObjId
) };
1187 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1188 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1190 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1191 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1195 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1196 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1202 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1204 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1206 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1207 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1208 if (ret
&& pcbDecoded
)
1209 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1214 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1215 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1216 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1218 struct AsnDecodeSequenceItem items
[] = {
1219 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1220 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1221 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1222 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1223 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1224 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1225 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1227 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1228 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1229 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1230 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1231 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1232 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1233 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1234 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1235 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1236 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1240 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1241 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1243 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
), pbEncoded
, cbEncoded
, dwFlags
,
1244 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1246 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1250 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1251 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1252 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1256 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1257 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1263 /* Unless told not to, first try to decode it as a signed crl. */
1264 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1266 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1268 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1269 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1274 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1275 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1276 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1277 pvStructInfo
, pcbStructInfo
);
1278 LocalFree(signedCrl
);
1281 /* Failing that, try it as an unsigned crl */
1285 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1286 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1287 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1292 SetLastError(STATUS_ACCESS_VIOLATION
);
1296 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1300 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1301 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1306 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1307 pvStructInfo
, *pcbStructInfo
);
1309 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1311 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1312 DWORD bytesNeeded
= sizeof(LPSTR
);
1319 snprintf(str
, sizeof(str
), "%d.%d",
1320 pbEncoded
[1 + lenBytes
] / 40,
1321 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1323 bytesNeeded
+= strlen(str
) + 1;
1324 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1325 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1329 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1336 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1339 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1346 snprintf(str
, sizeof(str
), ".%d", val
);
1347 bytesNeeded
+= strlen(str
);
1352 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1354 *pcbStructInfo
= bytesNeeded
;
1355 else if (*pcbStructInfo
< bytesNeeded
)
1357 *pcbStructInfo
= bytesNeeded
;
1358 SetLastError(ERROR_MORE_DATA
);
1366 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1369 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1370 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1372 pszObjId
+= strlen(pszObjId
);
1373 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1374 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1378 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1387 sprintf(pszObjId
, ".%d", val
);
1388 pszObjId
+= strlen(pszObjId
);
1392 *(LPSTR
*)pvStructInfo
= NULL
;
1393 *pcbStructInfo
= bytesNeeded
;
1399 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1400 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1404 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1405 pvStructInfo
, *pcbStructInfo
);
1407 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1408 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1409 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1412 SetLastError(CRYPT_E_ASN1_BADTAG
);
1418 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1419 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1421 struct AsnDecodeSequenceItem items
[] = {
1422 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1423 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1424 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1425 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1426 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1427 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1428 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1429 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1432 PCERT_EXTENSION ext
= pvStructInfo
;
1434 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1438 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1439 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1440 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1441 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1443 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1444 debugstr_a(ext
->pszObjId
));
1445 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1449 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1450 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1451 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1455 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1456 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1460 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1461 offsetof(CERT_EXTENSIONS
, cExtension
),
1462 offsetof(CERT_EXTENSIONS
, rgExtension
),
1463 sizeof(CERT_EXTENSIONS
),
1464 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1465 offsetof(CERT_EXTENSION
, pszObjId
) };
1466 CERT_EXTENSIONS
*exts
= pvStructInfo
;
1468 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1469 exts
->rgExtension
= (CERT_EXTENSION
*)(exts
+ 1);
1470 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1471 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1475 SetLastError(STATUS_ACCESS_VIOLATION
);
1482 /* Warning: this assumes the address of value->Value.pbData is already set, in
1483 * order to avoid overwriting memory. (In some cases, it may change it, if it
1484 * doesn't copy anything to memory.) Be sure to set it correctly!
1486 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1487 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1492 CERT_NAME_VALUE
*value
= pvStructInfo
;
1494 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1496 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1497 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1499 switch (pbEncoded
[0])
1501 case ASN_OCTETSTRING
:
1502 valueType
= CERT_RDN_OCTET_STRING
;
1503 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1504 bytesNeeded
+= dataLen
;
1506 case ASN_NUMERICSTRING
:
1507 valueType
= CERT_RDN_NUMERIC_STRING
;
1508 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1509 bytesNeeded
+= dataLen
;
1511 case ASN_PRINTABLESTRING
:
1512 valueType
= CERT_RDN_PRINTABLE_STRING
;
1513 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1514 bytesNeeded
+= dataLen
;
1517 valueType
= CERT_RDN_IA5_STRING
;
1518 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1519 bytesNeeded
+= dataLen
;
1522 valueType
= CERT_RDN_T61_STRING
;
1523 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1524 bytesNeeded
+= dataLen
;
1526 case ASN_VIDEOTEXSTRING
:
1527 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1528 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1529 bytesNeeded
+= dataLen
;
1531 case ASN_GRAPHICSTRING
:
1532 valueType
= CERT_RDN_GRAPHIC_STRING
;
1533 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1534 bytesNeeded
+= dataLen
;
1536 case ASN_VISIBLESTRING
:
1537 valueType
= CERT_RDN_VISIBLE_STRING
;
1538 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1539 bytesNeeded
+= dataLen
;
1541 case ASN_GENERALSTRING
:
1542 valueType
= CERT_RDN_GENERAL_STRING
;
1543 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1544 bytesNeeded
+= dataLen
;
1546 case ASN_UNIVERSALSTRING
:
1547 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1548 SetLastError(CRYPT_E_ASN1_BADTAG
);
1551 valueType
= CERT_RDN_BMP_STRING
;
1552 bytesNeeded
+= dataLen
;
1554 case ASN_UTF8STRING
:
1555 valueType
= CERT_RDN_UTF8_STRING
;
1556 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1557 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * sizeof(WCHAR
);
1560 SetLastError(CRYPT_E_ASN1_BADTAG
);
1565 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1567 *pcbStructInfo
= bytesNeeded
;
1568 else if (*pcbStructInfo
< bytesNeeded
)
1570 *pcbStructInfo
= bytesNeeded
;
1571 SetLastError(ERROR_MORE_DATA
);
1576 *pcbStructInfo
= bytesNeeded
;
1577 value
->dwValueType
= valueType
;
1582 assert(value
->Value
.pbData
);
1583 switch (pbEncoded
[0])
1585 case ASN_OCTETSTRING
:
1586 case ASN_NUMERICSTRING
:
1587 case ASN_PRINTABLESTRING
:
1590 case ASN_VIDEOTEXSTRING
:
1591 case ASN_GRAPHICSTRING
:
1592 case ASN_VISIBLESTRING
:
1593 case ASN_GENERALSTRING
:
1594 value
->Value
.cbData
= dataLen
;
1595 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1596 memcpy(value
->Value
.pbData
,
1597 pbEncoded
+ 1 + lenBytes
, dataLen
);
1599 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1604 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1606 value
->Value
.cbData
= dataLen
;
1607 for (i
= 0; i
< dataLen
/ 2; i
++)
1608 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1609 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1612 case ASN_UTF8STRING
:
1614 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1616 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1617 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1618 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1625 value
->Value
.cbData
= 0;
1626 value
->Value
.pbData
= NULL
;
1633 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1634 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1635 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1641 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1642 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1643 if (ret
&& pvStructInfo
)
1645 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1646 pcbStructInfo
, *pcbStructInfo
);
1649 CERT_NAME_VALUE
*value
;
1651 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1652 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1653 value
= pvStructInfo
;
1654 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1655 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1656 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1657 pcbStructInfo
, NULL
);
1658 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1659 CRYPT_FreeSpace(pDecodePara
, value
);
1665 SetLastError(STATUS_ACCESS_VIOLATION
);
1672 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1673 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1678 CERT_NAME_VALUE
*value
= pvStructInfo
;
1680 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1682 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1683 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1685 switch (pbEncoded
[0])
1687 case ASN_NUMERICSTRING
:
1688 valueType
= CERT_RDN_NUMERIC_STRING
;
1690 bytesNeeded
+= (dataLen
+ 1) * 2;
1692 case ASN_PRINTABLESTRING
:
1693 valueType
= CERT_RDN_PRINTABLE_STRING
;
1695 bytesNeeded
+= (dataLen
+ 1) * 2;
1698 valueType
= CERT_RDN_IA5_STRING
;
1700 bytesNeeded
+= (dataLen
+ 1) * 2;
1703 valueType
= CERT_RDN_T61_STRING
;
1705 bytesNeeded
+= (dataLen
+ 1) * 2;
1707 case ASN_VIDEOTEXSTRING
:
1708 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1710 bytesNeeded
+= (dataLen
+ 1) * 2;
1712 case ASN_GRAPHICSTRING
:
1713 valueType
= CERT_RDN_GRAPHIC_STRING
;
1715 bytesNeeded
+= (dataLen
+ 1) * 2;
1717 case ASN_VISIBLESTRING
:
1718 valueType
= CERT_RDN_VISIBLE_STRING
;
1720 bytesNeeded
+= (dataLen
+ 1) * 2;
1722 case ASN_GENERALSTRING
:
1723 valueType
= CERT_RDN_GENERAL_STRING
;
1725 bytesNeeded
+= (dataLen
+ 1) * 2;
1727 case ASN_UNIVERSALSTRING
:
1728 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1730 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1733 valueType
= CERT_RDN_BMP_STRING
;
1735 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1737 case ASN_UTF8STRING
:
1738 valueType
= CERT_RDN_UTF8_STRING
;
1740 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1741 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1744 SetLastError(CRYPT_E_ASN1_BADTAG
);
1749 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1751 *pcbStructInfo
= bytesNeeded
;
1752 else if (*pcbStructInfo
< bytesNeeded
)
1754 *pcbStructInfo
= bytesNeeded
;
1755 SetLastError(ERROR_MORE_DATA
);
1760 *pcbStructInfo
= bytesNeeded
;
1761 value
->dwValueType
= valueType
;
1765 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1767 assert(value
->Value
.pbData
);
1768 switch (pbEncoded
[0])
1770 case ASN_NUMERICSTRING
:
1771 case ASN_PRINTABLESTRING
:
1774 case ASN_VIDEOTEXSTRING
:
1775 case ASN_GRAPHICSTRING
:
1776 case ASN_VISIBLESTRING
:
1777 case ASN_GENERALSTRING
:
1778 value
->Value
.cbData
= dataLen
* 2;
1779 for (i
= 0; i
< dataLen
; i
++)
1780 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1783 case ASN_UNIVERSALSTRING
:
1784 value
->Value
.cbData
= dataLen
/ 2;
1785 for (i
= 0; i
< dataLen
/ 4; i
++)
1786 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1787 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1791 value
->Value
.cbData
= dataLen
;
1792 for (i
= 0; i
< dataLen
/ 2; i
++)
1793 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1794 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1797 case ASN_UTF8STRING
:
1798 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1799 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1800 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1801 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1802 value
->Value
.cbData
+= sizeof(WCHAR
);
1808 value
->Value
.cbData
= 0;
1809 value
->Value
.pbData
= NULL
;
1816 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1817 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1818 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1824 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1825 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1826 if (ret
&& pvStructInfo
)
1828 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1829 pcbStructInfo
, *pcbStructInfo
);
1832 CERT_NAME_VALUE
*value
;
1834 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1835 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1836 value
= pvStructInfo
;
1837 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1838 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1839 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1840 pcbStructInfo
, NULL
);
1841 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1842 CRYPT_FreeSpace(pDecodePara
, value
);
1848 SetLastError(STATUS_ACCESS_VIOLATION
);
1855 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1856 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1859 struct AsnDecodeSequenceItem items
[] = {
1860 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1861 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1862 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1863 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1864 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1865 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1867 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1869 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1870 pvStructInfo
, *pcbStructInfo
);
1873 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1874 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1875 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1876 attr
? attr
->pszObjId
: NULL
);
1879 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1880 debugstr_a(attr
->pszObjId
));
1881 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1883 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1887 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1888 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1891 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1892 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1894 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1895 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1897 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1898 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1902 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1903 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1904 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1910 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1911 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1912 sizeof(CERT_NAME_INFO
),
1913 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1914 offsetof(CERT_RDN
, rgRDNAttr
) };
1915 DWORD bytesNeeded
= 0;
1917 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1918 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1923 *pcbStructInfo
= bytesNeeded
;
1924 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1925 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1927 CERT_NAME_INFO
*info
;
1929 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1930 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1931 info
= pvStructInfo
;
1932 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1933 sizeof(CERT_NAME_INFO
));
1934 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1935 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1936 &bytesNeeded
, NULL
);
1937 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1938 CRYPT_FreeSpace(pDecodePara
, info
);
1944 SetLastError(STATUS_ACCESS_VIOLATION
);
1951 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1952 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1956 struct AsnDecodeSequenceItem items
[] = {
1957 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1958 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1959 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1960 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1961 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1962 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1964 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1966 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1967 pvStructInfo
, *pcbStructInfo
);
1970 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1971 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1972 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1973 attr
? attr
->pszObjId
: NULL
);
1976 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1977 debugstr_a(attr
->pszObjId
));
1978 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1980 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1984 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1985 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1988 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1989 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1991 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1992 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1994 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1995 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1999 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
2000 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2001 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2007 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2008 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2009 sizeof(CERT_NAME_INFO
),
2010 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2011 offsetof(CERT_RDN
, rgRDNAttr
) };
2012 DWORD bytesNeeded
= 0;
2014 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2015 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2020 *pcbStructInfo
= bytesNeeded
;
2021 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2022 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2024 CERT_NAME_INFO
*info
;
2026 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2027 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2028 info
= pvStructInfo
;
2029 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2030 sizeof(CERT_NAME_INFO
));
2031 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2032 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2033 &bytesNeeded
, NULL
);
2034 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2035 CRYPT_FreeSpace(pDecodePara
, info
);
2041 SetLastError(STATUS_ACCESS_VIOLATION
);
2048 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2051 BOOL ret
= TRUE
, done
= FALSE
;
2052 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2054 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2061 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2064 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2066 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2068 indefiniteNestingLevels
++;
2069 pbEncoded
+= 1 + lenBytes
;
2070 cbEncoded
-= 1 + lenBytes
;
2071 decoded
+= 1 + lenBytes
;
2072 TRACE("indefiniteNestingLevels = %d\n",
2073 indefiniteNestingLevels
);
2077 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2078 indefiniteNestingLevels
)
2080 indefiniteNestingLevels
--;
2081 TRACE("indefiniteNestingLevels = %d\n",
2082 indefiniteNestingLevels
);
2084 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2085 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2086 decoded
+= 1 + lenBytes
+ dataLen
;
2087 if (!indefiniteNestingLevels
)
2091 } while (ret
&& !done
);
2092 /* If we haven't found all 0 TLVs, we haven't found the end */
2093 if (ret
&& indefiniteNestingLevels
)
2095 SetLastError(CRYPT_E_ASN1_EOD
);
2099 *pcbDecoded
= decoded
;
2100 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2104 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2105 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2109 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2111 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2112 pvStructInfo
, *pcbStructInfo
);
2114 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2116 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2117 bytesNeeded
+= encodedLen
;
2119 *pcbStructInfo
= bytesNeeded
;
2120 else if (*pcbStructInfo
< bytesNeeded
)
2122 SetLastError(ERROR_MORE_DATA
);
2123 *pcbStructInfo
= bytesNeeded
;
2128 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2130 *pcbStructInfo
= bytesNeeded
;
2131 blob
->cbData
= encodedLen
;
2134 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2135 blob
->pbData
= (LPBYTE
)pbEncoded
;
2138 assert(blob
->pbData
);
2139 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2143 blob
->pbData
= NULL
;
2146 *pcbDecoded
= encodedLen
;
2151 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2152 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2155 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2156 offsetof(CTL_USAGE
, cUsageIdentifier
),
2157 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2159 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2161 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2162 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2166 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2167 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2170 struct AsnArrayDescriptor arrayDesc
= { 0,
2171 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2172 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2173 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2174 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2177 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2178 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2182 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2183 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2185 struct AsnDecodeSequenceItem items
[] = {
2186 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2187 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2188 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2189 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2190 CRYPT_AsnDecodeCTLEntryAttributes
,
2191 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2192 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2195 CTL_ENTRY
*entry
= pvStructInfo
;
2197 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2200 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2201 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2202 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2206 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2207 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2210 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2211 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2212 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2213 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2214 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2216 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2217 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2219 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2220 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2224 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2225 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2229 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2230 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2231 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2232 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2233 offsetof(CERT_EXTENSION
, pszObjId
) };
2235 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2236 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2238 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2239 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2243 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2244 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2250 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2252 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2254 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2255 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2256 if (ret
&& pcbDecoded
)
2257 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2262 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2263 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2264 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2268 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2269 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2273 struct AsnDecodeSequenceItem items
[] = {
2274 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2275 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2276 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2277 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2278 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2279 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2280 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2281 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2282 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2283 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2284 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2285 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2286 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2288 { 0, offsetof(CTL_INFO
, NextUpdate
),
2289 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2291 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2292 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2293 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2294 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2295 CRYPT_AsnDecodeCTLEntries
,
2296 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2297 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2298 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2299 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2300 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2303 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2304 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2305 pcbStructInfo
, NULL
, NULL
);
2309 SetLastError(STATUS_ACCESS_VIOLATION
);
2315 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2316 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2320 struct AsnDecodeSequenceItem items
[] = {
2321 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2322 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2323 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2324 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2325 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2326 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2328 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2330 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2331 pvStructInfo
, *pcbStructInfo
);
2333 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2334 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2335 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2336 TRACE("returning %d\n", ret
);
2340 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2341 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2342 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2346 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2347 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2351 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2352 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2353 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2354 sizeof(CRYPT_SMIME_CAPABILITIES
),
2355 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2356 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2357 CRYPT_SMIME_CAPABILITIES
*capabilities
= pvStructInfo
;
2359 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2360 capabilities
->rgCapability
= (CRYPT_SMIME_CAPABILITY
*)(capabilities
+ 1);
2361 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2362 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2366 SetLastError(STATUS_ACCESS_VIOLATION
);
2369 TRACE("returning %d\n", ret
);
2373 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2374 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2379 LPSTR
*pStr
= pvStructInfo
;
2381 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2383 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2384 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2386 if (pbEncoded
[0] != ASN_IA5STRING
)
2388 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2393 bytesNeeded
+= dataLen
;
2395 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2397 *pcbStructInfo
= bytesNeeded
;
2398 else if (*pcbStructInfo
< bytesNeeded
)
2400 *pcbStructInfo
= bytesNeeded
;
2401 SetLastError(ERROR_MORE_DATA
);
2406 *pcbStructInfo
= bytesNeeded
;
2412 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2423 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2424 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2427 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2428 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2429 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2430 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2431 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2434 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2435 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2437 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2438 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2439 TRACE("returning %d\n", ret
);
2443 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2444 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2448 struct AsnDecodeSequenceItem items
[] = {
2449 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2450 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2451 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2452 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2453 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2454 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2455 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2456 rgNoticeNumbers
), 0 },
2458 DWORD bytesNeeded
= 0;
2460 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2461 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2463 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2464 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2468 /* The caller is expecting a pointer to a
2469 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2470 * CRYPT_AsnDecodeSequence is decoding a
2471 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2472 * needed, and decode again if the requisite space is available.
2474 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2476 *pcbStructInfo
= bytesNeeded
;
2477 else if (*pcbStructInfo
< bytesNeeded
)
2479 *pcbStructInfo
= bytesNeeded
;
2480 SetLastError(ERROR_MORE_DATA
);
2485 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2487 *pcbStructInfo
= bytesNeeded
;
2488 /* The pointer (pvStructInfo) passed in points to the first dynamic
2489 * pointer, so use it as the pointer to the
2490 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2491 * appropriate offset for the first dynamic pointer within the
2492 * notice reference by pointing to the first memory location past
2493 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2496 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2497 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2498 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2499 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
), pbEncoded
, cbEncoded
, dwFlags
,
2500 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
, noticeRef
->pszOrganization
);
2503 TRACE("returning %d\n", ret
);
2507 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2508 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2514 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2516 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2517 DWORD bytesNeeded
= sizeof(LPWSTR
);
2519 switch (pbEncoded
[0])
2521 case ASN_NUMERICSTRING
:
2523 bytesNeeded
+= (dataLen
+ 1) * 2;
2525 case ASN_PRINTABLESTRING
:
2527 bytesNeeded
+= (dataLen
+ 1) * 2;
2531 bytesNeeded
+= (dataLen
+ 1) * 2;
2535 bytesNeeded
+= (dataLen
+ 1) * 2;
2537 case ASN_VIDEOTEXSTRING
:
2539 bytesNeeded
+= (dataLen
+ 1) * 2;
2541 case ASN_GRAPHICSTRING
:
2543 bytesNeeded
+= (dataLen
+ 1) * 2;
2545 case ASN_VISIBLESTRING
:
2547 bytesNeeded
+= (dataLen
+ 1) * 2;
2549 case ASN_GENERALSTRING
:
2551 bytesNeeded
+= (dataLen
+ 1) * 2;
2553 case ASN_UNIVERSALSTRING
:
2555 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2559 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2561 case ASN_UTF8STRING
:
2563 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2564 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2567 SetLastError(CRYPT_E_ASN1_BADTAG
);
2572 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2574 *pcbStructInfo
= bytesNeeded
;
2575 else if (*pcbStructInfo
< bytesNeeded
)
2577 *pcbStructInfo
= bytesNeeded
;
2578 SetLastError(ERROR_MORE_DATA
);
2583 LPWSTR
*pStr
= pvStructInfo
;
2585 *pcbStructInfo
= bytesNeeded
;
2592 switch (pbEncoded
[0])
2594 case ASN_NUMERICSTRING
:
2595 case ASN_PRINTABLESTRING
:
2598 case ASN_VIDEOTEXSTRING
:
2599 case ASN_GRAPHICSTRING
:
2600 case ASN_VISIBLESTRING
:
2601 case ASN_GENERALSTRING
:
2602 for (i
= 0; i
< dataLen
; i
++)
2603 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2606 case ASN_UNIVERSALSTRING
:
2607 for (i
= 0; i
< dataLen
/ 4; i
++)
2608 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2609 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2613 for (i
= 0; i
< dataLen
/ 2; i
++)
2614 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2615 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2618 case ASN_UTF8STRING
:
2620 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2621 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2622 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2635 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2636 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2637 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2640 struct AsnDecodeSequenceItem items
[] = {
2641 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2642 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2643 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2644 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2645 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2646 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2647 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2649 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2651 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2652 pvStructInfo
, *pcbStructInfo
);
2654 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2655 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2656 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2657 TRACE("returning %d\n", ret
);
2661 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2662 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2663 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2664 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2668 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2669 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2673 DWORD bytesNeeded
= 0;
2675 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2676 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2681 *pcbStructInfo
= bytesNeeded
;
2682 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2683 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2685 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2687 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2688 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2689 notice
= pvStructInfo
;
2690 notice
->pNoticeReference
=
2691 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2692 ((BYTE
*)pvStructInfo
+
2693 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2694 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2695 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2696 pvStructInfo
, &bytesNeeded
, NULL
);
2697 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2698 CRYPT_FreeSpace(pDecodePara
, notice
);
2704 SetLastError(STATUS_ACCESS_VIOLATION
);
2707 TRACE("returning %d\n", ret
);
2711 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2712 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2716 struct AsnArrayDescriptor arrayDesc
= { 0,
2717 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2718 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2719 CRYPT_AsnDecodeCopyBytes
,
2720 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2722 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2723 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2725 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2726 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2730 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2731 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2735 struct AsnDecodeSequenceItem items
[] = {
2736 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2737 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2738 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2739 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2740 CRYPT_AsnDecodePKCSAttributeValue
,
2741 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2742 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2744 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2746 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2747 pvStructInfo
, *pcbStructInfo
);
2749 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2750 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2751 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2752 TRACE("returning %d\n", ret
);
2756 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2757 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2758 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2762 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2763 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2767 DWORD bytesNeeded
= 0;
2769 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2770 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2774 *pcbStructInfo
= bytesNeeded
;
2775 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2776 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2778 PCRYPT_ATTRIBUTE attr
;
2780 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2781 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2782 attr
= pvStructInfo
;
2783 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2784 sizeof(CRYPT_ATTRIBUTE
));
2785 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2786 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2788 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2789 CRYPT_FreeSpace(pDecodePara
, attr
);
2795 SetLastError(STATUS_ACCESS_VIOLATION
);
2798 TRACE("returning %d\n", ret
);
2802 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2803 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2806 struct AsnArrayDescriptor arrayDesc
= { 0,
2807 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2808 sizeof(CRYPT_ATTRIBUTES
),
2809 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2810 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2813 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2814 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2818 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2819 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2820 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2824 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2825 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2829 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2830 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2831 sizeof(CRYPT_ATTRIBUTES
),
2832 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2833 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2834 CRYPT_ATTRIBUTES
*attrs
= pvStructInfo
;
2836 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2837 attrs
->rgAttr
= (CRYPT_ATTRIBUTE
*)(attrs
+ 1);
2838 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2839 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2843 SetLastError(STATUS_ACCESS_VIOLATION
);
2846 TRACE("returning %d\n", ret
);
2850 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2851 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2853 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2855 struct AsnDecodeSequenceItem items
[] = {
2856 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2857 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2858 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2859 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2860 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2861 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2864 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2865 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2867 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2868 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2869 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2870 if (ret
&& pvStructInfo
)
2872 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2873 debugstr_a(algo
->pszObjId
));
2878 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2879 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2883 struct AsnDecodeSequenceItem items
[] = {
2884 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2885 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2886 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2887 Algorithm
.pszObjId
) },
2888 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2889 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2890 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2892 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2894 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2895 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2896 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2900 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2901 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2902 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2908 DWORD bytesNeeded
= 0;
2910 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2911 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2914 *pcbStructInfo
= bytesNeeded
;
2915 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2916 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2918 PCERT_PUBLIC_KEY_INFO info
;
2920 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2921 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2922 info
= pvStructInfo
;
2923 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2924 sizeof(CERT_PUBLIC_KEY_INFO
);
2925 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2926 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2927 &bytesNeeded
, NULL
);
2928 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2929 CRYPT_FreeSpace(pDecodePara
, info
);
2935 SetLastError(STATUS_ACCESS_VIOLATION
);
2942 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2943 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2949 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2952 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2954 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2957 if (pbEncoded
[1] > 1)
2959 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2966 *pcbStructInfo
= sizeof(BOOL
);
2969 else if (*pcbStructInfo
< sizeof(BOOL
))
2971 *pcbStructInfo
= sizeof(BOOL
);
2972 SetLastError(ERROR_MORE_DATA
);
2977 *pcbStructInfo
= sizeof(BOOL
);
2978 *(BOOL
*)pvStructInfo
= pbEncoded
[2] != 0;
2981 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2985 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2986 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2988 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2989 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2992 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2993 pvStructInfo
, *pcbStructInfo
);
2997 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3000 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3001 if (1 + lenBytes
> cbEncoded
)
3003 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3006 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3008 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3010 case 1: /* rfc822Name */
3011 case 2: /* dNSName */
3012 case 6: /* uniformResourceIdentifier */
3013 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
3015 SetLastError(CRYPT_E_ASN1_RULE
);
3019 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3021 case 4: /* directoryName */
3022 case 7: /* iPAddress */
3023 bytesNeeded
+= dataLen
;
3025 case 8: /* registeredID */
3026 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3030 /* FIXME: ugly, shouldn't need to know internals of OID decode
3031 * function to use it.
3033 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3036 case 0: /* otherName */
3037 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3038 SetLastError(CRYPT_E_ASN1_BADTAG
);
3041 case 3: /* x400Address, unimplemented */
3042 case 5: /* ediPartyName, unimplemented */
3043 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3044 SetLastError(CRYPT_E_ASN1_BADTAG
);
3048 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3049 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3055 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3057 *pcbStructInfo
= bytesNeeded
;
3058 else if (*pcbStructInfo
< bytesNeeded
)
3060 *pcbStructInfo
= bytesNeeded
;
3061 SetLastError(ERROR_MORE_DATA
);
3066 *pcbStructInfo
= bytesNeeded
;
3067 /* MS used values one greater than the asn1 ones.. sigh */
3068 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3069 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3071 case 1: /* rfc822Name */
3072 case 2: /* dNSName */
3073 case 6: /* uniformResourceIdentifier */
3077 for (i
= 0; i
< dataLen
; i
++)
3078 entry
->u
.pwszURL
[i
] =
3079 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3080 entry
->u
.pwszURL
[i
] = 0;
3081 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3082 debugstr_w(entry
->u
.pwszURL
));
3085 case 4: /* directoryName */
3086 /* The data are memory-equivalent with the IPAddress case,
3089 case 7: /* iPAddress */
3090 /* The next data pointer is in the pwszURL spot, that is,
3091 * the first 4 bytes. Need to move it to the next spot.
3093 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3094 entry
->u
.IPAddress
.cbData
= dataLen
;
3095 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3098 case 8: /* registeredID */
3099 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3100 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3109 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3110 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3114 struct AsnArrayDescriptor arrayDesc
= { 0,
3115 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3116 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3117 sizeof(CERT_ALT_NAME_INFO
),
3118 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3119 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3121 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3122 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3124 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3125 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3129 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3130 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3131 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3137 struct AsnDecodeSequenceItem items
[] = {
3138 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3139 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3140 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3141 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3142 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3143 CRYPT_AsnDecodeOctets
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3144 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3145 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3146 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3147 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3148 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3151 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3152 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3153 pcbStructInfo
, NULL
, NULL
);
3157 SetLastError(STATUS_ACCESS_VIOLATION
);
3164 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3165 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3166 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3172 struct AsnDecodeSequenceItem items
[] = {
3173 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3174 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3175 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3176 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3177 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3178 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3179 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3180 AuthorityCertIssuer
.rgAltEntry
), 0 },
3181 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3182 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3183 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3184 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3185 AuthorityCertSerialNumber
.pbData
), 0 },
3188 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3189 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3190 pcbStructInfo
, NULL
, NULL
);
3194 SetLastError(STATUS_ACCESS_VIOLATION
);
3201 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3202 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3205 struct AsnDecodeSequenceItem items
[] = {
3206 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3207 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3208 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3209 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3210 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3211 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3213 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3215 return CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3216 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3217 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3220 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3221 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3222 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3226 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3227 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3231 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3232 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3233 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3234 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3235 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3236 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3237 CERT_AUTHORITY_INFO_ACCESS
*info
= pvStructInfo
;
3239 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3240 info
->rgAccDescr
= (CERT_ACCESS_DESCRIPTION
*)(info
+ 1);
3241 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3242 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3246 SetLastError(STATUS_ACCESS_VIOLATION
);
3253 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3254 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3259 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3260 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3262 /* The caller has already checked the tag, no need to check it again.
3263 * Check the outer length is valid:
3265 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3267 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3270 pbEncoded
+= 1 + lenBytes
;
3271 cbEncoded
-= 1 + lenBytes
;
3272 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3273 cbEncoded
-= 2; /* space for 0 TLV */
3274 /* Check the inner length is valid: */
3275 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3279 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3280 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3281 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3283 if (*(pbEncoded
+ decodedLen
) != 0 ||
3284 *(pbEncoded
+ decodedLen
+ 1) != 0)
3286 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3287 *(pbEncoded
+ decodedLen
),
3288 *(pbEncoded
+ decodedLen
+ 1));
3289 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3295 if (ret
&& pcbDecoded
)
3297 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3298 TRACE("decoded %d bytes\n", *pcbDecoded
);
3305 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3306 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3309 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3310 struct AsnDecodeSequenceItem items
[] = {
3311 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3312 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3313 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3314 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3315 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3316 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3317 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3321 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3322 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3324 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3325 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3326 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3330 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3331 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3332 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3336 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3337 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3341 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3342 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3343 if (ret
&& pvStructInfo
)
3345 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3346 pcbStructInfo
, *pcbStructInfo
);
3349 CRYPT_CONTENT_INFO
*info
;
3351 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3352 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3353 info
= pvStructInfo
;
3354 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3355 sizeof(CRYPT_CONTENT_INFO
));
3356 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3357 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3358 pcbStructInfo
, NULL
);
3359 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3360 CRYPT_FreeSpace(pDecodePara
, info
);
3366 SetLastError(STATUS_ACCESS_VIOLATION
);
3372 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3373 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3374 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3377 struct AsnDecodeSequenceItem items
[] = {
3378 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3379 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3380 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3381 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3382 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3384 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3385 CRYPT_AsnDecodePKCSContentInfoInternal
,
3386 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3387 ContentInfo
.pszObjId
), 0 },
3388 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3389 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3390 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3393 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3394 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3399 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3400 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3401 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3405 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3406 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3410 DWORD bytesNeeded
= 0;
3412 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3413 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3416 *pcbStructInfo
= bytesNeeded
;
3417 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3418 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3420 CERT_ALT_NAME_INFO
*name
;
3422 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3423 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3424 name
= pvStructInfo
;
3425 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3426 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3427 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3428 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3429 &bytesNeeded
, NULL
);
3430 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3431 CRYPT_FreeSpace(pDecodePara
, name
);
3437 SetLastError(STATUS_ACCESS_VIOLATION
);
3444 struct PATH_LEN_CONSTRAINT
3446 BOOL fPathLenConstraint
;
3447 DWORD dwPathLenConstraint
;
3450 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3451 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3455 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3457 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3458 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3462 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3464 *pcbStructInfo
= bytesNeeded
;
3466 else if (*pcbStructInfo
< bytesNeeded
)
3468 SetLastError(ERROR_MORE_DATA
);
3469 *pcbStructInfo
= bytesNeeded
;
3474 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3476 *pcbStructInfo
= bytesNeeded
;
3477 size
= sizeof(constraint
->dwPathLenConstraint
);
3478 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3479 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3481 constraint
->fPathLenConstraint
= TRUE
;
3482 TRACE("got an int, dwPathLenConstraint is %d\n",
3483 constraint
->dwPathLenConstraint
);
3485 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3489 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3490 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3494 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3495 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3496 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3497 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3498 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3499 offsetof(CERT_NAME_BLOB
, pbData
) };
3501 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3502 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3504 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3505 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3506 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3510 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3511 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3512 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3518 struct AsnDecodeSequenceItem items
[] = {
3519 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3520 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3521 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3522 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3523 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3524 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3525 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3526 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3527 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3529 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3532 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3533 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3534 pcbStructInfo
, NULL
, NULL
);
3538 SetLastError(STATUS_ACCESS_VIOLATION
);
3545 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3546 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3547 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3553 struct AsnDecodeSequenceItem items
[] = {
3554 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3555 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3556 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3557 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3558 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3561 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3562 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3563 pcbStructInfo
, NULL
, NULL
);
3567 SetLastError(STATUS_ACCESS_VIOLATION
);
3574 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3575 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3578 struct AsnDecodeSequenceItem items
[] = {
3579 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3580 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3581 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3583 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3584 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3585 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3588 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3590 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3591 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3593 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3594 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3595 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3599 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3600 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3604 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3605 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3606 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3607 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3608 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3609 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3611 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3612 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3614 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3615 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3616 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3620 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3621 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3623 struct AsnDecodeSequenceItem items
[] = {
3624 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3625 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3626 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3627 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3628 CRYPT_AsnDecodePolicyQualifiers
,
3629 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3630 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3632 CERT_POLICY_INFO
*info
= pvStructInfo
;
3635 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3636 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3638 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3639 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3640 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3644 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3645 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3646 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3650 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3651 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3655 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3656 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3657 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3658 sizeof(CERT_POLICIES_INFO
),
3659 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3660 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3661 CERT_POLICIES_INFO
*info
= pvStructInfo
;
3663 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3664 info
->rgPolicyInfo
= (CERT_POLICY_INFO
*)(info
+ 1);
3666 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3667 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3671 SetLastError(STATUS_ACCESS_VIOLATION
);
3677 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3678 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3681 struct AsnDecodeSequenceItem items
[] = {
3682 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3683 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3684 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3685 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3686 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3687 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3689 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3692 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3693 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3695 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3696 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3697 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3701 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3702 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3703 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3707 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3708 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3712 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3713 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3714 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3715 sizeof(CERT_POLICY_MAPPING
),
3716 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3717 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3718 CERT_POLICY_MAPPINGS_INFO
*info
= pvStructInfo
;
3720 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3721 info
->rgPolicyMapping
= (CERT_POLICY_MAPPING
*)(info
+ 1);
3722 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3723 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3727 SetLastError(STATUS_ACCESS_VIOLATION
);
3733 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3734 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3738 DWORD skip
, size
= sizeof(skip
);
3742 SetLastError(CRYPT_E_ASN1_EOD
);
3745 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3747 SetLastError(CRYPT_E_ASN1_BADTAG
);
3750 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3751 &skip
, &size
, pcbDecoded
)))
3753 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3754 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3757 *pcbStructInfo
= bytesNeeded
;
3758 else if (*pcbStructInfo
< bytesNeeded
)
3760 *pcbStructInfo
= bytesNeeded
;
3761 SetLastError(ERROR_MORE_DATA
);
3766 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3767 CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
);
3769 *pcbStructInfo
= bytesNeeded
;
3770 /* The BOOL is implicit: if the integer is present, then it's
3773 info
->fRequireExplicitPolicy
= TRUE
;
3774 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3780 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3781 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3785 DWORD skip
, size
= sizeof(skip
);
3789 SetLastError(CRYPT_E_ASN1_EOD
);
3792 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3794 SetLastError(CRYPT_E_ASN1_BADTAG
);
3797 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3798 &skip
, &size
, pcbDecoded
)))
3800 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3801 fInhibitPolicyMapping
);
3804 *pcbStructInfo
= bytesNeeded
;
3805 else if (*pcbStructInfo
< bytesNeeded
)
3807 *pcbStructInfo
= bytesNeeded
;
3808 SetLastError(ERROR_MORE_DATA
);
3813 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3814 CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
);
3816 *pcbStructInfo
= bytesNeeded
;
3817 /* The BOOL is implicit: if the integer is present, then it's
3820 info
->fInhibitPolicyMapping
= TRUE
;
3821 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3827 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3828 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3829 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3830 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3834 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3835 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3839 struct AsnDecodeSequenceItem items
[] = {
3841 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3842 CRYPT_AsnDecodeRequireExplicit
,
3843 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3844 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3846 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3847 CRYPT_AsnDecodeInhibitMapping
,
3848 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3849 TRUE
, FALSE
, 0, 0 },
3852 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3853 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3854 pcbStructInfo
, NULL
, NULL
);
3858 SetLastError(STATUS_ACCESS_VIOLATION
);
3864 #define RSA1_MAGIC 0x31415352
3866 struct DECODED_RSA_PUB_KEY
3869 CRYPT_INTEGER_BLOB modulus
;
3872 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3873 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3874 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3880 struct AsnDecodeSequenceItem items
[] = {
3881 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3882 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3883 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3885 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3886 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3888 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3891 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3892 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3896 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3897 decodedKey
->modulus
.cbData
;
3901 *pcbStructInfo
= bytesNeeded
;
3904 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3905 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3908 RSAPUBKEY
*rsaPubKey
;
3910 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3911 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3913 hdr
->bType
= PUBLICKEYBLOB
;
3914 hdr
->bVersion
= CUR_BLOB_VERSION
;
3916 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3917 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3918 sizeof(BLOBHEADER
));
3919 rsaPubKey
->magic
= RSA1_MAGIC
;
3920 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3921 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3922 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3923 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3924 decodedKey
->modulus
.cbData
);
3926 LocalFree(decodedKey
);
3931 SetLastError(STATUS_ACCESS_VIOLATION
);
3938 #define RSA2_MAGIC 0x32415352
3940 struct DECODED_RSA_PRIV_KEY
3944 CRYPT_INTEGER_BLOB modulus
;
3945 CRYPT_INTEGER_BLOB privexp
;
3946 CRYPT_INTEGER_BLOB prime1
;
3947 CRYPT_INTEGER_BLOB prime2
;
3948 CRYPT_INTEGER_BLOB exponent1
;
3949 CRYPT_INTEGER_BLOB exponent2
;
3950 CRYPT_INTEGER_BLOB coefficient
;
3953 static BOOL WINAPI
CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType
,
3954 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3955 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3962 struct AsnDecodeSequenceItem items
[] = {
3963 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, version
),
3964 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3965 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
),
3966 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3967 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
.pbData
),
3969 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, pubexp
),
3970 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3971 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
),
3972 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3973 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
.pbData
),
3975 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
),
3976 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3977 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
.pbData
),
3979 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
),
3980 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3981 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
.pbData
),
3983 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
),
3984 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3985 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
.pbData
),
3987 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
),
3988 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3989 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
.pbData
),
3991 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
),
3992 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3993 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
.pbData
),
3996 struct DECODED_RSA_PRIV_KEY
*decodedKey
= NULL
;
3999 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
4000 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
4004 halflen
= decodedKey
->prime1
.cbData
;
4005 if (halflen
< decodedKey
->prime2
.cbData
)
4006 halflen
= decodedKey
->prime2
.cbData
;
4007 if (halflen
< decodedKey
->exponent1
.cbData
)
4008 halflen
= decodedKey
->exponent1
.cbData
;
4009 if (halflen
< decodedKey
->exponent2
.cbData
)
4010 halflen
= decodedKey
->exponent2
.cbData
;
4011 if (halflen
< decodedKey
->coefficient
.cbData
)
4012 halflen
= decodedKey
->coefficient
.cbData
;
4013 if (halflen
* 2 < decodedKey
->modulus
.cbData
)
4014 halflen
= decodedKey
->modulus
.cbData
/ 2 + decodedKey
->modulus
.cbData
% 2;
4015 if (halflen
* 2 < decodedKey
->privexp
.cbData
)
4016 halflen
= decodedKey
->privexp
.cbData
/ 2 + decodedKey
->privexp
.cbData
% 2;
4020 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
4025 *pcbStructInfo
= bytesNeeded
;
4028 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4029 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4032 RSAPUBKEY
*rsaPubKey
;
4035 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4036 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4039 hdr
->bType
= PRIVATEKEYBLOB
;
4040 hdr
->bVersion
= CUR_BLOB_VERSION
;
4042 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
4044 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
4045 sizeof(BLOBHEADER
));
4046 rsaPubKey
->magic
= RSA2_MAGIC
;
4047 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
4048 rsaPubKey
->bitlen
= halflen
* 16;
4050 vardata
= (BYTE
*)(rsaPubKey
+ 1);
4051 memset(vardata
, 0, halflen
* 9);
4053 decodedKey
->modulus
.pbData
, decodedKey
->modulus
.cbData
);
4054 memcpy(vardata
+ halflen
* 2,
4055 decodedKey
->prime1
.pbData
, decodedKey
->prime1
.cbData
);
4056 memcpy(vardata
+ halflen
* 3,
4057 decodedKey
->prime2
.pbData
, decodedKey
->prime2
.cbData
);
4058 memcpy(vardata
+ halflen
* 4,
4059 decodedKey
->exponent1
.pbData
, decodedKey
->exponent1
.cbData
);
4060 memcpy(vardata
+ halflen
* 5,
4061 decodedKey
->exponent2
.pbData
, decodedKey
->exponent2
.cbData
);
4062 memcpy(vardata
+ halflen
* 6,
4063 decodedKey
->coefficient
.pbData
, decodedKey
->coefficient
.cbData
);
4064 memcpy(vardata
+ halflen
* 7,
4065 decodedKey
->privexp
.pbData
, decodedKey
->privexp
.cbData
);
4069 LocalFree(decodedKey
);
4074 SetLastError(STATUS_ACCESS_VIOLATION
);
4081 static BOOL
CRYPT_AsnDecodeOctets(const BYTE
*pbEncoded
,
4082 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4086 DWORD bytesNeeded
, dataLen
;
4088 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4089 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4091 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4093 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4095 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4096 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
4098 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
4100 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4102 *pcbStructInfo
= bytesNeeded
;
4103 else if (*pcbStructInfo
< bytesNeeded
)
4105 SetLastError(ERROR_MORE_DATA
);
4106 *pcbStructInfo
= bytesNeeded
;
4111 CRYPT_DATA_BLOB
*blob
;
4113 *pcbStructInfo
= bytesNeeded
;
4114 blob
= pvStructInfo
;
4115 blob
->cbData
= dataLen
;
4116 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4117 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
4120 assert(blob
->pbData
);
4122 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
4130 static BOOL
CRYPT_AsnDecodeOctetStringInternal(const BYTE
*encoded
, DWORD encoded_size
,
4131 DWORD flags
, void *buf
, DWORD
*buf_size
, DWORD
*ret_decoded
)
4133 DWORD decoded
= 0, indefinite_len_depth
= 0, len_size
, len
, bytes_needed
;
4134 CRYPT_DATA_BLOB
*blob
;
4137 while (encoded
[0] == (ASN_CONSTRUCTOR
| ASN_OCTETSTRING
))
4139 if (!CRYPT_GetLengthIndefinite(encoded
, encoded_size
, &len
))
4142 len_size
= GET_LEN_BYTES(encoded
[1]);
4143 encoded
+= 1 + len_size
;
4144 encoded_size
-= 1 + len_size
;
4145 decoded
+= 1 + len_size
;
4147 if (len
== CMSG_INDEFINITE_LENGTH
)
4149 indefinite_len_depth
++;
4150 if (encoded_size
< 2)
4152 SetLastError(CRYPT_E_ASN1_EOD
);
4160 if (encoded
[0] != ASN_OCTETSTRING
)
4162 WARN("Unexpected tag %02x\n", encoded
[0]);
4163 SetLastError(CRYPT_E_ASN1_BADTAG
);
4167 if (!CRYPT_GetLen(encoded
, encoded_size
, &len
))
4169 len_size
= GET_LEN_BYTES(encoded
[1]);
4170 decoded
+= 1 + len_size
+ len
;
4171 encoded_size
-= 1 + len_size
;
4173 if (len
> encoded_size
)
4175 SetLastError(CRYPT_E_ASN1_EOD
);
4179 *ret_decoded
= decoded
;
4181 encoded
+= 1 + len_size
;
4185 while (indefinite_len_depth
--)
4187 if (encoded
[0] || encoded
[1])
4189 TRACE("expected 0 TLV, got %02x %02x\n", encoded
[0], encoded
[1]);
4190 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4195 bytes_needed
= sizeof(*blob
);
4196 if (!(flags
& CRYPT_DECODE_NOCOPY_FLAG
)) bytes_needed
+= len
;
4199 *buf_size
= bytes_needed
;
4202 if (*buf_size
< bytes_needed
)
4204 SetLastError(ERROR_MORE_DATA
);
4205 *buf_size
= bytes_needed
;
4209 *buf_size
= bytes_needed
;
4212 if (flags
& CRYPT_DECODE_NOCOPY_FLAG
)
4213 blob
->pbData
= (BYTE
*)string
;
4214 else if (blob
->cbData
)
4215 memcpy(blob
->pbData
, string
, blob
->cbData
);
4218 *ret_decoded
= decoded
;
4222 static BOOL WINAPI
CRYPT_AsnDecodeOctetString(DWORD dwCertEncodingType
,
4223 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4224 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4228 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4229 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4233 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4239 DWORD bytesNeeded
= 0;
4241 if ((ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4242 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4245 *pcbStructInfo
= bytesNeeded
;
4246 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4247 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4249 CRYPT_DATA_BLOB
*blob
;
4251 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4252 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4253 blob
= pvStructInfo
;
4254 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4255 ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4256 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4257 &bytesNeeded
, NULL
);
4258 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4259 CRYPT_FreeSpace(pDecodePara
, blob
);
4265 SetLastError(STATUS_ACCESS_VIOLATION
);
4272 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4273 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4276 DWORD bytesNeeded
, dataLen
;
4277 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4279 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4280 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4282 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4284 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4285 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4287 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4289 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4291 *pcbStructInfo
= bytesNeeded
;
4292 else if (*pcbStructInfo
< bytesNeeded
)
4294 *pcbStructInfo
= bytesNeeded
;
4295 SetLastError(ERROR_MORE_DATA
);
4300 CRYPT_BIT_BLOB
*blob
;
4302 *pcbStructInfo
= bytesNeeded
;
4303 blob
= pvStructInfo
;
4304 blob
->cbData
= dataLen
- 1;
4305 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4306 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4308 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4312 assert(blob
->pbData
);
4315 BYTE mask
= 0xff << blob
->cUnusedBits
;
4317 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4319 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4327 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4328 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4329 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4333 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4334 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4338 DWORD bytesNeeded
= 0;
4342 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4345 else if (pbEncoded
[0] != ASN_BITSTRING
)
4347 SetLastError(CRYPT_E_ASN1_BADTAG
);
4350 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4351 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4354 *pcbStructInfo
= bytesNeeded
;
4355 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4356 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4358 CRYPT_BIT_BLOB
*blob
;
4360 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4361 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4362 blob
= pvStructInfo
;
4363 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4364 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4365 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4366 &bytesNeeded
, NULL
);
4367 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4368 CRYPT_FreeSpace(pDecodePara
, blob
);
4374 SetLastError(STATUS_ACCESS_VIOLATION
);
4378 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4382 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4383 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4384 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4389 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4391 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4394 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4395 if (dataLen
> sizeof(int))
4397 SetLastError(CRYPT_E_ASN1_LARGE
);
4400 else if (!pvStructInfo
)
4401 *pcbStructInfo
= sizeof(int);
4402 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4406 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4408 /* initialize to a negative value to sign-extend */
4413 for (i
= 0; i
< dataLen
; i
++)
4416 val
|= pbEncoded
[1 + lenBytes
+ i
];
4418 memcpy(pvStructInfo
, &val
, sizeof(int));
4424 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4425 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4426 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4432 DWORD bytesNeeded
= 0;
4436 SetLastError(CRYPT_E_ASN1_EOD
);
4439 else if (pbEncoded
[0] != ASN_INTEGER
)
4441 SetLastError(CRYPT_E_ASN1_BADTAG
);
4445 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4446 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4450 *pcbStructInfo
= bytesNeeded
;
4451 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4452 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4454 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4455 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4456 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4457 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4458 &bytesNeeded
, NULL
);
4459 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4460 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4466 SetLastError(STATUS_ACCESS_VIOLATION
);
4473 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4474 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4478 DWORD bytesNeeded
, dataLen
;
4480 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4482 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4484 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4486 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4488 *pcbStructInfo
= bytesNeeded
;
4489 else if (*pcbStructInfo
< bytesNeeded
)
4491 *pcbStructInfo
= bytesNeeded
;
4492 SetLastError(ERROR_MORE_DATA
);
4497 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4499 *pcbStructInfo
= bytesNeeded
;
4500 blob
->cbData
= dataLen
;
4501 assert(blob
->pbData
);
4506 for (i
= 0; i
< blob
->cbData
; i
++)
4508 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4517 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4518 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4519 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4525 DWORD bytesNeeded
= 0;
4527 if (pbEncoded
[0] != ASN_INTEGER
)
4529 SetLastError(CRYPT_E_ASN1_BADTAG
);
4533 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4534 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4538 *pcbStructInfo
= bytesNeeded
;
4539 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4540 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4542 CRYPT_INTEGER_BLOB
*blob
;
4544 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4545 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4546 blob
= pvStructInfo
;
4547 blob
->pbData
= (BYTE
*)pvStructInfo
+
4548 sizeof(CRYPT_INTEGER_BLOB
);
4549 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4550 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4551 &bytesNeeded
, NULL
);
4552 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4553 CRYPT_FreeSpace(pDecodePara
, blob
);
4559 SetLastError(STATUS_ACCESS_VIOLATION
);
4566 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4567 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4572 if (pbEncoded
[0] == ASN_INTEGER
)
4574 DWORD bytesNeeded
, dataLen
;
4576 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4578 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4581 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4582 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4584 *pcbStructInfo
= bytesNeeded
;
4585 else if (*pcbStructInfo
< bytesNeeded
)
4587 *pcbStructInfo
= bytesNeeded
;
4588 SetLastError(ERROR_MORE_DATA
);
4593 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4595 *pcbStructInfo
= bytesNeeded
;
4596 blob
->cbData
= dataLen
;
4597 assert(blob
->pbData
);
4598 /* remove leading zero byte if it exists */
4599 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4608 for (i
= 0; i
< blob
->cbData
; i
++)
4610 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4619 SetLastError(CRYPT_E_ASN1_BADTAG
);
4625 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4626 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4627 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4633 DWORD bytesNeeded
= 0;
4635 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4636 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4639 *pcbStructInfo
= bytesNeeded
;
4640 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4641 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4643 CRYPT_INTEGER_BLOB
*blob
;
4645 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4646 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4647 blob
= pvStructInfo
;
4648 blob
->pbData
= (BYTE
*)pvStructInfo
+
4649 sizeof(CRYPT_INTEGER_BLOB
);
4650 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4651 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4652 &bytesNeeded
, NULL
);
4653 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4654 CRYPT_FreeSpace(pDecodePara
, blob
);
4660 SetLastError(STATUS_ACCESS_VIOLATION
);
4667 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4668 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4669 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4675 *pcbStructInfo
= sizeof(int);
4680 if (pbEncoded
[0] == ASN_ENUMERATED
)
4682 unsigned int val
= 0, i
;
4686 SetLastError(CRYPT_E_ASN1_EOD
);
4689 else if (pbEncoded
[1] == 0)
4691 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4696 /* A little strange looking, but we have to accept a sign byte:
4697 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4698 * assuming a small length is okay here, it has to be in short
4701 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4703 SetLastError(CRYPT_E_ASN1_LARGE
);
4706 for (i
= 0; i
< pbEncoded
[1]; i
++)
4709 val
|= pbEncoded
[2 + i
];
4711 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4712 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4714 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4715 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4716 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4722 SetLastError(CRYPT_E_ASN1_BADTAG
);
4728 SetLastError(STATUS_ACCESS_VIOLATION
);
4735 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4738 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4743 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4745 if (!isdigit(*(pbEncoded))) \
4747 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4753 (word) += *(pbEncoded)++ - '0'; \
4758 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4759 SYSTEMTIME
*sysTime
)
4763 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4765 WORD hours
, minutes
= 0;
4766 BYTE sign
= *pbEncoded
++;
4769 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4770 if (ret
&& hours
>= 24)
4772 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4777 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4778 if (ret
&& minutes
>= 60)
4780 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4788 sysTime
->wHour
+= hours
;
4789 sysTime
->wMinute
+= minutes
;
4793 if (hours
> sysTime
->wHour
)
4796 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4799 sysTime
->wHour
-= hours
;
4800 if (minutes
> sysTime
->wMinute
)
4803 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4806 sysTime
->wMinute
-= minutes
;
4813 #define MIN_ENCODED_TIME_LENGTH 10
4815 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4816 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4821 if (pbEncoded
[0] == ASN_UTCTIME
)
4824 SetLastError(CRYPT_E_ASN1_EOD
);
4825 else if (pbEncoded
[1] > 0x7f)
4827 /* long-form date strings really can't be valid */
4828 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4832 SYSTEMTIME sysTime
= { 0 };
4833 BYTE len
= pbEncoded
[1];
4835 if (len
< MIN_ENCODED_TIME_LENGTH
)
4836 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4841 *pcbDecoded
= 2 + len
;
4843 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4844 if (sysTime
.wYear
>= 50)
4845 sysTime
.wYear
+= 1900;
4847 sysTime
.wYear
+= 2000;
4848 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4849 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4850 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4851 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4854 if (len
>= 2 && isdigit(*pbEncoded
) &&
4855 isdigit(*(pbEncoded
+ 1)))
4856 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4858 else if (isdigit(*pbEncoded
))
4859 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4862 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4868 *pcbStructInfo
= sizeof(FILETIME
);
4869 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4871 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4877 SetLastError(CRYPT_E_ASN1_BADTAG
);
4881 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4882 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4883 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4889 DWORD bytesNeeded
= 0;
4891 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4892 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4896 *pcbStructInfo
= bytesNeeded
;
4897 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4898 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4900 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4901 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4902 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4903 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4904 &bytesNeeded
, NULL
);
4905 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4906 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4912 SetLastError(STATUS_ACCESS_VIOLATION
);
4918 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4919 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4924 if (pbEncoded
[0] == ASN_GENERALTIME
)
4927 SetLastError(CRYPT_E_ASN1_EOD
);
4928 else if (pbEncoded
[1] > 0x7f)
4930 /* long-form date strings really can't be valid */
4931 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4935 BYTE len
= pbEncoded
[1];
4937 if (len
< MIN_ENCODED_TIME_LENGTH
)
4938 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4941 SYSTEMTIME sysTime
= { 0 };
4945 *pcbDecoded
= 2 + len
;
4947 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
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
);
4953 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4956 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4958 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4965 /* workaround macro weirdness */
4966 digits
= min(len
, 3);
4967 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4968 sysTime
.wMilliseconds
);
4971 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4977 *pcbStructInfo
= sizeof(FILETIME
);
4978 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4980 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4986 SetLastError(CRYPT_E_ASN1_BADTAG
);
4990 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4991 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4995 InternalDecodeFunc decode
= NULL
;
4997 if (pbEncoded
[0] == ASN_UTCTIME
)
4998 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4999 else if (pbEncoded
[0] == ASN_GENERALTIME
)
5000 decode
= CRYPT_AsnDecodeGeneralizedTime
;
5002 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
5003 pcbStructInfo
, pcbDecoded
);
5006 SetLastError(CRYPT_E_ASN1_BADTAG
);
5012 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
5013 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5014 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5020 DWORD bytesNeeded
= 0;
5022 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5023 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
5027 *pcbStructInfo
= bytesNeeded
;
5028 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5029 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5031 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5032 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5033 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5034 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5035 &bytesNeeded
, NULL
);
5036 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5037 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
5043 SetLastError(STATUS_ACCESS_VIOLATION
);
5050 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
5051 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5052 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5058 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
5060 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
5062 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5067 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5068 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
5070 ptr
= pbEncoded
+ 1 + lenBytes
;
5071 remainingLen
= dataLen
;
5072 while (ret
&& remainingLen
)
5076 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5079 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5081 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5082 ptr
+= 1 + nextLenBytes
+ nextLen
;
5083 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
5084 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
5085 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
5091 CRYPT_SEQUENCE_OF_ANY
*seq
;
5096 *pcbStructInfo
= bytesNeeded
;
5097 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5098 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5100 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5101 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5103 seq
->cValue
= cValue
;
5104 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
5106 nextPtr
= (BYTE
*)seq
->rgValue
+
5107 cValue
* sizeof(CRYPT_DER_BLOB
);
5108 ptr
= pbEncoded
+ 1 + lenBytes
;
5109 remainingLen
= dataLen
;
5111 while (ret
&& remainingLen
)
5115 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5118 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5120 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
5122 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
5123 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
5126 seq
->rgValue
[i
].pbData
= nextPtr
;
5127 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
5129 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
5131 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5132 ptr
+= 1 + nextLenBytes
+ nextLen
;
5136 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5137 CRYPT_FreeSpace(pDecodePara
, seq
);
5144 SetLastError(CRYPT_E_ASN1_BADTAG
);
5150 SetLastError(STATUS_ACCESS_VIOLATION
);
5157 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
5158 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5163 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
5165 DWORD bytesNeeded
= 0, dataLen
;
5167 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5169 struct AsnArrayDescriptor arrayDesc
= {
5170 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5171 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
5172 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
5173 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
5174 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
5175 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
5176 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5181 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5182 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5183 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
5184 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
5185 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
5188 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
5190 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
5192 *pcbStructInfo
= bytesNeeded
;
5193 else if (*pcbStructInfo
< bytesNeeded
)
5195 *pcbStructInfo
= bytesNeeded
;
5196 SetLastError(ERROR_MORE_DATA
);
5201 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
5203 *pcbStructInfo
= bytesNeeded
;
5206 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
5207 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5208 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5209 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
5213 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
5219 SetLastError(CRYPT_E_ASN1_BADTAG
);
5225 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5226 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5228 struct AsnDecodeSequenceItem items
[] = {
5229 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
5230 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5231 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
5232 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5233 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
5234 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
5235 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
5236 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
5237 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
5238 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
5240 CRL_DIST_POINT
*point
= pvStructInfo
;
5243 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5244 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5245 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5249 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5250 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5251 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5255 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5256 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5260 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5261 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
5262 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
5263 sizeof(CRL_DIST_POINTS_INFO
),
5264 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5265 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5266 CRL_DIST_POINTS_INFO
*info
= pvStructInfo
;
5268 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5269 info
->rgDistPoint
= (CRL_DIST_POINT
*)(info
+ 1);
5270 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5271 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5275 SetLastError(STATUS_ACCESS_VIOLATION
);
5282 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5283 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5284 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5288 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5289 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5293 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5294 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5295 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5296 sizeof(CERT_ENHKEY_USAGE
),
5297 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5298 CERT_ENHKEY_USAGE
*usage
= pvStructInfo
;
5300 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5301 usage
->rgpszUsageIdentifier
= (LPSTR
*)(usage
+ 1);
5302 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5303 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5307 SetLastError(STATUS_ACCESS_VIOLATION
);
5314 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5315 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5316 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5320 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5321 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5325 struct AsnDecodeSequenceItem items
[] = {
5326 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5327 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5328 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5329 offsetof(CRL_ISSUING_DIST_POINT
,
5330 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5331 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5332 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5334 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5335 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5337 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5338 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5339 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5340 OnlySomeReasonFlags
.pbData
), 0 },
5341 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5342 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5345 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5346 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5347 pcbStructInfo
, NULL
, NULL
);
5351 SetLastError(STATUS_ACCESS_VIOLATION
);
5358 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5359 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5363 DWORD max
, size
= sizeof(max
);
5365 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5366 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5370 SetLastError(CRYPT_E_ASN1_EOD
);
5373 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5375 SetLastError(CRYPT_E_ASN1_BADTAG
);
5378 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5379 &max
, &size
, pcbDecoded
)))
5381 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5384 *pcbStructInfo
= bytesNeeded
;
5385 else if (*pcbStructInfo
< bytesNeeded
)
5387 *pcbStructInfo
= bytesNeeded
;
5388 SetLastError(ERROR_MORE_DATA
);
5393 CERT_GENERAL_SUBTREE
*subtree
= CONTAINING_RECORD(pvStructInfo
,
5394 CERT_GENERAL_SUBTREE
, fMaximum
);
5396 *pcbStructInfo
= bytesNeeded
;
5397 /* The BOOL is implicit: if the integer is present, then it's
5400 subtree
->fMaximum
= TRUE
;
5401 subtree
->dwMaximum
= max
;
5404 TRACE("returning %d\n", ret
);
5408 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5409 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5413 struct AsnDecodeSequenceItem items
[] = {
5414 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5415 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5416 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5417 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5418 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5419 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5420 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5421 TRUE
, FALSE
, 0, 0 },
5423 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5425 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5426 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5428 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5429 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5430 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5433 TRACE("%d\n", *pcbDecoded
);
5434 if (*pcbDecoded
< cbEncoded
)
5435 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5436 *(pbEncoded
+ *pcbDecoded
+ 1));
5438 TRACE("returning %d\n", ret
);
5442 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5443 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5447 struct AsnArrayDescriptor arrayDesc
= { 0,
5448 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5449 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5450 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5452 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5453 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5455 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5456 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5458 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5459 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5463 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5464 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5468 struct AsnArrayDescriptor arrayDesc
= { 0,
5469 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5470 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5471 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5472 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5473 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5475 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5476 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5478 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5479 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5483 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5484 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5485 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5489 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5490 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5494 struct AsnDecodeSequenceItem items
[] = {
5495 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5496 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5497 CRYPT_AsnDecodePermittedSubtree
,
5498 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5499 cExcludedSubtree
), TRUE
, TRUE
,
5500 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5501 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5502 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5503 CRYPT_AsnDecodeExcludedSubtree
,
5504 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5506 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5509 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5510 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5511 pcbStructInfo
, NULL
, NULL
);
5515 SetLastError(STATUS_ACCESS_VIOLATION
);
5521 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5522 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5526 struct AsnDecodeSequenceItem items
[] = {
5527 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5528 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5530 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5531 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5532 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5534 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5536 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5537 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5539 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5540 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5541 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5542 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5544 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5547 TRACE("returning %d\n", ret
);
5551 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5552 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5555 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5556 struct AsnDecodeSequenceItem items
[] = {
5557 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5558 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5559 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5560 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5561 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5562 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5563 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5564 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5565 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5566 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5567 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5568 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5569 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5570 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5571 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5572 HashEncryptionAlgorithm
.pszObjId
), 0 },
5573 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5574 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5575 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5576 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5577 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5578 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5579 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5583 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5584 pvStructInfo
, *pcbStructInfo
);
5586 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5587 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5588 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5592 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5593 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5594 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5598 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5599 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5603 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5604 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5605 if (ret
&& pvStructInfo
)
5607 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5608 pcbStructInfo
, *pcbStructInfo
);
5611 CMSG_SIGNER_INFO
*info
;
5613 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5614 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5615 info
= pvStructInfo
;
5616 info
->Issuer
.pbData
= ((BYTE
*)info
+
5617 sizeof(CMSG_SIGNER_INFO
));
5618 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5619 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5620 pcbStructInfo
, NULL
);
5621 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5622 CRYPT_FreeSpace(pDecodePara
, info
);
5628 SetLastError(STATUS_ACCESS_VIOLATION
);
5631 TRACE("returning %d\n", ret
);
5635 static BOOL
verify_and_copy_certificate(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5636 void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5638 PCCERT_CONTEXT cert
;
5640 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, pbEncoded
, cbEncoded
);
5643 WARN("CertCreateCertificateContext error %#x\n", GetLastError());
5649 CertFreeCertificateContext(cert
);
5651 return CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5654 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5655 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5659 struct AsnArrayDescriptor arrayDesc
= { 0,
5660 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5661 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5662 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5663 verify_and_copy_certificate
,
5664 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5666 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5667 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5669 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5670 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5674 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5675 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5679 struct AsnArrayDescriptor arrayDesc
= { 0,
5680 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5681 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5682 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5683 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5684 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5686 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5687 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5689 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5690 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5694 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5695 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5698 CERT_ID
*id
= pvStructInfo
;
5701 if (*pbEncoded
== ASN_SEQUENCEOF
)
5703 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5704 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5708 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5709 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5710 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5711 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5713 *pcbStructInfo
= sizeof(CERT_ID
);
5716 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5718 ret
= CRYPT_AsnDecodeOctets(pbEncoded
, cbEncoded
, dwFlags
,
5719 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5723 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5724 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5725 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5726 sizeof(CRYPT_DATA_BLOB
);
5728 *pcbStructInfo
= sizeof(CERT_ID
);
5732 SetLastError(CRYPT_E_ASN1_BADTAG
);
5736 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5737 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5740 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5741 struct AsnDecodeSequenceItem items
[] = {
5742 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5743 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5744 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5745 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5746 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5747 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5748 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5749 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5750 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5751 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5752 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5753 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5754 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5755 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5756 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5757 HashEncryptionAlgorithm
.pszObjId
), 0 },
5758 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5759 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5760 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5761 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5762 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5763 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5764 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5768 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5769 pvStructInfo
, *pcbStructInfo
);
5771 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5772 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5773 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5777 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5778 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5779 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5783 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5784 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5788 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5789 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5790 if (ret
&& pvStructInfo
)
5792 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5793 pcbStructInfo
, *pcbStructInfo
);
5796 CMSG_CMS_SIGNER_INFO
*info
;
5798 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5799 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5800 info
= pvStructInfo
;
5801 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5802 sizeof(CMSG_CMS_SIGNER_INFO
));
5803 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5804 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5805 pcbStructInfo
, NULL
);
5806 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5807 CRYPT_FreeSpace(pDecodePara
, info
);
5813 SetLastError(STATUS_ACCESS_VIOLATION
);
5816 TRACE("returning %d\n", ret
);
5820 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5821 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5824 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5825 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5826 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5827 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5828 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5829 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5831 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5832 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5834 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5835 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5839 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5840 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5841 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5844 struct AsnDecodeSequenceItem items
[] = {
5845 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5846 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5847 /* Placeholder for the hash algorithms - redundant with those in the
5848 * signers, so just ignore them.
5850 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5851 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5852 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5853 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5854 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5855 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5856 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5857 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5858 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5859 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5860 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5861 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5862 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5863 CRYPT_DecodeSignerArray
,
5864 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5865 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5868 TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5869 pDecodePara
, signedInfo
, pcbSignedInfo
);
5871 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5872 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5874 TRACE("returning %d\n", ret
);
5878 static BOOL
CRYPT_AsnDecodeRecipientInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5879 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5882 CMSG_KEY_TRANS_RECIPIENT_INFO
*info
= pvStructInfo
;
5883 struct AsnDecodeSequenceItem items
[] = {
5884 { ASN_INTEGER
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, dwVersion
),
5885 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5886 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5887 RecipientId
.u
.IssuerSerialNumber
), CRYPT_AsnDecodeIssuerSerialNumber
,
5888 sizeof(CERT_ISSUER_SERIAL_NUMBER
), FALSE
, TRUE
,
5889 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5890 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
), 0 },
5891 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5892 KeyEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5893 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5894 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5895 KeyEncryptionAlgorithm
.pszObjId
), 0 },
5896 { ASN_OCTETSTRING
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
),
5897 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
5898 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
.pbData
), 0 },
5901 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5902 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5904 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5905 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5906 pcbDecoded
, info
? info
->RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
:
5909 info
->RecipientId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5910 TRACE("returning %d\n", ret
);
5914 static BOOL
CRYPT_DecodeRecipientInfoArray(const BYTE
*pbEncoded
,
5915 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5919 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5920 offsetof(CRYPT_ENVELOPED_DATA
, cRecipientInfo
),
5921 offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
),
5922 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5923 CRYPT_AsnDecodeRecipientInfo
, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO
), TRUE
,
5924 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5925 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
) };
5927 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5928 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5930 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5931 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5932 TRACE("returning %d\n", ret
);
5936 static BOOL
CRYPT_AsnDecodeEncryptedContentInfo(const BYTE
*pbEncoded
,
5937 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5941 CRYPT_ENCRYPTED_CONTENT_INFO
*info
= pvStructInfo
;
5942 struct AsnDecodeSequenceItem items
[] = {
5943 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5944 contentType
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
5945 FALSE
, TRUE
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5947 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5948 contentEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5949 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5950 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5951 contentEncryptionAlgorithm
.pszObjId
), 0 },
5952 { ASN_CONTEXT
| 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5953 encryptedContent
), CRYPT_AsnDecodeOctets
,
5954 sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
5955 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
, encryptedContent
.pbData
) },
5958 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5959 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5961 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5962 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5963 pcbDecoded
, info
? info
->contentType
: NULL
);
5964 TRACE("returning %d\n", ret
);
5968 BOOL
CRYPT_AsnDecodePKCSEnvelopedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5969 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5970 CRYPT_ENVELOPED_DATA
*envelopedData
, DWORD
*pcbEnvelopedData
)
5973 struct AsnDecodeSequenceItem items
[] = {
5974 { ASN_INTEGER
, offsetof(CRYPT_ENVELOPED_DATA
, version
),
5975 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5976 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ENVELOPED_DATA
,
5977 cRecipientInfo
), CRYPT_DecodeRecipientInfoArray
,
5978 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5979 FALSE
, TRUE
, offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
), 0 },
5980 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
),
5981 CRYPT_AsnDecodeEncryptedContentInfo
,
5982 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO
), FALSE
, TRUE
,
5983 offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
.contentType
), 0 },
5986 TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5987 pDecodePara
, envelopedData
, pcbEnvelopedData
);
5989 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5990 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, envelopedData
,
5991 pcbEnvelopedData
, NULL
, NULL
);
5992 TRACE("returning %d\n", ret
);
5996 static BOOL WINAPI
CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType
,
5997 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5998 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6000 DWORD bytesNeeded
= 0;
6005 ret
= CRYPT_AsnDecodeOidInternal(pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
6006 NULL
, &bytesNeeded
, NULL
);
6010 *pcbStructInfo
= bytesNeeded
;
6011 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
6015 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6016 pvStructInfo
= *(BYTE
**)pvStructInfo
;
6018 info
= pvStructInfo
;
6019 *info
= (void *)((BYTE
*)info
+ sizeof(*info
));
6020 ret
= CRYPT_AsnDecodeOidInternal(pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
6021 pvStructInfo
, &bytesNeeded
, NULL
);
6022 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
6023 CRYPT_FreeSpace(pDecodePara
, info
);
6029 SetLastError(STATUS_ACCESS_VIOLATION
);
6036 static BOOL WINAPI
CRYPT_AsnDecodeEccSignature(DWORD dwCertEncodingType
,
6037 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6038 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6041 struct AsnDecodeSequenceItem items
[] = {
6042 { ASN_INTEGER
, offsetof(CERT_ECC_SIGNATURE
, r
),
6043 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_UINT_BLOB
), FALSE
,
6044 TRUE
, offsetof(CERT_ECC_SIGNATURE
, r
.pbData
), 0 },
6045 { ASN_INTEGER
, offsetof(CERT_ECC_SIGNATURE
, s
),
6046 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_UINT_BLOB
), FALSE
,
6047 TRUE
, offsetof(CERT_ECC_SIGNATURE
, s
.pbData
), 0 },
6052 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6053 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
6054 pcbStructInfo
, NULL
, NULL
);
6058 SetLastError(STATUS_ACCESS_VIOLATION
);
6065 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
6066 LPCSTR lpszStructType
)
6068 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6070 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
6071 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
6073 SetLastError(ERROR_FILE_NOT_FOUND
);
6076 if (IS_INTOID(lpszStructType
))
6078 switch (LOWORD(lpszStructType
))
6080 case LOWORD(X509_CERT
):
6081 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
6083 case LOWORD(X509_CERT_TO_BE_SIGNED
):
6084 decodeFunc
= CRYPT_AsnDecodeCert
;
6086 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
6087 decodeFunc
= CRYPT_AsnDecodeCRL
;
6089 case LOWORD(X509_EXTENSIONS
):
6090 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6092 case LOWORD(X509_NAME_VALUE
):
6093 decodeFunc
= CRYPT_AsnDecodeNameValue
;
6095 case LOWORD(X509_NAME
):
6096 decodeFunc
= CRYPT_AsnDecodeName
;
6098 case LOWORD(X509_PUBLIC_KEY_INFO
):
6099 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
6101 case LOWORD(X509_AUTHORITY_KEY_ID
):
6102 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6104 case LOWORD(X509_ALTERNATE_NAME
):
6105 decodeFunc
= CRYPT_AsnDecodeAltName
;
6107 case LOWORD(X509_BASIC_CONSTRAINTS
):
6108 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6110 case LOWORD(X509_BASIC_CONSTRAINTS2
):
6111 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6113 case LOWORD(X509_CERT_POLICIES
):
6114 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6116 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
6117 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
6119 case LOWORD(PKCS_RSA_PRIVATE_KEY
):
6120 decodeFunc
= CRYPT_AsnDecodeRsaPrivKey
;
6122 case LOWORD(X509_UNICODE_NAME
):
6123 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
6125 case LOWORD(PKCS_ATTRIBUTE
):
6126 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
6128 case LOWORD(X509_UNICODE_NAME_VALUE
):
6129 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
6131 case LOWORD(X509_OCTET_STRING
):
6132 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6134 case LOWORD(X509_BITS
):
6135 case LOWORD(X509_KEY_USAGE
):
6136 decodeFunc
= CRYPT_AsnDecodeBits
;
6138 case LOWORD(X509_INTEGER
):
6139 decodeFunc
= CRYPT_AsnDecodeInt
;
6141 case LOWORD(X509_MULTI_BYTE_INTEGER
):
6142 decodeFunc
= CRYPT_AsnDecodeInteger
;
6144 case LOWORD(X509_MULTI_BYTE_UINT
):
6145 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
6147 case LOWORD(X509_ENUMERATED
):
6148 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6150 case LOWORD(X509_CHOICE_OF_TIME
):
6151 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
6153 case LOWORD(X509_AUTHORITY_KEY_ID2
):
6154 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6156 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
6157 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6159 case LOWORD(PKCS_CONTENT_INFO
):
6160 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
6162 case LOWORD(X509_SEQUENCE_OF_ANY
):
6163 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
6165 case LOWORD(PKCS_UTC_TIME
):
6166 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6168 case LOWORD(X509_CRL_DIST_POINTS
):
6169 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6171 case LOWORD(X509_ENHANCED_KEY_USAGE
):
6172 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6174 case LOWORD(PKCS_CTL
):
6175 decodeFunc
= CRYPT_AsnDecodeCTL
;
6177 case LOWORD(PKCS_SMIME_CAPABILITIES
):
6178 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6180 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
6181 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6183 case LOWORD(PKCS_ATTRIBUTES
):
6184 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
6186 case LOWORD(X509_ISSUING_DIST_POINT
):
6187 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6189 case LOWORD(X509_NAME_CONSTRAINTS
):
6190 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6192 case LOWORD(X509_POLICY_MAPPINGS
):
6193 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6195 case LOWORD(X509_POLICY_CONSTRAINTS
):
6196 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6198 case LOWORD(PKCS7_SIGNER_INFO
):
6199 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
6201 case LOWORD(CMS_SIGNER_INFO
):
6202 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
6204 case LOWORD(X509_OBJECT_IDENTIFIER
):
6205 decodeFunc
= CRYPT_AsnDecodeObjectIdentifier
;
6207 case LOWORD(X509_ECC_SIGNATURE
):
6208 decodeFunc
= CRYPT_AsnDecodeEccSignature
;
6212 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
6213 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6214 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
6215 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6216 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
6217 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6218 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
6219 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6220 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
6221 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6222 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
6223 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6224 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
6225 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6226 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
6227 decodeFunc
= CRYPT_AsnDecodeBits
;
6228 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
6229 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6230 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
6231 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6232 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
6233 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6234 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
6235 decodeFunc
= CRYPT_AsnDecodeAltName
;
6236 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
6237 decodeFunc
= CRYPT_AsnDecodeAltName
;
6238 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
6239 decodeFunc
= CRYPT_AsnDecodeAltName
;
6240 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
6241 decodeFunc
= CRYPT_AsnDecodeAltName
;
6242 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
6243 decodeFunc
= CRYPT_AsnDecodeAltName
;
6244 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
6245 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6246 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
6247 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6248 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
6249 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6250 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
6251 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6252 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
6253 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6254 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
6255 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6256 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
6257 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6258 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
6259 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6260 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
6261 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6262 else if (!strcmp(lpszStructType
, szOID_CTL
))
6263 decodeFunc
= CRYPT_AsnDecodeCTL
;
6264 else if (!strcmp(lpszStructType
, szOID_ECC_PUBLIC_KEY
))
6265 decodeFunc
= CRYPT_AsnDecodeObjectIdentifier
;
6269 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
6270 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6272 static HCRYPTOIDFUNCSET set
= NULL
;
6273 CryptDecodeObjectFunc decodeFunc
= NULL
;
6276 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
6277 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6278 (void **)&decodeFunc
, hFunc
);
6282 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
6283 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6285 static HCRYPTOIDFUNCSET set
= NULL
;
6286 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6289 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
6290 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6291 (void **)&decodeFunc
, hFunc
);
6295 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6296 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
6297 DWORD
*pcbStructInfo
)
6299 return CryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
6300 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
);
6303 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6304 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6305 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6308 CryptDecodeObjectExFunc decodeFunc
;
6309 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6311 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6312 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
6313 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6315 if (!pvStructInfo
&& !pcbStructInfo
)
6317 SetLastError(ERROR_INVALID_PARAMETER
);
6320 if (cbEncoded
> MAX_ENCODED_LEN
)
6322 SetLastError(CRYPT_E_ASN1_LARGE
);
6326 SetLastError(NOERROR
);
6327 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6331 SetLastError(ERROR_INVALID_PARAMETER
);
6334 *(BYTE
**)pvStructInfo
= NULL
;
6336 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
6339 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6340 debugstr_a(lpszStructType
));
6341 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
6345 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
6346 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6349 CryptDecodeObjectFunc pCryptDecodeObject
=
6350 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
6352 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6353 * directly, as that could cause an infinite loop.
6355 if (pCryptDecodeObject
)
6357 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6359 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6360 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
6361 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
6362 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
6364 ret
= pCryptDecodeObject(dwCertEncodingType
,
6365 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
6366 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
6368 CRYPT_FreeSpace(pDecodePara
, *(BYTE
**)pvStructInfo
);
6372 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6373 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6377 CryptFreeOIDFunctionAddress(hFunc
, 0);
6378 TRACE_(crypt
)("returning %d\n", ret
);
6382 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
6386 TRACE_(crypt
)("(%p)\n", pPFX
);
6388 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6389 * version integer of length 1 (3 encoded byes) and at least one other
6390 * datum (two encoded bytes), plus at least two bytes for the outer
6391 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6393 if (pPFX
->cbData
< 7)
6395 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
6399 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
6401 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
6403 /* Need at least three bytes for the integer version */
6404 if (pPFX
->cbData
< 1 + lenLen
+ 3)
6406 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
6407 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
6408 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */