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