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
);
1313 /* The largest possible string for the first two components
1314 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1319 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1320 pbEncoded
[1 + lenBytes
] / 40,
1321 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1323 bytesNeeded
+= strlen(firstTwo
) + 1;
1324 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1325 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1327 /* large enough for ".4000000" */
1331 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1338 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1341 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1348 snprintf(str
, sizeof(str
), ".%d", val
);
1349 bytesNeeded
+= strlen(str
);
1354 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1356 *pcbStructInfo
= bytesNeeded
;
1357 else if (*pcbStructInfo
< bytesNeeded
)
1359 *pcbStructInfo
= bytesNeeded
;
1360 SetLastError(ERROR_MORE_DATA
);
1368 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1371 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1372 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1374 pszObjId
+= strlen(pszObjId
);
1375 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1376 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1380 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1389 sprintf(pszObjId
, ".%d", val
);
1390 pszObjId
+= strlen(pszObjId
);
1394 *(LPSTR
*)pvStructInfo
= NULL
;
1395 *pcbStructInfo
= bytesNeeded
;
1401 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1402 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1406 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1407 pvStructInfo
, *pcbStructInfo
);
1409 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1410 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1411 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1414 SetLastError(CRYPT_E_ASN1_BADTAG
);
1420 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1421 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1423 struct AsnDecodeSequenceItem items
[] = {
1424 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1425 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1426 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1427 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1428 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1429 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1430 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1431 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1434 PCERT_EXTENSION ext
= pvStructInfo
;
1436 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1440 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1441 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1442 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1443 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1445 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1446 debugstr_a(ext
->pszObjId
));
1447 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1451 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1452 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1453 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1457 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1458 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1462 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1463 offsetof(CERT_EXTENSIONS
, cExtension
),
1464 offsetof(CERT_EXTENSIONS
, rgExtension
),
1465 sizeof(CERT_EXTENSIONS
),
1466 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1467 offsetof(CERT_EXTENSION
, pszObjId
) };
1468 CERT_EXTENSIONS
*exts
= pvStructInfo
;
1470 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1471 exts
->rgExtension
= (CERT_EXTENSION
*)(exts
+ 1);
1472 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1473 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1477 SetLastError(STATUS_ACCESS_VIOLATION
);
1484 /* Warning: this assumes the address of value->Value.pbData is already set, in
1485 * order to avoid overwriting memory. (In some cases, it may change it, if it
1486 * doesn't copy anything to memory.) Be sure to set it correctly!
1488 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1489 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1494 CERT_NAME_VALUE
*value
= pvStructInfo
;
1496 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1498 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1499 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1501 switch (pbEncoded
[0])
1503 case ASN_OCTETSTRING
:
1504 valueType
= CERT_RDN_OCTET_STRING
;
1505 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1506 bytesNeeded
+= dataLen
;
1508 case ASN_NUMERICSTRING
:
1509 valueType
= CERT_RDN_NUMERIC_STRING
;
1510 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1511 bytesNeeded
+= dataLen
;
1513 case ASN_PRINTABLESTRING
:
1514 valueType
= CERT_RDN_PRINTABLE_STRING
;
1515 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1516 bytesNeeded
+= dataLen
;
1519 valueType
= CERT_RDN_IA5_STRING
;
1520 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1521 bytesNeeded
+= dataLen
;
1524 valueType
= CERT_RDN_T61_STRING
;
1525 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1526 bytesNeeded
+= dataLen
;
1528 case ASN_VIDEOTEXSTRING
:
1529 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1530 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1531 bytesNeeded
+= dataLen
;
1533 case ASN_GRAPHICSTRING
:
1534 valueType
= CERT_RDN_GRAPHIC_STRING
;
1535 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1536 bytesNeeded
+= dataLen
;
1538 case ASN_VISIBLESTRING
:
1539 valueType
= CERT_RDN_VISIBLE_STRING
;
1540 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1541 bytesNeeded
+= dataLen
;
1543 case ASN_GENERALSTRING
:
1544 valueType
= CERT_RDN_GENERAL_STRING
;
1545 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1546 bytesNeeded
+= dataLen
;
1548 case ASN_UNIVERSALSTRING
:
1549 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1550 SetLastError(CRYPT_E_ASN1_BADTAG
);
1553 valueType
= CERT_RDN_BMP_STRING
;
1554 bytesNeeded
+= dataLen
;
1556 case ASN_UTF8STRING
:
1557 valueType
= CERT_RDN_UTF8_STRING
;
1558 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1559 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1562 SetLastError(CRYPT_E_ASN1_BADTAG
);
1567 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1569 *pcbStructInfo
= bytesNeeded
;
1570 else if (*pcbStructInfo
< bytesNeeded
)
1572 *pcbStructInfo
= bytesNeeded
;
1573 SetLastError(ERROR_MORE_DATA
);
1578 *pcbStructInfo
= bytesNeeded
;
1579 value
->dwValueType
= valueType
;
1584 assert(value
->Value
.pbData
);
1585 switch (pbEncoded
[0])
1587 case ASN_OCTETSTRING
:
1588 case ASN_NUMERICSTRING
:
1589 case ASN_PRINTABLESTRING
:
1592 case ASN_VIDEOTEXSTRING
:
1593 case ASN_GRAPHICSTRING
:
1594 case ASN_VISIBLESTRING
:
1595 case ASN_GENERALSTRING
:
1596 value
->Value
.cbData
= dataLen
;
1599 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1600 memcpy(value
->Value
.pbData
,
1601 pbEncoded
+ 1 + lenBytes
, dataLen
);
1603 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1609 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1611 value
->Value
.cbData
= dataLen
;
1612 for (i
= 0; i
< dataLen
/ 2; i
++)
1613 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1614 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1617 case ASN_UTF8STRING
:
1619 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1621 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1622 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1623 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1630 value
->Value
.cbData
= 0;
1631 value
->Value
.pbData
= NULL
;
1638 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1639 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1640 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1646 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1647 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1648 if (ret
&& pvStructInfo
)
1650 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1651 pcbStructInfo
, *pcbStructInfo
);
1654 CERT_NAME_VALUE
*value
;
1656 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1657 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1658 value
= pvStructInfo
;
1659 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1660 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1661 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1662 pcbStructInfo
, NULL
);
1663 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1664 CRYPT_FreeSpace(pDecodePara
, value
);
1670 SetLastError(STATUS_ACCESS_VIOLATION
);
1677 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1678 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1683 CERT_NAME_VALUE
*value
= pvStructInfo
;
1685 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1687 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1688 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1690 switch (pbEncoded
[0])
1692 case ASN_NUMERICSTRING
:
1693 valueType
= CERT_RDN_NUMERIC_STRING
;
1695 bytesNeeded
+= (dataLen
+ 1) * 2;
1697 case ASN_PRINTABLESTRING
:
1698 valueType
= CERT_RDN_PRINTABLE_STRING
;
1700 bytesNeeded
+= (dataLen
+ 1) * 2;
1703 valueType
= CERT_RDN_IA5_STRING
;
1705 bytesNeeded
+= (dataLen
+ 1) * 2;
1708 valueType
= CERT_RDN_T61_STRING
;
1710 bytesNeeded
+= (dataLen
+ 1) * 2;
1712 case ASN_VIDEOTEXSTRING
:
1713 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1715 bytesNeeded
+= (dataLen
+ 1) * 2;
1717 case ASN_GRAPHICSTRING
:
1718 valueType
= CERT_RDN_GRAPHIC_STRING
;
1720 bytesNeeded
+= (dataLen
+ 1) * 2;
1722 case ASN_VISIBLESTRING
:
1723 valueType
= CERT_RDN_VISIBLE_STRING
;
1725 bytesNeeded
+= (dataLen
+ 1) * 2;
1727 case ASN_GENERALSTRING
:
1728 valueType
= CERT_RDN_GENERAL_STRING
;
1730 bytesNeeded
+= (dataLen
+ 1) * 2;
1732 case ASN_UNIVERSALSTRING
:
1733 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1735 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1738 valueType
= CERT_RDN_BMP_STRING
;
1740 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1742 case ASN_UTF8STRING
:
1743 valueType
= CERT_RDN_UTF8_STRING
;
1745 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1746 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1749 SetLastError(CRYPT_E_ASN1_BADTAG
);
1754 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1756 *pcbStructInfo
= bytesNeeded
;
1757 else if (*pcbStructInfo
< bytesNeeded
)
1759 *pcbStructInfo
= bytesNeeded
;
1760 SetLastError(ERROR_MORE_DATA
);
1765 *pcbStructInfo
= bytesNeeded
;
1766 value
->dwValueType
= valueType
;
1770 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1772 assert(value
->Value
.pbData
);
1773 switch (pbEncoded
[0])
1775 case ASN_NUMERICSTRING
:
1776 case ASN_PRINTABLESTRING
:
1779 case ASN_VIDEOTEXSTRING
:
1780 case ASN_GRAPHICSTRING
:
1781 case ASN_VISIBLESTRING
:
1782 case ASN_GENERALSTRING
:
1783 value
->Value
.cbData
= dataLen
* 2;
1784 for (i
= 0; i
< dataLen
; i
++)
1785 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1788 case ASN_UNIVERSALSTRING
:
1789 value
->Value
.cbData
= dataLen
/ 2;
1790 for (i
= 0; i
< dataLen
/ 4; i
++)
1791 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1792 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1796 value
->Value
.cbData
= dataLen
;
1797 for (i
= 0; i
< dataLen
/ 2; i
++)
1798 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1799 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1802 case ASN_UTF8STRING
:
1803 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1804 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1805 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1806 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1807 value
->Value
.cbData
+= sizeof(WCHAR
);
1813 value
->Value
.cbData
= 0;
1814 value
->Value
.pbData
= NULL
;
1821 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1822 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1823 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1829 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1830 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1831 if (ret
&& pvStructInfo
)
1833 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1834 pcbStructInfo
, *pcbStructInfo
);
1837 CERT_NAME_VALUE
*value
;
1839 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1840 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1841 value
= pvStructInfo
;
1842 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1843 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1844 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1845 pcbStructInfo
, NULL
);
1846 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1847 CRYPT_FreeSpace(pDecodePara
, value
);
1853 SetLastError(STATUS_ACCESS_VIOLATION
);
1860 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1861 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1864 struct AsnDecodeSequenceItem items
[] = {
1865 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1866 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1867 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1868 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1869 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1870 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1872 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1874 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1875 pvStructInfo
, *pcbStructInfo
);
1878 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1879 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1880 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1881 attr
? attr
->pszObjId
: NULL
);
1884 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1885 debugstr_a(attr
->pszObjId
));
1886 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1888 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1892 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1893 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1896 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1897 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1899 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1900 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1902 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1903 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1907 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1908 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1909 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1915 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1916 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1917 sizeof(CERT_NAME_INFO
),
1918 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1919 offsetof(CERT_RDN
, rgRDNAttr
) };
1922 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1923 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1928 *pcbStructInfo
= bytesNeeded
;
1929 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1930 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1932 CERT_NAME_INFO
*info
;
1934 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1935 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1936 info
= pvStructInfo
;
1937 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1938 sizeof(CERT_NAME_INFO
));
1939 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1940 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1941 &bytesNeeded
, NULL
);
1942 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1943 CRYPT_FreeSpace(pDecodePara
, info
);
1949 SetLastError(STATUS_ACCESS_VIOLATION
);
1956 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1957 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1961 struct AsnDecodeSequenceItem items
[] = {
1962 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1963 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1964 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1965 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1966 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1967 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1969 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1971 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1972 pvStructInfo
, *pcbStructInfo
);
1975 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1976 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1977 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1978 attr
? attr
->pszObjId
: NULL
);
1981 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1982 debugstr_a(attr
->pszObjId
));
1983 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1985 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1989 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1990 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1993 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1994 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1996 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1997 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1999 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2000 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2004 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
2005 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2006 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2012 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2013 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2014 sizeof(CERT_NAME_INFO
),
2015 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2016 offsetof(CERT_RDN
, rgRDNAttr
) };
2019 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2020 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2025 *pcbStructInfo
= bytesNeeded
;
2026 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2027 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2029 CERT_NAME_INFO
*info
;
2031 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2032 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2033 info
= pvStructInfo
;
2034 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2035 sizeof(CERT_NAME_INFO
));
2036 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2037 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2038 &bytesNeeded
, NULL
);
2039 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2040 CRYPT_FreeSpace(pDecodePara
, info
);
2046 SetLastError(STATUS_ACCESS_VIOLATION
);
2053 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2056 BOOL ret
= TRUE
, done
= FALSE
;
2057 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2059 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2066 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2069 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2071 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2073 indefiniteNestingLevels
++;
2074 pbEncoded
+= 1 + lenBytes
;
2075 cbEncoded
-= 1 + lenBytes
;
2076 decoded
+= 1 + lenBytes
;
2077 TRACE("indefiniteNestingLevels = %d\n",
2078 indefiniteNestingLevels
);
2082 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2083 indefiniteNestingLevels
)
2085 indefiniteNestingLevels
--;
2086 TRACE("indefiniteNestingLevels = %d\n",
2087 indefiniteNestingLevels
);
2089 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2090 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2091 decoded
+= 1 + lenBytes
+ dataLen
;
2092 if (!indefiniteNestingLevels
)
2096 } while (ret
&& !done
);
2097 /* If we haven't found all 0 TLVs, we haven't found the end */
2098 if (ret
&& indefiniteNestingLevels
)
2100 SetLastError(CRYPT_E_ASN1_EOD
);
2104 *pcbDecoded
= decoded
;
2105 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2109 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2110 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2114 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2116 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2117 pvStructInfo
, *pcbStructInfo
);
2119 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2121 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2122 bytesNeeded
+= encodedLen
;
2124 *pcbStructInfo
= bytesNeeded
;
2125 else if (*pcbStructInfo
< bytesNeeded
)
2127 SetLastError(ERROR_MORE_DATA
);
2128 *pcbStructInfo
= bytesNeeded
;
2133 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2135 *pcbStructInfo
= bytesNeeded
;
2136 blob
->cbData
= encodedLen
;
2139 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2140 blob
->pbData
= (LPBYTE
)pbEncoded
;
2143 assert(blob
->pbData
);
2144 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2148 blob
->pbData
= NULL
;
2151 *pcbDecoded
= encodedLen
;
2156 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2157 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2160 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2161 offsetof(CTL_USAGE
, cUsageIdentifier
),
2162 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2164 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2166 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2167 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2171 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2172 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2175 struct AsnArrayDescriptor arrayDesc
= { 0,
2176 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2177 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2178 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2179 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2182 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2183 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2187 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2188 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2190 struct AsnDecodeSequenceItem items
[] = {
2191 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2192 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2193 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2194 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2195 CRYPT_AsnDecodeCTLEntryAttributes
,
2196 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2197 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2200 CTL_ENTRY
*entry
= pvStructInfo
;
2202 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2205 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2206 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2207 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2211 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2212 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2215 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2216 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2217 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2218 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2219 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2221 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2222 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2224 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2225 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2229 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2230 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2234 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2235 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2236 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2237 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2238 offsetof(CERT_EXTENSION
, pszObjId
) };
2240 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2241 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2243 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2244 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2248 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2249 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2255 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2257 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2259 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2260 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2261 if (ret
&& pcbDecoded
)
2262 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2267 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2268 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2269 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2273 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2274 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2278 struct AsnDecodeSequenceItem items
[] = {
2279 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2280 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2281 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2282 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2283 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2284 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2285 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2286 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2287 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2288 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2289 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2290 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2291 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2293 { 0, offsetof(CTL_INFO
, NextUpdate
),
2294 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2296 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2297 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2298 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2299 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2300 CRYPT_AsnDecodeCTLEntries
,
2301 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2302 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2303 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2304 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2305 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2308 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2309 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2310 pcbStructInfo
, NULL
, NULL
);
2314 SetLastError(STATUS_ACCESS_VIOLATION
);
2320 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2321 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2325 struct AsnDecodeSequenceItem items
[] = {
2326 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2327 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2328 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2329 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2330 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2331 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2333 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2335 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2336 pvStructInfo
, *pcbStructInfo
);
2338 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2339 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2340 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2341 TRACE("returning %d\n", ret
);
2345 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2346 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2347 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2351 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2352 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2356 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2357 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2358 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2359 sizeof(CRYPT_SMIME_CAPABILITIES
),
2360 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2361 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2362 CRYPT_SMIME_CAPABILITIES
*capabilities
= pvStructInfo
;
2364 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2365 capabilities
->rgCapability
= (CRYPT_SMIME_CAPABILITY
*)(capabilities
+ 1);
2366 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2367 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2371 SetLastError(STATUS_ACCESS_VIOLATION
);
2374 TRACE("returning %d\n", ret
);
2378 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2379 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2384 LPSTR
*pStr
= pvStructInfo
;
2386 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2388 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2389 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2391 if (pbEncoded
[0] != ASN_IA5STRING
)
2393 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2398 bytesNeeded
+= dataLen
;
2400 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2402 *pcbStructInfo
= bytesNeeded
;
2403 else if (*pcbStructInfo
< bytesNeeded
)
2405 *pcbStructInfo
= bytesNeeded
;
2406 SetLastError(ERROR_MORE_DATA
);
2411 *pcbStructInfo
= bytesNeeded
;
2417 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2428 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2429 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2432 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2433 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2434 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2435 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2436 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2439 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2440 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2442 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2443 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2444 TRACE("returning %d\n", ret
);
2448 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2449 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2453 struct AsnDecodeSequenceItem items
[] = {
2454 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2455 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2456 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2457 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2458 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2459 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2460 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2461 rgNoticeNumbers
), 0 },
2465 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2466 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2468 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2469 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2473 /* The caller is expecting a pointer to a
2474 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2475 * CRYPT_AsnDecodeSequence is decoding a
2476 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2477 * needed, and decode again if the requisite space is available.
2479 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2481 *pcbStructInfo
= bytesNeeded
;
2482 else if (*pcbStructInfo
< bytesNeeded
)
2484 *pcbStructInfo
= bytesNeeded
;
2485 SetLastError(ERROR_MORE_DATA
);
2490 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2492 *pcbStructInfo
= bytesNeeded
;
2493 /* The pointer (pvStructInfo) passed in points to the first dynamic
2494 * pointer, so use it as the pointer to the
2495 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2496 * appropriate offset for the first dynamic pointer within the
2497 * notice reference by pointing to the first memory location past
2498 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2501 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2502 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2503 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2504 ret
= CRYPT_AsnDecodeSequence(items
,
2505 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2506 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2507 noticeRef
->pszOrganization
);
2510 TRACE("returning %d\n", ret
);
2514 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2515 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2521 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2523 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2524 DWORD bytesNeeded
= sizeof(LPWSTR
);
2526 switch (pbEncoded
[0])
2528 case ASN_NUMERICSTRING
:
2530 bytesNeeded
+= (dataLen
+ 1) * 2;
2532 case ASN_PRINTABLESTRING
:
2534 bytesNeeded
+= (dataLen
+ 1) * 2;
2538 bytesNeeded
+= (dataLen
+ 1) * 2;
2542 bytesNeeded
+= (dataLen
+ 1) * 2;
2544 case ASN_VIDEOTEXSTRING
:
2546 bytesNeeded
+= (dataLen
+ 1) * 2;
2548 case ASN_GRAPHICSTRING
:
2550 bytesNeeded
+= (dataLen
+ 1) * 2;
2552 case ASN_VISIBLESTRING
:
2554 bytesNeeded
+= (dataLen
+ 1) * 2;
2556 case ASN_GENERALSTRING
:
2558 bytesNeeded
+= (dataLen
+ 1) * 2;
2560 case ASN_UNIVERSALSTRING
:
2562 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2566 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2568 case ASN_UTF8STRING
:
2570 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2571 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2574 SetLastError(CRYPT_E_ASN1_BADTAG
);
2579 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2581 *pcbStructInfo
= bytesNeeded
;
2582 else if (*pcbStructInfo
< bytesNeeded
)
2584 *pcbStructInfo
= bytesNeeded
;
2585 SetLastError(ERROR_MORE_DATA
);
2590 LPWSTR
*pStr
= pvStructInfo
;
2592 *pcbStructInfo
= bytesNeeded
;
2596 LPWSTR str
= *(LPWSTR
*)pStr
;
2599 switch (pbEncoded
[0])
2601 case ASN_NUMERICSTRING
:
2602 case ASN_PRINTABLESTRING
:
2605 case ASN_VIDEOTEXSTRING
:
2606 case ASN_GRAPHICSTRING
:
2607 case ASN_VISIBLESTRING
:
2608 case ASN_GENERALSTRING
:
2609 for (i
= 0; i
< dataLen
; i
++)
2610 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2613 case ASN_UNIVERSALSTRING
:
2614 for (i
= 0; i
< dataLen
/ 4; i
++)
2615 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2616 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2620 for (i
= 0; i
< dataLen
/ 2; i
++)
2621 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2622 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2625 case ASN_UTF8STRING
:
2627 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2628 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2629 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2642 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2643 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2644 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2647 struct AsnDecodeSequenceItem items
[] = {
2648 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2649 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2650 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2651 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2652 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2653 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2654 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2656 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2658 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2659 pvStructInfo
, *pcbStructInfo
);
2661 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2662 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2663 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2664 TRACE("returning %d\n", ret
);
2668 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2669 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2670 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2671 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2675 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2676 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2682 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2683 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2688 *pcbStructInfo
= bytesNeeded
;
2689 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2690 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2692 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2694 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2695 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2696 notice
= pvStructInfo
;
2697 notice
->pNoticeReference
=
2698 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2699 ((BYTE
*)pvStructInfo
+
2700 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2701 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2702 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2703 pvStructInfo
, &bytesNeeded
, NULL
);
2704 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2705 CRYPT_FreeSpace(pDecodePara
, notice
);
2711 SetLastError(STATUS_ACCESS_VIOLATION
);
2714 TRACE("returning %d\n", ret
);
2718 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2719 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2723 struct AsnArrayDescriptor arrayDesc
= { 0,
2724 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2725 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2726 CRYPT_AsnDecodeCopyBytes
,
2727 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2729 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2730 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2732 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2733 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2737 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2738 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2742 struct AsnDecodeSequenceItem items
[] = {
2743 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2744 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2745 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2746 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2747 CRYPT_AsnDecodePKCSAttributeValue
,
2748 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2749 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2751 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2753 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2754 pvStructInfo
, *pcbStructInfo
);
2756 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2757 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2758 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2759 TRACE("returning %d\n", ret
);
2763 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2764 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2765 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2769 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2770 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2776 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2777 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2781 *pcbStructInfo
= bytesNeeded
;
2782 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2783 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2785 PCRYPT_ATTRIBUTE attr
;
2787 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2788 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2789 attr
= pvStructInfo
;
2790 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2791 sizeof(CRYPT_ATTRIBUTE
));
2792 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2793 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2795 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2796 CRYPT_FreeSpace(pDecodePara
, attr
);
2802 SetLastError(STATUS_ACCESS_VIOLATION
);
2805 TRACE("returning %d\n", ret
);
2809 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2810 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2813 struct AsnArrayDescriptor arrayDesc
= { 0,
2814 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2815 sizeof(CRYPT_ATTRIBUTES
),
2816 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2817 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2820 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2821 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2825 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2826 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2827 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2831 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2832 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2836 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2837 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2838 sizeof(CRYPT_ATTRIBUTES
),
2839 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2840 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2841 CRYPT_ATTRIBUTES
*attrs
= pvStructInfo
;
2843 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2844 attrs
->rgAttr
= (CRYPT_ATTRIBUTE
*)(attrs
+ 1);
2845 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2846 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2850 SetLastError(STATUS_ACCESS_VIOLATION
);
2853 TRACE("returning %d\n", ret
);
2857 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2858 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2860 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2862 struct AsnDecodeSequenceItem items
[] = {
2863 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2864 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2865 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2866 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2867 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2868 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2871 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2872 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2874 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2875 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2876 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2877 if (ret
&& pvStructInfo
)
2879 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2880 debugstr_a(algo
->pszObjId
));
2885 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2886 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2890 struct AsnDecodeSequenceItem items
[] = {
2891 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2892 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2893 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2894 Algorithm
.pszObjId
) },
2895 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2896 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2897 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2899 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2901 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2902 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2903 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2907 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2908 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2909 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2917 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2918 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2921 *pcbStructInfo
= bytesNeeded
;
2922 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2923 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2925 PCERT_PUBLIC_KEY_INFO info
;
2927 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2928 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2929 info
= pvStructInfo
;
2930 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2931 sizeof(CERT_PUBLIC_KEY_INFO
);
2932 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2933 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2934 &bytesNeeded
, NULL
);
2935 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2936 CRYPT_FreeSpace(pDecodePara
, info
);
2942 SetLastError(STATUS_ACCESS_VIOLATION
);
2949 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2950 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2956 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2959 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2961 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2964 if (pbEncoded
[1] > 1)
2966 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2973 *pcbStructInfo
= sizeof(BOOL
);
2976 else if (*pcbStructInfo
< sizeof(BOOL
))
2978 *pcbStructInfo
= sizeof(BOOL
);
2979 SetLastError(ERROR_MORE_DATA
);
2984 *pcbStructInfo
= sizeof(BOOL
);
2985 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2988 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2992 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2993 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2995 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2996 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2999 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3000 pvStructInfo
, *pcbStructInfo
);
3004 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3007 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3008 if (1 + lenBytes
> cbEncoded
)
3010 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3013 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3015 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3017 case 1: /* rfc822Name */
3018 case 2: /* dNSName */
3019 case 6: /* uniformResourceIdentifier */
3020 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
3022 SetLastError(CRYPT_E_ASN1_RULE
);
3026 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3028 case 4: /* directoryName */
3029 case 7: /* iPAddress */
3030 bytesNeeded
+= dataLen
;
3032 case 8: /* registeredID */
3033 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3037 /* FIXME: ugly, shouldn't need to know internals of OID decode
3038 * function to use it.
3040 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3043 case 0: /* otherName */
3044 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3045 SetLastError(CRYPT_E_ASN1_BADTAG
);
3048 case 3: /* x400Address, unimplemented */
3049 case 5: /* ediPartyName, unimplemented */
3050 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3051 SetLastError(CRYPT_E_ASN1_BADTAG
);
3055 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3056 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3062 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3064 *pcbStructInfo
= bytesNeeded
;
3065 else if (*pcbStructInfo
< bytesNeeded
)
3067 *pcbStructInfo
= bytesNeeded
;
3068 SetLastError(ERROR_MORE_DATA
);
3073 *pcbStructInfo
= bytesNeeded
;
3074 /* MS used values one greater than the asn1 ones.. sigh */
3075 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3076 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3078 case 1: /* rfc822Name */
3079 case 2: /* dNSName */
3080 case 6: /* uniformResourceIdentifier */
3084 for (i
= 0; i
< dataLen
; i
++)
3085 entry
->u
.pwszURL
[i
] =
3086 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3087 entry
->u
.pwszURL
[i
] = 0;
3088 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3089 debugstr_w(entry
->u
.pwszURL
));
3092 case 4: /* directoryName */
3093 /* The data are memory-equivalent with the IPAddress case,
3096 case 7: /* iPAddress */
3097 /* The next data pointer is in the pwszURL spot, that is,
3098 * the first 4 bytes. Need to move it to the next spot.
3100 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3101 entry
->u
.IPAddress
.cbData
= dataLen
;
3102 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3105 case 8: /* registeredID */
3106 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3107 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3116 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3117 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3121 struct AsnArrayDescriptor arrayDesc
= { 0,
3122 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3123 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3124 sizeof(CERT_ALT_NAME_INFO
),
3125 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3126 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3128 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3129 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3131 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3132 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3136 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3137 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3138 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3144 struct AsnDecodeSequenceItem items
[] = {
3145 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3146 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3147 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3148 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3149 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3150 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3151 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3152 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3153 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3154 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3155 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3158 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3159 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3160 pcbStructInfo
, NULL
, NULL
);
3164 SetLastError(STATUS_ACCESS_VIOLATION
);
3171 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3172 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3173 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3179 struct AsnDecodeSequenceItem items
[] = {
3180 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3181 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3182 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3183 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3184 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3185 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3186 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3187 AuthorityCertIssuer
.rgAltEntry
), 0 },
3188 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3189 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3190 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3191 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3192 AuthorityCertSerialNumber
.pbData
), 0 },
3195 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3196 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3197 pcbStructInfo
, NULL
, NULL
);
3201 SetLastError(STATUS_ACCESS_VIOLATION
);
3208 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3209 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3212 struct AsnDecodeSequenceItem items
[] = {
3213 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3214 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3215 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3216 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3217 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3218 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3220 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3222 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3223 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3224 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3227 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3228 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3229 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3233 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3234 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3238 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3239 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3240 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3241 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3242 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3243 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3244 CERT_AUTHORITY_INFO_ACCESS
*info
= pvStructInfo
;
3246 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3247 info
->rgAccDescr
= (CERT_ACCESS_DESCRIPTION
*)(info
+ 1);
3248 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3249 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3253 SetLastError(STATUS_ACCESS_VIOLATION
);
3260 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3261 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3266 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3267 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3269 /* The caller has already checked the tag, no need to check it again.
3270 * Check the outer length is valid:
3272 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3274 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3277 pbEncoded
+= 1 + lenBytes
;
3278 cbEncoded
-= 1 + lenBytes
;
3279 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3280 cbEncoded
-= 2; /* space for 0 TLV */
3281 /* Check the inner length is valid: */
3282 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3286 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3287 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3288 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3290 if (*(pbEncoded
+ decodedLen
) != 0 ||
3291 *(pbEncoded
+ decodedLen
+ 1) != 0)
3293 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3294 *(pbEncoded
+ decodedLen
),
3295 *(pbEncoded
+ decodedLen
+ 1));
3296 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3302 if (ret
&& pcbDecoded
)
3304 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3305 TRACE("decoded %d bytes\n", *pcbDecoded
);
3312 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3313 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3316 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3317 struct AsnDecodeSequenceItem items
[] = {
3318 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3319 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3320 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3321 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3322 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3323 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3324 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3328 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3329 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3331 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3332 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3333 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3337 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3338 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3339 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3343 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3344 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3348 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3349 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3350 if (ret
&& pvStructInfo
)
3352 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3353 pcbStructInfo
, *pcbStructInfo
);
3356 CRYPT_CONTENT_INFO
*info
;
3358 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3359 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3360 info
= pvStructInfo
;
3361 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3362 sizeof(CRYPT_CONTENT_INFO
));
3363 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3364 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3365 pcbStructInfo
, NULL
);
3366 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3367 CRYPT_FreeSpace(pDecodePara
, info
);
3373 SetLastError(STATUS_ACCESS_VIOLATION
);
3379 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3380 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3381 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3384 struct AsnDecodeSequenceItem items
[] = {
3385 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3386 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3387 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3388 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3389 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3391 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3392 CRYPT_AsnDecodePKCSContentInfoInternal
,
3393 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3394 ContentInfo
.pszObjId
), 0 },
3395 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3396 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3397 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3400 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3401 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3406 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3407 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3408 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3412 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3413 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3419 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3420 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3423 *pcbStructInfo
= bytesNeeded
;
3424 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3425 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3427 CERT_ALT_NAME_INFO
*name
;
3429 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3430 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3431 name
= pvStructInfo
;
3432 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3433 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3434 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3435 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3436 &bytesNeeded
, NULL
);
3437 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3438 CRYPT_FreeSpace(pDecodePara
, name
);
3444 SetLastError(STATUS_ACCESS_VIOLATION
);
3451 struct PATH_LEN_CONSTRAINT
3453 BOOL fPathLenConstraint
;
3454 DWORD dwPathLenConstraint
;
3457 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3458 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3462 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3464 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3465 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3469 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3471 *pcbStructInfo
= bytesNeeded
;
3473 else if (*pcbStructInfo
< bytesNeeded
)
3475 SetLastError(ERROR_MORE_DATA
);
3476 *pcbStructInfo
= bytesNeeded
;
3481 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3483 *pcbStructInfo
= bytesNeeded
;
3484 size
= sizeof(constraint
->dwPathLenConstraint
);
3485 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3486 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3488 constraint
->fPathLenConstraint
= TRUE
;
3489 TRACE("got an int, dwPathLenConstraint is %d\n",
3490 constraint
->dwPathLenConstraint
);
3492 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3496 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3497 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3501 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3502 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3503 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3504 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3505 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3506 offsetof(CERT_NAME_BLOB
, pbData
) };
3508 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3509 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3511 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3512 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3513 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3517 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3518 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3519 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3525 struct AsnDecodeSequenceItem items
[] = {
3526 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3527 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3528 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3529 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3530 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3531 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3532 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3533 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3534 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3536 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3539 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3540 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3541 pcbStructInfo
, NULL
, NULL
);
3545 SetLastError(STATUS_ACCESS_VIOLATION
);
3552 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3553 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3554 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3560 struct AsnDecodeSequenceItem items
[] = {
3561 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3562 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3563 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3564 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3565 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3568 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3569 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3570 pcbStructInfo
, NULL
, NULL
);
3574 SetLastError(STATUS_ACCESS_VIOLATION
);
3581 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3582 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3585 struct AsnDecodeSequenceItem items
[] = {
3586 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3587 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3588 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3590 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3591 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3592 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3595 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3597 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3598 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3600 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3601 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3602 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3606 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3607 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3611 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3612 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3613 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3614 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3615 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3616 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3618 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3619 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3621 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3622 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3623 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3627 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3628 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3630 struct AsnDecodeSequenceItem items
[] = {
3631 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3632 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3633 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3634 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3635 CRYPT_AsnDecodePolicyQualifiers
,
3636 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3637 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3639 CERT_POLICY_INFO
*info
= pvStructInfo
;
3642 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3643 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3645 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3646 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3647 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3651 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3652 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3653 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3657 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3658 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3662 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3663 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3664 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3665 sizeof(CERT_POLICIES_INFO
),
3666 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3667 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3668 CERT_POLICIES_INFO
*info
= pvStructInfo
;
3670 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3671 info
->rgPolicyInfo
= (CERT_POLICY_INFO
*)(info
+ 1);
3673 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3674 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3678 SetLastError(STATUS_ACCESS_VIOLATION
);
3684 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3685 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3688 struct AsnDecodeSequenceItem items
[] = {
3689 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3690 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3691 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3692 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3693 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3694 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3696 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3699 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3700 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3702 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3703 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3704 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3708 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3709 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3710 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3714 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3715 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3719 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3720 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3721 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3722 sizeof(CERT_POLICY_MAPPING
),
3723 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3724 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3725 CERT_POLICY_MAPPINGS_INFO
*info
= pvStructInfo
;
3727 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3728 info
->rgPolicyMapping
= (CERT_POLICY_MAPPING
*)(info
+ 1);
3729 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3730 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3734 SetLastError(STATUS_ACCESS_VIOLATION
);
3740 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3741 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3745 DWORD skip
, size
= sizeof(skip
);
3749 SetLastError(CRYPT_E_ASN1_EOD
);
3752 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3754 SetLastError(CRYPT_E_ASN1_BADTAG
);
3757 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3758 &skip
, &size
, pcbDecoded
)))
3760 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3761 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3764 *pcbStructInfo
= bytesNeeded
;
3765 else if (*pcbStructInfo
< bytesNeeded
)
3767 *pcbStructInfo
= bytesNeeded
;
3768 SetLastError(ERROR_MORE_DATA
);
3773 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3774 CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
);
3776 *pcbStructInfo
= bytesNeeded
;
3777 /* The BOOL is implicit: if the integer is present, then it's
3780 info
->fRequireExplicitPolicy
= TRUE
;
3781 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3787 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3788 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3792 DWORD skip
, size
= sizeof(skip
);
3796 SetLastError(CRYPT_E_ASN1_EOD
);
3799 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3801 SetLastError(CRYPT_E_ASN1_BADTAG
);
3804 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3805 &skip
, &size
, pcbDecoded
)))
3807 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3808 fInhibitPolicyMapping
);
3811 *pcbStructInfo
= bytesNeeded
;
3812 else if (*pcbStructInfo
< bytesNeeded
)
3814 *pcbStructInfo
= bytesNeeded
;
3815 SetLastError(ERROR_MORE_DATA
);
3820 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3821 CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
);
3823 *pcbStructInfo
= bytesNeeded
;
3824 /* The BOOL is implicit: if the integer is present, then it's
3827 info
->fInhibitPolicyMapping
= TRUE
;
3828 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3834 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3835 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3836 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3837 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3841 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3842 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3846 struct AsnDecodeSequenceItem items
[] = {
3848 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3849 CRYPT_AsnDecodeRequireExplicit
,
3850 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3851 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3853 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3854 CRYPT_AsnDecodeInhibitMapping
,
3855 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3856 TRUE
, FALSE
, 0, 0 },
3859 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3860 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3861 pcbStructInfo
, NULL
, NULL
);
3865 SetLastError(STATUS_ACCESS_VIOLATION
);
3871 #define RSA1_MAGIC 0x31415352
3873 struct DECODED_RSA_PUB_KEY
3876 CRYPT_INTEGER_BLOB modulus
;
3879 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3880 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3881 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3887 struct AsnDecodeSequenceItem items
[] = {
3888 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3889 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3890 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3892 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3893 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3895 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3898 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3899 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3903 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3904 decodedKey
->modulus
.cbData
;
3908 *pcbStructInfo
= bytesNeeded
;
3911 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3912 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3915 RSAPUBKEY
*rsaPubKey
;
3917 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3918 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3920 hdr
->bType
= PUBLICKEYBLOB
;
3921 hdr
->bVersion
= CUR_BLOB_VERSION
;
3923 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3924 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3925 sizeof(BLOBHEADER
));
3926 rsaPubKey
->magic
= RSA1_MAGIC
;
3927 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3928 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3929 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3930 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3931 decodedKey
->modulus
.cbData
);
3933 LocalFree(decodedKey
);
3938 SetLastError(STATUS_ACCESS_VIOLATION
);
3945 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3946 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3950 DWORD bytesNeeded
, dataLen
;
3952 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3953 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3955 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3957 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3959 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3960 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3962 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3964 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3966 *pcbStructInfo
= bytesNeeded
;
3967 else if (*pcbStructInfo
< bytesNeeded
)
3969 SetLastError(ERROR_MORE_DATA
);
3970 *pcbStructInfo
= bytesNeeded
;
3975 CRYPT_DATA_BLOB
*blob
;
3977 *pcbStructInfo
= bytesNeeded
;
3978 blob
= pvStructInfo
;
3979 blob
->cbData
= dataLen
;
3980 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3981 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3984 assert(blob
->pbData
);
3986 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3994 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3995 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3996 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4000 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4001 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4009 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4012 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
4014 SetLastError(CRYPT_E_ASN1_BADTAG
);
4017 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4018 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4021 *pcbStructInfo
= bytesNeeded
;
4022 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4023 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4025 CRYPT_DATA_BLOB
*blob
;
4027 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4028 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4029 blob
= pvStructInfo
;
4030 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4031 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4032 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4033 &bytesNeeded
, NULL
);
4034 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4035 CRYPT_FreeSpace(pDecodePara
, blob
);
4041 SetLastError(STATUS_ACCESS_VIOLATION
);
4048 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4049 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4052 DWORD bytesNeeded
, dataLen
;
4053 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4055 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4056 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4058 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4060 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4061 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4063 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4065 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4067 *pcbStructInfo
= bytesNeeded
;
4068 else if (*pcbStructInfo
< bytesNeeded
)
4070 *pcbStructInfo
= bytesNeeded
;
4071 SetLastError(ERROR_MORE_DATA
);
4076 CRYPT_BIT_BLOB
*blob
;
4078 *pcbStructInfo
= bytesNeeded
;
4079 blob
= pvStructInfo
;
4080 blob
->cbData
= dataLen
- 1;
4081 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4082 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4084 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4088 assert(blob
->pbData
);
4091 BYTE mask
= 0xff << blob
->cUnusedBits
;
4093 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4095 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4103 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4104 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4105 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4109 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4110 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4118 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4121 else if (pbEncoded
[0] != ASN_BITSTRING
)
4123 SetLastError(CRYPT_E_ASN1_BADTAG
);
4126 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4127 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4130 *pcbStructInfo
= bytesNeeded
;
4131 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4132 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4134 CRYPT_BIT_BLOB
*blob
;
4136 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4137 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4138 blob
= pvStructInfo
;
4139 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4140 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4141 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4142 &bytesNeeded
, NULL
);
4143 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4144 CRYPT_FreeSpace(pDecodePara
, blob
);
4150 SetLastError(STATUS_ACCESS_VIOLATION
);
4154 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4158 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4159 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4160 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4165 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4167 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4170 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4171 if (dataLen
> sizeof(int))
4173 SetLastError(CRYPT_E_ASN1_LARGE
);
4176 else if (!pvStructInfo
)
4177 *pcbStructInfo
= sizeof(int);
4178 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4182 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4184 /* initialize to a negative value to sign-extend */
4189 for (i
= 0; i
< dataLen
; i
++)
4192 val
|= pbEncoded
[1 + lenBytes
+ i
];
4194 memcpy(pvStructInfo
, &val
, sizeof(int));
4200 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4201 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4202 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4212 SetLastError(CRYPT_E_ASN1_EOD
);
4215 else if (pbEncoded
[0] != ASN_INTEGER
)
4217 SetLastError(CRYPT_E_ASN1_BADTAG
);
4221 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4222 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4226 *pcbStructInfo
= bytesNeeded
;
4227 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4228 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4230 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4231 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4232 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4233 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4234 &bytesNeeded
, NULL
);
4235 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4236 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4242 SetLastError(STATUS_ACCESS_VIOLATION
);
4249 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4250 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4254 DWORD bytesNeeded
, dataLen
;
4256 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4258 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4260 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4262 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4264 *pcbStructInfo
= bytesNeeded
;
4265 else if (*pcbStructInfo
< bytesNeeded
)
4267 *pcbStructInfo
= bytesNeeded
;
4268 SetLastError(ERROR_MORE_DATA
);
4273 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4275 *pcbStructInfo
= bytesNeeded
;
4276 blob
->cbData
= dataLen
;
4277 assert(blob
->pbData
);
4282 for (i
= 0; i
< blob
->cbData
; i
++)
4284 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4293 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4294 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4295 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4303 if (pbEncoded
[0] != ASN_INTEGER
)
4305 SetLastError(CRYPT_E_ASN1_BADTAG
);
4309 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4310 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4314 *pcbStructInfo
= bytesNeeded
;
4315 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4316 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4318 CRYPT_INTEGER_BLOB
*blob
;
4320 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4321 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4322 blob
= pvStructInfo
;
4323 blob
->pbData
= (BYTE
*)pvStructInfo
+
4324 sizeof(CRYPT_INTEGER_BLOB
);
4325 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4326 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4327 &bytesNeeded
, NULL
);
4328 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4329 CRYPT_FreeSpace(pDecodePara
, blob
);
4335 SetLastError(STATUS_ACCESS_VIOLATION
);
4342 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4343 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4348 if (pbEncoded
[0] == ASN_INTEGER
)
4350 DWORD bytesNeeded
, dataLen
;
4352 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4354 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4357 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4358 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4360 *pcbStructInfo
= bytesNeeded
;
4361 else if (*pcbStructInfo
< bytesNeeded
)
4363 *pcbStructInfo
= bytesNeeded
;
4364 SetLastError(ERROR_MORE_DATA
);
4369 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4371 *pcbStructInfo
= bytesNeeded
;
4372 blob
->cbData
= dataLen
;
4373 assert(blob
->pbData
);
4374 /* remove leading zero byte if it exists */
4375 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4384 for (i
= 0; i
< blob
->cbData
; i
++)
4386 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4395 SetLastError(CRYPT_E_ASN1_BADTAG
);
4401 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4402 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4403 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4411 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4412 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4415 *pcbStructInfo
= bytesNeeded
;
4416 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4417 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4419 CRYPT_INTEGER_BLOB
*blob
;
4421 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4422 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4423 blob
= pvStructInfo
;
4424 blob
->pbData
= (BYTE
*)pvStructInfo
+
4425 sizeof(CRYPT_INTEGER_BLOB
);
4426 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4427 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4428 &bytesNeeded
, NULL
);
4429 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4430 CRYPT_FreeSpace(pDecodePara
, blob
);
4436 SetLastError(STATUS_ACCESS_VIOLATION
);
4443 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4444 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4445 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4451 *pcbStructInfo
= sizeof(int);
4456 if (pbEncoded
[0] == ASN_ENUMERATED
)
4458 unsigned int val
= 0, i
;
4462 SetLastError(CRYPT_E_ASN1_EOD
);
4465 else if (pbEncoded
[1] == 0)
4467 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4472 /* A little strange looking, but we have to accept a sign byte:
4473 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4474 * assuming a small length is okay here, it has to be in short
4477 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4479 SetLastError(CRYPT_E_ASN1_LARGE
);
4482 for (i
= 0; i
< pbEncoded
[1]; i
++)
4485 val
|= pbEncoded
[2 + i
];
4487 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4488 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4490 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4491 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4492 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4498 SetLastError(CRYPT_E_ASN1_BADTAG
);
4504 SetLastError(STATUS_ACCESS_VIOLATION
);
4511 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4514 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4519 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4521 if (!isdigit(*(pbEncoded))) \
4523 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4529 (word) += *(pbEncoded)++ - '0'; \
4534 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4535 SYSTEMTIME
*sysTime
)
4539 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4541 WORD hours
, minutes
= 0;
4542 BYTE sign
= *pbEncoded
++;
4545 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4546 if (ret
&& hours
>= 24)
4548 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4553 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4554 if (ret
&& minutes
>= 60)
4556 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4564 sysTime
->wHour
+= hours
;
4565 sysTime
->wMinute
+= minutes
;
4569 if (hours
> sysTime
->wHour
)
4572 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4575 sysTime
->wHour
-= hours
;
4576 if (minutes
> sysTime
->wMinute
)
4579 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4582 sysTime
->wMinute
-= minutes
;
4589 #define MIN_ENCODED_TIME_LENGTH 10
4591 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4592 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4597 if (pbEncoded
[0] == ASN_UTCTIME
)
4600 SetLastError(CRYPT_E_ASN1_EOD
);
4601 else if (pbEncoded
[1] > 0x7f)
4603 /* long-form date strings really can't be valid */
4604 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4608 SYSTEMTIME sysTime
= { 0 };
4609 BYTE len
= pbEncoded
[1];
4611 if (len
< MIN_ENCODED_TIME_LENGTH
)
4612 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4617 *pcbDecoded
= 2 + len
;
4619 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4620 if (sysTime
.wYear
>= 50)
4621 sysTime
.wYear
+= 1900;
4623 sysTime
.wYear
+= 2000;
4624 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4625 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4626 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4627 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4630 if (len
>= 2 && isdigit(*pbEncoded
) &&
4631 isdigit(*(pbEncoded
+ 1)))
4632 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4634 else if (isdigit(*pbEncoded
))
4635 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4638 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4644 *pcbStructInfo
= sizeof(FILETIME
);
4645 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4647 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4653 SetLastError(CRYPT_E_ASN1_BADTAG
);
4657 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4658 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4659 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4667 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4668 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4672 *pcbStructInfo
= bytesNeeded
;
4673 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4674 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4676 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4677 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4678 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4679 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4680 &bytesNeeded
, NULL
);
4681 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4682 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4688 SetLastError(STATUS_ACCESS_VIOLATION
);
4694 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4695 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4700 if (pbEncoded
[0] == ASN_GENERALTIME
)
4703 SetLastError(CRYPT_E_ASN1_EOD
);
4704 else if (pbEncoded
[1] > 0x7f)
4706 /* long-form date strings really can't be valid */
4707 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4711 BYTE len
= pbEncoded
[1];
4713 if (len
< MIN_ENCODED_TIME_LENGTH
)
4714 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4717 SYSTEMTIME sysTime
= { 0 };
4721 *pcbDecoded
= 2 + len
;
4723 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4724 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4725 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4726 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4729 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4732 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4734 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4741 /* workaround macro weirdness */
4742 digits
= min(len
, 3);
4743 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4744 sysTime
.wMilliseconds
);
4747 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4753 *pcbStructInfo
= sizeof(FILETIME
);
4754 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4756 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4762 SetLastError(CRYPT_E_ASN1_BADTAG
);
4766 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4767 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4771 InternalDecodeFunc decode
= NULL
;
4773 if (pbEncoded
[0] == ASN_UTCTIME
)
4774 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4775 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4776 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4778 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4779 pcbStructInfo
, pcbDecoded
);
4782 SetLastError(CRYPT_E_ASN1_BADTAG
);
4788 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4789 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4790 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4798 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4799 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4803 *pcbStructInfo
= bytesNeeded
;
4804 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4805 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4807 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4808 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4809 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4810 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4811 &bytesNeeded
, NULL
);
4812 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4813 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4819 SetLastError(STATUS_ACCESS_VIOLATION
);
4826 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4827 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4828 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4834 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4836 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4838 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4843 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4844 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4846 ptr
= pbEncoded
+ 1 + lenBytes
;
4847 remainingLen
= dataLen
;
4848 while (ret
&& remainingLen
)
4852 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4855 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4857 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4858 ptr
+= 1 + nextLenBytes
+ nextLen
;
4859 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4860 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4861 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4867 CRYPT_SEQUENCE_OF_ANY
*seq
;
4872 *pcbStructInfo
= bytesNeeded
;
4873 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4874 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4876 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4877 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4879 seq
->cValue
= cValue
;
4880 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4882 nextPtr
= (BYTE
*)seq
->rgValue
+
4883 cValue
* sizeof(CRYPT_DER_BLOB
);
4884 ptr
= pbEncoded
+ 1 + lenBytes
;
4885 remainingLen
= dataLen
;
4887 while (ret
&& remainingLen
)
4891 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4894 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4896 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4898 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4899 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4902 seq
->rgValue
[i
].pbData
= nextPtr
;
4903 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4905 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4907 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4908 ptr
+= 1 + nextLenBytes
+ nextLen
;
4912 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4913 CRYPT_FreeSpace(pDecodePara
, seq
);
4920 SetLastError(CRYPT_E_ASN1_BADTAG
);
4926 SetLastError(STATUS_ACCESS_VIOLATION
);
4933 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4934 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4939 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4941 DWORD bytesNeeded
, dataLen
;
4943 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4945 struct AsnArrayDescriptor arrayDesc
= {
4946 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4947 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
4948 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
4949 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
4950 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4951 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4952 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4957 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4958 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4959 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
4960 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4961 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
4964 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4966 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4968 *pcbStructInfo
= bytesNeeded
;
4969 else if (*pcbStructInfo
< bytesNeeded
)
4971 *pcbStructInfo
= bytesNeeded
;
4972 SetLastError(ERROR_MORE_DATA
);
4977 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
4979 *pcbStructInfo
= bytesNeeded
;
4982 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4983 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4984 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4985 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
4989 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4995 SetLastError(CRYPT_E_ASN1_BADTAG
);
5001 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5002 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5004 struct AsnDecodeSequenceItem items
[] = {
5005 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
5006 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5007 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
5008 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5009 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
5010 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
5011 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
5012 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
5013 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
5014 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
5016 CRL_DIST_POINT
*point
= pvStructInfo
;
5019 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5020 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5021 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5025 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5026 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5027 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5031 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5032 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5036 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5037 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
5038 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
5039 sizeof(CRL_DIST_POINTS_INFO
),
5040 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5041 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5042 CRL_DIST_POINTS_INFO
*info
= pvStructInfo
;
5044 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5045 info
->rgDistPoint
= (CRL_DIST_POINT
*)(info
+ 1);
5046 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5047 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5051 SetLastError(STATUS_ACCESS_VIOLATION
);
5058 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5059 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5060 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5064 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5065 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5069 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5070 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5071 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5072 sizeof(CERT_ENHKEY_USAGE
),
5073 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5074 CERT_ENHKEY_USAGE
*usage
= pvStructInfo
;
5076 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5077 usage
->rgpszUsageIdentifier
= (LPSTR
*)(usage
+ 1);
5078 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5079 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5083 SetLastError(STATUS_ACCESS_VIOLATION
);
5090 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5091 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5092 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5096 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5097 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5101 struct AsnDecodeSequenceItem items
[] = {
5102 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5103 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5104 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5105 offsetof(CRL_ISSUING_DIST_POINT
,
5106 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5107 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5108 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5110 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5111 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5113 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5114 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5115 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5116 OnlySomeReasonFlags
.pbData
), 0 },
5117 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5118 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5121 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5122 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5123 pcbStructInfo
, NULL
, NULL
);
5127 SetLastError(STATUS_ACCESS_VIOLATION
);
5134 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5135 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5139 DWORD max
, size
= sizeof(max
);
5141 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5142 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5146 SetLastError(CRYPT_E_ASN1_EOD
);
5149 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5151 SetLastError(CRYPT_E_ASN1_BADTAG
);
5154 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5155 &max
, &size
, pcbDecoded
)))
5157 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5160 *pcbStructInfo
= bytesNeeded
;
5161 else if (*pcbStructInfo
< bytesNeeded
)
5163 *pcbStructInfo
= bytesNeeded
;
5164 SetLastError(ERROR_MORE_DATA
);
5169 CERT_GENERAL_SUBTREE
*subtree
= CONTAINING_RECORD(pvStructInfo
,
5170 CERT_GENERAL_SUBTREE
, fMaximum
);
5172 *pcbStructInfo
= bytesNeeded
;
5173 /* The BOOL is implicit: if the integer is present, then it's
5176 subtree
->fMaximum
= TRUE
;
5177 subtree
->dwMaximum
= max
;
5180 TRACE("returning %d\n", ret
);
5184 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5185 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5189 struct AsnDecodeSequenceItem items
[] = {
5190 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5191 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5192 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5193 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5194 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5195 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5196 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5197 TRUE
, FALSE
, 0, 0 },
5199 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5201 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5202 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5204 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5205 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5206 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5209 TRACE("%d\n", *pcbDecoded
);
5210 if (*pcbDecoded
< cbEncoded
)
5211 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5212 *(pbEncoded
+ *pcbDecoded
+ 1));
5214 TRACE("returning %d\n", ret
);
5218 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5219 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5223 struct AsnArrayDescriptor arrayDesc
= { 0,
5224 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5225 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5226 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5228 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5229 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5231 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5232 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5234 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5235 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5239 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5240 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5244 struct AsnArrayDescriptor arrayDesc
= { 0,
5245 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5246 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5247 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5248 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5249 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5251 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5252 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5254 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5255 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5259 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5260 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5261 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5265 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5266 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5270 struct AsnDecodeSequenceItem items
[] = {
5271 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5272 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5273 CRYPT_AsnDecodePermittedSubtree
,
5274 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5275 cExcludedSubtree
), TRUE
, TRUE
,
5276 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5277 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5278 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5279 CRYPT_AsnDecodeExcludedSubtree
,
5280 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5282 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5285 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5286 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5287 pcbStructInfo
, NULL
, NULL
);
5291 SetLastError(STATUS_ACCESS_VIOLATION
);
5297 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5298 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5302 struct AsnDecodeSequenceItem items
[] = {
5303 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5304 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5306 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5307 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5308 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5310 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5312 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5313 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5315 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5316 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5317 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5318 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5320 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5323 TRACE("returning %d\n", ret
);
5327 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5328 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5331 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5332 struct AsnDecodeSequenceItem items
[] = {
5333 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5334 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5335 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5336 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5337 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5338 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5339 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5340 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5341 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5342 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5343 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5344 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5345 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5346 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5347 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5348 HashEncryptionAlgorithm
.pszObjId
), 0 },
5349 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5350 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5351 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5352 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5353 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5354 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5355 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5359 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5360 pvStructInfo
, *pcbStructInfo
);
5362 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5363 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5364 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5368 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5369 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5370 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5374 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5375 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5379 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5380 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5381 if (ret
&& pvStructInfo
)
5383 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5384 pcbStructInfo
, *pcbStructInfo
);
5387 CMSG_SIGNER_INFO
*info
;
5389 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5390 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5391 info
= pvStructInfo
;
5392 info
->Issuer
.pbData
= ((BYTE
*)info
+
5393 sizeof(CMSG_SIGNER_INFO
));
5394 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5395 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5396 pcbStructInfo
, NULL
);
5397 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5398 CRYPT_FreeSpace(pDecodePara
, info
);
5404 SetLastError(STATUS_ACCESS_VIOLATION
);
5407 TRACE("returning %d\n", ret
);
5411 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5412 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5416 struct AsnArrayDescriptor arrayDesc
= { 0,
5417 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5418 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5419 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5420 CRYPT_AsnDecodeCopyBytes
,
5421 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5423 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5424 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5426 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5427 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5431 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5432 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5436 struct AsnArrayDescriptor arrayDesc
= { 0,
5437 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5438 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5439 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5440 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5441 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5443 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5444 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5446 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5447 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5451 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5452 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5455 CERT_ID
*id
= pvStructInfo
;
5458 if (*pbEncoded
== ASN_SEQUENCEOF
)
5460 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5461 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5465 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5466 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5467 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5468 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5470 *pcbStructInfo
= sizeof(CERT_ID
);
5473 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5475 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5476 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5480 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5481 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5482 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5483 sizeof(CRYPT_DATA_BLOB
);
5485 *pcbStructInfo
= sizeof(CERT_ID
);
5489 SetLastError(CRYPT_E_ASN1_BADTAG
);
5493 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5494 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5497 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5498 struct AsnDecodeSequenceItem items
[] = {
5499 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5500 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5501 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5502 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5503 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5504 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5505 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5506 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5507 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5508 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5509 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5510 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5511 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5512 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5513 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5514 HashEncryptionAlgorithm
.pszObjId
), 0 },
5515 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5516 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5517 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5518 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5519 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5520 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5521 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5525 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5526 pvStructInfo
, *pcbStructInfo
);
5528 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5529 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5530 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5534 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5535 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5536 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5540 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5541 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5545 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5546 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5547 if (ret
&& pvStructInfo
)
5549 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5550 pcbStructInfo
, *pcbStructInfo
);
5553 CMSG_CMS_SIGNER_INFO
*info
;
5555 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5556 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5557 info
= pvStructInfo
;
5558 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5559 sizeof(CMSG_CMS_SIGNER_INFO
));
5560 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5561 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5562 pcbStructInfo
, NULL
);
5563 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5564 CRYPT_FreeSpace(pDecodePara
, info
);
5570 SetLastError(STATUS_ACCESS_VIOLATION
);
5573 TRACE("returning %d\n", ret
);
5577 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5578 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5581 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5582 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5583 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5584 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5585 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5586 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5588 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5589 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5591 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5592 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5596 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5597 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5598 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5601 struct AsnDecodeSequenceItem items
[] = {
5602 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5603 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5604 /* Placeholder for the hash algorithms - redundant with those in the
5605 * signers, so just ignore them.
5607 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5608 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5609 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5610 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5611 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5612 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5613 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5614 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5615 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5616 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5617 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5618 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5619 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5620 CRYPT_DecodeSignerArray
,
5621 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5622 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5625 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5626 pDecodePara
, signedInfo
, *pcbSignedInfo
);
5628 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5629 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5631 TRACE("returning %d\n", ret
);
5635 static BOOL
CRYPT_AsnDecodeRecipientInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5636 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5639 CMSG_KEY_TRANS_RECIPIENT_INFO
*info
= pvStructInfo
;
5640 struct AsnDecodeSequenceItem items
[] = {
5641 { ASN_INTEGER
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, dwVersion
),
5642 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5643 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5644 RecipientId
.u
.IssuerSerialNumber
), CRYPT_AsnDecodeIssuerSerialNumber
,
5645 sizeof(CERT_ISSUER_SERIAL_NUMBER
), FALSE
, TRUE
,
5646 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5647 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
), 0 },
5648 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5649 KeyEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5650 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5651 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5652 KeyEncryptionAlgorithm
.pszObjId
), 0 },
5653 { ASN_OCTETSTRING
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
),
5654 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
5655 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
.pbData
), 0 },
5658 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5659 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5661 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5662 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5663 pcbDecoded
, info
? info
->RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
:
5666 info
->RecipientId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5667 TRACE("returning %d\n", ret
);
5671 static BOOL
CRYPT_DecodeRecipientInfoArray(const BYTE
*pbEncoded
,
5672 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5676 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5677 offsetof(CRYPT_ENVELOPED_DATA
, cRecipientInfo
),
5678 offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
),
5679 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5680 CRYPT_AsnDecodeRecipientInfo
, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO
), TRUE
,
5681 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5682 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
) };
5684 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5685 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5687 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5688 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5689 TRACE("returning %d\n", ret
);
5693 static BOOL
CRYPT_AsnDecodeEncryptedContentInfo(const BYTE
*pbEncoded
,
5694 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5698 CRYPT_ENCRYPTED_CONTENT_INFO
*info
= pvStructInfo
;
5699 struct AsnDecodeSequenceItem items
[] = {
5700 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5701 contentType
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
5702 FALSE
, TRUE
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5704 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5705 contentEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5706 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5707 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5708 contentEncryptionAlgorithm
.pszObjId
), 0 },
5709 { ASN_CONTEXT
| 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5710 encryptedContent
), CRYPT_AsnDecodeOctetsInternal
,
5711 sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
5712 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
, encryptedContent
.pbData
) },
5715 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5716 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5718 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5719 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5720 pcbDecoded
, info
? info
->contentType
: NULL
);
5721 TRACE("returning %d\n", ret
);
5725 BOOL
CRYPT_AsnDecodePKCSEnvelopedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5726 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5727 CRYPT_ENVELOPED_DATA
*envelopedData
, DWORD
*pcbEnvelopedData
)
5730 struct AsnDecodeSequenceItem items
[] = {
5731 { ASN_INTEGER
, offsetof(CRYPT_ENVELOPED_DATA
, version
),
5732 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5733 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ENVELOPED_DATA
,
5734 cRecipientInfo
), CRYPT_DecodeRecipientInfoArray
,
5735 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5736 FALSE
, TRUE
, offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
), 0 },
5737 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
),
5738 CRYPT_AsnDecodeEncryptedContentInfo
,
5739 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO
), FALSE
, TRUE
,
5740 offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
.contentType
), 0 },
5743 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5744 pDecodePara
, envelopedData
, *pcbEnvelopedData
);
5746 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5747 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, envelopedData
,
5748 pcbEnvelopedData
, NULL
, NULL
);
5749 TRACE("returning %d\n", ret
);
5753 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5754 LPCSTR lpszStructType
)
5756 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5758 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5759 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5761 SetLastError(ERROR_FILE_NOT_FOUND
);
5764 if (IS_INTOID(lpszStructType
))
5766 switch (LOWORD(lpszStructType
))
5768 case LOWORD(X509_CERT
):
5769 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5771 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5772 decodeFunc
= CRYPT_AsnDecodeCert
;
5774 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5775 decodeFunc
= CRYPT_AsnDecodeCRL
;
5777 case LOWORD(X509_EXTENSIONS
):
5778 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5780 case LOWORD(X509_NAME_VALUE
):
5781 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5783 case LOWORD(X509_NAME
):
5784 decodeFunc
= CRYPT_AsnDecodeName
;
5786 case LOWORD(X509_PUBLIC_KEY_INFO
):
5787 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5789 case LOWORD(X509_AUTHORITY_KEY_ID
):
5790 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5792 case LOWORD(X509_ALTERNATE_NAME
):
5793 decodeFunc
= CRYPT_AsnDecodeAltName
;
5795 case LOWORD(X509_BASIC_CONSTRAINTS
):
5796 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5798 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5799 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5801 case LOWORD(X509_CERT_POLICIES
):
5802 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5804 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5805 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5807 case LOWORD(X509_UNICODE_NAME
):
5808 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5810 case LOWORD(PKCS_ATTRIBUTE
):
5811 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5813 case LOWORD(X509_UNICODE_NAME_VALUE
):
5814 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5816 case LOWORD(X509_OCTET_STRING
):
5817 decodeFunc
= CRYPT_AsnDecodeOctets
;
5819 case LOWORD(X509_BITS
):
5820 case LOWORD(X509_KEY_USAGE
):
5821 decodeFunc
= CRYPT_AsnDecodeBits
;
5823 case LOWORD(X509_INTEGER
):
5824 decodeFunc
= CRYPT_AsnDecodeInt
;
5826 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5827 decodeFunc
= CRYPT_AsnDecodeInteger
;
5829 case LOWORD(X509_MULTI_BYTE_UINT
):
5830 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5832 case LOWORD(X509_ENUMERATED
):
5833 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5835 case LOWORD(X509_CHOICE_OF_TIME
):
5836 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5838 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5839 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5841 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5842 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5844 case LOWORD(PKCS_CONTENT_INFO
):
5845 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5847 case LOWORD(X509_SEQUENCE_OF_ANY
):
5848 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5850 case LOWORD(PKCS_UTC_TIME
):
5851 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5853 case LOWORD(X509_CRL_DIST_POINTS
):
5854 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5856 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5857 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5859 case LOWORD(PKCS_CTL
):
5860 decodeFunc
= CRYPT_AsnDecodeCTL
;
5862 case LOWORD(PKCS_SMIME_CAPABILITIES
):
5863 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5865 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
5866 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5868 case LOWORD(PKCS_ATTRIBUTES
):
5869 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
5871 case LOWORD(X509_ISSUING_DIST_POINT
):
5872 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5874 case LOWORD(X509_NAME_CONSTRAINTS
):
5875 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5877 case LOWORD(X509_POLICY_MAPPINGS
):
5878 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5880 case LOWORD(X509_POLICY_CONSTRAINTS
):
5881 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5883 case LOWORD(PKCS7_SIGNER_INFO
):
5884 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
5886 case LOWORD(CMS_SIGNER_INFO
):
5887 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
5891 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
5892 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5893 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
5894 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5895 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
5896 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5897 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
5898 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5899 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
5900 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5901 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
5902 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5903 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
5904 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5905 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
5906 decodeFunc
= CRYPT_AsnDecodeBits
;
5907 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
5908 decodeFunc
= CRYPT_AsnDecodeOctets
;
5909 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
5910 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5911 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
5912 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5913 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
5914 decodeFunc
= CRYPT_AsnDecodeAltName
;
5915 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
5916 decodeFunc
= CRYPT_AsnDecodeAltName
;
5917 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
5918 decodeFunc
= CRYPT_AsnDecodeAltName
;
5919 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
5920 decodeFunc
= CRYPT_AsnDecodeAltName
;
5921 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
5922 decodeFunc
= CRYPT_AsnDecodeAltName
;
5923 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
5924 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5925 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
5926 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5927 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
5928 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5929 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
5930 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5931 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
5932 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5933 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
5934 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5935 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
5936 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5937 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
5938 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5939 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
5940 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5941 else if (!strcmp(lpszStructType
, szOID_CTL
))
5942 decodeFunc
= CRYPT_AsnDecodeCTL
;
5946 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
5947 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5949 static HCRYPTOIDFUNCSET set
= NULL
;
5950 CryptDecodeObjectFunc decodeFunc
= NULL
;
5953 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
5954 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5955 (void **)&decodeFunc
, hFunc
);
5959 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
5960 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5962 static HCRYPTOIDFUNCSET set
= NULL
;
5963 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5966 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
5967 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5968 (void **)&decodeFunc
, hFunc
);
5972 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5973 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
5974 DWORD
*pcbStructInfo
)
5977 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
5978 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
5979 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5981 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
5982 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
5983 pvStructInfo
, pcbStructInfo
);
5985 if (!pvStructInfo
&& !pcbStructInfo
)
5987 SetLastError(ERROR_INVALID_PARAMETER
);
5990 if (cbEncoded
> MAX_ENCODED_LEN
)
5992 SetLastError(CRYPT_E_ASN1_LARGE
);
5996 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
5999 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6000 debugstr_a(lpszStructType
));
6001 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
6002 lpszStructType
, &hFunc
);
6003 if (!pCryptDecodeObject
)
6004 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
6005 lpszStructType
, &hFunc
);
6007 if (pCryptDecodeObject
)
6008 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6009 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6010 else if (pCryptDecodeObjectEx
)
6011 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
6012 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6013 pvStructInfo
, pcbStructInfo
);
6015 CryptFreeOIDFunctionAddress(hFunc
, 0);
6016 TRACE_(crypt
)("returning %d\n", ret
);
6020 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6021 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6022 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6025 CryptDecodeObjectExFunc decodeFunc
;
6026 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6028 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6029 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
6030 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6032 if (!pvStructInfo
&& !pcbStructInfo
)
6034 SetLastError(ERROR_INVALID_PARAMETER
);
6037 if (cbEncoded
> MAX_ENCODED_LEN
)
6039 SetLastError(CRYPT_E_ASN1_LARGE
);
6043 SetLastError(NOERROR
);
6044 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6048 SetLastError(ERROR_INVALID_PARAMETER
);
6051 *(BYTE
**)pvStructInfo
= NULL
;
6053 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
6056 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6057 debugstr_a(lpszStructType
));
6058 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
6062 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
6063 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6066 CryptDecodeObjectFunc pCryptDecodeObject
=
6067 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
6069 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6070 * directly, as that could cause an infinite loop.
6072 if (pCryptDecodeObject
)
6074 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6076 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6077 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
6078 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
6079 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
6081 ret
= pCryptDecodeObject(dwCertEncodingType
,
6082 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
6083 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
6085 CRYPT_FreeSpace(pDecodePara
, *(BYTE
**)pvStructInfo
);
6089 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6090 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6094 CryptFreeOIDFunctionAddress(hFunc
, 0);
6095 TRACE_(crypt
)("returning %d\n", ret
);
6099 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
6103 TRACE_(crypt
)("(%p)\n", pPFX
);
6105 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6106 * version integer of length 1 (3 encoded byes) and at least one other
6107 * datum (two encoded bytes), plus at least two bytes for the outer
6108 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6110 if (pPFX
->cbData
< 7)
6112 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
6116 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
6118 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
6120 /* Need at least three bytes for the integer version */
6121 if (pPFX
->cbData
< 1 + lenLen
+ 3)
6123 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
6124 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
6125 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
6134 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6137 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);
6141 BOOL WINAPI
PFXVerifyPassword(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6144 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);