2 * Copyright 2005-2009 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
61 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
62 DWORD
, DWORD
, void *, DWORD
*);
63 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
64 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
66 /* Internal decoders don't do memory allocation or exception handling, and
67 * they report how many bytes they decoded.
69 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
70 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
72 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
73 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
75 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
76 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
78 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
80 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
81 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
82 /* Assumes algo->Parameters.pbData is set ahead of time. */
83 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
84 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
85 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
86 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
87 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
88 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
89 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
91 /* Doesn't check the tag, assumes the caller does so */
92 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
93 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
94 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
95 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
96 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
97 * member has been initialized, doesn't do exception handling, and doesn't do
98 * memory allocation. Also doesn't check tag, assumes the caller has checked
101 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
102 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
104 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
105 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
106 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
108 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
109 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
112 /* Gets the number of length bytes from the given (leading) length byte */
113 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
115 /* Helper function to get the encoded length of the data starting at pbEncoded,
116 * where pbEncoded[0] is the tag. If the data are too short to contain a
117 * length or if the length is too large for cbEncoded, sets an appropriate
118 * error code and returns FALSE. If the encoded length is unknown due to
119 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
121 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
128 SetLastError(CRYPT_E_ASN1_CORRUPT
);
131 else if (pbEncoded
[1] <= 0x7f)
133 if (pbEncoded
[1] + 1 > cbEncoded
)
135 SetLastError(CRYPT_E_ASN1_EOD
);
144 else if (pbEncoded
[1] == 0x80)
146 *len
= CMSG_INDEFINITE_LENGTH
;
151 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
153 if (lenLen
> sizeof(DWORD
) + 1)
155 SetLastError(CRYPT_E_ASN1_LARGE
);
158 else if (lenLen
+ 2 > cbEncoded
)
160 SetLastError(CRYPT_E_ASN1_CORRUPT
);
173 if (out
+ lenLen
+ 1 > cbEncoded
)
175 SetLastError(CRYPT_E_ASN1_EOD
);
188 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
189 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
193 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
194 *len
== CMSG_INDEFINITE_LENGTH
)
196 SetLastError(CRYPT_E_ASN1_CORRUPT
);
202 /* Helper function to check *pcbStructInfo, set it to the required size, and
203 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
204 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
205 * pointer to the newly allocated memory.
207 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
208 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
213 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
215 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
216 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
218 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
219 if (!*(BYTE
**)pvStructInfo
)
222 *pcbStructInfo
= bytesNeeded
;
224 else if (*pcbStructInfo
< bytesNeeded
)
226 *pcbStructInfo
= bytesNeeded
;
227 SetLastError(ERROR_MORE_DATA
);
231 *pcbStructInfo
= bytesNeeded
;
235 static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA
*pDecodePara
, LPVOID pv
)
237 if (pDecodePara
&& pDecodePara
->pfnFree
)
238 pDecodePara
->pfnFree(pv
);
243 /* Helper function to check *pcbStructInfo and set it to the required size.
244 * Assumes pvStructInfo is not NULL.
246 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
250 if (*pcbStructInfo
< bytesNeeded
)
252 *pcbStructInfo
= bytesNeeded
;
253 SetLastError(ERROR_MORE_DATA
);
258 *pcbStructInfo
= bytesNeeded
;
265 * The expected tag of the item. If tag is 0, decodeFunc is called
266 * regardless of the tag value seen.
268 * A sequence is decoded into a struct. The offset member is the
269 * offset of this item within that struct.
271 * The decoder function to use. If this is NULL, then the member isn't
272 * decoded, but minSize space is reserved for it.
274 * The minimum amount of space occupied after decoding. You must set this.
276 * If true, and the tag doesn't match the expected tag for this item,
277 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
278 * filled with 0 for this member.
279 * hasPointer, pointerOffset:
280 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
281 * the offset within the struct of the data pointer (or to the
282 * first data pointer, if more than one exist).
284 * Used by CRYPT_AsnDecodeSequence, not for your use.
286 struct AsnDecodeSequenceItem
290 InternalDecodeFunc decodeFunc
;
298 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
299 #define MEMBERSIZE(s, member, nextmember) \
300 (offsetof(s, nextmember) - offsetof(s, member))
302 /* Decodes the items in a sequence, where the items are described in items,
303 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
304 * pvStructInfo. nextData is a pointer to the memory location at which the
305 * first decoded item with a dynamic pointer should point.
306 * Upon decoding, *cbDecoded is the total number of bytes decoded.
307 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
309 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
310 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
311 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
314 DWORD i
, decoded
= 0;
315 const BYTE
*ptr
= pbEncoded
;
317 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
318 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
320 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
322 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
326 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
327 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
329 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
331 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
333 DWORD itemEncodedLen
;
335 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
336 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
338 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
339 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
341 TRACE("Setting next pointer to %p\n",
343 *(BYTE
**)((BYTE
*)pvStructInfo
+
344 items
[i
].pointerOffset
) = nextData
;
346 if (items
[i
].decodeFunc
)
351 TRACE("decoding item %d\n", i
);
353 TRACE("sizing item %d\n", i
);
354 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
355 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
356 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
357 : NULL
, &items
[i
].size
, &itemDecoded
);
360 if (items
[i
].size
< items
[i
].minSize
)
361 items
[i
].size
= items
[i
].minSize
;
362 else if (items
[i
].size
> items
[i
].minSize
)
364 /* Account for alignment padding */
365 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
367 TRACE("item %d size: %d\n", i
, items
[i
].size
);
368 if (nextData
&& items
[i
].hasPointer
&&
369 items
[i
].size
> items
[i
].minSize
)
370 nextData
+= items
[i
].size
- items
[i
].minSize
;
371 if (itemDecoded
> itemEncodedLen
)
373 WARN("decoded length %d exceeds encoded %d\n",
374 itemDecoded
, itemEncodedLen
);
375 SetLastError(CRYPT_E_ASN1_CORRUPT
);
381 decoded
+= itemDecoded
;
382 TRACE("item %d: decoded %d bytes\n", i
,
386 else if (items
[i
].optional
&&
387 GetLastError() == CRYPT_E_ASN1_BADTAG
)
389 TRACE("skipping optional item %d\n", i
);
390 items
[i
].size
= items
[i
].minSize
;
391 SetLastError(NOERROR
);
395 TRACE("item %d failed: %08x\n", i
,
398 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
400 ERR("can't use indefinite length encoding without a decoder\n");
401 SetLastError(CRYPT_E_ASN1_CORRUPT
);
406 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
407 ptr
+= itemEncodedLen
;
408 decoded
+= itemEncodedLen
;
409 items
[i
].size
= items
[i
].minSize
;
412 else if (items
[i
].optional
)
414 TRACE("skipping optional item %d\n", i
);
415 items
[i
].size
= items
[i
].minSize
;
419 TRACE("item %d: tag %02x doesn't match expected %02x\n",
420 i
, ptr
[0], items
[i
].tag
);
421 SetLastError(CRYPT_E_ASN1_BADTAG
);
426 else if (items
[i
].optional
)
428 TRACE("missing optional item %d, skipping\n", i
);
429 items
[i
].size
= items
[i
].minSize
;
433 TRACE("not enough bytes for item %d, failing\n", i
);
434 SetLastError(CRYPT_E_ASN1_CORRUPT
);
439 *cbDecoded
= decoded
;
440 TRACE("returning %d\n", ret
);
444 /* This decodes an arbitrary sequence into a contiguous block of memory
445 * (basically, a struct.) Each element being decoded is described by a struct
446 * AsnDecodeSequenceItem, see above.
447 * startingPointer is an optional pointer to the first place where dynamic
448 * data will be stored. If you know the starting offset, you may pass it
449 * here. Otherwise, pass NULL, and one will be inferred from the items.
451 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
452 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
453 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
454 DWORD
*pcbDecoded
, void *startingPointer
)
458 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
459 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
464 SetLastError(CRYPT_E_ASN1_EOD
);
467 if (pbEncoded
[0] == ASN_SEQUENCE
)
471 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
473 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
474 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
475 BOOL indefinite
= FALSE
;
477 cbEncoded
-= 1 + lenBytes
;
478 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
483 else if (cbEncoded
< dataLen
)
485 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
487 SetLastError(CRYPT_E_ASN1_CORRUPT
);
492 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
493 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
494 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
496 if (cbDecoded
> cbEncoded
- 2)
498 /* Not enough space for 0 TLV */
499 SetLastError(CRYPT_E_ASN1_CORRUPT
);
502 else if (*(ptr
+ cbDecoded
) != 0 ||
503 *(ptr
+ cbDecoded
+ 1) != 0)
505 TRACE("expected 0 TLV\n");
506 SetLastError(CRYPT_E_ASN1_CORRUPT
);
513 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
515 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
517 SetLastError(CRYPT_E_ASN1_CORRUPT
);
522 DWORD i
, bytesNeeded
= 0, structSize
= 0;
524 for (i
= 0; i
< cItem
; i
++)
526 if (items
[i
].size
> items
[i
].minSize
)
527 bytesNeeded
+= items
[i
].size
- items
[i
].minSize
;
528 structSize
= max( structSize
, items
[i
].offset
+ items
[i
].minSize
);
530 bytesNeeded
+= structSize
;
532 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
534 *pcbStructInfo
= bytesNeeded
;
535 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
536 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
540 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
541 pvStructInfo
= *(BYTE
**)pvStructInfo
;
543 nextData
= startingPointer
;
545 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
546 memset(pvStructInfo
, 0, structSize
);
547 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
548 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
550 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
551 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
558 SetLastError(CRYPT_E_ASN1_BADTAG
);
561 TRACE("returning %d (%08x)\n", ret
, GetLastError());
566 * The expected tag of the entire encoded array (usually a variant
567 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
568 * regardless of the tag seen.
570 * The offset within the outer structure at which the count exists.
571 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
572 * while CRYPT_ATTRIBUTE has countOffset ==
573 * offsetof(CRYPT_ATTRIBUTE, cValue).
575 * The offset within the outer structure at which the array pointer exists.
576 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
577 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
579 * The minimum size of the decoded array. On WIN32, this is always 8:
580 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
583 * used to decode each item in the array
585 * is the minimum size of each decoded item
587 * indicates whether each item has a dynamic pointer
589 * indicates the offset within itemSize at which the pointer exists
591 struct AsnArrayDescriptor
597 InternalDecodeFunc decodeFunc
;
603 struct AsnArrayItemSize
609 /* Decodes an array of like types into a structure described by a struct
610 * AsnArrayDescriptor.
612 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
613 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
614 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
619 TRACE("%p, %p, %d, %p, %d\n", arrayDesc
, pbEncoded
,
620 cbEncoded
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
624 SetLastError(CRYPT_E_ASN1_EOD
);
627 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
631 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
633 DWORD bytesNeeded
= arrayDesc
->minArraySize
, cItems
= 0, decoded
;
634 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
635 /* There can be arbitrarily many items, but there is often only one.
637 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
639 decoded
= 1 + lenBytes
;
643 BOOL doneDecoding
= FALSE
;
645 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
647 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
654 SetLastError(CRYPT_E_ASN1_CORRUPT
);
661 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
665 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
667 /* Each item decoded may not tolerate extraneous bytes,
668 * so get the length of the next element if known.
670 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
671 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
673 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
674 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
676 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
680 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
681 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
686 if (itemSizes
!= &itemSize
)
687 itemSizes
= CryptMemRealloc(itemSizes
,
688 cItems
* sizeof(struct AsnArrayItemSize
));
693 cItems
* sizeof(struct AsnArrayItemSize
));
695 memcpy(itemSizes
, &itemSize
,
700 decoded
+= itemDecoded
;
701 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
702 itemSizes
[cItems
- 1].size
= size
;
715 *pcbDecoded
= decoded
;
717 *pcbStructInfo
= bytesNeeded
;
718 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
719 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
726 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
727 pvStructInfo
= *(void **)pvStructInfo
;
728 pcItems
= pvStructInfo
;
730 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
732 rgItems
= (BYTE
*)pvStructInfo
+
733 arrayDesc
->minArraySize
;
734 *(void **)((BYTE
*)pcItems
-
735 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
) =
739 rgItems
= *(void **)((BYTE
*)pcItems
-
740 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
);
741 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
742 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
743 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
748 if (arrayDesc
->hasPointer
)
749 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
750 + arrayDesc
->pointerOffset
) = nextData
;
751 ret
= arrayDesc
->decodeFunc(ptr
,
752 itemSizes
[i
].encodedLen
,
753 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
754 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
755 &itemSizes
[i
].size
, &itemDecoded
);
758 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
762 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
763 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
766 if (itemSizes
!= &itemSize
)
767 CryptMemFree(itemSizes
);
772 SetLastError(CRYPT_E_ASN1_BADTAG
);
778 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
779 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
780 * to CRYPT_E_ASN1_CORRUPT.
781 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
784 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
785 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
790 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
792 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
793 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
795 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
796 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
799 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
801 *pcbStructInfo
= bytesNeeded
;
802 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
804 CRYPT_DER_BLOB
*blob
;
806 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
807 pvStructInfo
= *(BYTE
**)pvStructInfo
;
809 blob
->cbData
= 1 + lenBytes
+ dataLen
;
812 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
813 blob
->pbData
= (BYTE
*)pbEncoded
;
816 assert(blob
->pbData
);
817 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
822 SetLastError(CRYPT_E_ASN1_CORRUPT
);
830 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
831 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
832 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
837 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
838 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
840 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
843 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
844 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
846 if (ret
&& pvStructInfo
)
848 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
855 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
857 temp
= blob
->pbData
[i
];
858 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
859 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
863 TRACE("returning %d (%08x)\n", ret
, GetLastError());
867 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
868 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
869 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
873 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
874 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
878 struct AsnDecodeSequenceItem items
[] = {
879 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
880 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
881 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
882 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
883 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
884 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
885 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
886 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
887 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
888 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
891 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
892 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
893 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
894 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
895 pcbStructInfo
, NULL
, NULL
);
899 SetLastError(STATUS_ACCESS_VIOLATION
);
904 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
908 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
909 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
914 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
916 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
918 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
919 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
921 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
926 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
927 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
931 struct AsnDecodeSequenceItem items
[] = {
932 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
933 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
934 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
935 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
938 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
939 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
944 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
945 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
949 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
950 offsetof(CERT_INFO
, cExtension
), offsetof(CERT_INFO
, rgExtension
),
951 FINALMEMBERSIZE(CERT_INFO
, cExtension
),
952 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
953 offsetof(CERT_EXTENSION
, pszObjId
) };
955 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
956 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
958 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
959 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
963 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
964 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
970 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
972 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
974 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
975 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
976 if (ret
&& pcbDecoded
)
977 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
982 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
983 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
984 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
987 struct AsnDecodeSequenceItem items
[] = {
988 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
989 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
990 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
991 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
992 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
993 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
994 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
995 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
996 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
997 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
999 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
1000 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
1002 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
1003 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1005 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
1006 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
1007 FALSE
, TRUE
, offsetof(CERT_INFO
,
1008 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
1009 { ASN_CONTEXT
| 1, offsetof(CERT_INFO
, IssuerUniqueId
),
1010 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1011 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
1012 { ASN_CONTEXT
| 2, offsetof(CERT_INFO
, SubjectUniqueId
),
1013 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1014 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
1015 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
1016 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
1017 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1020 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1021 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1023 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1024 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1026 if (ret
&& pvStructInfo
)
1030 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1031 info
= *(CERT_INFO
**)pvStructInfo
;
1033 info
= pvStructInfo
;
1034 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1035 !info
->Subject
.cbData
)
1037 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1038 /* Don't need to deallocate, because it should have failed on the
1039 * first pass (and no memory was allocated.)
1045 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1049 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1050 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1051 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1055 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1056 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1062 /* Unless told not to, first try to decode it as a signed cert. */
1063 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1065 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1067 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1068 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1069 &signedCert
, &size
);
1073 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1074 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1075 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1076 pvStructInfo
, pcbStructInfo
);
1077 LocalFree(signedCert
);
1080 /* Failing that, try it as an unsigned cert */
1084 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1085 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1086 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1091 SetLastError(STATUS_ACCESS_VIOLATION
);
1095 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1099 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1100 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1104 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1105 offsetof(CRL_ENTRY
, cExtension
), offsetof(CRL_ENTRY
, rgExtension
),
1106 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
),
1107 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1108 offsetof(CERT_EXTENSION
, pszObjId
) };
1110 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1111 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1113 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1114 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1118 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1119 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1122 struct AsnDecodeSequenceItem items
[] = {
1123 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1124 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1125 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1126 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1127 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1128 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1129 CRYPT_AsnDecodeCRLEntryExtensions
,
1130 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1131 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1133 PCRL_ENTRY entry
= pvStructInfo
;
1135 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1138 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1139 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1140 entry
? entry
->SerialNumber
.pbData
: NULL
);
1141 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1143 WARN("empty CRL entry serial number\n");
1144 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1150 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1151 * whose rgCRLEntry member has been set prior to calling.
1153 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1154 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1157 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1158 offsetof(CRL_INFO
, cCRLEntry
), offsetof(CRL_INFO
, rgCRLEntry
),
1159 MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1160 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1161 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1163 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1164 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1166 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1167 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1168 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1172 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1173 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1177 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1178 offsetof(CRL_INFO
, cExtension
), offsetof(CRL_INFO
, rgExtension
),
1179 FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1180 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1181 offsetof(CERT_EXTENSION
, pszObjId
) };
1183 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1184 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1186 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1187 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1191 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1192 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1198 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1200 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1202 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1203 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1204 if (ret
&& pcbDecoded
)
1205 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1210 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1211 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1212 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1214 struct AsnDecodeSequenceItem items
[] = {
1215 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1216 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1217 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1218 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1219 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1220 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1221 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1223 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1224 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1225 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1226 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1227 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1228 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1229 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1230 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1231 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1232 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1236 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1237 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1239 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1240 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1243 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1247 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1248 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1249 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1253 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1254 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1260 /* Unless told not to, first try to decode it as a signed crl. */
1261 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1263 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1265 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1266 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1271 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1272 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1273 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1274 pvStructInfo
, pcbStructInfo
);
1275 LocalFree(signedCrl
);
1278 /* Failing that, try it as an unsigned crl */
1282 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1283 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1284 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1289 SetLastError(STATUS_ACCESS_VIOLATION
);
1293 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1297 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1298 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1303 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1304 pvStructInfo
, *pcbStructInfo
);
1306 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1308 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1309 DWORD bytesNeeded
= sizeof(LPSTR
);
1316 snprintf(str
, sizeof(str
), "%d.%d",
1317 pbEncoded
[1 + lenBytes
] / 40,
1318 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1320 bytesNeeded
+= strlen(str
) + 1;
1321 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1322 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1326 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1333 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1336 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1343 snprintf(str
, sizeof(str
), ".%d", val
);
1344 bytesNeeded
+= strlen(str
);
1349 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1351 *pcbStructInfo
= bytesNeeded
;
1352 else if (*pcbStructInfo
< bytesNeeded
)
1354 *pcbStructInfo
= bytesNeeded
;
1355 SetLastError(ERROR_MORE_DATA
);
1363 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1366 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1367 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1369 pszObjId
+= strlen(pszObjId
);
1370 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1371 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1375 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1384 sprintf(pszObjId
, ".%d", val
);
1385 pszObjId
+= strlen(pszObjId
);
1389 *(LPSTR
*)pvStructInfo
= NULL
;
1390 *pcbStructInfo
= bytesNeeded
;
1396 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1397 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1401 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1402 pvStructInfo
, *pcbStructInfo
);
1404 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1405 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1406 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1409 SetLastError(CRYPT_E_ASN1_BADTAG
);
1415 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1416 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1418 struct AsnDecodeSequenceItem items
[] = {
1419 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1420 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1421 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1422 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1423 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1424 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1425 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1426 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1429 PCERT_EXTENSION ext
= pvStructInfo
;
1431 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1435 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1436 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1437 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1438 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1440 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1441 debugstr_a(ext
->pszObjId
));
1442 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1446 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1447 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1448 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1452 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1453 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1457 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1458 offsetof(CERT_EXTENSIONS
, cExtension
),
1459 offsetof(CERT_EXTENSIONS
, rgExtension
),
1460 sizeof(CERT_EXTENSIONS
),
1461 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1462 offsetof(CERT_EXTENSION
, pszObjId
) };
1463 CERT_EXTENSIONS
*exts
= pvStructInfo
;
1465 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1466 exts
->rgExtension
= (CERT_EXTENSION
*)(exts
+ 1);
1467 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1468 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1472 SetLastError(STATUS_ACCESS_VIOLATION
);
1479 /* Warning: this assumes the address of value->Value.pbData is already set, in
1480 * order to avoid overwriting memory. (In some cases, it may change it, if it
1481 * doesn't copy anything to memory.) Be sure to set it correctly!
1483 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1484 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1489 CERT_NAME_VALUE
*value
= pvStructInfo
;
1491 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1493 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1494 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1496 switch (pbEncoded
[0])
1498 case ASN_OCTETSTRING
:
1499 valueType
= CERT_RDN_OCTET_STRING
;
1500 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1501 bytesNeeded
+= dataLen
;
1503 case ASN_NUMERICSTRING
:
1504 valueType
= CERT_RDN_NUMERIC_STRING
;
1505 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1506 bytesNeeded
+= dataLen
;
1508 case ASN_PRINTABLESTRING
:
1509 valueType
= CERT_RDN_PRINTABLE_STRING
;
1510 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1511 bytesNeeded
+= dataLen
;
1514 valueType
= CERT_RDN_IA5_STRING
;
1515 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1516 bytesNeeded
+= dataLen
;
1519 valueType
= CERT_RDN_T61_STRING
;
1520 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1521 bytesNeeded
+= dataLen
;
1523 case ASN_VIDEOTEXSTRING
:
1524 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1525 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1526 bytesNeeded
+= dataLen
;
1528 case ASN_GRAPHICSTRING
:
1529 valueType
= CERT_RDN_GRAPHIC_STRING
;
1530 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1531 bytesNeeded
+= dataLen
;
1533 case ASN_VISIBLESTRING
:
1534 valueType
= CERT_RDN_VISIBLE_STRING
;
1535 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1536 bytesNeeded
+= dataLen
;
1538 case ASN_GENERALSTRING
:
1539 valueType
= CERT_RDN_GENERAL_STRING
;
1540 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1541 bytesNeeded
+= dataLen
;
1543 case ASN_UNIVERSALSTRING
:
1544 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1545 SetLastError(CRYPT_E_ASN1_BADTAG
);
1548 valueType
= CERT_RDN_BMP_STRING
;
1549 bytesNeeded
+= dataLen
;
1551 case ASN_UTF8STRING
:
1552 valueType
= CERT_RDN_UTF8_STRING
;
1553 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1554 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1557 SetLastError(CRYPT_E_ASN1_BADTAG
);
1562 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1564 *pcbStructInfo
= bytesNeeded
;
1565 else if (*pcbStructInfo
< bytesNeeded
)
1567 *pcbStructInfo
= bytesNeeded
;
1568 SetLastError(ERROR_MORE_DATA
);
1573 *pcbStructInfo
= bytesNeeded
;
1574 value
->dwValueType
= valueType
;
1579 assert(value
->Value
.pbData
);
1580 switch (pbEncoded
[0])
1582 case ASN_OCTETSTRING
:
1583 case ASN_NUMERICSTRING
:
1584 case ASN_PRINTABLESTRING
:
1587 case ASN_VIDEOTEXSTRING
:
1588 case ASN_GRAPHICSTRING
:
1589 case ASN_VISIBLESTRING
:
1590 case ASN_GENERALSTRING
:
1591 value
->Value
.cbData
= dataLen
;
1594 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1595 memcpy(value
->Value
.pbData
,
1596 pbEncoded
+ 1 + lenBytes
, dataLen
);
1598 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1604 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1606 value
->Value
.cbData
= dataLen
;
1607 for (i
= 0; i
< dataLen
/ 2; i
++)
1608 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1609 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1612 case ASN_UTF8STRING
:
1614 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1616 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1617 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1618 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1625 value
->Value
.cbData
= 0;
1626 value
->Value
.pbData
= NULL
;
1633 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1634 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1635 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1641 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1642 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1643 if (ret
&& pvStructInfo
)
1645 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1646 pcbStructInfo
, *pcbStructInfo
);
1649 CERT_NAME_VALUE
*value
;
1651 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1652 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1653 value
= pvStructInfo
;
1654 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1655 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1656 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1657 pcbStructInfo
, NULL
);
1658 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1659 CRYPT_FreeSpace(pDecodePara
, value
);
1665 SetLastError(STATUS_ACCESS_VIOLATION
);
1672 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1673 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1678 CERT_NAME_VALUE
*value
= pvStructInfo
;
1680 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1682 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1683 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1685 switch (pbEncoded
[0])
1687 case ASN_NUMERICSTRING
:
1688 valueType
= CERT_RDN_NUMERIC_STRING
;
1690 bytesNeeded
+= (dataLen
+ 1) * 2;
1692 case ASN_PRINTABLESTRING
:
1693 valueType
= CERT_RDN_PRINTABLE_STRING
;
1695 bytesNeeded
+= (dataLen
+ 1) * 2;
1698 valueType
= CERT_RDN_IA5_STRING
;
1700 bytesNeeded
+= (dataLen
+ 1) * 2;
1703 valueType
= CERT_RDN_T61_STRING
;
1705 bytesNeeded
+= (dataLen
+ 1) * 2;
1707 case ASN_VIDEOTEXSTRING
:
1708 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1710 bytesNeeded
+= (dataLen
+ 1) * 2;
1712 case ASN_GRAPHICSTRING
:
1713 valueType
= CERT_RDN_GRAPHIC_STRING
;
1715 bytesNeeded
+= (dataLen
+ 1) * 2;
1717 case ASN_VISIBLESTRING
:
1718 valueType
= CERT_RDN_VISIBLE_STRING
;
1720 bytesNeeded
+= (dataLen
+ 1) * 2;
1722 case ASN_GENERALSTRING
:
1723 valueType
= CERT_RDN_GENERAL_STRING
;
1725 bytesNeeded
+= (dataLen
+ 1) * 2;
1727 case ASN_UNIVERSALSTRING
:
1728 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1730 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1733 valueType
= CERT_RDN_BMP_STRING
;
1735 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1737 case ASN_UTF8STRING
:
1738 valueType
= CERT_RDN_UTF8_STRING
;
1740 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1741 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1744 SetLastError(CRYPT_E_ASN1_BADTAG
);
1749 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1751 *pcbStructInfo
= bytesNeeded
;
1752 else if (*pcbStructInfo
< bytesNeeded
)
1754 *pcbStructInfo
= bytesNeeded
;
1755 SetLastError(ERROR_MORE_DATA
);
1760 *pcbStructInfo
= bytesNeeded
;
1761 value
->dwValueType
= valueType
;
1765 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1767 assert(value
->Value
.pbData
);
1768 switch (pbEncoded
[0])
1770 case ASN_NUMERICSTRING
:
1771 case ASN_PRINTABLESTRING
:
1774 case ASN_VIDEOTEXSTRING
:
1775 case ASN_GRAPHICSTRING
:
1776 case ASN_VISIBLESTRING
:
1777 case ASN_GENERALSTRING
:
1778 value
->Value
.cbData
= dataLen
* 2;
1779 for (i
= 0; i
< dataLen
; i
++)
1780 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1783 case ASN_UNIVERSALSTRING
:
1784 value
->Value
.cbData
= dataLen
/ 2;
1785 for (i
= 0; i
< dataLen
/ 4; i
++)
1786 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1787 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1791 value
->Value
.cbData
= dataLen
;
1792 for (i
= 0; i
< dataLen
/ 2; i
++)
1793 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1794 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1797 case ASN_UTF8STRING
:
1798 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1799 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1800 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1801 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1802 value
->Value
.cbData
+= sizeof(WCHAR
);
1808 value
->Value
.cbData
= 0;
1809 value
->Value
.pbData
= NULL
;
1816 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1817 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1818 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1824 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1825 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1826 if (ret
&& pvStructInfo
)
1828 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1829 pcbStructInfo
, *pcbStructInfo
);
1832 CERT_NAME_VALUE
*value
;
1834 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1835 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1836 value
= pvStructInfo
;
1837 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1838 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1839 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1840 pcbStructInfo
, NULL
);
1841 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1842 CRYPT_FreeSpace(pDecodePara
, value
);
1848 SetLastError(STATUS_ACCESS_VIOLATION
);
1855 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1856 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1859 struct AsnDecodeSequenceItem items
[] = {
1860 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1861 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1862 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1863 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1864 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1865 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1867 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1869 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1870 pvStructInfo
, *pcbStructInfo
);
1873 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1874 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1875 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1876 attr
? attr
->pszObjId
: NULL
);
1879 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1880 debugstr_a(attr
->pszObjId
));
1881 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1883 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1887 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1888 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1891 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1892 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1894 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1895 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1897 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1898 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1902 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1903 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1904 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1910 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1911 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1912 sizeof(CERT_NAME_INFO
),
1913 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1914 offsetof(CERT_RDN
, rgRDNAttr
) };
1917 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1918 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1923 *pcbStructInfo
= bytesNeeded
;
1924 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1925 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1927 CERT_NAME_INFO
*info
;
1929 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1930 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1931 info
= pvStructInfo
;
1932 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1933 sizeof(CERT_NAME_INFO
));
1934 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1935 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1936 &bytesNeeded
, NULL
);
1937 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1938 CRYPT_FreeSpace(pDecodePara
, info
);
1944 SetLastError(STATUS_ACCESS_VIOLATION
);
1951 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1952 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1956 struct AsnDecodeSequenceItem items
[] = {
1957 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1958 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1959 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1960 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1961 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1962 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1964 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1966 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1967 pvStructInfo
, *pcbStructInfo
);
1970 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1971 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1972 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1973 attr
? attr
->pszObjId
: NULL
);
1976 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1977 debugstr_a(attr
->pszObjId
));
1978 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1980 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1984 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1985 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1988 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1989 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1991 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1992 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1994 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1995 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1999 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
2000 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2001 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2007 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2008 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2009 sizeof(CERT_NAME_INFO
),
2010 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2011 offsetof(CERT_RDN
, rgRDNAttr
) };
2014 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2015 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2020 *pcbStructInfo
= bytesNeeded
;
2021 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2022 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2024 CERT_NAME_INFO
*info
;
2026 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2027 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2028 info
= pvStructInfo
;
2029 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2030 sizeof(CERT_NAME_INFO
));
2031 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2032 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2033 &bytesNeeded
, NULL
);
2034 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2035 CRYPT_FreeSpace(pDecodePara
, info
);
2041 SetLastError(STATUS_ACCESS_VIOLATION
);
2048 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2051 BOOL ret
= TRUE
, done
= FALSE
;
2052 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2054 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2061 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2064 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2066 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2068 indefiniteNestingLevels
++;
2069 pbEncoded
+= 1 + lenBytes
;
2070 cbEncoded
-= 1 + lenBytes
;
2071 decoded
+= 1 + lenBytes
;
2072 TRACE("indefiniteNestingLevels = %d\n",
2073 indefiniteNestingLevels
);
2077 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2078 indefiniteNestingLevels
)
2080 indefiniteNestingLevels
--;
2081 TRACE("indefiniteNestingLevels = %d\n",
2082 indefiniteNestingLevels
);
2084 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2085 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2086 decoded
+= 1 + lenBytes
+ dataLen
;
2087 if (!indefiniteNestingLevels
)
2091 } while (ret
&& !done
);
2092 /* If we haven't found all 0 TLVs, we haven't found the end */
2093 if (ret
&& indefiniteNestingLevels
)
2095 SetLastError(CRYPT_E_ASN1_EOD
);
2099 *pcbDecoded
= decoded
;
2100 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2104 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2105 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2109 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2111 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2112 pvStructInfo
, *pcbStructInfo
);
2114 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2116 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2117 bytesNeeded
+= encodedLen
;
2119 *pcbStructInfo
= bytesNeeded
;
2120 else if (*pcbStructInfo
< bytesNeeded
)
2122 SetLastError(ERROR_MORE_DATA
);
2123 *pcbStructInfo
= bytesNeeded
;
2128 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2130 *pcbStructInfo
= bytesNeeded
;
2131 blob
->cbData
= encodedLen
;
2134 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2135 blob
->pbData
= (LPBYTE
)pbEncoded
;
2138 assert(blob
->pbData
);
2139 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2143 blob
->pbData
= NULL
;
2146 *pcbDecoded
= encodedLen
;
2151 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2152 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2155 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2156 offsetof(CTL_USAGE
, cUsageIdentifier
),
2157 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2159 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2161 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2162 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2166 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2167 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2170 struct AsnArrayDescriptor arrayDesc
= { 0,
2171 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2172 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2173 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2174 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2177 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2178 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2182 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2183 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2185 struct AsnDecodeSequenceItem items
[] = {
2186 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2187 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2188 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2189 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2190 CRYPT_AsnDecodeCTLEntryAttributes
,
2191 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2192 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2195 CTL_ENTRY
*entry
= pvStructInfo
;
2197 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2200 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2201 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2202 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2206 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2207 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2210 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2211 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2212 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2213 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2214 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2216 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2217 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2219 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2220 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2224 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2225 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2229 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2230 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2231 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2232 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2233 offsetof(CERT_EXTENSION
, pszObjId
) };
2235 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2236 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2238 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2239 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2243 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2244 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2250 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2252 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2254 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2255 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2256 if (ret
&& pcbDecoded
)
2257 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2262 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2263 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2264 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2268 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2269 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2273 struct AsnDecodeSequenceItem items
[] = {
2274 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2275 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2276 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2277 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2278 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2279 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2280 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2281 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2282 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2283 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2284 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2285 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2286 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2288 { 0, offsetof(CTL_INFO
, NextUpdate
),
2289 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2291 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2292 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2293 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2294 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2295 CRYPT_AsnDecodeCTLEntries
,
2296 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2297 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2298 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2299 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2300 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2303 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2304 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2305 pcbStructInfo
, NULL
, NULL
);
2309 SetLastError(STATUS_ACCESS_VIOLATION
);
2315 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2316 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2320 struct AsnDecodeSequenceItem items
[] = {
2321 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2322 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2323 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2324 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2325 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2326 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2328 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2330 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2331 pvStructInfo
, *pcbStructInfo
);
2333 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2334 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2335 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2336 TRACE("returning %d\n", ret
);
2340 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2341 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2342 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2346 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2347 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2351 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2352 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2353 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2354 sizeof(CRYPT_SMIME_CAPABILITIES
),
2355 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2356 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2357 CRYPT_SMIME_CAPABILITIES
*capabilities
= pvStructInfo
;
2359 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2360 capabilities
->rgCapability
= (CRYPT_SMIME_CAPABILITY
*)(capabilities
+ 1);
2361 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2362 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2366 SetLastError(STATUS_ACCESS_VIOLATION
);
2369 TRACE("returning %d\n", ret
);
2373 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2374 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2379 LPSTR
*pStr
= pvStructInfo
;
2381 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2383 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2384 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2386 if (pbEncoded
[0] != ASN_IA5STRING
)
2388 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2393 bytesNeeded
+= dataLen
;
2395 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2397 *pcbStructInfo
= bytesNeeded
;
2398 else if (*pcbStructInfo
< bytesNeeded
)
2400 *pcbStructInfo
= bytesNeeded
;
2401 SetLastError(ERROR_MORE_DATA
);
2406 *pcbStructInfo
= bytesNeeded
;
2412 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2423 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2424 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2427 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2428 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2429 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2430 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2431 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2434 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2435 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2437 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2438 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2439 TRACE("returning %d\n", ret
);
2443 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2444 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2448 struct AsnDecodeSequenceItem items
[] = {
2449 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2450 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2451 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2452 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2453 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2454 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2455 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2456 rgNoticeNumbers
), 0 },
2460 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2461 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2463 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2464 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2468 /* The caller is expecting a pointer to a
2469 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2470 * CRYPT_AsnDecodeSequence is decoding a
2471 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2472 * needed, and decode again if the requisite space is available.
2474 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2476 *pcbStructInfo
= bytesNeeded
;
2477 else if (*pcbStructInfo
< bytesNeeded
)
2479 *pcbStructInfo
= bytesNeeded
;
2480 SetLastError(ERROR_MORE_DATA
);
2485 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2487 *pcbStructInfo
= bytesNeeded
;
2488 /* The pointer (pvStructInfo) passed in points to the first dynamic
2489 * pointer, so use it as the pointer to the
2490 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2491 * appropriate offset for the first dynamic pointer within the
2492 * notice reference by pointing to the first memory location past
2493 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2496 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2497 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2498 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2499 ret
= CRYPT_AsnDecodeSequence(items
,
2500 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2501 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2502 noticeRef
->pszOrganization
);
2505 TRACE("returning %d\n", ret
);
2509 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2510 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2516 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2518 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2519 DWORD bytesNeeded
= sizeof(LPWSTR
);
2521 switch (pbEncoded
[0])
2523 case ASN_NUMERICSTRING
:
2525 bytesNeeded
+= (dataLen
+ 1) * 2;
2527 case ASN_PRINTABLESTRING
:
2529 bytesNeeded
+= (dataLen
+ 1) * 2;
2533 bytesNeeded
+= (dataLen
+ 1) * 2;
2537 bytesNeeded
+= (dataLen
+ 1) * 2;
2539 case ASN_VIDEOTEXSTRING
:
2541 bytesNeeded
+= (dataLen
+ 1) * 2;
2543 case ASN_GRAPHICSTRING
:
2545 bytesNeeded
+= (dataLen
+ 1) * 2;
2547 case ASN_VISIBLESTRING
:
2549 bytesNeeded
+= (dataLen
+ 1) * 2;
2551 case ASN_GENERALSTRING
:
2553 bytesNeeded
+= (dataLen
+ 1) * 2;
2555 case ASN_UNIVERSALSTRING
:
2557 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2561 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2563 case ASN_UTF8STRING
:
2565 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2566 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2569 SetLastError(CRYPT_E_ASN1_BADTAG
);
2574 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2576 *pcbStructInfo
= bytesNeeded
;
2577 else if (*pcbStructInfo
< bytesNeeded
)
2579 *pcbStructInfo
= bytesNeeded
;
2580 SetLastError(ERROR_MORE_DATA
);
2585 LPWSTR
*pStr
= pvStructInfo
;
2587 *pcbStructInfo
= bytesNeeded
;
2591 LPWSTR str
= *(LPWSTR
*)pStr
;
2594 switch (pbEncoded
[0])
2596 case ASN_NUMERICSTRING
:
2597 case ASN_PRINTABLESTRING
:
2600 case ASN_VIDEOTEXSTRING
:
2601 case ASN_GRAPHICSTRING
:
2602 case ASN_VISIBLESTRING
:
2603 case ASN_GENERALSTRING
:
2604 for (i
= 0; i
< dataLen
; i
++)
2605 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2608 case ASN_UNIVERSALSTRING
:
2609 for (i
= 0; i
< dataLen
/ 4; i
++)
2610 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2611 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2615 for (i
= 0; i
< dataLen
/ 2; i
++)
2616 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2617 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2620 case ASN_UTF8STRING
:
2622 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2623 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2624 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2637 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2638 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2639 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2642 struct AsnDecodeSequenceItem items
[] = {
2643 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2644 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2645 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2646 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2647 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2648 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2649 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2651 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2653 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2654 pvStructInfo
, *pcbStructInfo
);
2656 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2657 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2658 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2659 TRACE("returning %d\n", ret
);
2663 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2664 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2665 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2666 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2670 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2671 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2677 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2678 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2683 *pcbStructInfo
= bytesNeeded
;
2684 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2685 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2687 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2689 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2690 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2691 notice
= pvStructInfo
;
2692 notice
->pNoticeReference
=
2693 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2694 ((BYTE
*)pvStructInfo
+
2695 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2696 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2697 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2698 pvStructInfo
, &bytesNeeded
, NULL
);
2699 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2700 CRYPT_FreeSpace(pDecodePara
, notice
);
2706 SetLastError(STATUS_ACCESS_VIOLATION
);
2709 TRACE("returning %d\n", ret
);
2713 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2714 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2718 struct AsnArrayDescriptor arrayDesc
= { 0,
2719 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2720 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2721 CRYPT_AsnDecodeCopyBytes
,
2722 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2724 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2725 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2727 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2728 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2732 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2733 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2737 struct AsnDecodeSequenceItem items
[] = {
2738 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2739 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2740 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2741 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2742 CRYPT_AsnDecodePKCSAttributeValue
,
2743 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2744 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2746 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2748 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2749 pvStructInfo
, *pcbStructInfo
);
2751 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2752 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2753 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2754 TRACE("returning %d\n", ret
);
2758 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2759 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2760 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2764 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2765 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2771 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2772 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2776 *pcbStructInfo
= bytesNeeded
;
2777 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2778 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2780 PCRYPT_ATTRIBUTE attr
;
2782 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2783 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2784 attr
= pvStructInfo
;
2785 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2786 sizeof(CRYPT_ATTRIBUTE
));
2787 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2788 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2790 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2791 CRYPT_FreeSpace(pDecodePara
, attr
);
2797 SetLastError(STATUS_ACCESS_VIOLATION
);
2800 TRACE("returning %d\n", ret
);
2804 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2805 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2808 struct AsnArrayDescriptor arrayDesc
= { 0,
2809 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2810 sizeof(CRYPT_ATTRIBUTES
),
2811 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2812 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2815 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2816 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2820 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2821 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2822 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2826 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2827 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2831 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2832 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2833 sizeof(CRYPT_ATTRIBUTES
),
2834 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2835 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2836 CRYPT_ATTRIBUTES
*attrs
= pvStructInfo
;
2838 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2839 attrs
->rgAttr
= (CRYPT_ATTRIBUTE
*)(attrs
+ 1);
2840 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2841 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2845 SetLastError(STATUS_ACCESS_VIOLATION
);
2848 TRACE("returning %d\n", ret
);
2852 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2853 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2855 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2857 struct AsnDecodeSequenceItem items
[] = {
2858 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2859 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2860 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2861 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2862 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2863 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2866 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2867 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2869 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2870 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2871 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2872 if (ret
&& pvStructInfo
)
2874 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2875 debugstr_a(algo
->pszObjId
));
2880 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2881 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2885 struct AsnDecodeSequenceItem items
[] = {
2886 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2887 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2888 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2889 Algorithm
.pszObjId
) },
2890 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2891 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2892 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2894 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2896 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2897 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2898 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2902 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2903 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2904 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2912 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2913 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2916 *pcbStructInfo
= bytesNeeded
;
2917 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2918 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2920 PCERT_PUBLIC_KEY_INFO info
;
2922 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2923 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2924 info
= pvStructInfo
;
2925 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2926 sizeof(CERT_PUBLIC_KEY_INFO
);
2927 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2928 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2929 &bytesNeeded
, NULL
);
2930 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2931 CRYPT_FreeSpace(pDecodePara
, info
);
2937 SetLastError(STATUS_ACCESS_VIOLATION
);
2944 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2945 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2951 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2954 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2956 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2959 if (pbEncoded
[1] > 1)
2961 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2968 *pcbStructInfo
= sizeof(BOOL
);
2971 else if (*pcbStructInfo
< sizeof(BOOL
))
2973 *pcbStructInfo
= sizeof(BOOL
);
2974 SetLastError(ERROR_MORE_DATA
);
2979 *pcbStructInfo
= sizeof(BOOL
);
2980 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2983 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2987 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2988 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2990 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2991 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2994 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2995 pvStructInfo
, *pcbStructInfo
);
2999 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3002 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3003 if (1 + lenBytes
> cbEncoded
)
3005 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3008 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3010 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3012 case 1: /* rfc822Name */
3013 case 2: /* dNSName */
3014 case 6: /* uniformResourceIdentifier */
3015 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
3017 SetLastError(CRYPT_E_ASN1_RULE
);
3021 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3023 case 4: /* directoryName */
3024 case 7: /* iPAddress */
3025 bytesNeeded
+= dataLen
;
3027 case 8: /* registeredID */
3028 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3032 /* FIXME: ugly, shouldn't need to know internals of OID decode
3033 * function to use it.
3035 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3038 case 0: /* otherName */
3039 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3040 SetLastError(CRYPT_E_ASN1_BADTAG
);
3043 case 3: /* x400Address, unimplemented */
3044 case 5: /* ediPartyName, unimplemented */
3045 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3046 SetLastError(CRYPT_E_ASN1_BADTAG
);
3050 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3051 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3057 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3059 *pcbStructInfo
= bytesNeeded
;
3060 else if (*pcbStructInfo
< bytesNeeded
)
3062 *pcbStructInfo
= bytesNeeded
;
3063 SetLastError(ERROR_MORE_DATA
);
3068 *pcbStructInfo
= bytesNeeded
;
3069 /* MS used values one greater than the asn1 ones.. sigh */
3070 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3071 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3073 case 1: /* rfc822Name */
3074 case 2: /* dNSName */
3075 case 6: /* uniformResourceIdentifier */
3079 for (i
= 0; i
< dataLen
; i
++)
3080 entry
->u
.pwszURL
[i
] =
3081 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3082 entry
->u
.pwszURL
[i
] = 0;
3083 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3084 debugstr_w(entry
->u
.pwszURL
));
3087 case 4: /* directoryName */
3088 /* The data are memory-equivalent with the IPAddress case,
3091 case 7: /* iPAddress */
3092 /* The next data pointer is in the pwszURL spot, that is,
3093 * the first 4 bytes. Need to move it to the next spot.
3095 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3096 entry
->u
.IPAddress
.cbData
= dataLen
;
3097 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3100 case 8: /* registeredID */
3101 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3102 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3111 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3112 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3116 struct AsnArrayDescriptor arrayDesc
= { 0,
3117 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3118 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3119 sizeof(CERT_ALT_NAME_INFO
),
3120 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3121 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3123 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3124 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3126 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3127 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3131 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3132 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3133 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3139 struct AsnDecodeSequenceItem items
[] = {
3140 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3141 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3142 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3143 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3144 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3145 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3146 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3147 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3148 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3149 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3150 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3153 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3154 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3155 pcbStructInfo
, NULL
, NULL
);
3159 SetLastError(STATUS_ACCESS_VIOLATION
);
3166 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3167 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3168 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3174 struct AsnDecodeSequenceItem items
[] = {
3175 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3176 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3177 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3178 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3179 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3180 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3181 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3182 AuthorityCertIssuer
.rgAltEntry
), 0 },
3183 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3184 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3185 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3186 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3187 AuthorityCertSerialNumber
.pbData
), 0 },
3190 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3191 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3192 pcbStructInfo
, NULL
, NULL
);
3196 SetLastError(STATUS_ACCESS_VIOLATION
);
3203 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3204 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3207 struct AsnDecodeSequenceItem items
[] = {
3208 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3209 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3210 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3211 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3212 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3213 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3215 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3217 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3218 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3219 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3222 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3223 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3224 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3228 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3229 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3233 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3234 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3235 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3236 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3237 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3238 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3239 CERT_AUTHORITY_INFO_ACCESS
*info
= pvStructInfo
;
3241 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3242 info
->rgAccDescr
= (CERT_ACCESS_DESCRIPTION
*)(info
+ 1);
3243 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3244 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3248 SetLastError(STATUS_ACCESS_VIOLATION
);
3255 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3256 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3261 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3262 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3264 /* The caller has already checked the tag, no need to check it again.
3265 * Check the outer length is valid:
3267 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3269 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3272 pbEncoded
+= 1 + lenBytes
;
3273 cbEncoded
-= 1 + lenBytes
;
3274 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3275 cbEncoded
-= 2; /* space for 0 TLV */
3276 /* Check the inner length is valid: */
3277 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3281 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3282 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3283 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3285 if (*(pbEncoded
+ decodedLen
) != 0 ||
3286 *(pbEncoded
+ decodedLen
+ 1) != 0)
3288 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3289 *(pbEncoded
+ decodedLen
),
3290 *(pbEncoded
+ decodedLen
+ 1));
3291 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3297 if (ret
&& pcbDecoded
)
3299 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3300 TRACE("decoded %d bytes\n", *pcbDecoded
);
3307 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3308 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3311 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3312 struct AsnDecodeSequenceItem items
[] = {
3313 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3314 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3315 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3316 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3317 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3318 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3319 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3323 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3324 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3326 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3327 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3328 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3332 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3333 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3334 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3338 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3339 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3343 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3344 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3345 if (ret
&& pvStructInfo
)
3347 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3348 pcbStructInfo
, *pcbStructInfo
);
3351 CRYPT_CONTENT_INFO
*info
;
3353 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3354 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3355 info
= pvStructInfo
;
3356 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3357 sizeof(CRYPT_CONTENT_INFO
));
3358 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3359 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3360 pcbStructInfo
, NULL
);
3361 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3362 CRYPT_FreeSpace(pDecodePara
, info
);
3368 SetLastError(STATUS_ACCESS_VIOLATION
);
3374 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3375 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3376 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3379 struct AsnDecodeSequenceItem items
[] = {
3380 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3381 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3382 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3383 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3384 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3386 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3387 CRYPT_AsnDecodePKCSContentInfoInternal
,
3388 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3389 ContentInfo
.pszObjId
), 0 },
3390 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3391 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3392 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3395 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3396 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3401 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3402 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3403 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3407 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3408 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3414 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3415 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3418 *pcbStructInfo
= bytesNeeded
;
3419 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3420 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3422 CERT_ALT_NAME_INFO
*name
;
3424 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3425 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3426 name
= pvStructInfo
;
3427 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3428 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3429 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3430 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3431 &bytesNeeded
, NULL
);
3432 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3433 CRYPT_FreeSpace(pDecodePara
, name
);
3439 SetLastError(STATUS_ACCESS_VIOLATION
);
3446 struct PATH_LEN_CONSTRAINT
3448 BOOL fPathLenConstraint
;
3449 DWORD dwPathLenConstraint
;
3452 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3453 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3457 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3459 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3460 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3464 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3466 *pcbStructInfo
= bytesNeeded
;
3468 else if (*pcbStructInfo
< bytesNeeded
)
3470 SetLastError(ERROR_MORE_DATA
);
3471 *pcbStructInfo
= bytesNeeded
;
3476 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3478 *pcbStructInfo
= bytesNeeded
;
3479 size
= sizeof(constraint
->dwPathLenConstraint
);
3480 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3481 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3483 constraint
->fPathLenConstraint
= TRUE
;
3484 TRACE("got an int, dwPathLenConstraint is %d\n",
3485 constraint
->dwPathLenConstraint
);
3487 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3491 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3492 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3496 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3497 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3498 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3499 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3500 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3501 offsetof(CERT_NAME_BLOB
, pbData
) };
3503 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3504 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3506 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3507 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3508 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3512 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3513 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3514 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3520 struct AsnDecodeSequenceItem items
[] = {
3521 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3522 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3523 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3524 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3525 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3526 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3527 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3528 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3529 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3531 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3534 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3535 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3536 pcbStructInfo
, NULL
, NULL
);
3540 SetLastError(STATUS_ACCESS_VIOLATION
);
3547 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3548 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3549 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3555 struct AsnDecodeSequenceItem items
[] = {
3556 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3557 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3558 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3559 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3560 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3563 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3564 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3565 pcbStructInfo
, NULL
, NULL
);
3569 SetLastError(STATUS_ACCESS_VIOLATION
);
3576 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3577 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3580 struct AsnDecodeSequenceItem items
[] = {
3581 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3582 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3583 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3585 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3586 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3587 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3590 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3592 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3593 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3595 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3596 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3597 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3601 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3602 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3606 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3607 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3608 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3609 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3610 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3611 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3613 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3614 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3616 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3617 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3618 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3622 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3623 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3625 struct AsnDecodeSequenceItem items
[] = {
3626 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3627 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3628 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3629 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3630 CRYPT_AsnDecodePolicyQualifiers
,
3631 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3632 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3634 CERT_POLICY_INFO
*info
= pvStructInfo
;
3637 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3638 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3640 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3641 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3642 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3646 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3647 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3648 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3652 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3653 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3657 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3658 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3659 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3660 sizeof(CERT_POLICIES_INFO
),
3661 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3662 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3663 CERT_POLICIES_INFO
*info
= pvStructInfo
;
3665 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3666 info
->rgPolicyInfo
= (CERT_POLICY_INFO
*)(info
+ 1);
3668 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3669 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3673 SetLastError(STATUS_ACCESS_VIOLATION
);
3679 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3680 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3683 struct AsnDecodeSequenceItem items
[] = {
3684 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3685 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3686 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3687 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3688 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3689 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3691 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3694 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3695 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3697 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3698 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3699 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3703 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3704 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3705 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3709 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3710 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3714 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3715 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3716 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3717 sizeof(CERT_POLICY_MAPPING
),
3718 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3719 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3720 CERT_POLICY_MAPPINGS_INFO
*info
= pvStructInfo
;
3722 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3723 info
->rgPolicyMapping
= (CERT_POLICY_MAPPING
*)(info
+ 1);
3724 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3725 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3729 SetLastError(STATUS_ACCESS_VIOLATION
);
3735 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3736 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3740 DWORD skip
, size
= sizeof(skip
);
3744 SetLastError(CRYPT_E_ASN1_EOD
);
3747 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3749 SetLastError(CRYPT_E_ASN1_BADTAG
);
3752 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3753 &skip
, &size
, pcbDecoded
)))
3755 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3756 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3759 *pcbStructInfo
= bytesNeeded
;
3760 else if (*pcbStructInfo
< bytesNeeded
)
3762 *pcbStructInfo
= bytesNeeded
;
3763 SetLastError(ERROR_MORE_DATA
);
3768 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3769 CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
);
3771 *pcbStructInfo
= bytesNeeded
;
3772 /* The BOOL is implicit: if the integer is present, then it's
3775 info
->fRequireExplicitPolicy
= TRUE
;
3776 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3782 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3783 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3787 DWORD skip
, size
= sizeof(skip
);
3791 SetLastError(CRYPT_E_ASN1_EOD
);
3794 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3796 SetLastError(CRYPT_E_ASN1_BADTAG
);
3799 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3800 &skip
, &size
, pcbDecoded
)))
3802 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3803 fInhibitPolicyMapping
);
3806 *pcbStructInfo
= bytesNeeded
;
3807 else if (*pcbStructInfo
< bytesNeeded
)
3809 *pcbStructInfo
= bytesNeeded
;
3810 SetLastError(ERROR_MORE_DATA
);
3815 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3816 CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
);
3818 *pcbStructInfo
= bytesNeeded
;
3819 /* The BOOL is implicit: if the integer is present, then it's
3822 info
->fInhibitPolicyMapping
= TRUE
;
3823 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3829 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3830 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3831 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3832 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3836 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3837 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3841 struct AsnDecodeSequenceItem items
[] = {
3843 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3844 CRYPT_AsnDecodeRequireExplicit
,
3845 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3846 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3848 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3849 CRYPT_AsnDecodeInhibitMapping
,
3850 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3851 TRUE
, FALSE
, 0, 0 },
3854 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3855 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3856 pcbStructInfo
, NULL
, NULL
);
3860 SetLastError(STATUS_ACCESS_VIOLATION
);
3866 #define RSA1_MAGIC 0x31415352
3868 struct DECODED_RSA_PUB_KEY
3871 CRYPT_INTEGER_BLOB modulus
;
3874 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3875 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3876 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3882 struct AsnDecodeSequenceItem items
[] = {
3883 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3884 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3885 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3887 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3888 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3890 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3893 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3894 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3898 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3899 decodedKey
->modulus
.cbData
;
3903 *pcbStructInfo
= bytesNeeded
;
3906 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3907 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3910 RSAPUBKEY
*rsaPubKey
;
3912 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3913 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3915 hdr
->bType
= PUBLICKEYBLOB
;
3916 hdr
->bVersion
= CUR_BLOB_VERSION
;
3918 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3919 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3920 sizeof(BLOBHEADER
));
3921 rsaPubKey
->magic
= RSA1_MAGIC
;
3922 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3923 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3924 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3925 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3926 decodedKey
->modulus
.cbData
);
3928 LocalFree(decodedKey
);
3933 SetLastError(STATUS_ACCESS_VIOLATION
);
3940 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3941 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3945 DWORD bytesNeeded
, dataLen
;
3947 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3948 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3950 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3952 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3954 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3955 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3957 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3959 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3961 *pcbStructInfo
= bytesNeeded
;
3962 else if (*pcbStructInfo
< bytesNeeded
)
3964 SetLastError(ERROR_MORE_DATA
);
3965 *pcbStructInfo
= bytesNeeded
;
3970 CRYPT_DATA_BLOB
*blob
;
3972 *pcbStructInfo
= bytesNeeded
;
3973 blob
= pvStructInfo
;
3974 blob
->cbData
= dataLen
;
3975 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3976 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3979 assert(blob
->pbData
);
3981 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3989 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3990 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3991 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3995 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3996 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4004 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4007 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
4009 SetLastError(CRYPT_E_ASN1_BADTAG
);
4012 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4013 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4016 *pcbStructInfo
= bytesNeeded
;
4017 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4018 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4020 CRYPT_DATA_BLOB
*blob
;
4022 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4023 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4024 blob
= pvStructInfo
;
4025 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4026 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4027 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4028 &bytesNeeded
, NULL
);
4029 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4030 CRYPT_FreeSpace(pDecodePara
, blob
);
4036 SetLastError(STATUS_ACCESS_VIOLATION
);
4043 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4044 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4047 DWORD bytesNeeded
, dataLen
;
4048 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4050 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4051 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4053 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4055 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4056 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4058 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4060 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4062 *pcbStructInfo
= bytesNeeded
;
4063 else if (*pcbStructInfo
< bytesNeeded
)
4065 *pcbStructInfo
= bytesNeeded
;
4066 SetLastError(ERROR_MORE_DATA
);
4071 CRYPT_BIT_BLOB
*blob
;
4073 *pcbStructInfo
= bytesNeeded
;
4074 blob
= pvStructInfo
;
4075 blob
->cbData
= dataLen
- 1;
4076 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4077 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4079 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4083 assert(blob
->pbData
);
4086 BYTE mask
= 0xff << blob
->cUnusedBits
;
4088 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4090 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4098 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4099 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4100 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4104 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4105 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4113 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4116 else if (pbEncoded
[0] != ASN_BITSTRING
)
4118 SetLastError(CRYPT_E_ASN1_BADTAG
);
4121 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4122 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4125 *pcbStructInfo
= bytesNeeded
;
4126 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4127 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4129 CRYPT_BIT_BLOB
*blob
;
4131 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4132 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4133 blob
= pvStructInfo
;
4134 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4135 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4136 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4137 &bytesNeeded
, NULL
);
4138 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4139 CRYPT_FreeSpace(pDecodePara
, blob
);
4145 SetLastError(STATUS_ACCESS_VIOLATION
);
4149 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4153 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4154 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4155 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4160 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4162 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4165 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4166 if (dataLen
> sizeof(int))
4168 SetLastError(CRYPT_E_ASN1_LARGE
);
4171 else if (!pvStructInfo
)
4172 *pcbStructInfo
= sizeof(int);
4173 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4177 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4179 /* initialize to a negative value to sign-extend */
4184 for (i
= 0; i
< dataLen
; i
++)
4187 val
|= pbEncoded
[1 + lenBytes
+ i
];
4189 memcpy(pvStructInfo
, &val
, sizeof(int));
4195 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4196 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4197 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4207 SetLastError(CRYPT_E_ASN1_EOD
);
4210 else if (pbEncoded
[0] != ASN_INTEGER
)
4212 SetLastError(CRYPT_E_ASN1_BADTAG
);
4216 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4217 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4221 *pcbStructInfo
= bytesNeeded
;
4222 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4223 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4225 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4226 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4227 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4228 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4229 &bytesNeeded
, NULL
);
4230 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4231 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4237 SetLastError(STATUS_ACCESS_VIOLATION
);
4244 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4245 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4249 DWORD bytesNeeded
, dataLen
;
4251 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4253 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4255 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4257 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4259 *pcbStructInfo
= bytesNeeded
;
4260 else if (*pcbStructInfo
< bytesNeeded
)
4262 *pcbStructInfo
= bytesNeeded
;
4263 SetLastError(ERROR_MORE_DATA
);
4268 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4270 *pcbStructInfo
= bytesNeeded
;
4271 blob
->cbData
= dataLen
;
4272 assert(blob
->pbData
);
4277 for (i
= 0; i
< blob
->cbData
; i
++)
4279 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4288 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4289 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4290 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4298 if (pbEncoded
[0] != ASN_INTEGER
)
4300 SetLastError(CRYPT_E_ASN1_BADTAG
);
4304 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4305 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4309 *pcbStructInfo
= bytesNeeded
;
4310 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4311 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4313 CRYPT_INTEGER_BLOB
*blob
;
4315 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4316 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4317 blob
= pvStructInfo
;
4318 blob
->pbData
= (BYTE
*)pvStructInfo
+
4319 sizeof(CRYPT_INTEGER_BLOB
);
4320 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4321 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4322 &bytesNeeded
, NULL
);
4323 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4324 CRYPT_FreeSpace(pDecodePara
, blob
);
4330 SetLastError(STATUS_ACCESS_VIOLATION
);
4337 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4338 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4343 if (pbEncoded
[0] == ASN_INTEGER
)
4345 DWORD bytesNeeded
, dataLen
;
4347 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4349 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4352 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4353 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4355 *pcbStructInfo
= bytesNeeded
;
4356 else if (*pcbStructInfo
< bytesNeeded
)
4358 *pcbStructInfo
= bytesNeeded
;
4359 SetLastError(ERROR_MORE_DATA
);
4364 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4366 *pcbStructInfo
= bytesNeeded
;
4367 blob
->cbData
= dataLen
;
4368 assert(blob
->pbData
);
4369 /* remove leading zero byte if it exists */
4370 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4379 for (i
= 0; i
< blob
->cbData
; i
++)
4381 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4390 SetLastError(CRYPT_E_ASN1_BADTAG
);
4396 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4397 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4398 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4406 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4407 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4410 *pcbStructInfo
= bytesNeeded
;
4411 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4412 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4414 CRYPT_INTEGER_BLOB
*blob
;
4416 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4417 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4418 blob
= pvStructInfo
;
4419 blob
->pbData
= (BYTE
*)pvStructInfo
+
4420 sizeof(CRYPT_INTEGER_BLOB
);
4421 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4422 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4423 &bytesNeeded
, NULL
);
4424 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4425 CRYPT_FreeSpace(pDecodePara
, blob
);
4431 SetLastError(STATUS_ACCESS_VIOLATION
);
4438 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4439 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4440 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4446 *pcbStructInfo
= sizeof(int);
4451 if (pbEncoded
[0] == ASN_ENUMERATED
)
4453 unsigned int val
= 0, i
;
4457 SetLastError(CRYPT_E_ASN1_EOD
);
4460 else if (pbEncoded
[1] == 0)
4462 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4467 /* A little strange looking, but we have to accept a sign byte:
4468 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4469 * assuming a small length is okay here, it has to be in short
4472 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4474 SetLastError(CRYPT_E_ASN1_LARGE
);
4477 for (i
= 0; i
< pbEncoded
[1]; i
++)
4480 val
|= pbEncoded
[2 + i
];
4482 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4483 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4485 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4486 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4487 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4493 SetLastError(CRYPT_E_ASN1_BADTAG
);
4499 SetLastError(STATUS_ACCESS_VIOLATION
);
4506 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4509 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4514 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4516 if (!isdigit(*(pbEncoded))) \
4518 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4524 (word) += *(pbEncoded)++ - '0'; \
4529 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4530 SYSTEMTIME
*sysTime
)
4534 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4536 WORD hours
, minutes
= 0;
4537 BYTE sign
= *pbEncoded
++;
4540 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4541 if (ret
&& hours
>= 24)
4543 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4548 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4549 if (ret
&& minutes
>= 60)
4551 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4559 sysTime
->wHour
+= hours
;
4560 sysTime
->wMinute
+= minutes
;
4564 if (hours
> sysTime
->wHour
)
4567 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4570 sysTime
->wHour
-= hours
;
4571 if (minutes
> sysTime
->wMinute
)
4574 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4577 sysTime
->wMinute
-= minutes
;
4584 #define MIN_ENCODED_TIME_LENGTH 10
4586 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4587 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4592 if (pbEncoded
[0] == ASN_UTCTIME
)
4595 SetLastError(CRYPT_E_ASN1_EOD
);
4596 else if (pbEncoded
[1] > 0x7f)
4598 /* long-form date strings really can't be valid */
4599 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4603 SYSTEMTIME sysTime
= { 0 };
4604 BYTE len
= pbEncoded
[1];
4606 if (len
< MIN_ENCODED_TIME_LENGTH
)
4607 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4612 *pcbDecoded
= 2 + len
;
4614 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4615 if (sysTime
.wYear
>= 50)
4616 sysTime
.wYear
+= 1900;
4618 sysTime
.wYear
+= 2000;
4619 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4620 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4621 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4622 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4625 if (len
>= 2 && isdigit(*pbEncoded
) &&
4626 isdigit(*(pbEncoded
+ 1)))
4627 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4629 else if (isdigit(*pbEncoded
))
4630 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4633 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4639 *pcbStructInfo
= sizeof(FILETIME
);
4640 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4642 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4648 SetLastError(CRYPT_E_ASN1_BADTAG
);
4652 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4653 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4654 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4662 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4663 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4667 *pcbStructInfo
= bytesNeeded
;
4668 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4669 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4671 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4672 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4673 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4674 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4675 &bytesNeeded
, NULL
);
4676 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4677 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4683 SetLastError(STATUS_ACCESS_VIOLATION
);
4689 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4690 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4695 if (pbEncoded
[0] == ASN_GENERALTIME
)
4698 SetLastError(CRYPT_E_ASN1_EOD
);
4699 else if (pbEncoded
[1] > 0x7f)
4701 /* long-form date strings really can't be valid */
4702 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4706 BYTE len
= pbEncoded
[1];
4708 if (len
< MIN_ENCODED_TIME_LENGTH
)
4709 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4712 SYSTEMTIME sysTime
= { 0 };
4716 *pcbDecoded
= 2 + len
;
4718 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4719 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4720 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4721 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4724 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4727 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4729 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4736 /* workaround macro weirdness */
4737 digits
= min(len
, 3);
4738 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4739 sysTime
.wMilliseconds
);
4742 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4748 *pcbStructInfo
= sizeof(FILETIME
);
4749 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4751 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4757 SetLastError(CRYPT_E_ASN1_BADTAG
);
4761 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4762 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4766 InternalDecodeFunc decode
= NULL
;
4768 if (pbEncoded
[0] == ASN_UTCTIME
)
4769 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4770 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4771 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4773 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4774 pcbStructInfo
, pcbDecoded
);
4777 SetLastError(CRYPT_E_ASN1_BADTAG
);
4783 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4784 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4785 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4793 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4794 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4798 *pcbStructInfo
= bytesNeeded
;
4799 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4800 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4802 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4803 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4804 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4805 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4806 &bytesNeeded
, NULL
);
4807 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4808 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4814 SetLastError(STATUS_ACCESS_VIOLATION
);
4821 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4822 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4823 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4829 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4831 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4833 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4838 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4839 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4841 ptr
= pbEncoded
+ 1 + lenBytes
;
4842 remainingLen
= dataLen
;
4843 while (ret
&& remainingLen
)
4847 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4850 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4852 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4853 ptr
+= 1 + nextLenBytes
+ nextLen
;
4854 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4855 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4856 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4862 CRYPT_SEQUENCE_OF_ANY
*seq
;
4867 *pcbStructInfo
= bytesNeeded
;
4868 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4869 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4871 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4872 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4874 seq
->cValue
= cValue
;
4875 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4877 nextPtr
= (BYTE
*)seq
->rgValue
+
4878 cValue
* sizeof(CRYPT_DER_BLOB
);
4879 ptr
= pbEncoded
+ 1 + lenBytes
;
4880 remainingLen
= dataLen
;
4882 while (ret
&& remainingLen
)
4886 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4889 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4891 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4893 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4894 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4897 seq
->rgValue
[i
].pbData
= nextPtr
;
4898 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4900 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4902 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4903 ptr
+= 1 + nextLenBytes
+ nextLen
;
4907 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4908 CRYPT_FreeSpace(pDecodePara
, seq
);
4915 SetLastError(CRYPT_E_ASN1_BADTAG
);
4921 SetLastError(STATUS_ACCESS_VIOLATION
);
4928 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4929 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4934 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4936 DWORD bytesNeeded
, dataLen
;
4938 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4940 struct AsnArrayDescriptor arrayDesc
= {
4941 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4942 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
4943 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
4944 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
4945 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4946 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4947 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4952 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4953 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4954 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
4955 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4956 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
4959 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4961 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4963 *pcbStructInfo
= bytesNeeded
;
4964 else if (*pcbStructInfo
< bytesNeeded
)
4966 *pcbStructInfo
= bytesNeeded
;
4967 SetLastError(ERROR_MORE_DATA
);
4972 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
4974 *pcbStructInfo
= bytesNeeded
;
4977 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4978 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4979 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4980 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
4984 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4990 SetLastError(CRYPT_E_ASN1_BADTAG
);
4996 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4997 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4999 struct AsnDecodeSequenceItem items
[] = {
5000 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
5001 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5002 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
5003 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5004 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
5005 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
5006 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
5007 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
5008 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
5009 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
5011 CRL_DIST_POINT
*point
= pvStructInfo
;
5014 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5015 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5016 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5020 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5021 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5022 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5026 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5027 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5031 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5032 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
5033 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
5034 sizeof(CRL_DIST_POINTS_INFO
),
5035 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5036 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5037 CRL_DIST_POINTS_INFO
*info
= pvStructInfo
;
5039 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5040 info
->rgDistPoint
= (CRL_DIST_POINT
*)(info
+ 1);
5041 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5042 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5046 SetLastError(STATUS_ACCESS_VIOLATION
);
5053 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5054 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5055 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5059 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5060 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5064 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5065 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5066 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5067 sizeof(CERT_ENHKEY_USAGE
),
5068 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5069 CERT_ENHKEY_USAGE
*usage
= pvStructInfo
;
5071 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5072 usage
->rgpszUsageIdentifier
= (LPSTR
*)(usage
+ 1);
5073 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5074 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5078 SetLastError(STATUS_ACCESS_VIOLATION
);
5085 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5086 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5087 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5091 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5092 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5096 struct AsnDecodeSequenceItem items
[] = {
5097 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5098 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5099 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5100 offsetof(CRL_ISSUING_DIST_POINT
,
5101 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5102 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5103 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5105 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5106 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5108 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5109 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5110 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5111 OnlySomeReasonFlags
.pbData
), 0 },
5112 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5113 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5116 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5117 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5118 pcbStructInfo
, NULL
, NULL
);
5122 SetLastError(STATUS_ACCESS_VIOLATION
);
5129 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5130 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5134 DWORD max
, size
= sizeof(max
);
5136 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5137 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5141 SetLastError(CRYPT_E_ASN1_EOD
);
5144 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5146 SetLastError(CRYPT_E_ASN1_BADTAG
);
5149 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5150 &max
, &size
, pcbDecoded
)))
5152 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5155 *pcbStructInfo
= bytesNeeded
;
5156 else if (*pcbStructInfo
< bytesNeeded
)
5158 *pcbStructInfo
= bytesNeeded
;
5159 SetLastError(ERROR_MORE_DATA
);
5164 CERT_GENERAL_SUBTREE
*subtree
= CONTAINING_RECORD(pvStructInfo
,
5165 CERT_GENERAL_SUBTREE
, fMaximum
);
5167 *pcbStructInfo
= bytesNeeded
;
5168 /* The BOOL is implicit: if the integer is present, then it's
5171 subtree
->fMaximum
= TRUE
;
5172 subtree
->dwMaximum
= max
;
5175 TRACE("returning %d\n", ret
);
5179 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5180 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5184 struct AsnDecodeSequenceItem items
[] = {
5185 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5186 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5187 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5188 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5189 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5190 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5191 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5192 TRUE
, FALSE
, 0, 0 },
5194 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5196 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5197 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5199 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5200 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5201 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5204 TRACE("%d\n", *pcbDecoded
);
5205 if (*pcbDecoded
< cbEncoded
)
5206 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5207 *(pbEncoded
+ *pcbDecoded
+ 1));
5209 TRACE("returning %d\n", ret
);
5213 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5214 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5218 struct AsnArrayDescriptor arrayDesc
= { 0,
5219 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5220 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5221 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5223 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5224 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5226 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5227 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5229 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5230 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5234 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5235 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5239 struct AsnArrayDescriptor arrayDesc
= { 0,
5240 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5241 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5242 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5243 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5244 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5246 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5247 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5249 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5250 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5254 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5255 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5256 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5260 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5261 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5265 struct AsnDecodeSequenceItem items
[] = {
5266 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5267 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5268 CRYPT_AsnDecodePermittedSubtree
,
5269 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5270 cExcludedSubtree
), TRUE
, TRUE
,
5271 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5272 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5273 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5274 CRYPT_AsnDecodeExcludedSubtree
,
5275 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5277 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5280 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5281 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5282 pcbStructInfo
, NULL
, NULL
);
5286 SetLastError(STATUS_ACCESS_VIOLATION
);
5292 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5293 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5297 struct AsnDecodeSequenceItem items
[] = {
5298 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5299 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5301 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5302 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5303 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5305 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5307 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5308 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5310 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5311 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5312 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5313 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5315 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5318 TRACE("returning %d\n", ret
);
5322 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5323 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5326 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5327 struct AsnDecodeSequenceItem items
[] = {
5328 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5329 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5330 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5331 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5332 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5333 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5334 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5335 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5336 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5337 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5338 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5339 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5340 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5341 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5342 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5343 HashEncryptionAlgorithm
.pszObjId
), 0 },
5344 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5345 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5346 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5347 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5348 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5349 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5350 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5354 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5355 pvStructInfo
, *pcbStructInfo
);
5357 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5358 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5359 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5363 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5364 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5365 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5369 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5370 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5374 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5375 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5376 if (ret
&& pvStructInfo
)
5378 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5379 pcbStructInfo
, *pcbStructInfo
);
5382 CMSG_SIGNER_INFO
*info
;
5384 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5385 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5386 info
= pvStructInfo
;
5387 info
->Issuer
.pbData
= ((BYTE
*)info
+
5388 sizeof(CMSG_SIGNER_INFO
));
5389 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5390 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5391 pcbStructInfo
, NULL
);
5392 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5393 CRYPT_FreeSpace(pDecodePara
, info
);
5399 SetLastError(STATUS_ACCESS_VIOLATION
);
5402 TRACE("returning %d\n", ret
);
5406 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5407 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5411 struct AsnArrayDescriptor arrayDesc
= { 0,
5412 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5413 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5414 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5415 CRYPT_AsnDecodeCopyBytes
,
5416 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5418 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5419 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5421 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5422 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5426 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5427 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5431 struct AsnArrayDescriptor arrayDesc
= { 0,
5432 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5433 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5434 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5435 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5436 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5438 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5439 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5441 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5442 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5446 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5447 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5450 CERT_ID
*id
= pvStructInfo
;
5453 if (*pbEncoded
== ASN_SEQUENCEOF
)
5455 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5456 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5460 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5461 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5462 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5463 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5465 *pcbStructInfo
= sizeof(CERT_ID
);
5468 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5470 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5471 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5475 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5476 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5477 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5478 sizeof(CRYPT_DATA_BLOB
);
5480 *pcbStructInfo
= sizeof(CERT_ID
);
5484 SetLastError(CRYPT_E_ASN1_BADTAG
);
5488 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5489 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5492 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5493 struct AsnDecodeSequenceItem items
[] = {
5494 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5495 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5496 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5497 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5498 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5499 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5500 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5501 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5502 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5503 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5504 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5505 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5506 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5507 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5508 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5509 HashEncryptionAlgorithm
.pszObjId
), 0 },
5510 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5511 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5512 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5513 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5514 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5515 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5516 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5520 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5521 pvStructInfo
, *pcbStructInfo
);
5523 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5524 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5525 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5529 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5530 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5531 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5535 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5536 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5540 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5541 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5542 if (ret
&& pvStructInfo
)
5544 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5545 pcbStructInfo
, *pcbStructInfo
);
5548 CMSG_CMS_SIGNER_INFO
*info
;
5550 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5551 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5552 info
= pvStructInfo
;
5553 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5554 sizeof(CMSG_CMS_SIGNER_INFO
));
5555 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5556 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5557 pcbStructInfo
, NULL
);
5558 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5559 CRYPT_FreeSpace(pDecodePara
, info
);
5565 SetLastError(STATUS_ACCESS_VIOLATION
);
5568 TRACE("returning %d\n", ret
);
5572 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5573 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5576 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5577 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5578 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5579 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5580 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5581 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5583 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5584 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5586 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5587 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5591 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5592 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5593 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5596 struct AsnDecodeSequenceItem items
[] = {
5597 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5598 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5599 /* Placeholder for the hash algorithms - redundant with those in the
5600 * signers, so just ignore them.
5602 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5603 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5604 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5605 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5606 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5607 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5608 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5609 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5610 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5611 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5612 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5613 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5614 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5615 CRYPT_DecodeSignerArray
,
5616 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5617 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5620 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5621 pDecodePara
, signedInfo
, *pcbSignedInfo
);
5623 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5624 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5626 TRACE("returning %d\n", ret
);
5630 static BOOL
CRYPT_AsnDecodeRecipientInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5631 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5634 CMSG_KEY_TRANS_RECIPIENT_INFO
*info
= pvStructInfo
;
5635 struct AsnDecodeSequenceItem items
[] = {
5636 { ASN_INTEGER
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, dwVersion
),
5637 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5638 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5639 RecipientId
.u
.IssuerSerialNumber
), CRYPT_AsnDecodeIssuerSerialNumber
,
5640 sizeof(CERT_ISSUER_SERIAL_NUMBER
), FALSE
, TRUE
,
5641 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5642 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
), 0 },
5643 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5644 KeyEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5645 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5646 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5647 KeyEncryptionAlgorithm
.pszObjId
), 0 },
5648 { ASN_OCTETSTRING
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
),
5649 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
5650 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
.pbData
), 0 },
5653 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5654 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5656 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5657 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5658 pcbDecoded
, info
? info
->RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
:
5661 info
->RecipientId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5662 TRACE("returning %d\n", ret
);
5666 static BOOL
CRYPT_DecodeRecipientInfoArray(const BYTE
*pbEncoded
,
5667 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5671 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5672 offsetof(CRYPT_ENVELOPED_DATA
, cRecipientInfo
),
5673 offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
),
5674 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5675 CRYPT_AsnDecodeRecipientInfo
, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO
), TRUE
,
5676 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5677 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
) };
5679 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5680 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5682 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5683 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5684 TRACE("returning %d\n", ret
);
5688 static BOOL
CRYPT_AsnDecodeEncryptedContentInfo(const BYTE
*pbEncoded
,
5689 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5693 CRYPT_ENCRYPTED_CONTENT_INFO
*info
= pvStructInfo
;
5694 struct AsnDecodeSequenceItem items
[] = {
5695 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5696 contentType
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
5697 FALSE
, TRUE
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5699 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5700 contentEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5701 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5702 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5703 contentEncryptionAlgorithm
.pszObjId
), 0 },
5704 { ASN_CONTEXT
| 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5705 encryptedContent
), CRYPT_AsnDecodeOctetsInternal
,
5706 sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
5707 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
, encryptedContent
.pbData
) },
5710 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5711 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5713 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5714 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5715 pcbDecoded
, info
? info
->contentType
: NULL
);
5716 TRACE("returning %d\n", ret
);
5720 BOOL
CRYPT_AsnDecodePKCSEnvelopedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5721 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5722 CRYPT_ENVELOPED_DATA
*envelopedData
, DWORD
*pcbEnvelopedData
)
5725 struct AsnDecodeSequenceItem items
[] = {
5726 { ASN_INTEGER
, offsetof(CRYPT_ENVELOPED_DATA
, version
),
5727 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5728 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ENVELOPED_DATA
,
5729 cRecipientInfo
), CRYPT_DecodeRecipientInfoArray
,
5730 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5731 FALSE
, TRUE
, offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
), 0 },
5732 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
),
5733 CRYPT_AsnDecodeEncryptedContentInfo
,
5734 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO
), FALSE
, TRUE
,
5735 offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
.contentType
), 0 },
5738 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5739 pDecodePara
, envelopedData
, *pcbEnvelopedData
);
5741 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5742 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, envelopedData
,
5743 pcbEnvelopedData
, NULL
, NULL
);
5744 TRACE("returning %d\n", ret
);
5748 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5749 LPCSTR lpszStructType
)
5751 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5753 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5754 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5756 SetLastError(ERROR_FILE_NOT_FOUND
);
5759 if (IS_INTOID(lpszStructType
))
5761 switch (LOWORD(lpszStructType
))
5763 case LOWORD(X509_CERT
):
5764 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5766 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5767 decodeFunc
= CRYPT_AsnDecodeCert
;
5769 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5770 decodeFunc
= CRYPT_AsnDecodeCRL
;
5772 case LOWORD(X509_EXTENSIONS
):
5773 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5775 case LOWORD(X509_NAME_VALUE
):
5776 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5778 case LOWORD(X509_NAME
):
5779 decodeFunc
= CRYPT_AsnDecodeName
;
5781 case LOWORD(X509_PUBLIC_KEY_INFO
):
5782 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5784 case LOWORD(X509_AUTHORITY_KEY_ID
):
5785 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5787 case LOWORD(X509_ALTERNATE_NAME
):
5788 decodeFunc
= CRYPT_AsnDecodeAltName
;
5790 case LOWORD(X509_BASIC_CONSTRAINTS
):
5791 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5793 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5794 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5796 case LOWORD(X509_CERT_POLICIES
):
5797 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5799 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5800 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5802 case LOWORD(X509_UNICODE_NAME
):
5803 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5805 case LOWORD(PKCS_ATTRIBUTE
):
5806 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5808 case LOWORD(X509_UNICODE_NAME_VALUE
):
5809 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5811 case LOWORD(X509_OCTET_STRING
):
5812 decodeFunc
= CRYPT_AsnDecodeOctets
;
5814 case LOWORD(X509_BITS
):
5815 case LOWORD(X509_KEY_USAGE
):
5816 decodeFunc
= CRYPT_AsnDecodeBits
;
5818 case LOWORD(X509_INTEGER
):
5819 decodeFunc
= CRYPT_AsnDecodeInt
;
5821 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5822 decodeFunc
= CRYPT_AsnDecodeInteger
;
5824 case LOWORD(X509_MULTI_BYTE_UINT
):
5825 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5827 case LOWORD(X509_ENUMERATED
):
5828 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5830 case LOWORD(X509_CHOICE_OF_TIME
):
5831 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5833 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5834 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5836 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5837 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5839 case LOWORD(PKCS_CONTENT_INFO
):
5840 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5842 case LOWORD(X509_SEQUENCE_OF_ANY
):
5843 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5845 case LOWORD(PKCS_UTC_TIME
):
5846 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5848 case LOWORD(X509_CRL_DIST_POINTS
):
5849 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5851 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5852 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5854 case LOWORD(PKCS_CTL
):
5855 decodeFunc
= CRYPT_AsnDecodeCTL
;
5857 case LOWORD(PKCS_SMIME_CAPABILITIES
):
5858 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5860 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
5861 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5863 case LOWORD(PKCS_ATTRIBUTES
):
5864 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
5866 case LOWORD(X509_ISSUING_DIST_POINT
):
5867 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5869 case LOWORD(X509_NAME_CONSTRAINTS
):
5870 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5872 case LOWORD(X509_POLICY_MAPPINGS
):
5873 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5875 case LOWORD(X509_POLICY_CONSTRAINTS
):
5876 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5878 case LOWORD(PKCS7_SIGNER_INFO
):
5879 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
5881 case LOWORD(CMS_SIGNER_INFO
):
5882 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
5886 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
5887 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5888 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
5889 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5890 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
5891 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5892 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
5893 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5894 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
5895 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5896 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
5897 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5898 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
5899 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5900 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
5901 decodeFunc
= CRYPT_AsnDecodeBits
;
5902 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
5903 decodeFunc
= CRYPT_AsnDecodeOctets
;
5904 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
5905 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5906 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
5907 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5908 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
5909 decodeFunc
= CRYPT_AsnDecodeAltName
;
5910 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
5911 decodeFunc
= CRYPT_AsnDecodeAltName
;
5912 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
5913 decodeFunc
= CRYPT_AsnDecodeAltName
;
5914 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
5915 decodeFunc
= CRYPT_AsnDecodeAltName
;
5916 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
5917 decodeFunc
= CRYPT_AsnDecodeAltName
;
5918 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
5919 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5920 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
5921 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5922 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
5923 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5924 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
5925 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5926 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
5927 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5928 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
5929 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5930 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
5931 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5932 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
5933 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5934 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
5935 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5936 else if (!strcmp(lpszStructType
, szOID_CTL
))
5937 decodeFunc
= CRYPT_AsnDecodeCTL
;
5941 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
5942 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5944 static HCRYPTOIDFUNCSET set
= NULL
;
5945 CryptDecodeObjectFunc decodeFunc
= NULL
;
5948 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
5949 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5950 (void **)&decodeFunc
, hFunc
);
5954 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
5955 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5957 static HCRYPTOIDFUNCSET set
= NULL
;
5958 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5961 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
5962 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5963 (void **)&decodeFunc
, hFunc
);
5967 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5968 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
5969 DWORD
*pcbStructInfo
)
5972 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
5973 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
5974 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5976 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
5977 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
5978 pvStructInfo
, pcbStructInfo
);
5980 if (!pvStructInfo
&& !pcbStructInfo
)
5982 SetLastError(ERROR_INVALID_PARAMETER
);
5985 if (cbEncoded
> MAX_ENCODED_LEN
)
5987 SetLastError(CRYPT_E_ASN1_LARGE
);
5991 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
5994 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5995 debugstr_a(lpszStructType
));
5996 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
5997 lpszStructType
, &hFunc
);
5998 if (!pCryptDecodeObject
)
5999 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
6000 lpszStructType
, &hFunc
);
6002 if (pCryptDecodeObject
)
6003 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6004 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6005 else if (pCryptDecodeObjectEx
)
6006 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
6007 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6008 pvStructInfo
, pcbStructInfo
);
6010 CryptFreeOIDFunctionAddress(hFunc
, 0);
6011 TRACE_(crypt
)("returning %d\n", ret
);
6015 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6016 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6017 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6020 CryptDecodeObjectExFunc decodeFunc
;
6021 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6023 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6024 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
6025 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6027 if (!pvStructInfo
&& !pcbStructInfo
)
6029 SetLastError(ERROR_INVALID_PARAMETER
);
6032 if (cbEncoded
> MAX_ENCODED_LEN
)
6034 SetLastError(CRYPT_E_ASN1_LARGE
);
6038 SetLastError(NOERROR
);
6039 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6043 SetLastError(ERROR_INVALID_PARAMETER
);
6046 *(BYTE
**)pvStructInfo
= NULL
;
6048 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
6051 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6052 debugstr_a(lpszStructType
));
6053 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
6057 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
6058 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6061 CryptDecodeObjectFunc pCryptDecodeObject
=
6062 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
6064 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6065 * directly, as that could cause an infinite loop.
6067 if (pCryptDecodeObject
)
6069 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6071 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6072 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
6073 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
6074 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
6076 ret
= pCryptDecodeObject(dwCertEncodingType
,
6077 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
6078 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
6080 CRYPT_FreeSpace(pDecodePara
, *(BYTE
**)pvStructInfo
);
6084 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6085 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6089 CryptFreeOIDFunctionAddress(hFunc
, 0);
6090 TRACE_(crypt
)("returning %d\n", ret
);
6094 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
6098 TRACE_(crypt
)("(%p)\n", pPFX
);
6100 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6101 * version integer of length 1 (3 encoded byes) and at least one other
6102 * datum (two encoded bytes), plus at least two bytes for the outer
6103 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6105 if (pPFX
->cbData
< 7)
6107 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
6111 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
6113 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
6115 /* Need at least three bytes for the integer version */
6116 if (pPFX
->cbData
< 1 + lenLen
+ 3)
6118 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
6119 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
6120 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
6129 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6132 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);
6136 BOOL WINAPI
PFXVerifyPassword(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6139 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);