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"
33 #include "crypt32_private.h"
35 /* This is a bit arbitrary, but to set some limit: */
36 #define MAX_ENCODED_LEN 0x02000000
38 #define ASN_FLAGS_MASK 0xe0
39 #define ASN_TYPE_MASK 0x1f
41 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
42 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
44 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
45 DWORD
, DWORD
, void *, DWORD
*);
46 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
47 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
49 /* Internal decoders don't do memory allocation or exception handling, and
50 * they report how many bytes they decoded.
52 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
53 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
55 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
56 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
58 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
59 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
61 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
63 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
64 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
65 /* Assumes algo->Parameters.pbData is set ahead of time. */
66 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
67 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
68 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
69 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
70 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
71 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
72 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
74 /* Doesn't check the tag, assumes the caller does so */
75 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
76 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
77 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
78 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
79 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
80 * member has been initialized, doesn't do exception handling, and doesn't do
81 * memory allocation. Also doesn't check tag, assumes the caller has checked
84 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
85 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
87 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
88 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
89 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
91 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
92 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
95 /* Gets the number of length bytes from the given (leading) length byte */
96 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
98 /* Helper function to get the encoded length of the data starting at pbEncoded,
99 * where pbEncoded[0] is the tag. If the data are too short to contain a
100 * length or if the length is too large for cbEncoded, sets an appropriate
101 * error code and returns FALSE. If the encoded length is unknown due to
102 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
104 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
111 SetLastError(CRYPT_E_ASN1_CORRUPT
);
114 else if (pbEncoded
[1] <= 0x7f)
116 if (pbEncoded
[1] + 1 > cbEncoded
)
118 SetLastError(CRYPT_E_ASN1_EOD
);
127 else if (pbEncoded
[1] == 0x80)
129 *len
= CMSG_INDEFINITE_LENGTH
;
134 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
136 if (lenLen
> sizeof(DWORD
) + 1)
138 SetLastError(CRYPT_E_ASN1_LARGE
);
141 else if (lenLen
+ 2 > cbEncoded
)
143 SetLastError(CRYPT_E_ASN1_CORRUPT
);
156 if (out
+ lenLen
+ 1 > cbEncoded
)
158 SetLastError(CRYPT_E_ASN1_EOD
);
171 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
172 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
176 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
177 *len
== CMSG_INDEFINITE_LENGTH
)
179 SetLastError(CRYPT_E_ASN1_CORRUPT
);
185 /* Helper function to check *pcbStructInfo, set it to the required size, and
186 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
187 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
188 * pointer to the newly allocated memory.
190 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
191 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
196 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
198 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
199 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
201 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
202 if (!*(BYTE
**)pvStructInfo
)
205 *pcbStructInfo
= bytesNeeded
;
207 else if (*pcbStructInfo
< bytesNeeded
)
209 *pcbStructInfo
= bytesNeeded
;
210 SetLastError(ERROR_MORE_DATA
);
214 *pcbStructInfo
= bytesNeeded
;
218 static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA
*pDecodePara
, LPVOID pv
)
220 if (pDecodePara
&& pDecodePara
->pfnFree
)
221 pDecodePara
->pfnFree(pv
);
226 /* Helper function to check *pcbStructInfo and set it to the required size.
227 * Assumes pvStructInfo is not NULL.
229 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
233 if (*pcbStructInfo
< bytesNeeded
)
235 *pcbStructInfo
= bytesNeeded
;
236 SetLastError(ERROR_MORE_DATA
);
241 *pcbStructInfo
= bytesNeeded
;
248 * The expected tag of the item. If tag is 0, decodeFunc is called
249 * regardless of the tag value seen.
251 * A sequence is decoded into a struct. The offset member is the
252 * offset of this item within that struct.
254 * The decoder function to use. If this is NULL, then the member isn't
255 * decoded, but minSize space is reserved for it.
257 * The minimum amount of space occupied after decoding. You must set this.
259 * If true, and the tag doesn't match the expected tag for this item,
260 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
261 * filled with 0 for this member.
262 * hasPointer, pointerOffset:
263 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
264 * the offset within the struct of the data pointer (or to the
265 * first data pointer, if more than one exist).
267 * Used by CRYPT_AsnDecodeSequence, not for your use.
269 struct AsnDecodeSequenceItem
273 InternalDecodeFunc decodeFunc
;
281 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
282 #define MEMBERSIZE(s, member, nextmember) \
283 (offsetof(s, nextmember) - offsetof(s, member))
285 /* Decodes the items in a sequence, where the items are described in items,
286 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
287 * pvStructInfo. nextData is a pointer to the memory location at which the
288 * first decoded item with a dynamic pointer should point.
289 * Upon decoding, *cbDecoded is the total number of bytes decoded.
290 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
292 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
293 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
294 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
297 DWORD i
, decoded
= 0;
298 const BYTE
*ptr
= pbEncoded
;
300 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
301 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
303 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
305 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
309 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
310 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
312 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
314 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
316 DWORD itemEncodedLen
;
318 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
319 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
321 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
322 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
324 TRACE("Setting next pointer to %p\n",
326 *(BYTE
**)((BYTE
*)pvStructInfo
+
327 items
[i
].pointerOffset
) = nextData
;
329 if (items
[i
].decodeFunc
)
334 TRACE("decoding item %d\n", i
);
336 TRACE("sizing item %d\n", i
);
337 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
338 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
339 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
340 : NULL
, &items
[i
].size
, &itemDecoded
);
343 if (items
[i
].size
< items
[i
].minSize
)
344 items
[i
].size
= items
[i
].minSize
;
345 else if (items
[i
].size
> items
[i
].minSize
)
347 /* Account for alignment padding */
348 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
350 TRACE("item %d size: %d\n", i
, items
[i
].size
);
351 if (nextData
&& items
[i
].hasPointer
&&
352 items
[i
].size
> items
[i
].minSize
)
353 nextData
+= items
[i
].size
- items
[i
].minSize
;
354 if (itemDecoded
> itemEncodedLen
)
356 WARN("decoded length %d exceeds encoded %d\n",
357 itemDecoded
, itemEncodedLen
);
358 SetLastError(CRYPT_E_ASN1_CORRUPT
);
364 decoded
+= itemDecoded
;
365 TRACE("item %d: decoded %d bytes\n", i
,
369 else if (items
[i
].optional
&&
370 GetLastError() == CRYPT_E_ASN1_BADTAG
)
372 TRACE("skipping optional item %d\n", i
);
373 items
[i
].size
= items
[i
].minSize
;
374 SetLastError(NOERROR
);
378 TRACE("item %d failed: %08x\n", i
,
381 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
383 ERR("can't use indefinite length encoding without a decoder\n");
384 SetLastError(CRYPT_E_ASN1_CORRUPT
);
389 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
390 ptr
+= itemEncodedLen
;
391 decoded
+= itemEncodedLen
;
392 items
[i
].size
= items
[i
].minSize
;
395 else if (items
[i
].optional
)
397 TRACE("skipping optional item %d\n", i
);
398 items
[i
].size
= items
[i
].minSize
;
402 TRACE("item %d: tag %02x doesn't match expected %02x\n",
403 i
, ptr
[0], items
[i
].tag
);
404 SetLastError(CRYPT_E_ASN1_BADTAG
);
409 else if (items
[i
].optional
)
411 TRACE("missing optional item %d, skipping\n", i
);
412 items
[i
].size
= items
[i
].minSize
;
416 TRACE("not enough bytes for item %d, failing\n", i
);
417 SetLastError(CRYPT_E_ASN1_CORRUPT
);
422 *cbDecoded
= decoded
;
423 TRACE("returning %d\n", ret
);
427 /* This decodes an arbitrary sequence into a contiguous block of memory
428 * (basically, a struct.) Each element being decoded is described by a struct
429 * AsnDecodeSequenceItem, see above.
430 * startingPointer is an optional pointer to the first place where dynamic
431 * data will be stored. If you know the starting offset, you may pass it
432 * here. Otherwise, pass NULL, and one will be inferred from the items.
434 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
435 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
436 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
437 DWORD
*pcbDecoded
, void *startingPointer
)
441 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
442 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
447 SetLastError(CRYPT_E_ASN1_EOD
);
450 if (pbEncoded
[0] == ASN_SEQUENCE
)
454 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
456 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
457 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
458 BOOL indefinite
= FALSE
;
460 cbEncoded
-= 1 + lenBytes
;
461 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
466 else if (cbEncoded
< dataLen
)
468 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
470 SetLastError(CRYPT_E_ASN1_CORRUPT
);
475 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
476 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
477 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
479 if (cbDecoded
> cbEncoded
- 2)
481 /* Not enough space for 0 TLV */
482 SetLastError(CRYPT_E_ASN1_CORRUPT
);
485 else if (*(ptr
+ cbDecoded
) != 0 ||
486 *(ptr
+ cbDecoded
+ 1) != 0)
488 TRACE("expected 0 TLV\n");
489 SetLastError(CRYPT_E_ASN1_CORRUPT
);
496 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
498 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
500 SetLastError(CRYPT_E_ASN1_CORRUPT
);
505 DWORD i
, bytesNeeded
= 0, structSize
= 0;
507 for (i
= 0; i
< cItem
; i
++)
509 if (items
[i
].size
> items
[i
].minSize
)
510 bytesNeeded
+= items
[i
].size
- items
[i
].minSize
;
511 structSize
= max( structSize
, items
[i
].offset
+ items
[i
].minSize
);
513 bytesNeeded
+= structSize
;
515 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
517 *pcbStructInfo
= bytesNeeded
;
518 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
519 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
523 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
524 pvStructInfo
= *(BYTE
**)pvStructInfo
;
526 nextData
= startingPointer
;
528 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
529 memset(pvStructInfo
, 0, structSize
);
530 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
531 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
533 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
534 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
541 SetLastError(CRYPT_E_ASN1_BADTAG
);
544 TRACE("returning %d (%08x)\n", ret
, GetLastError());
549 * The expected tag of the entire encoded array (usually a variant
550 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
551 * regardless of the tag seen.
553 * The offset within the outer structure at which the count exists.
554 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
555 * while CRYPT_ATTRIBUTE has countOffset ==
556 * offsetof(CRYPT_ATTRIBUTE, cValue).
558 * The offset within the outer structure at which the array pointer exists.
559 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
560 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
562 * The minimum size of the decoded array. On WIN32, this is always 8:
563 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
566 * used to decode each item in the array
568 * is the minimum size of each decoded item
570 * indicates whether each item has a dynamic pointer
572 * indicates the offset within itemSize at which the pointer exists
574 struct AsnArrayDescriptor
580 InternalDecodeFunc decodeFunc
;
586 struct AsnArrayItemSize
592 /* Decodes an array of like types into a structure described by a struct
593 * AsnArrayDescriptor.
595 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
596 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
597 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
602 TRACE("%p, %p, %d, %p, %d\n", arrayDesc
, pbEncoded
,
603 cbEncoded
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
607 SetLastError(CRYPT_E_ASN1_EOD
);
610 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
614 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
616 DWORD bytesNeeded
= arrayDesc
->minArraySize
, cItems
= 0, decoded
;
617 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
618 /* There can be arbitrarily many items, but there is often only one.
620 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
622 decoded
= 1 + lenBytes
;
626 BOOL doneDecoding
= FALSE
;
628 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
630 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
637 SetLastError(CRYPT_E_ASN1_CORRUPT
);
644 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
648 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
650 /* Each item decoded may not tolerate extraneous bytes,
651 * so get the length of the next element if known.
653 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
654 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
656 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
657 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
659 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
663 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
664 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
669 if (itemSizes
!= &itemSize
)
670 itemSizes
= CryptMemRealloc(itemSizes
,
671 cItems
* sizeof(struct AsnArrayItemSize
));
676 cItems
* sizeof(struct AsnArrayItemSize
));
678 *itemSizes
= itemSize
;
682 decoded
+= itemDecoded
;
683 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
684 itemSizes
[cItems
- 1].size
= size
;
697 *pcbDecoded
= decoded
;
699 *pcbStructInfo
= bytesNeeded
;
700 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
701 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
708 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
709 pvStructInfo
= *(void **)pvStructInfo
;
710 pcItems
= pvStructInfo
;
712 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
714 rgItems
= (BYTE
*)pvStructInfo
+
715 arrayDesc
->minArraySize
;
716 *(void **)((BYTE
*)pcItems
-
717 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
) =
721 rgItems
= *(void **)((BYTE
*)pcItems
-
722 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
);
723 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
724 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
725 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
730 if (arrayDesc
->hasPointer
)
731 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
732 + arrayDesc
->pointerOffset
) = nextData
;
733 ret
= arrayDesc
->decodeFunc(ptr
,
734 itemSizes
[i
].encodedLen
,
735 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
736 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
737 &itemSizes
[i
].size
, &itemDecoded
);
740 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
744 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
745 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
748 if (itemSizes
!= &itemSize
)
749 CryptMemFree(itemSizes
);
754 SetLastError(CRYPT_E_ASN1_BADTAG
);
760 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
761 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
762 * to CRYPT_E_ASN1_CORRUPT.
763 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
766 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
767 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
772 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
774 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
775 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
777 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
778 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
781 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
783 *pcbStructInfo
= bytesNeeded
;
784 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
786 CRYPT_DER_BLOB
*blob
;
788 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
789 pvStructInfo
= *(BYTE
**)pvStructInfo
;
791 blob
->cbData
= 1 + lenBytes
+ dataLen
;
794 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
795 blob
->pbData
= (BYTE
*)pbEncoded
;
798 assert(blob
->pbData
);
799 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
804 SetLastError(CRYPT_E_ASN1_CORRUPT
);
812 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
813 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
814 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
819 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
820 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
822 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
825 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
826 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
828 if (ret
&& pvStructInfo
)
830 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
837 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
839 temp
= blob
->pbData
[i
];
840 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
841 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
845 TRACE("returning %d (%08x)\n", ret
, GetLastError());
849 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
850 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
851 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
855 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
856 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
860 struct AsnDecodeSequenceItem items
[] = {
861 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
862 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
863 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
864 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
865 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
866 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
867 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
868 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
869 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
870 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
873 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
874 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
875 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
876 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
877 pcbStructInfo
, NULL
, NULL
);
881 SetLastError(STATUS_ACCESS_VIOLATION
);
886 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
890 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
891 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
896 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
898 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
900 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
901 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
903 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
908 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
909 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
913 struct AsnDecodeSequenceItem items
[] = {
914 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
915 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
916 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
917 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
920 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
921 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
926 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
927 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
931 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
932 offsetof(CERT_INFO
, cExtension
), offsetof(CERT_INFO
, rgExtension
),
933 FINALMEMBERSIZE(CERT_INFO
, cExtension
),
934 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
935 offsetof(CERT_EXTENSION
, pszObjId
) };
937 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
938 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
940 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
941 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
945 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
946 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
952 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
954 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
956 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
957 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
958 if (ret
&& pcbDecoded
)
959 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
964 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
965 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
966 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
969 struct AsnDecodeSequenceItem items
[] = {
970 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
971 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
972 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
973 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
974 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
975 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
976 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
977 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
978 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
979 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
981 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
982 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
984 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
985 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
987 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
988 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
989 FALSE
, TRUE
, offsetof(CERT_INFO
,
990 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
991 { ASN_CONTEXT
| 1, offsetof(CERT_INFO
, IssuerUniqueId
),
992 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
993 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
994 { ASN_CONTEXT
| 2, offsetof(CERT_INFO
, SubjectUniqueId
),
995 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
996 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
997 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
998 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
999 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1002 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1003 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1005 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1006 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1008 if (ret
&& pvStructInfo
)
1012 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1013 info
= *(CERT_INFO
**)pvStructInfo
;
1015 info
= pvStructInfo
;
1016 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1017 !info
->Subject
.cbData
)
1019 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1020 /* Don't need to deallocate, because it should have failed on the
1021 * first pass (and no memory was allocated.)
1027 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1031 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1032 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1033 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1037 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1038 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1044 /* Unless told not to, first try to decode it as a signed cert. */
1045 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1047 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1049 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1050 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1051 &signedCert
, &size
);
1055 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1056 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1057 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1058 pvStructInfo
, pcbStructInfo
);
1059 LocalFree(signedCert
);
1062 /* Failing that, try it as an unsigned cert */
1066 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1067 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1068 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1073 SetLastError(STATUS_ACCESS_VIOLATION
);
1077 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1081 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1082 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1086 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1087 offsetof(CRL_ENTRY
, cExtension
), offsetof(CRL_ENTRY
, rgExtension
),
1088 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
),
1089 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1090 offsetof(CERT_EXTENSION
, pszObjId
) };
1092 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1093 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1095 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1096 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1100 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1101 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1104 struct AsnDecodeSequenceItem items
[] = {
1105 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1106 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1107 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1108 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1109 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1110 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1111 CRYPT_AsnDecodeCRLEntryExtensions
,
1112 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1113 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1115 PCRL_ENTRY entry
= pvStructInfo
;
1117 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1120 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1121 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1122 entry
? entry
->SerialNumber
.pbData
: NULL
);
1123 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1125 WARN("empty CRL entry serial number\n");
1126 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1132 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1133 * whose rgCRLEntry member has been set prior to calling.
1135 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1136 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1139 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1140 offsetof(CRL_INFO
, cCRLEntry
), offsetof(CRL_INFO
, rgCRLEntry
),
1141 MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1142 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1143 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1145 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1146 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1148 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1149 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1150 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1154 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1155 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1159 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1160 offsetof(CRL_INFO
, cExtension
), offsetof(CRL_INFO
, rgExtension
),
1161 FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1162 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1163 offsetof(CERT_EXTENSION
, pszObjId
) };
1165 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1166 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1168 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1169 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1173 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1174 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1180 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1182 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1184 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1185 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1186 if (ret
&& pcbDecoded
)
1187 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1192 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1193 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1194 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1196 struct AsnDecodeSequenceItem items
[] = {
1197 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1198 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1199 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1200 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1201 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1202 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1203 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1205 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1206 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1207 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1208 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1209 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1210 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1211 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1212 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1213 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1214 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1218 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1219 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1221 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1222 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1225 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1229 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1230 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1231 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1235 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1236 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1242 /* Unless told not to, first try to decode it as a signed crl. */
1243 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1245 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1247 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1248 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1253 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1254 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1255 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1256 pvStructInfo
, pcbStructInfo
);
1257 LocalFree(signedCrl
);
1260 /* Failing that, try it as an unsigned crl */
1264 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1265 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1266 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1271 SetLastError(STATUS_ACCESS_VIOLATION
);
1275 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1279 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1280 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1285 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1286 pvStructInfo
, *pcbStructInfo
);
1288 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1290 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1291 DWORD bytesNeeded
= sizeof(LPSTR
);
1298 snprintf(str
, sizeof(str
), "%d.%d",
1299 pbEncoded
[1 + lenBytes
] / 40,
1300 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1302 bytesNeeded
+= strlen(str
) + 1;
1303 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1304 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1308 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1315 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1318 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1325 snprintf(str
, sizeof(str
), ".%d", val
);
1326 bytesNeeded
+= strlen(str
);
1331 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1333 *pcbStructInfo
= bytesNeeded
;
1334 else if (*pcbStructInfo
< bytesNeeded
)
1336 *pcbStructInfo
= bytesNeeded
;
1337 SetLastError(ERROR_MORE_DATA
);
1345 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1348 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1349 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1351 pszObjId
+= strlen(pszObjId
);
1352 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1353 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1357 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1366 sprintf(pszObjId
, ".%d", val
);
1367 pszObjId
+= strlen(pszObjId
);
1371 *(LPSTR
*)pvStructInfo
= NULL
;
1372 *pcbStructInfo
= bytesNeeded
;
1378 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1379 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1383 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1384 pvStructInfo
, *pcbStructInfo
);
1386 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1387 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1388 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1391 SetLastError(CRYPT_E_ASN1_BADTAG
);
1397 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1398 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1400 struct AsnDecodeSequenceItem items
[] = {
1401 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1402 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1403 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1404 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1405 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1406 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1407 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1408 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1411 PCERT_EXTENSION ext
= pvStructInfo
;
1413 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1417 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1418 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1419 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1420 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1422 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1423 debugstr_a(ext
->pszObjId
));
1424 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1428 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1429 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1430 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1434 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1435 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1439 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1440 offsetof(CERT_EXTENSIONS
, cExtension
),
1441 offsetof(CERT_EXTENSIONS
, rgExtension
),
1442 sizeof(CERT_EXTENSIONS
),
1443 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1444 offsetof(CERT_EXTENSION
, pszObjId
) };
1445 CERT_EXTENSIONS
*exts
= pvStructInfo
;
1447 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1448 exts
->rgExtension
= (CERT_EXTENSION
*)(exts
+ 1);
1449 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1450 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1454 SetLastError(STATUS_ACCESS_VIOLATION
);
1461 /* Warning: this assumes the address of value->Value.pbData is already set, in
1462 * order to avoid overwriting memory. (In some cases, it may change it, if it
1463 * doesn't copy anything to memory.) Be sure to set it correctly!
1465 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1466 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1471 CERT_NAME_VALUE
*value
= pvStructInfo
;
1473 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1475 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1476 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1478 switch (pbEncoded
[0])
1480 case ASN_OCTETSTRING
:
1481 valueType
= CERT_RDN_OCTET_STRING
;
1482 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1483 bytesNeeded
+= dataLen
;
1485 case ASN_NUMERICSTRING
:
1486 valueType
= CERT_RDN_NUMERIC_STRING
;
1487 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1488 bytesNeeded
+= dataLen
;
1490 case ASN_PRINTABLESTRING
:
1491 valueType
= CERT_RDN_PRINTABLE_STRING
;
1492 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1493 bytesNeeded
+= dataLen
;
1496 valueType
= CERT_RDN_IA5_STRING
;
1497 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1498 bytesNeeded
+= dataLen
;
1501 valueType
= CERT_RDN_T61_STRING
;
1502 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1503 bytesNeeded
+= dataLen
;
1505 case ASN_VIDEOTEXSTRING
:
1506 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1507 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1508 bytesNeeded
+= dataLen
;
1510 case ASN_GRAPHICSTRING
:
1511 valueType
= CERT_RDN_GRAPHIC_STRING
;
1512 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1513 bytesNeeded
+= dataLen
;
1515 case ASN_VISIBLESTRING
:
1516 valueType
= CERT_RDN_VISIBLE_STRING
;
1517 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1518 bytesNeeded
+= dataLen
;
1520 case ASN_GENERALSTRING
:
1521 valueType
= CERT_RDN_GENERAL_STRING
;
1522 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1523 bytesNeeded
+= dataLen
;
1525 case ASN_UNIVERSALSTRING
:
1526 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1527 SetLastError(CRYPT_E_ASN1_BADTAG
);
1530 valueType
= CERT_RDN_BMP_STRING
;
1531 bytesNeeded
+= dataLen
;
1533 case ASN_UTF8STRING
:
1534 valueType
= CERT_RDN_UTF8_STRING
;
1535 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1536 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1539 SetLastError(CRYPT_E_ASN1_BADTAG
);
1544 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1546 *pcbStructInfo
= bytesNeeded
;
1547 else if (*pcbStructInfo
< bytesNeeded
)
1549 *pcbStructInfo
= bytesNeeded
;
1550 SetLastError(ERROR_MORE_DATA
);
1555 *pcbStructInfo
= bytesNeeded
;
1556 value
->dwValueType
= valueType
;
1561 assert(value
->Value
.pbData
);
1562 switch (pbEncoded
[0])
1564 case ASN_OCTETSTRING
:
1565 case ASN_NUMERICSTRING
:
1566 case ASN_PRINTABLESTRING
:
1569 case ASN_VIDEOTEXSTRING
:
1570 case ASN_GRAPHICSTRING
:
1571 case ASN_VISIBLESTRING
:
1572 case ASN_GENERALSTRING
:
1573 value
->Value
.cbData
= dataLen
;
1576 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1577 memcpy(value
->Value
.pbData
,
1578 pbEncoded
+ 1 + lenBytes
, dataLen
);
1580 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1586 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1588 value
->Value
.cbData
= dataLen
;
1589 for (i
= 0; i
< dataLen
/ 2; i
++)
1590 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1591 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1594 case ASN_UTF8STRING
:
1596 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1598 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1599 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1600 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1607 value
->Value
.cbData
= 0;
1608 value
->Value
.pbData
= NULL
;
1615 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1616 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1617 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1623 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1624 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1625 if (ret
&& pvStructInfo
)
1627 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1628 pcbStructInfo
, *pcbStructInfo
);
1631 CERT_NAME_VALUE
*value
;
1633 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1634 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1635 value
= pvStructInfo
;
1636 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1637 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1638 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1639 pcbStructInfo
, NULL
);
1640 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1641 CRYPT_FreeSpace(pDecodePara
, value
);
1647 SetLastError(STATUS_ACCESS_VIOLATION
);
1654 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1655 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1660 CERT_NAME_VALUE
*value
= pvStructInfo
;
1662 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1664 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1665 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1667 switch (pbEncoded
[0])
1669 case ASN_NUMERICSTRING
:
1670 valueType
= CERT_RDN_NUMERIC_STRING
;
1672 bytesNeeded
+= (dataLen
+ 1) * 2;
1674 case ASN_PRINTABLESTRING
:
1675 valueType
= CERT_RDN_PRINTABLE_STRING
;
1677 bytesNeeded
+= (dataLen
+ 1) * 2;
1680 valueType
= CERT_RDN_IA5_STRING
;
1682 bytesNeeded
+= (dataLen
+ 1) * 2;
1685 valueType
= CERT_RDN_T61_STRING
;
1687 bytesNeeded
+= (dataLen
+ 1) * 2;
1689 case ASN_VIDEOTEXSTRING
:
1690 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1692 bytesNeeded
+= (dataLen
+ 1) * 2;
1694 case ASN_GRAPHICSTRING
:
1695 valueType
= CERT_RDN_GRAPHIC_STRING
;
1697 bytesNeeded
+= (dataLen
+ 1) * 2;
1699 case ASN_VISIBLESTRING
:
1700 valueType
= CERT_RDN_VISIBLE_STRING
;
1702 bytesNeeded
+= (dataLen
+ 1) * 2;
1704 case ASN_GENERALSTRING
:
1705 valueType
= CERT_RDN_GENERAL_STRING
;
1707 bytesNeeded
+= (dataLen
+ 1) * 2;
1709 case ASN_UNIVERSALSTRING
:
1710 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1712 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1715 valueType
= CERT_RDN_BMP_STRING
;
1717 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1719 case ASN_UTF8STRING
:
1720 valueType
= CERT_RDN_UTF8_STRING
;
1722 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1723 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1726 SetLastError(CRYPT_E_ASN1_BADTAG
);
1731 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1733 *pcbStructInfo
= bytesNeeded
;
1734 else if (*pcbStructInfo
< bytesNeeded
)
1736 *pcbStructInfo
= bytesNeeded
;
1737 SetLastError(ERROR_MORE_DATA
);
1742 *pcbStructInfo
= bytesNeeded
;
1743 value
->dwValueType
= valueType
;
1747 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1749 assert(value
->Value
.pbData
);
1750 switch (pbEncoded
[0])
1752 case ASN_NUMERICSTRING
:
1753 case ASN_PRINTABLESTRING
:
1756 case ASN_VIDEOTEXSTRING
:
1757 case ASN_GRAPHICSTRING
:
1758 case ASN_VISIBLESTRING
:
1759 case ASN_GENERALSTRING
:
1760 value
->Value
.cbData
= dataLen
* 2;
1761 for (i
= 0; i
< dataLen
; i
++)
1762 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1765 case ASN_UNIVERSALSTRING
:
1766 value
->Value
.cbData
= dataLen
/ 2;
1767 for (i
= 0; i
< dataLen
/ 4; i
++)
1768 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1769 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1773 value
->Value
.cbData
= dataLen
;
1774 for (i
= 0; i
< dataLen
/ 2; i
++)
1775 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1776 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1779 case ASN_UTF8STRING
:
1780 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1781 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1782 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1783 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1784 value
->Value
.cbData
+= sizeof(WCHAR
);
1790 value
->Value
.cbData
= 0;
1791 value
->Value
.pbData
= NULL
;
1798 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1799 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1800 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1806 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1807 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1808 if (ret
&& pvStructInfo
)
1810 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1811 pcbStructInfo
, *pcbStructInfo
);
1814 CERT_NAME_VALUE
*value
;
1816 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1817 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1818 value
= pvStructInfo
;
1819 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1820 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1821 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1822 pcbStructInfo
, NULL
);
1823 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1824 CRYPT_FreeSpace(pDecodePara
, value
);
1830 SetLastError(STATUS_ACCESS_VIOLATION
);
1837 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1838 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1841 struct AsnDecodeSequenceItem items
[] = {
1842 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1843 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1844 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1845 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1846 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1847 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1849 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1851 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1852 pvStructInfo
, *pcbStructInfo
);
1855 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1856 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1857 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1858 attr
? attr
->pszObjId
: NULL
);
1861 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1862 debugstr_a(attr
->pszObjId
));
1863 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1865 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1869 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1870 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1873 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1874 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1876 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1877 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1879 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1880 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1884 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1885 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1886 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1892 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1893 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1894 sizeof(CERT_NAME_INFO
),
1895 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1896 offsetof(CERT_RDN
, rgRDNAttr
) };
1897 DWORD bytesNeeded
= 0;
1899 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1900 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1905 *pcbStructInfo
= bytesNeeded
;
1906 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1907 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1909 CERT_NAME_INFO
*info
;
1911 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1912 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1913 info
= pvStructInfo
;
1914 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1915 sizeof(CERT_NAME_INFO
));
1916 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1917 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1918 &bytesNeeded
, NULL
);
1919 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1920 CRYPT_FreeSpace(pDecodePara
, info
);
1926 SetLastError(STATUS_ACCESS_VIOLATION
);
1933 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1934 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1938 struct AsnDecodeSequenceItem items
[] = {
1939 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1940 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1941 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1942 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1943 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1944 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1946 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1948 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1949 pvStructInfo
, *pcbStructInfo
);
1952 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1953 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1954 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1955 attr
? attr
->pszObjId
: NULL
);
1958 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1959 debugstr_a(attr
->pszObjId
));
1960 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1962 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1966 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1967 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1970 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1971 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1973 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1974 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1976 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1977 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1981 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1982 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1983 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1989 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1990 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1991 sizeof(CERT_NAME_INFO
),
1992 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1993 offsetof(CERT_RDN
, rgRDNAttr
) };
1994 DWORD bytesNeeded
= 0;
1996 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1997 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2002 *pcbStructInfo
= bytesNeeded
;
2003 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2004 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2006 CERT_NAME_INFO
*info
;
2008 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2009 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2010 info
= pvStructInfo
;
2011 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2012 sizeof(CERT_NAME_INFO
));
2013 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2014 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2015 &bytesNeeded
, NULL
);
2016 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2017 CRYPT_FreeSpace(pDecodePara
, info
);
2023 SetLastError(STATUS_ACCESS_VIOLATION
);
2030 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2033 BOOL ret
= TRUE
, done
= FALSE
;
2034 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2036 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2043 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2046 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2048 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2050 indefiniteNestingLevels
++;
2051 pbEncoded
+= 1 + lenBytes
;
2052 cbEncoded
-= 1 + lenBytes
;
2053 decoded
+= 1 + lenBytes
;
2054 TRACE("indefiniteNestingLevels = %d\n",
2055 indefiniteNestingLevels
);
2059 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2060 indefiniteNestingLevels
)
2062 indefiniteNestingLevels
--;
2063 TRACE("indefiniteNestingLevels = %d\n",
2064 indefiniteNestingLevels
);
2066 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2067 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2068 decoded
+= 1 + lenBytes
+ dataLen
;
2069 if (!indefiniteNestingLevels
)
2073 } while (ret
&& !done
);
2074 /* If we haven't found all 0 TLVs, we haven't found the end */
2075 if (ret
&& indefiniteNestingLevels
)
2077 SetLastError(CRYPT_E_ASN1_EOD
);
2081 *pcbDecoded
= decoded
;
2082 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2086 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2087 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2091 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2093 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2094 pvStructInfo
, *pcbStructInfo
);
2096 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2098 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2099 bytesNeeded
+= encodedLen
;
2101 *pcbStructInfo
= bytesNeeded
;
2102 else if (*pcbStructInfo
< bytesNeeded
)
2104 SetLastError(ERROR_MORE_DATA
);
2105 *pcbStructInfo
= bytesNeeded
;
2110 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2112 *pcbStructInfo
= bytesNeeded
;
2113 blob
->cbData
= encodedLen
;
2116 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2117 blob
->pbData
= (LPBYTE
)pbEncoded
;
2120 assert(blob
->pbData
);
2121 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2125 blob
->pbData
= NULL
;
2128 *pcbDecoded
= encodedLen
;
2133 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2134 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2137 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2138 offsetof(CTL_USAGE
, cUsageIdentifier
),
2139 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2141 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2143 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2144 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2148 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2149 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2152 struct AsnArrayDescriptor arrayDesc
= { 0,
2153 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2154 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2155 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2156 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2159 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2160 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2164 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2165 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2167 struct AsnDecodeSequenceItem items
[] = {
2168 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2169 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2170 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2171 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2172 CRYPT_AsnDecodeCTLEntryAttributes
,
2173 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2174 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2177 CTL_ENTRY
*entry
= pvStructInfo
;
2179 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2182 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2183 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2184 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2188 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2189 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2192 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2193 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2194 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2195 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2196 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2198 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2199 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2201 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2202 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2206 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2207 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2211 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2212 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2213 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2214 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2215 offsetof(CERT_EXTENSION
, pszObjId
) };
2217 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2218 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2220 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2221 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2225 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2226 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2232 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2234 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2236 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2237 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2238 if (ret
&& pcbDecoded
)
2239 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2244 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2245 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2246 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2250 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2251 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2255 struct AsnDecodeSequenceItem items
[] = {
2256 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2257 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2258 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2259 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2260 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2261 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2262 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2263 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2264 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2265 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2266 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2267 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2268 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2270 { 0, offsetof(CTL_INFO
, NextUpdate
),
2271 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2273 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2274 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2275 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2276 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2277 CRYPT_AsnDecodeCTLEntries
,
2278 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2279 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2280 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2281 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2282 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2285 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2286 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2287 pcbStructInfo
, NULL
, NULL
);
2291 SetLastError(STATUS_ACCESS_VIOLATION
);
2297 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2298 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2302 struct AsnDecodeSequenceItem items
[] = {
2303 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2304 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2305 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2306 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2307 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2308 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2310 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2312 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2313 pvStructInfo
, *pcbStructInfo
);
2315 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2316 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2317 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2318 TRACE("returning %d\n", ret
);
2322 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2323 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2324 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2328 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2329 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2333 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2334 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2335 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2336 sizeof(CRYPT_SMIME_CAPABILITIES
),
2337 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2338 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2339 CRYPT_SMIME_CAPABILITIES
*capabilities
= pvStructInfo
;
2341 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2342 capabilities
->rgCapability
= (CRYPT_SMIME_CAPABILITY
*)(capabilities
+ 1);
2343 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2344 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2348 SetLastError(STATUS_ACCESS_VIOLATION
);
2351 TRACE("returning %d\n", ret
);
2355 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2356 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2361 LPSTR
*pStr
= pvStructInfo
;
2363 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2365 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2366 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2368 if (pbEncoded
[0] != ASN_IA5STRING
)
2370 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2375 bytesNeeded
+= dataLen
;
2377 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2379 *pcbStructInfo
= bytesNeeded
;
2380 else if (*pcbStructInfo
< bytesNeeded
)
2382 *pcbStructInfo
= bytesNeeded
;
2383 SetLastError(ERROR_MORE_DATA
);
2388 *pcbStructInfo
= bytesNeeded
;
2394 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2405 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2406 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2409 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2410 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2411 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2412 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2413 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2416 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2417 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2419 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2420 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2421 TRACE("returning %d\n", ret
);
2425 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2426 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2430 struct AsnDecodeSequenceItem items
[] = {
2431 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2432 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2433 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2434 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2435 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2436 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2437 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2438 rgNoticeNumbers
), 0 },
2440 DWORD bytesNeeded
= 0;
2442 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2443 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2445 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2446 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2450 /* The caller is expecting a pointer to a
2451 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2452 * CRYPT_AsnDecodeSequence is decoding a
2453 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2454 * needed, and decode again if the requisite space is available.
2456 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2458 *pcbStructInfo
= bytesNeeded
;
2459 else if (*pcbStructInfo
< bytesNeeded
)
2461 *pcbStructInfo
= bytesNeeded
;
2462 SetLastError(ERROR_MORE_DATA
);
2467 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2469 *pcbStructInfo
= bytesNeeded
;
2470 /* The pointer (pvStructInfo) passed in points to the first dynamic
2471 * pointer, so use it as the pointer to the
2472 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2473 * appropriate offset for the first dynamic pointer within the
2474 * notice reference by pointing to the first memory location past
2475 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2478 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2479 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2480 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2481 ret
= CRYPT_AsnDecodeSequence(items
,
2482 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2483 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2484 noticeRef
->pszOrganization
);
2487 TRACE("returning %d\n", ret
);
2491 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2492 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2498 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2500 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2501 DWORD bytesNeeded
= sizeof(LPWSTR
);
2503 switch (pbEncoded
[0])
2505 case ASN_NUMERICSTRING
:
2507 bytesNeeded
+= (dataLen
+ 1) * 2;
2509 case ASN_PRINTABLESTRING
:
2511 bytesNeeded
+= (dataLen
+ 1) * 2;
2515 bytesNeeded
+= (dataLen
+ 1) * 2;
2519 bytesNeeded
+= (dataLen
+ 1) * 2;
2521 case ASN_VIDEOTEXSTRING
:
2523 bytesNeeded
+= (dataLen
+ 1) * 2;
2525 case ASN_GRAPHICSTRING
:
2527 bytesNeeded
+= (dataLen
+ 1) * 2;
2529 case ASN_VISIBLESTRING
:
2531 bytesNeeded
+= (dataLen
+ 1) * 2;
2533 case ASN_GENERALSTRING
:
2535 bytesNeeded
+= (dataLen
+ 1) * 2;
2537 case ASN_UNIVERSALSTRING
:
2539 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2543 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2545 case ASN_UTF8STRING
:
2547 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2548 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2551 SetLastError(CRYPT_E_ASN1_BADTAG
);
2556 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2558 *pcbStructInfo
= bytesNeeded
;
2559 else if (*pcbStructInfo
< bytesNeeded
)
2561 *pcbStructInfo
= bytesNeeded
;
2562 SetLastError(ERROR_MORE_DATA
);
2567 LPWSTR
*pStr
= pvStructInfo
;
2569 *pcbStructInfo
= bytesNeeded
;
2573 LPWSTR str
= *(LPWSTR
*)pStr
;
2576 switch (pbEncoded
[0])
2578 case ASN_NUMERICSTRING
:
2579 case ASN_PRINTABLESTRING
:
2582 case ASN_VIDEOTEXSTRING
:
2583 case ASN_GRAPHICSTRING
:
2584 case ASN_VISIBLESTRING
:
2585 case ASN_GENERALSTRING
:
2586 for (i
= 0; i
< dataLen
; i
++)
2587 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2590 case ASN_UNIVERSALSTRING
:
2591 for (i
= 0; i
< dataLen
/ 4; i
++)
2592 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2593 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2597 for (i
= 0; i
< dataLen
/ 2; i
++)
2598 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2599 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2602 case ASN_UTF8STRING
:
2604 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2605 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2606 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2619 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2620 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2621 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2624 struct AsnDecodeSequenceItem items
[] = {
2625 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2626 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2627 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2628 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2629 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2630 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2631 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2633 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2635 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2636 pvStructInfo
, *pcbStructInfo
);
2638 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2639 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2640 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2641 TRACE("returning %d\n", ret
);
2645 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2646 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2647 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2648 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2652 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2653 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2657 DWORD bytesNeeded
= 0;
2659 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2660 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2665 *pcbStructInfo
= bytesNeeded
;
2666 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2667 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2669 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2671 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2672 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2673 notice
= pvStructInfo
;
2674 notice
->pNoticeReference
=
2675 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2676 ((BYTE
*)pvStructInfo
+
2677 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2678 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2679 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2680 pvStructInfo
, &bytesNeeded
, NULL
);
2681 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2682 CRYPT_FreeSpace(pDecodePara
, notice
);
2688 SetLastError(STATUS_ACCESS_VIOLATION
);
2691 TRACE("returning %d\n", ret
);
2695 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2696 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2700 struct AsnArrayDescriptor arrayDesc
= { 0,
2701 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2702 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2703 CRYPT_AsnDecodeCopyBytes
,
2704 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2706 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2707 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2709 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2710 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2714 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2715 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2719 struct AsnDecodeSequenceItem items
[] = {
2720 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2721 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2722 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2723 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2724 CRYPT_AsnDecodePKCSAttributeValue
,
2725 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2726 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2728 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2730 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2731 pvStructInfo
, *pcbStructInfo
);
2733 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2734 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2735 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2736 TRACE("returning %d\n", ret
);
2740 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2741 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2742 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2746 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2747 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2751 DWORD bytesNeeded
= 0;
2753 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2754 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2758 *pcbStructInfo
= bytesNeeded
;
2759 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2760 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2762 PCRYPT_ATTRIBUTE attr
;
2764 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2765 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2766 attr
= pvStructInfo
;
2767 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2768 sizeof(CRYPT_ATTRIBUTE
));
2769 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2770 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2772 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2773 CRYPT_FreeSpace(pDecodePara
, attr
);
2779 SetLastError(STATUS_ACCESS_VIOLATION
);
2782 TRACE("returning %d\n", ret
);
2786 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2787 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2790 struct AsnArrayDescriptor arrayDesc
= { 0,
2791 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2792 sizeof(CRYPT_ATTRIBUTES
),
2793 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2794 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2797 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2798 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2802 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2803 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2804 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2808 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2809 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2813 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2814 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2815 sizeof(CRYPT_ATTRIBUTES
),
2816 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2817 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2818 CRYPT_ATTRIBUTES
*attrs
= pvStructInfo
;
2820 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2821 attrs
->rgAttr
= (CRYPT_ATTRIBUTE
*)(attrs
+ 1);
2822 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2823 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2827 SetLastError(STATUS_ACCESS_VIOLATION
);
2830 TRACE("returning %d\n", ret
);
2834 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2835 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2837 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2839 struct AsnDecodeSequenceItem items
[] = {
2840 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2841 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2842 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2843 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2844 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2845 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2848 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2849 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2851 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2852 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2853 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2854 if (ret
&& pvStructInfo
)
2856 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2857 debugstr_a(algo
->pszObjId
));
2862 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2863 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2867 struct AsnDecodeSequenceItem items
[] = {
2868 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2869 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2870 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2871 Algorithm
.pszObjId
) },
2872 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2873 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2874 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2876 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2878 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2879 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2880 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2884 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2885 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2886 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2892 DWORD bytesNeeded
= 0;
2894 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2895 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2898 *pcbStructInfo
= bytesNeeded
;
2899 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2900 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2902 PCERT_PUBLIC_KEY_INFO info
;
2904 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2905 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2906 info
= pvStructInfo
;
2907 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2908 sizeof(CERT_PUBLIC_KEY_INFO
);
2909 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2910 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2911 &bytesNeeded
, NULL
);
2912 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2913 CRYPT_FreeSpace(pDecodePara
, info
);
2919 SetLastError(STATUS_ACCESS_VIOLATION
);
2926 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2927 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2933 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2936 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2938 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2941 if (pbEncoded
[1] > 1)
2943 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2950 *pcbStructInfo
= sizeof(BOOL
);
2953 else if (*pcbStructInfo
< sizeof(BOOL
))
2955 *pcbStructInfo
= sizeof(BOOL
);
2956 SetLastError(ERROR_MORE_DATA
);
2961 *pcbStructInfo
= sizeof(BOOL
);
2962 *(BOOL
*)pvStructInfo
= pbEncoded
[2] != 0;
2965 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2969 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2970 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2972 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2973 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2976 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2977 pvStructInfo
, *pcbStructInfo
);
2981 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2984 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2985 if (1 + lenBytes
> cbEncoded
)
2987 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2990 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2992 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2994 case 1: /* rfc822Name */
2995 case 2: /* dNSName */
2996 case 6: /* uniformResourceIdentifier */
2997 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
2999 SetLastError(CRYPT_E_ASN1_RULE
);
3003 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3005 case 4: /* directoryName */
3006 case 7: /* iPAddress */
3007 bytesNeeded
+= dataLen
;
3009 case 8: /* registeredID */
3010 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3014 /* FIXME: ugly, shouldn't need to know internals of OID decode
3015 * function to use it.
3017 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3020 case 0: /* otherName */
3021 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3022 SetLastError(CRYPT_E_ASN1_BADTAG
);
3025 case 3: /* x400Address, unimplemented */
3026 case 5: /* ediPartyName, unimplemented */
3027 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3028 SetLastError(CRYPT_E_ASN1_BADTAG
);
3032 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3033 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3039 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3041 *pcbStructInfo
= bytesNeeded
;
3042 else if (*pcbStructInfo
< bytesNeeded
)
3044 *pcbStructInfo
= bytesNeeded
;
3045 SetLastError(ERROR_MORE_DATA
);
3050 *pcbStructInfo
= bytesNeeded
;
3051 /* MS used values one greater than the asn1 ones.. sigh */
3052 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3053 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3055 case 1: /* rfc822Name */
3056 case 2: /* dNSName */
3057 case 6: /* uniformResourceIdentifier */
3061 for (i
= 0; i
< dataLen
; i
++)
3062 entry
->u
.pwszURL
[i
] =
3063 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3064 entry
->u
.pwszURL
[i
] = 0;
3065 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3066 debugstr_w(entry
->u
.pwszURL
));
3069 case 4: /* directoryName */
3070 /* The data are memory-equivalent with the IPAddress case,
3073 case 7: /* iPAddress */
3074 /* The next data pointer is in the pwszURL spot, that is,
3075 * the first 4 bytes. Need to move it to the next spot.
3077 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3078 entry
->u
.IPAddress
.cbData
= dataLen
;
3079 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3082 case 8: /* registeredID */
3083 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3084 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3093 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3094 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3098 struct AsnArrayDescriptor arrayDesc
= { 0,
3099 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3100 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3101 sizeof(CERT_ALT_NAME_INFO
),
3102 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3103 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3105 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3106 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3108 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3109 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3113 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3114 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3115 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3121 struct AsnDecodeSequenceItem items
[] = {
3122 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3123 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3124 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3125 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3126 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3127 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3128 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3129 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3130 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3131 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3132 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3135 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3136 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3137 pcbStructInfo
, NULL
, NULL
);
3141 SetLastError(STATUS_ACCESS_VIOLATION
);
3148 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3149 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3150 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3156 struct AsnDecodeSequenceItem items
[] = {
3157 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3158 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3159 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3160 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3161 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3162 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3163 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3164 AuthorityCertIssuer
.rgAltEntry
), 0 },
3165 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3166 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3167 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3168 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3169 AuthorityCertSerialNumber
.pbData
), 0 },
3172 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3173 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3174 pcbStructInfo
, NULL
, NULL
);
3178 SetLastError(STATUS_ACCESS_VIOLATION
);
3185 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3186 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3189 struct AsnDecodeSequenceItem items
[] = {
3190 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3191 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3192 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3193 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3194 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3195 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3197 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3199 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3200 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3201 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3204 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3205 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3206 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3210 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3211 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3215 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3216 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3217 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3218 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3219 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3220 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3221 CERT_AUTHORITY_INFO_ACCESS
*info
= pvStructInfo
;
3223 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3224 info
->rgAccDescr
= (CERT_ACCESS_DESCRIPTION
*)(info
+ 1);
3225 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3226 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3230 SetLastError(STATUS_ACCESS_VIOLATION
);
3237 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3238 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3243 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3244 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3246 /* The caller has already checked the tag, no need to check it again.
3247 * Check the outer length is valid:
3249 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3251 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3254 pbEncoded
+= 1 + lenBytes
;
3255 cbEncoded
-= 1 + lenBytes
;
3256 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3257 cbEncoded
-= 2; /* space for 0 TLV */
3258 /* Check the inner length is valid: */
3259 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3263 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3264 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3265 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3267 if (*(pbEncoded
+ decodedLen
) != 0 ||
3268 *(pbEncoded
+ decodedLen
+ 1) != 0)
3270 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3271 *(pbEncoded
+ decodedLen
),
3272 *(pbEncoded
+ decodedLen
+ 1));
3273 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3279 if (ret
&& pcbDecoded
)
3281 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3282 TRACE("decoded %d bytes\n", *pcbDecoded
);
3289 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3290 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3293 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3294 struct AsnDecodeSequenceItem items
[] = {
3295 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3296 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3297 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3298 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3299 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3300 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3301 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3305 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3306 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3308 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3309 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3310 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3314 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3315 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3316 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3320 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3321 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3325 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3326 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3327 if (ret
&& pvStructInfo
)
3329 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3330 pcbStructInfo
, *pcbStructInfo
);
3333 CRYPT_CONTENT_INFO
*info
;
3335 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3336 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3337 info
= pvStructInfo
;
3338 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3339 sizeof(CRYPT_CONTENT_INFO
));
3340 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3341 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3342 pcbStructInfo
, NULL
);
3343 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3344 CRYPT_FreeSpace(pDecodePara
, info
);
3350 SetLastError(STATUS_ACCESS_VIOLATION
);
3356 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3357 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3358 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3361 struct AsnDecodeSequenceItem items
[] = {
3362 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3363 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3364 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3365 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3366 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3368 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3369 CRYPT_AsnDecodePKCSContentInfoInternal
,
3370 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3371 ContentInfo
.pszObjId
), 0 },
3372 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3373 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3374 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3377 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3378 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3383 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3384 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3385 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3389 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3390 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3394 DWORD bytesNeeded
= 0;
3396 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3397 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3400 *pcbStructInfo
= bytesNeeded
;
3401 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3402 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3404 CERT_ALT_NAME_INFO
*name
;
3406 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3407 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3408 name
= pvStructInfo
;
3409 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3410 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3411 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3412 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3413 &bytesNeeded
, NULL
);
3414 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3415 CRYPT_FreeSpace(pDecodePara
, name
);
3421 SetLastError(STATUS_ACCESS_VIOLATION
);
3428 struct PATH_LEN_CONSTRAINT
3430 BOOL fPathLenConstraint
;
3431 DWORD dwPathLenConstraint
;
3434 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3435 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3439 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3441 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3442 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3446 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3448 *pcbStructInfo
= bytesNeeded
;
3450 else if (*pcbStructInfo
< bytesNeeded
)
3452 SetLastError(ERROR_MORE_DATA
);
3453 *pcbStructInfo
= bytesNeeded
;
3458 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3460 *pcbStructInfo
= bytesNeeded
;
3461 size
= sizeof(constraint
->dwPathLenConstraint
);
3462 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3463 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3465 constraint
->fPathLenConstraint
= TRUE
;
3466 TRACE("got an int, dwPathLenConstraint is %d\n",
3467 constraint
->dwPathLenConstraint
);
3469 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3473 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3474 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3478 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3479 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3480 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3481 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3482 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3483 offsetof(CERT_NAME_BLOB
, pbData
) };
3485 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3486 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3488 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3489 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3490 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3494 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3495 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3496 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3502 struct AsnDecodeSequenceItem items
[] = {
3503 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3504 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3505 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3506 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3507 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3508 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3509 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3510 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3511 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3513 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 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 WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3530 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3531 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3537 struct AsnDecodeSequenceItem items
[] = {
3538 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3539 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3540 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3541 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3542 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3545 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3546 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3547 pcbStructInfo
, NULL
, NULL
);
3551 SetLastError(STATUS_ACCESS_VIOLATION
);
3558 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3559 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3562 struct AsnDecodeSequenceItem items
[] = {
3563 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3564 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3565 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3567 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3568 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3569 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3572 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3574 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3575 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3577 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3578 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3579 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3583 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3584 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3588 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3589 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3590 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3591 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3592 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3593 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3595 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3596 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3598 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3599 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3600 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3604 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3605 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3607 struct AsnDecodeSequenceItem items
[] = {
3608 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3609 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3610 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3611 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3612 CRYPT_AsnDecodePolicyQualifiers
,
3613 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3614 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3616 CERT_POLICY_INFO
*info
= pvStructInfo
;
3619 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3620 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3622 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3623 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3624 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3628 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3629 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3630 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3634 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3635 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3639 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3640 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3641 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3642 sizeof(CERT_POLICIES_INFO
),
3643 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3644 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3645 CERT_POLICIES_INFO
*info
= pvStructInfo
;
3647 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3648 info
->rgPolicyInfo
= (CERT_POLICY_INFO
*)(info
+ 1);
3650 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3651 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3655 SetLastError(STATUS_ACCESS_VIOLATION
);
3661 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3662 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3665 struct AsnDecodeSequenceItem items
[] = {
3666 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3667 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3668 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3669 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3670 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3671 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3673 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3676 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3677 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3679 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3680 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3681 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3685 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3686 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3687 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3691 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3692 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3696 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3697 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3698 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3699 sizeof(CERT_POLICY_MAPPING
),
3700 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3701 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3702 CERT_POLICY_MAPPINGS_INFO
*info
= pvStructInfo
;
3704 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3705 info
->rgPolicyMapping
= (CERT_POLICY_MAPPING
*)(info
+ 1);
3706 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3707 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3711 SetLastError(STATUS_ACCESS_VIOLATION
);
3717 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3718 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3722 DWORD skip
, size
= sizeof(skip
);
3726 SetLastError(CRYPT_E_ASN1_EOD
);
3729 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3731 SetLastError(CRYPT_E_ASN1_BADTAG
);
3734 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3735 &skip
, &size
, pcbDecoded
)))
3737 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3738 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3741 *pcbStructInfo
= bytesNeeded
;
3742 else if (*pcbStructInfo
< bytesNeeded
)
3744 *pcbStructInfo
= bytesNeeded
;
3745 SetLastError(ERROR_MORE_DATA
);
3750 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3751 CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
);
3753 *pcbStructInfo
= bytesNeeded
;
3754 /* The BOOL is implicit: if the integer is present, then it's
3757 info
->fRequireExplicitPolicy
= TRUE
;
3758 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3764 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3765 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3769 DWORD skip
, size
= sizeof(skip
);
3773 SetLastError(CRYPT_E_ASN1_EOD
);
3776 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3778 SetLastError(CRYPT_E_ASN1_BADTAG
);
3781 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3782 &skip
, &size
, pcbDecoded
)))
3784 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3785 fInhibitPolicyMapping
);
3788 *pcbStructInfo
= bytesNeeded
;
3789 else if (*pcbStructInfo
< bytesNeeded
)
3791 *pcbStructInfo
= bytesNeeded
;
3792 SetLastError(ERROR_MORE_DATA
);
3797 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3798 CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
);
3800 *pcbStructInfo
= bytesNeeded
;
3801 /* The BOOL is implicit: if the integer is present, then it's
3804 info
->fInhibitPolicyMapping
= TRUE
;
3805 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3811 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3812 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3813 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3814 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3818 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3819 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3823 struct AsnDecodeSequenceItem items
[] = {
3825 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3826 CRYPT_AsnDecodeRequireExplicit
,
3827 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3828 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3830 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3831 CRYPT_AsnDecodeInhibitMapping
,
3832 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3833 TRUE
, FALSE
, 0, 0 },
3836 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3837 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3838 pcbStructInfo
, NULL
, NULL
);
3842 SetLastError(STATUS_ACCESS_VIOLATION
);
3848 #define RSA1_MAGIC 0x31415352
3850 struct DECODED_RSA_PUB_KEY
3853 CRYPT_INTEGER_BLOB modulus
;
3856 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3857 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3858 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3864 struct AsnDecodeSequenceItem items
[] = {
3865 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3866 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3867 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3869 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3870 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3872 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3875 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3876 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3880 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3881 decodedKey
->modulus
.cbData
;
3885 *pcbStructInfo
= bytesNeeded
;
3888 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3889 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3892 RSAPUBKEY
*rsaPubKey
;
3894 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3895 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3897 hdr
->bType
= PUBLICKEYBLOB
;
3898 hdr
->bVersion
= CUR_BLOB_VERSION
;
3900 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3901 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3902 sizeof(BLOBHEADER
));
3903 rsaPubKey
->magic
= RSA1_MAGIC
;
3904 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3905 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3906 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3907 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3908 decodedKey
->modulus
.cbData
);
3910 LocalFree(decodedKey
);
3915 SetLastError(STATUS_ACCESS_VIOLATION
);
3922 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3923 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3927 DWORD bytesNeeded
, dataLen
;
3929 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3930 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3932 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3934 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3936 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3937 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3939 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3941 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3943 *pcbStructInfo
= bytesNeeded
;
3944 else if (*pcbStructInfo
< bytesNeeded
)
3946 SetLastError(ERROR_MORE_DATA
);
3947 *pcbStructInfo
= bytesNeeded
;
3952 CRYPT_DATA_BLOB
*blob
;
3954 *pcbStructInfo
= bytesNeeded
;
3955 blob
= pvStructInfo
;
3956 blob
->cbData
= dataLen
;
3957 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3958 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3961 assert(blob
->pbData
);
3963 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3971 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3972 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3973 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3977 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3978 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3982 DWORD bytesNeeded
= 0;
3986 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3989 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
3991 SetLastError(CRYPT_E_ASN1_BADTAG
);
3994 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3995 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3998 *pcbStructInfo
= bytesNeeded
;
3999 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4000 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4002 CRYPT_DATA_BLOB
*blob
;
4004 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4005 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4006 blob
= pvStructInfo
;
4007 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4008 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4009 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4010 &bytesNeeded
, NULL
);
4011 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4012 CRYPT_FreeSpace(pDecodePara
, blob
);
4018 SetLastError(STATUS_ACCESS_VIOLATION
);
4025 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4026 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4029 DWORD bytesNeeded
, dataLen
;
4030 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4032 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4033 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4035 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4037 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4038 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4040 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4042 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4044 *pcbStructInfo
= bytesNeeded
;
4045 else if (*pcbStructInfo
< bytesNeeded
)
4047 *pcbStructInfo
= bytesNeeded
;
4048 SetLastError(ERROR_MORE_DATA
);
4053 CRYPT_BIT_BLOB
*blob
;
4055 *pcbStructInfo
= bytesNeeded
;
4056 blob
= pvStructInfo
;
4057 blob
->cbData
= dataLen
- 1;
4058 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4059 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4061 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4065 assert(blob
->pbData
);
4068 BYTE mask
= 0xff << blob
->cUnusedBits
;
4070 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4072 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4080 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4081 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4082 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4086 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4087 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4091 DWORD bytesNeeded
= 0;
4095 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4098 else if (pbEncoded
[0] != ASN_BITSTRING
)
4100 SetLastError(CRYPT_E_ASN1_BADTAG
);
4103 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4104 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4107 *pcbStructInfo
= bytesNeeded
;
4108 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4109 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4111 CRYPT_BIT_BLOB
*blob
;
4113 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4114 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4115 blob
= pvStructInfo
;
4116 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4117 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4118 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4119 &bytesNeeded
, NULL
);
4120 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4121 CRYPT_FreeSpace(pDecodePara
, blob
);
4127 SetLastError(STATUS_ACCESS_VIOLATION
);
4131 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4135 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4136 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4137 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4142 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4144 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4147 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4148 if (dataLen
> sizeof(int))
4150 SetLastError(CRYPT_E_ASN1_LARGE
);
4153 else if (!pvStructInfo
)
4154 *pcbStructInfo
= sizeof(int);
4155 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4159 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4161 /* initialize to a negative value to sign-extend */
4166 for (i
= 0; i
< dataLen
; i
++)
4169 val
|= pbEncoded
[1 + lenBytes
+ i
];
4171 memcpy(pvStructInfo
, &val
, sizeof(int));
4177 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4178 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4179 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4185 DWORD bytesNeeded
= 0;
4189 SetLastError(CRYPT_E_ASN1_EOD
);
4192 else if (pbEncoded
[0] != ASN_INTEGER
)
4194 SetLastError(CRYPT_E_ASN1_BADTAG
);
4198 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4199 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4203 *pcbStructInfo
= bytesNeeded
;
4204 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4205 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4207 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4208 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4209 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4210 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4211 &bytesNeeded
, NULL
);
4212 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4213 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4219 SetLastError(STATUS_ACCESS_VIOLATION
);
4226 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4227 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4231 DWORD bytesNeeded
, dataLen
;
4233 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4235 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4237 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4239 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4241 *pcbStructInfo
= bytesNeeded
;
4242 else if (*pcbStructInfo
< bytesNeeded
)
4244 *pcbStructInfo
= bytesNeeded
;
4245 SetLastError(ERROR_MORE_DATA
);
4250 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4252 *pcbStructInfo
= bytesNeeded
;
4253 blob
->cbData
= dataLen
;
4254 assert(blob
->pbData
);
4259 for (i
= 0; i
< blob
->cbData
; i
++)
4261 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4270 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4271 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4272 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4278 DWORD bytesNeeded
= 0;
4280 if (pbEncoded
[0] != ASN_INTEGER
)
4282 SetLastError(CRYPT_E_ASN1_BADTAG
);
4286 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4287 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4291 *pcbStructInfo
= bytesNeeded
;
4292 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4293 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4295 CRYPT_INTEGER_BLOB
*blob
;
4297 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4298 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4299 blob
= pvStructInfo
;
4300 blob
->pbData
= (BYTE
*)pvStructInfo
+
4301 sizeof(CRYPT_INTEGER_BLOB
);
4302 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4303 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4304 &bytesNeeded
, NULL
);
4305 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4306 CRYPT_FreeSpace(pDecodePara
, blob
);
4312 SetLastError(STATUS_ACCESS_VIOLATION
);
4319 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4320 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4325 if (pbEncoded
[0] == ASN_INTEGER
)
4327 DWORD bytesNeeded
, dataLen
;
4329 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4331 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4334 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4335 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4337 *pcbStructInfo
= bytesNeeded
;
4338 else if (*pcbStructInfo
< bytesNeeded
)
4340 *pcbStructInfo
= bytesNeeded
;
4341 SetLastError(ERROR_MORE_DATA
);
4346 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4348 *pcbStructInfo
= bytesNeeded
;
4349 blob
->cbData
= dataLen
;
4350 assert(blob
->pbData
);
4351 /* remove leading zero byte if it exists */
4352 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4361 for (i
= 0; i
< blob
->cbData
; i
++)
4363 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4372 SetLastError(CRYPT_E_ASN1_BADTAG
);
4378 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4379 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4380 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4386 DWORD bytesNeeded
= 0;
4388 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4389 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4392 *pcbStructInfo
= bytesNeeded
;
4393 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4394 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4396 CRYPT_INTEGER_BLOB
*blob
;
4398 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4399 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4400 blob
= pvStructInfo
;
4401 blob
->pbData
= (BYTE
*)pvStructInfo
+
4402 sizeof(CRYPT_INTEGER_BLOB
);
4403 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4404 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4405 &bytesNeeded
, NULL
);
4406 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4407 CRYPT_FreeSpace(pDecodePara
, blob
);
4413 SetLastError(STATUS_ACCESS_VIOLATION
);
4420 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4421 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4422 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4428 *pcbStructInfo
= sizeof(int);
4433 if (pbEncoded
[0] == ASN_ENUMERATED
)
4435 unsigned int val
= 0, i
;
4439 SetLastError(CRYPT_E_ASN1_EOD
);
4442 else if (pbEncoded
[1] == 0)
4444 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4449 /* A little strange looking, but we have to accept a sign byte:
4450 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4451 * assuming a small length is okay here, it has to be in short
4454 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4456 SetLastError(CRYPT_E_ASN1_LARGE
);
4459 for (i
= 0; i
< pbEncoded
[1]; i
++)
4462 val
|= pbEncoded
[2 + i
];
4464 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4465 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4467 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4468 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4469 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4475 SetLastError(CRYPT_E_ASN1_BADTAG
);
4481 SetLastError(STATUS_ACCESS_VIOLATION
);
4488 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4491 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4496 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4498 if (!isdigit(*(pbEncoded))) \
4500 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4506 (word) += *(pbEncoded)++ - '0'; \
4511 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4512 SYSTEMTIME
*sysTime
)
4516 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4518 WORD hours
, minutes
= 0;
4519 BYTE sign
= *pbEncoded
++;
4522 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4523 if (ret
&& hours
>= 24)
4525 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4530 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4531 if (ret
&& minutes
>= 60)
4533 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4541 sysTime
->wHour
+= hours
;
4542 sysTime
->wMinute
+= minutes
;
4546 if (hours
> sysTime
->wHour
)
4549 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4552 sysTime
->wHour
-= hours
;
4553 if (minutes
> sysTime
->wMinute
)
4556 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4559 sysTime
->wMinute
-= minutes
;
4566 #define MIN_ENCODED_TIME_LENGTH 10
4568 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4569 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4574 if (pbEncoded
[0] == ASN_UTCTIME
)
4577 SetLastError(CRYPT_E_ASN1_EOD
);
4578 else if (pbEncoded
[1] > 0x7f)
4580 /* long-form date strings really can't be valid */
4581 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4585 SYSTEMTIME sysTime
= { 0 };
4586 BYTE len
= pbEncoded
[1];
4588 if (len
< MIN_ENCODED_TIME_LENGTH
)
4589 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4594 *pcbDecoded
= 2 + len
;
4596 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4597 if (sysTime
.wYear
>= 50)
4598 sysTime
.wYear
+= 1900;
4600 sysTime
.wYear
+= 2000;
4601 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4602 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4603 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4604 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4607 if (len
>= 2 && isdigit(*pbEncoded
) &&
4608 isdigit(*(pbEncoded
+ 1)))
4609 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4611 else if (isdigit(*pbEncoded
))
4612 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4615 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4621 *pcbStructInfo
= sizeof(FILETIME
);
4622 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4624 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4630 SetLastError(CRYPT_E_ASN1_BADTAG
);
4634 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4635 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4636 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4642 DWORD bytesNeeded
= 0;
4644 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4645 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4649 *pcbStructInfo
= bytesNeeded
;
4650 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4651 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4653 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4654 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4655 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4656 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4657 &bytesNeeded
, NULL
);
4658 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4659 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4665 SetLastError(STATUS_ACCESS_VIOLATION
);
4671 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4672 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4677 if (pbEncoded
[0] == ASN_GENERALTIME
)
4680 SetLastError(CRYPT_E_ASN1_EOD
);
4681 else if (pbEncoded
[1] > 0x7f)
4683 /* long-form date strings really can't be valid */
4684 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4688 BYTE len
= pbEncoded
[1];
4690 if (len
< MIN_ENCODED_TIME_LENGTH
)
4691 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4694 SYSTEMTIME sysTime
= { 0 };
4698 *pcbDecoded
= 2 + len
;
4700 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4701 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4702 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4703 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4706 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4709 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4711 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4718 /* workaround macro weirdness */
4719 digits
= min(len
, 3);
4720 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4721 sysTime
.wMilliseconds
);
4724 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4730 *pcbStructInfo
= sizeof(FILETIME
);
4731 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4733 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4739 SetLastError(CRYPT_E_ASN1_BADTAG
);
4743 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4744 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4748 InternalDecodeFunc decode
= NULL
;
4750 if (pbEncoded
[0] == ASN_UTCTIME
)
4751 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4752 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4753 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4755 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4756 pcbStructInfo
, pcbDecoded
);
4759 SetLastError(CRYPT_E_ASN1_BADTAG
);
4765 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4766 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4767 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4773 DWORD bytesNeeded
= 0;
4775 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4776 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4780 *pcbStructInfo
= bytesNeeded
;
4781 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4782 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4784 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4785 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4786 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4787 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4788 &bytesNeeded
, NULL
);
4789 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4790 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4796 SetLastError(STATUS_ACCESS_VIOLATION
);
4803 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4804 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4805 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4811 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4813 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4815 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4820 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4821 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4823 ptr
= pbEncoded
+ 1 + lenBytes
;
4824 remainingLen
= dataLen
;
4825 while (ret
&& remainingLen
)
4829 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4832 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4834 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4835 ptr
+= 1 + nextLenBytes
+ nextLen
;
4836 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4837 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4838 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4844 CRYPT_SEQUENCE_OF_ANY
*seq
;
4849 *pcbStructInfo
= bytesNeeded
;
4850 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4851 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4853 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4854 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4856 seq
->cValue
= cValue
;
4857 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4859 nextPtr
= (BYTE
*)seq
->rgValue
+
4860 cValue
* sizeof(CRYPT_DER_BLOB
);
4861 ptr
= pbEncoded
+ 1 + lenBytes
;
4862 remainingLen
= dataLen
;
4864 while (ret
&& remainingLen
)
4868 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4871 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4873 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4875 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4876 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4879 seq
->rgValue
[i
].pbData
= nextPtr
;
4880 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4882 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4884 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4885 ptr
+= 1 + nextLenBytes
+ nextLen
;
4889 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4890 CRYPT_FreeSpace(pDecodePara
, seq
);
4897 SetLastError(CRYPT_E_ASN1_BADTAG
);
4903 SetLastError(STATUS_ACCESS_VIOLATION
);
4910 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4911 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4916 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4918 DWORD bytesNeeded
= 0, dataLen
;
4920 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4922 struct AsnArrayDescriptor arrayDesc
= {
4923 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4924 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
4925 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
4926 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
4927 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4928 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4929 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4934 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4935 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4936 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
4937 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4938 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
4941 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4943 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4945 *pcbStructInfo
= bytesNeeded
;
4946 else if (*pcbStructInfo
< bytesNeeded
)
4948 *pcbStructInfo
= bytesNeeded
;
4949 SetLastError(ERROR_MORE_DATA
);
4954 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
4956 *pcbStructInfo
= bytesNeeded
;
4959 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4960 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4961 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4962 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
4966 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4972 SetLastError(CRYPT_E_ASN1_BADTAG
);
4978 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4979 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4981 struct AsnDecodeSequenceItem items
[] = {
4982 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4983 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4984 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4985 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4986 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4987 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4988 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4989 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4990 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4991 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4993 CRL_DIST_POINT
*point
= pvStructInfo
;
4996 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4997 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4998 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5002 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5003 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5004 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5008 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5009 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5013 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5014 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
5015 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
5016 sizeof(CRL_DIST_POINTS_INFO
),
5017 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5018 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5019 CRL_DIST_POINTS_INFO
*info
= pvStructInfo
;
5021 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5022 info
->rgDistPoint
= (CRL_DIST_POINT
*)(info
+ 1);
5023 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5024 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5028 SetLastError(STATUS_ACCESS_VIOLATION
);
5035 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5036 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5037 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5041 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5042 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5046 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5047 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5048 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5049 sizeof(CERT_ENHKEY_USAGE
),
5050 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5051 CERT_ENHKEY_USAGE
*usage
= pvStructInfo
;
5053 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5054 usage
->rgpszUsageIdentifier
= (LPSTR
*)(usage
+ 1);
5055 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5056 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5060 SetLastError(STATUS_ACCESS_VIOLATION
);
5067 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5068 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5069 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5073 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5074 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5078 struct AsnDecodeSequenceItem items
[] = {
5079 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5080 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5081 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5082 offsetof(CRL_ISSUING_DIST_POINT
,
5083 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5084 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5085 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5087 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5088 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5090 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5091 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5092 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5093 OnlySomeReasonFlags
.pbData
), 0 },
5094 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5095 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5098 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5099 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5100 pcbStructInfo
, NULL
, NULL
);
5104 SetLastError(STATUS_ACCESS_VIOLATION
);
5111 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5112 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5116 DWORD max
, size
= sizeof(max
);
5118 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5119 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5123 SetLastError(CRYPT_E_ASN1_EOD
);
5126 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5128 SetLastError(CRYPT_E_ASN1_BADTAG
);
5131 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5132 &max
, &size
, pcbDecoded
)))
5134 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5137 *pcbStructInfo
= bytesNeeded
;
5138 else if (*pcbStructInfo
< bytesNeeded
)
5140 *pcbStructInfo
= bytesNeeded
;
5141 SetLastError(ERROR_MORE_DATA
);
5146 CERT_GENERAL_SUBTREE
*subtree
= CONTAINING_RECORD(pvStructInfo
,
5147 CERT_GENERAL_SUBTREE
, fMaximum
);
5149 *pcbStructInfo
= bytesNeeded
;
5150 /* The BOOL is implicit: if the integer is present, then it's
5153 subtree
->fMaximum
= TRUE
;
5154 subtree
->dwMaximum
= max
;
5157 TRACE("returning %d\n", ret
);
5161 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5162 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5166 struct AsnDecodeSequenceItem items
[] = {
5167 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5168 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5169 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5170 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5171 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5172 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5173 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5174 TRUE
, FALSE
, 0, 0 },
5176 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5178 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5179 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5181 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5182 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5183 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5186 TRACE("%d\n", *pcbDecoded
);
5187 if (*pcbDecoded
< cbEncoded
)
5188 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5189 *(pbEncoded
+ *pcbDecoded
+ 1));
5191 TRACE("returning %d\n", ret
);
5195 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5196 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5200 struct AsnArrayDescriptor arrayDesc
= { 0,
5201 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5202 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5203 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5205 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5206 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5208 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5209 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5211 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5212 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5216 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5217 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5221 struct AsnArrayDescriptor arrayDesc
= { 0,
5222 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5223 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5224 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5225 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5226 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5228 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5229 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5231 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5232 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5236 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5237 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5238 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5242 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5243 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5247 struct AsnDecodeSequenceItem items
[] = {
5248 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5249 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5250 CRYPT_AsnDecodePermittedSubtree
,
5251 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5252 cExcludedSubtree
), TRUE
, TRUE
,
5253 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5254 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5255 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5256 CRYPT_AsnDecodeExcludedSubtree
,
5257 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5259 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5262 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5263 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5264 pcbStructInfo
, NULL
, NULL
);
5268 SetLastError(STATUS_ACCESS_VIOLATION
);
5274 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5275 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5279 struct AsnDecodeSequenceItem items
[] = {
5280 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5281 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5283 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5284 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5285 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5287 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5289 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5290 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5292 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5293 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5294 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5295 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5297 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5300 TRACE("returning %d\n", ret
);
5304 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5305 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5308 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5309 struct AsnDecodeSequenceItem items
[] = {
5310 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5311 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5312 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5313 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5314 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5315 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5316 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5317 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5318 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5319 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5320 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5321 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5322 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5323 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5324 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5325 HashEncryptionAlgorithm
.pszObjId
), 0 },
5326 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5327 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5328 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5329 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5330 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5331 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5332 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5336 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5337 pvStructInfo
, *pcbStructInfo
);
5339 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5340 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5341 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5345 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5346 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5347 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5351 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5352 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5356 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5357 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5358 if (ret
&& pvStructInfo
)
5360 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5361 pcbStructInfo
, *pcbStructInfo
);
5364 CMSG_SIGNER_INFO
*info
;
5366 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5367 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5368 info
= pvStructInfo
;
5369 info
->Issuer
.pbData
= ((BYTE
*)info
+
5370 sizeof(CMSG_SIGNER_INFO
));
5371 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5372 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5373 pcbStructInfo
, NULL
);
5374 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5375 CRYPT_FreeSpace(pDecodePara
, info
);
5381 SetLastError(STATUS_ACCESS_VIOLATION
);
5384 TRACE("returning %d\n", ret
);
5388 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5389 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5393 struct AsnArrayDescriptor arrayDesc
= { 0,
5394 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5395 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5396 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5397 CRYPT_AsnDecodeCopyBytes
,
5398 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5400 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5401 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5403 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5404 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5408 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5409 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5413 struct AsnArrayDescriptor arrayDesc
= { 0,
5414 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5415 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5416 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5417 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5418 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5420 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5421 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5423 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5424 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5428 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5429 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5432 CERT_ID
*id
= pvStructInfo
;
5435 if (*pbEncoded
== ASN_SEQUENCEOF
)
5437 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5438 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5442 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5443 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5444 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5445 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5447 *pcbStructInfo
= sizeof(CERT_ID
);
5450 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5452 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5453 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5457 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5458 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5459 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5460 sizeof(CRYPT_DATA_BLOB
);
5462 *pcbStructInfo
= sizeof(CERT_ID
);
5466 SetLastError(CRYPT_E_ASN1_BADTAG
);
5470 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5471 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5474 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5475 struct AsnDecodeSequenceItem items
[] = {
5476 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5477 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5478 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5479 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5480 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5481 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5482 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5483 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5484 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5485 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5486 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5487 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5488 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5489 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5490 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5491 HashEncryptionAlgorithm
.pszObjId
), 0 },
5492 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5493 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5494 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5495 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5496 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5497 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5498 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5502 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5503 pvStructInfo
, *pcbStructInfo
);
5505 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5506 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5507 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5511 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5512 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5513 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5517 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5518 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5522 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5523 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5524 if (ret
&& pvStructInfo
)
5526 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5527 pcbStructInfo
, *pcbStructInfo
);
5530 CMSG_CMS_SIGNER_INFO
*info
;
5532 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5533 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5534 info
= pvStructInfo
;
5535 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5536 sizeof(CMSG_CMS_SIGNER_INFO
));
5537 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5538 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5539 pcbStructInfo
, NULL
);
5540 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5541 CRYPT_FreeSpace(pDecodePara
, info
);
5547 SetLastError(STATUS_ACCESS_VIOLATION
);
5550 TRACE("returning %d\n", ret
);
5554 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5555 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5558 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5559 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5560 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5561 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5562 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5563 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5565 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5566 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5568 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5569 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5573 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5574 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5575 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5578 struct AsnDecodeSequenceItem items
[] = {
5579 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5580 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5581 /* Placeholder for the hash algorithms - redundant with those in the
5582 * signers, so just ignore them.
5584 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5585 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5586 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5587 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5588 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5589 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5590 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5591 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5592 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5593 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5594 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5595 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5596 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5597 CRYPT_DecodeSignerArray
,
5598 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5599 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5602 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5603 pDecodePara
, signedInfo
, *pcbSignedInfo
);
5605 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5606 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5608 TRACE("returning %d\n", ret
);
5612 static BOOL
CRYPT_AsnDecodeRecipientInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5613 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5616 CMSG_KEY_TRANS_RECIPIENT_INFO
*info
= pvStructInfo
;
5617 struct AsnDecodeSequenceItem items
[] = {
5618 { ASN_INTEGER
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, dwVersion
),
5619 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5620 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5621 RecipientId
.u
.IssuerSerialNumber
), CRYPT_AsnDecodeIssuerSerialNumber
,
5622 sizeof(CERT_ISSUER_SERIAL_NUMBER
), FALSE
, TRUE
,
5623 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5624 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
), 0 },
5625 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5626 KeyEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5627 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5628 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5629 KeyEncryptionAlgorithm
.pszObjId
), 0 },
5630 { ASN_OCTETSTRING
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
),
5631 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
5632 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
.pbData
), 0 },
5635 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5636 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5638 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5639 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5640 pcbDecoded
, info
? info
->RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
:
5643 info
->RecipientId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5644 TRACE("returning %d\n", ret
);
5648 static BOOL
CRYPT_DecodeRecipientInfoArray(const BYTE
*pbEncoded
,
5649 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5653 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5654 offsetof(CRYPT_ENVELOPED_DATA
, cRecipientInfo
),
5655 offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
),
5656 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5657 CRYPT_AsnDecodeRecipientInfo
, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO
), TRUE
,
5658 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5659 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
) };
5661 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5662 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5664 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5665 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5666 TRACE("returning %d\n", ret
);
5670 static BOOL
CRYPT_AsnDecodeEncryptedContentInfo(const BYTE
*pbEncoded
,
5671 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5675 CRYPT_ENCRYPTED_CONTENT_INFO
*info
= pvStructInfo
;
5676 struct AsnDecodeSequenceItem items
[] = {
5677 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5678 contentType
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
5679 FALSE
, TRUE
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5681 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5682 contentEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5683 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5684 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5685 contentEncryptionAlgorithm
.pszObjId
), 0 },
5686 { ASN_CONTEXT
| 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5687 encryptedContent
), CRYPT_AsnDecodeOctetsInternal
,
5688 sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
5689 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
, encryptedContent
.pbData
) },
5692 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5693 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5695 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5696 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5697 pcbDecoded
, info
? info
->contentType
: NULL
);
5698 TRACE("returning %d\n", ret
);
5702 BOOL
CRYPT_AsnDecodePKCSEnvelopedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5703 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5704 CRYPT_ENVELOPED_DATA
*envelopedData
, DWORD
*pcbEnvelopedData
)
5707 struct AsnDecodeSequenceItem items
[] = {
5708 { ASN_INTEGER
, offsetof(CRYPT_ENVELOPED_DATA
, version
),
5709 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5710 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ENVELOPED_DATA
,
5711 cRecipientInfo
), CRYPT_DecodeRecipientInfoArray
,
5712 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5713 FALSE
, TRUE
, offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
), 0 },
5714 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
),
5715 CRYPT_AsnDecodeEncryptedContentInfo
,
5716 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO
), FALSE
, TRUE
,
5717 offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
.contentType
), 0 },
5720 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5721 pDecodePara
, envelopedData
, *pcbEnvelopedData
);
5723 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5724 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, envelopedData
,
5725 pcbEnvelopedData
, NULL
, NULL
);
5726 TRACE("returning %d\n", ret
);
5730 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5731 LPCSTR lpszStructType
)
5733 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5735 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5736 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5738 SetLastError(ERROR_FILE_NOT_FOUND
);
5741 if (IS_INTOID(lpszStructType
))
5743 switch (LOWORD(lpszStructType
))
5745 case LOWORD(X509_CERT
):
5746 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5748 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5749 decodeFunc
= CRYPT_AsnDecodeCert
;
5751 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5752 decodeFunc
= CRYPT_AsnDecodeCRL
;
5754 case LOWORD(X509_EXTENSIONS
):
5755 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5757 case LOWORD(X509_NAME_VALUE
):
5758 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5760 case LOWORD(X509_NAME
):
5761 decodeFunc
= CRYPT_AsnDecodeName
;
5763 case LOWORD(X509_PUBLIC_KEY_INFO
):
5764 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5766 case LOWORD(X509_AUTHORITY_KEY_ID
):
5767 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5769 case LOWORD(X509_ALTERNATE_NAME
):
5770 decodeFunc
= CRYPT_AsnDecodeAltName
;
5772 case LOWORD(X509_BASIC_CONSTRAINTS
):
5773 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5775 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5776 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5778 case LOWORD(X509_CERT_POLICIES
):
5779 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5781 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5782 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5784 case LOWORD(X509_UNICODE_NAME
):
5785 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5787 case LOWORD(PKCS_ATTRIBUTE
):
5788 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5790 case LOWORD(X509_UNICODE_NAME_VALUE
):
5791 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5793 case LOWORD(X509_OCTET_STRING
):
5794 decodeFunc
= CRYPT_AsnDecodeOctets
;
5796 case LOWORD(X509_BITS
):
5797 case LOWORD(X509_KEY_USAGE
):
5798 decodeFunc
= CRYPT_AsnDecodeBits
;
5800 case LOWORD(X509_INTEGER
):
5801 decodeFunc
= CRYPT_AsnDecodeInt
;
5803 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5804 decodeFunc
= CRYPT_AsnDecodeInteger
;
5806 case LOWORD(X509_MULTI_BYTE_UINT
):
5807 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5809 case LOWORD(X509_ENUMERATED
):
5810 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5812 case LOWORD(X509_CHOICE_OF_TIME
):
5813 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5815 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5816 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5818 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5819 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5821 case LOWORD(PKCS_CONTENT_INFO
):
5822 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5824 case LOWORD(X509_SEQUENCE_OF_ANY
):
5825 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5827 case LOWORD(PKCS_UTC_TIME
):
5828 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5830 case LOWORD(X509_CRL_DIST_POINTS
):
5831 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5833 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5834 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5836 case LOWORD(PKCS_CTL
):
5837 decodeFunc
= CRYPT_AsnDecodeCTL
;
5839 case LOWORD(PKCS_SMIME_CAPABILITIES
):
5840 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5842 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
5843 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5845 case LOWORD(PKCS_ATTRIBUTES
):
5846 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
5848 case LOWORD(X509_ISSUING_DIST_POINT
):
5849 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5851 case LOWORD(X509_NAME_CONSTRAINTS
):
5852 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5854 case LOWORD(X509_POLICY_MAPPINGS
):
5855 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5857 case LOWORD(X509_POLICY_CONSTRAINTS
):
5858 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5860 case LOWORD(PKCS7_SIGNER_INFO
):
5861 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
5863 case LOWORD(CMS_SIGNER_INFO
):
5864 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
5868 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
5869 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5870 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
5871 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5872 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
5873 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5874 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
5875 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5876 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
5877 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5878 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
5879 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5880 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
5881 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5882 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
5883 decodeFunc
= CRYPT_AsnDecodeBits
;
5884 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
5885 decodeFunc
= CRYPT_AsnDecodeOctets
;
5886 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
5887 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5888 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
5889 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5890 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
5891 decodeFunc
= CRYPT_AsnDecodeAltName
;
5892 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
5893 decodeFunc
= CRYPT_AsnDecodeAltName
;
5894 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
5895 decodeFunc
= CRYPT_AsnDecodeAltName
;
5896 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
5897 decodeFunc
= CRYPT_AsnDecodeAltName
;
5898 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
5899 decodeFunc
= CRYPT_AsnDecodeAltName
;
5900 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
5901 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5902 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
5903 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5904 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
5905 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5906 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
5907 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5908 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
5909 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5910 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
5911 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5912 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
5913 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5914 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
5915 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5916 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
5917 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5918 else if (!strcmp(lpszStructType
, szOID_CTL
))
5919 decodeFunc
= CRYPT_AsnDecodeCTL
;
5923 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
5924 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5926 static HCRYPTOIDFUNCSET set
= NULL
;
5927 CryptDecodeObjectFunc decodeFunc
= NULL
;
5930 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
5931 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5932 (void **)&decodeFunc
, hFunc
);
5936 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
5937 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5939 static HCRYPTOIDFUNCSET set
= NULL
;
5940 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5943 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
5944 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5945 (void **)&decodeFunc
, hFunc
);
5949 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5950 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
5951 DWORD
*pcbStructInfo
)
5954 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
5955 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
5956 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5958 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
5959 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
5960 pvStructInfo
, pcbStructInfo
);
5962 if (!pvStructInfo
&& !pcbStructInfo
)
5964 SetLastError(ERROR_INVALID_PARAMETER
);
5967 if (cbEncoded
> MAX_ENCODED_LEN
)
5969 SetLastError(CRYPT_E_ASN1_LARGE
);
5973 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
5976 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5977 debugstr_a(lpszStructType
));
5978 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
5979 lpszStructType
, &hFunc
);
5980 if (!pCryptDecodeObject
)
5981 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
5982 lpszStructType
, &hFunc
);
5984 if (pCryptDecodeObject
)
5985 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5986 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5987 else if (pCryptDecodeObjectEx
)
5988 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
5989 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5990 pvStructInfo
, pcbStructInfo
);
5992 CryptFreeOIDFunctionAddress(hFunc
, 0);
5993 TRACE_(crypt
)("returning %d\n", ret
);
5997 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5998 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5999 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6002 CryptDecodeObjectExFunc decodeFunc
;
6003 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6005 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6006 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
6007 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6009 if (!pvStructInfo
&& !pcbStructInfo
)
6011 SetLastError(ERROR_INVALID_PARAMETER
);
6014 if (cbEncoded
> MAX_ENCODED_LEN
)
6016 SetLastError(CRYPT_E_ASN1_LARGE
);
6020 SetLastError(NOERROR
);
6021 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6025 SetLastError(ERROR_INVALID_PARAMETER
);
6028 *(BYTE
**)pvStructInfo
= NULL
;
6030 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
6033 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6034 debugstr_a(lpszStructType
));
6035 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
6039 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
6040 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6043 CryptDecodeObjectFunc pCryptDecodeObject
=
6044 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
6046 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6047 * directly, as that could cause an infinite loop.
6049 if (pCryptDecodeObject
)
6051 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6053 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6054 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
6055 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
6056 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
6058 ret
= pCryptDecodeObject(dwCertEncodingType
,
6059 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
6060 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
6062 CRYPT_FreeSpace(pDecodePara
, *(BYTE
**)pvStructInfo
);
6066 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6067 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6071 CryptFreeOIDFunctionAddress(hFunc
, 0);
6072 TRACE_(crypt
)("returning %d\n", ret
);
6076 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
6080 TRACE_(crypt
)("(%p)\n", pPFX
);
6082 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6083 * version integer of length 1 (3 encoded byes) and at least one other
6084 * datum (two encoded bytes), plus at least two bytes for the outer
6085 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6087 if (pPFX
->cbData
< 7)
6089 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
6093 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
6095 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
6097 /* Need at least three bytes for the integer version */
6098 if (pPFX
->cbData
< 1 + lenLen
+ 3)
6100 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
6101 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
6102 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
6111 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6114 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);
6118 BOOL WINAPI
PFXVerifyPassword(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6121 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);