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
) };
1469 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1470 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1474 SetLastError(STATUS_ACCESS_VIOLATION
);
1481 /* Warning: this assumes the address of value->Value.pbData is already set, in
1482 * order to avoid overwriting memory. (In some cases, it may change it, if it
1483 * doesn't copy anything to memory.) Be sure to set it correctly!
1485 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1486 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1491 CERT_NAME_VALUE
*value
= pvStructInfo
;
1493 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1495 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1496 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1498 switch (pbEncoded
[0])
1500 case ASN_OCTETSTRING
:
1501 valueType
= CERT_RDN_OCTET_STRING
;
1502 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1503 bytesNeeded
+= dataLen
;
1505 case ASN_NUMERICSTRING
:
1506 valueType
= CERT_RDN_NUMERIC_STRING
;
1507 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1508 bytesNeeded
+= dataLen
;
1510 case ASN_PRINTABLESTRING
:
1511 valueType
= CERT_RDN_PRINTABLE_STRING
;
1512 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1513 bytesNeeded
+= dataLen
;
1516 valueType
= CERT_RDN_IA5_STRING
;
1517 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1518 bytesNeeded
+= dataLen
;
1521 valueType
= CERT_RDN_T61_STRING
;
1522 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1523 bytesNeeded
+= dataLen
;
1525 case ASN_VIDEOTEXSTRING
:
1526 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1527 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1528 bytesNeeded
+= dataLen
;
1530 case ASN_GRAPHICSTRING
:
1531 valueType
= CERT_RDN_GRAPHIC_STRING
;
1532 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1533 bytesNeeded
+= dataLen
;
1535 case ASN_VISIBLESTRING
:
1536 valueType
= CERT_RDN_VISIBLE_STRING
;
1537 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1538 bytesNeeded
+= dataLen
;
1540 case ASN_GENERALSTRING
:
1541 valueType
= CERT_RDN_GENERAL_STRING
;
1542 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1543 bytesNeeded
+= dataLen
;
1545 case ASN_UNIVERSALSTRING
:
1546 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1547 SetLastError(CRYPT_E_ASN1_BADTAG
);
1550 valueType
= CERT_RDN_BMP_STRING
;
1551 bytesNeeded
+= dataLen
;
1553 case ASN_UTF8STRING
:
1554 valueType
= CERT_RDN_UTF8_STRING
;
1555 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1556 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1559 SetLastError(CRYPT_E_ASN1_BADTAG
);
1564 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1566 *pcbStructInfo
= bytesNeeded
;
1567 else if (*pcbStructInfo
< bytesNeeded
)
1569 *pcbStructInfo
= bytesNeeded
;
1570 SetLastError(ERROR_MORE_DATA
);
1575 *pcbStructInfo
= bytesNeeded
;
1576 value
->dwValueType
= valueType
;
1581 assert(value
->Value
.pbData
);
1582 switch (pbEncoded
[0])
1584 case ASN_OCTETSTRING
:
1585 case ASN_NUMERICSTRING
:
1586 case ASN_PRINTABLESTRING
:
1589 case ASN_VIDEOTEXSTRING
:
1590 case ASN_GRAPHICSTRING
:
1591 case ASN_VISIBLESTRING
:
1592 case ASN_GENERALSTRING
:
1593 value
->Value
.cbData
= dataLen
;
1596 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1597 memcpy(value
->Value
.pbData
,
1598 pbEncoded
+ 1 + lenBytes
, dataLen
);
1600 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1606 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1608 value
->Value
.cbData
= dataLen
;
1609 for (i
= 0; i
< dataLen
/ 2; i
++)
1610 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1611 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1614 case ASN_UTF8STRING
:
1616 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1618 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1619 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1620 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1627 value
->Value
.cbData
= 0;
1628 value
->Value
.pbData
= NULL
;
1635 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1636 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1637 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1643 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1644 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1645 if (ret
&& pvStructInfo
)
1647 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1648 pcbStructInfo
, *pcbStructInfo
);
1651 CERT_NAME_VALUE
*value
;
1653 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1654 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1655 value
= pvStructInfo
;
1656 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1657 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1658 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1659 pcbStructInfo
, NULL
);
1660 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1661 CRYPT_FreeSpace(pDecodePara
, value
);
1667 SetLastError(STATUS_ACCESS_VIOLATION
);
1674 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1675 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1680 CERT_NAME_VALUE
*value
= pvStructInfo
;
1682 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1684 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1685 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1687 switch (pbEncoded
[0])
1689 case ASN_NUMERICSTRING
:
1690 valueType
= CERT_RDN_NUMERIC_STRING
;
1692 bytesNeeded
+= (dataLen
+ 1) * 2;
1694 case ASN_PRINTABLESTRING
:
1695 valueType
= CERT_RDN_PRINTABLE_STRING
;
1697 bytesNeeded
+= (dataLen
+ 1) * 2;
1700 valueType
= CERT_RDN_IA5_STRING
;
1702 bytesNeeded
+= (dataLen
+ 1) * 2;
1705 valueType
= CERT_RDN_T61_STRING
;
1707 bytesNeeded
+= (dataLen
+ 1) * 2;
1709 case ASN_VIDEOTEXSTRING
:
1710 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1712 bytesNeeded
+= (dataLen
+ 1) * 2;
1714 case ASN_GRAPHICSTRING
:
1715 valueType
= CERT_RDN_GRAPHIC_STRING
;
1717 bytesNeeded
+= (dataLen
+ 1) * 2;
1719 case ASN_VISIBLESTRING
:
1720 valueType
= CERT_RDN_VISIBLE_STRING
;
1722 bytesNeeded
+= (dataLen
+ 1) * 2;
1724 case ASN_GENERALSTRING
:
1725 valueType
= CERT_RDN_GENERAL_STRING
;
1727 bytesNeeded
+= (dataLen
+ 1) * 2;
1729 case ASN_UNIVERSALSTRING
:
1730 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1732 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1735 valueType
= CERT_RDN_BMP_STRING
;
1737 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1739 case ASN_UTF8STRING
:
1740 valueType
= CERT_RDN_UTF8_STRING
;
1742 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1743 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1746 SetLastError(CRYPT_E_ASN1_BADTAG
);
1751 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1753 *pcbStructInfo
= bytesNeeded
;
1754 else if (*pcbStructInfo
< bytesNeeded
)
1756 *pcbStructInfo
= bytesNeeded
;
1757 SetLastError(ERROR_MORE_DATA
);
1762 *pcbStructInfo
= bytesNeeded
;
1763 value
->dwValueType
= valueType
;
1767 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1769 assert(value
->Value
.pbData
);
1770 switch (pbEncoded
[0])
1772 case ASN_NUMERICSTRING
:
1773 case ASN_PRINTABLESTRING
:
1776 case ASN_VIDEOTEXSTRING
:
1777 case ASN_GRAPHICSTRING
:
1778 case ASN_VISIBLESTRING
:
1779 case ASN_GENERALSTRING
:
1780 value
->Value
.cbData
= dataLen
* 2;
1781 for (i
= 0; i
< dataLen
; i
++)
1782 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1785 case ASN_UNIVERSALSTRING
:
1786 value
->Value
.cbData
= dataLen
/ 2;
1787 for (i
= 0; i
< dataLen
/ 4; i
++)
1788 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1789 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1793 value
->Value
.cbData
= dataLen
;
1794 for (i
= 0; i
< dataLen
/ 2; i
++)
1795 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1796 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1799 case ASN_UTF8STRING
:
1800 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1801 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1802 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1803 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1804 value
->Value
.cbData
+= sizeof(WCHAR
);
1810 value
->Value
.cbData
= 0;
1811 value
->Value
.pbData
= NULL
;
1818 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1819 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1820 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1826 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1827 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1828 if (ret
&& pvStructInfo
)
1830 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1831 pcbStructInfo
, *pcbStructInfo
);
1834 CERT_NAME_VALUE
*value
;
1836 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1837 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1838 value
= pvStructInfo
;
1839 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1840 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1841 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1842 pcbStructInfo
, NULL
);
1843 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1844 CRYPT_FreeSpace(pDecodePara
, value
);
1850 SetLastError(STATUS_ACCESS_VIOLATION
);
1857 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1858 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1861 struct AsnDecodeSequenceItem items
[] = {
1862 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1863 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1864 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1865 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1866 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1867 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1869 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1871 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1872 pvStructInfo
, *pcbStructInfo
);
1875 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1876 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1877 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1878 attr
? attr
->pszObjId
: NULL
);
1881 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1882 debugstr_a(attr
->pszObjId
));
1883 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1885 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1889 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1890 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1893 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1894 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1896 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1897 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1899 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1900 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1904 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1905 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1906 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1912 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1913 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1914 sizeof(CERT_NAME_INFO
),
1915 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1916 offsetof(CERT_RDN
, rgRDNAttr
) };
1919 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1920 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1925 *pcbStructInfo
= bytesNeeded
;
1926 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1927 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1929 CERT_NAME_INFO
*info
;
1931 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1932 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1933 info
= pvStructInfo
;
1934 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1935 sizeof(CERT_NAME_INFO
));
1936 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1937 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1938 &bytesNeeded
, NULL
);
1939 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1940 CRYPT_FreeSpace(pDecodePara
, info
);
1946 SetLastError(STATUS_ACCESS_VIOLATION
);
1953 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1954 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1958 struct AsnDecodeSequenceItem items
[] = {
1959 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1960 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1961 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1962 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1963 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1964 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1966 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1968 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1969 pvStructInfo
, *pcbStructInfo
);
1972 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1973 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1974 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1975 attr
? attr
->pszObjId
: NULL
);
1978 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1979 debugstr_a(attr
->pszObjId
));
1980 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1982 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1986 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1987 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1990 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1991 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1993 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1994 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1996 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1997 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2001 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
2002 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2003 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2009 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2010 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2011 sizeof(CERT_NAME_INFO
),
2012 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2013 offsetof(CERT_RDN
, rgRDNAttr
) };
2016 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2017 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2022 *pcbStructInfo
= bytesNeeded
;
2023 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2024 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2026 CERT_NAME_INFO
*info
;
2028 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2029 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2030 info
= pvStructInfo
;
2031 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2032 sizeof(CERT_NAME_INFO
));
2033 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2034 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2035 &bytesNeeded
, NULL
);
2036 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2037 CRYPT_FreeSpace(pDecodePara
, info
);
2043 SetLastError(STATUS_ACCESS_VIOLATION
);
2050 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2053 BOOL ret
= TRUE
, done
= FALSE
;
2054 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2056 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2063 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2066 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2068 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2070 indefiniteNestingLevels
++;
2071 pbEncoded
+= 1 + lenBytes
;
2072 cbEncoded
-= 1 + lenBytes
;
2073 decoded
+= 1 + lenBytes
;
2074 TRACE("indefiniteNestingLevels = %d\n",
2075 indefiniteNestingLevels
);
2079 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2080 indefiniteNestingLevels
)
2082 indefiniteNestingLevels
--;
2083 TRACE("indefiniteNestingLevels = %d\n",
2084 indefiniteNestingLevels
);
2086 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2087 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2088 decoded
+= 1 + lenBytes
+ dataLen
;
2089 if (!indefiniteNestingLevels
)
2093 } while (ret
&& !done
);
2094 /* If we haven't found all 0 TLVs, we haven't found the end */
2095 if (ret
&& indefiniteNestingLevels
)
2097 SetLastError(CRYPT_E_ASN1_EOD
);
2101 *pcbDecoded
= decoded
;
2102 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2106 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2107 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2111 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2113 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2114 pvStructInfo
, *pcbStructInfo
);
2116 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2118 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2119 bytesNeeded
+= encodedLen
;
2121 *pcbStructInfo
= bytesNeeded
;
2122 else if (*pcbStructInfo
< bytesNeeded
)
2124 SetLastError(ERROR_MORE_DATA
);
2125 *pcbStructInfo
= bytesNeeded
;
2130 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2132 *pcbStructInfo
= bytesNeeded
;
2133 blob
->cbData
= encodedLen
;
2136 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2137 blob
->pbData
= (LPBYTE
)pbEncoded
;
2140 assert(blob
->pbData
);
2141 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2145 blob
->pbData
= NULL
;
2148 *pcbDecoded
= encodedLen
;
2153 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2154 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2157 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2158 offsetof(CTL_USAGE
, cUsageIdentifier
),
2159 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2161 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2163 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2164 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2168 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2169 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2172 struct AsnArrayDescriptor arrayDesc
= { 0,
2173 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2174 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2175 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2176 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2179 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2180 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2184 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2185 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2187 struct AsnDecodeSequenceItem items
[] = {
2188 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2189 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2190 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2191 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2192 CRYPT_AsnDecodeCTLEntryAttributes
,
2193 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2194 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2197 CTL_ENTRY
*entry
= pvStructInfo
;
2199 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2202 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2203 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2204 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2208 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2209 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2212 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2213 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2214 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2215 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2216 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2218 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2219 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2221 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2222 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2226 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2227 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2231 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2232 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2233 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2234 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2235 offsetof(CERT_EXTENSION
, pszObjId
) };
2237 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2238 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2240 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2241 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2245 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2246 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2252 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2254 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2256 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2257 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2258 if (ret
&& pcbDecoded
)
2259 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2264 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2265 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2266 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2270 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2271 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2275 struct AsnDecodeSequenceItem items
[] = {
2276 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2277 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2278 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2279 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2280 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2281 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2282 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2283 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2284 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2285 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2286 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2287 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2288 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2290 { 0, offsetof(CTL_INFO
, NextUpdate
),
2291 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2293 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2294 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2295 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2296 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2297 CRYPT_AsnDecodeCTLEntries
,
2298 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2299 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2300 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2301 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2302 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2305 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2306 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2307 pcbStructInfo
, NULL
, NULL
);
2311 SetLastError(STATUS_ACCESS_VIOLATION
);
2317 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2318 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2322 struct AsnDecodeSequenceItem items
[] = {
2323 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2324 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2325 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2326 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2327 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2328 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2330 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2332 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2333 pvStructInfo
, *pcbStructInfo
);
2335 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2336 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2337 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2338 TRACE("returning %d\n", ret
);
2342 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2343 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2344 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2348 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2349 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2353 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2354 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2355 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2356 sizeof(CRYPT_SMIME_CAPABILITIES
),
2357 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2358 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2360 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2361 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2365 SetLastError(STATUS_ACCESS_VIOLATION
);
2368 TRACE("returning %d\n", ret
);
2372 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2373 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2378 LPSTR
*pStr
= pvStructInfo
;
2380 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2382 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2383 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2385 if (pbEncoded
[0] != ASN_IA5STRING
)
2387 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2392 bytesNeeded
+= dataLen
;
2394 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2396 *pcbStructInfo
= bytesNeeded
;
2397 else if (*pcbStructInfo
< bytesNeeded
)
2399 *pcbStructInfo
= bytesNeeded
;
2400 SetLastError(ERROR_MORE_DATA
);
2405 *pcbStructInfo
= bytesNeeded
;
2411 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2422 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2423 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2426 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2427 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2428 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2429 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2430 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2433 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2434 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2436 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2437 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2438 TRACE("returning %d\n", ret
);
2442 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2443 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2447 struct AsnDecodeSequenceItem items
[] = {
2448 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2449 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2450 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2451 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2452 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2453 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2454 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2455 rgNoticeNumbers
), 0 },
2459 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2460 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2462 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2463 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2467 /* The caller is expecting a pointer to a
2468 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2469 * CRYPT_AsnDecodeSequence is decoding a
2470 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2471 * needed, and decode again if the requisite space is available.
2473 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2475 *pcbStructInfo
= bytesNeeded
;
2476 else if (*pcbStructInfo
< bytesNeeded
)
2478 *pcbStructInfo
= bytesNeeded
;
2479 SetLastError(ERROR_MORE_DATA
);
2484 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2486 *pcbStructInfo
= bytesNeeded
;
2487 /* The pointer (pvStructInfo) passed in points to the first dynamic
2488 * pointer, so use it as the pointer to the
2489 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2490 * appropriate offset for the first dynamic pointer within the
2491 * notice reference by pointing to the first memory location past
2492 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2495 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2496 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2497 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2498 ret
= CRYPT_AsnDecodeSequence(items
,
2499 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2500 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2501 noticeRef
->pszOrganization
);
2504 TRACE("returning %d\n", ret
);
2508 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2509 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2515 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2517 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2518 DWORD bytesNeeded
= sizeof(LPWSTR
);
2520 switch (pbEncoded
[0])
2522 case ASN_NUMERICSTRING
:
2524 bytesNeeded
+= (dataLen
+ 1) * 2;
2526 case ASN_PRINTABLESTRING
:
2528 bytesNeeded
+= (dataLen
+ 1) * 2;
2532 bytesNeeded
+= (dataLen
+ 1) * 2;
2536 bytesNeeded
+= (dataLen
+ 1) * 2;
2538 case ASN_VIDEOTEXSTRING
:
2540 bytesNeeded
+= (dataLen
+ 1) * 2;
2542 case ASN_GRAPHICSTRING
:
2544 bytesNeeded
+= (dataLen
+ 1) * 2;
2546 case ASN_VISIBLESTRING
:
2548 bytesNeeded
+= (dataLen
+ 1) * 2;
2550 case ASN_GENERALSTRING
:
2552 bytesNeeded
+= (dataLen
+ 1) * 2;
2554 case ASN_UNIVERSALSTRING
:
2556 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2560 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2562 case ASN_UTF8STRING
:
2564 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2565 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2568 SetLastError(CRYPT_E_ASN1_BADTAG
);
2573 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2575 *pcbStructInfo
= bytesNeeded
;
2576 else if (*pcbStructInfo
< bytesNeeded
)
2578 *pcbStructInfo
= bytesNeeded
;
2579 SetLastError(ERROR_MORE_DATA
);
2584 LPWSTR
*pStr
= pvStructInfo
;
2586 *pcbStructInfo
= bytesNeeded
;
2590 LPWSTR str
= *(LPWSTR
*)pStr
;
2593 switch (pbEncoded
[0])
2595 case ASN_NUMERICSTRING
:
2596 case ASN_PRINTABLESTRING
:
2599 case ASN_VIDEOTEXSTRING
:
2600 case ASN_GRAPHICSTRING
:
2601 case ASN_VISIBLESTRING
:
2602 case ASN_GENERALSTRING
:
2603 for (i
= 0; i
< dataLen
; i
++)
2604 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2607 case ASN_UNIVERSALSTRING
:
2608 for (i
= 0; i
< dataLen
/ 4; i
++)
2609 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2610 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2614 for (i
= 0; i
< dataLen
/ 2; i
++)
2615 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2616 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2619 case ASN_UTF8STRING
:
2621 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2622 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2623 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2636 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2637 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2638 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2641 struct AsnDecodeSequenceItem items
[] = {
2642 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2643 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2644 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2645 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2646 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2647 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2648 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2650 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2652 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2653 pvStructInfo
, *pcbStructInfo
);
2655 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2656 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2657 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2658 TRACE("returning %d\n", ret
);
2662 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2663 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2664 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2665 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2669 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2670 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2676 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2677 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2682 *pcbStructInfo
= bytesNeeded
;
2683 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2684 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2686 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2688 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2689 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2690 notice
= pvStructInfo
;
2691 notice
->pNoticeReference
=
2692 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2693 ((BYTE
*)pvStructInfo
+
2694 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2695 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2696 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2697 pvStructInfo
, &bytesNeeded
, NULL
);
2698 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2699 CRYPT_FreeSpace(pDecodePara
, notice
);
2705 SetLastError(STATUS_ACCESS_VIOLATION
);
2708 TRACE("returning %d\n", ret
);
2712 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2713 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2717 struct AsnArrayDescriptor arrayDesc
= { 0,
2718 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2719 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2720 CRYPT_AsnDecodeCopyBytes
,
2721 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2723 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2724 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2726 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2727 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2731 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2732 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2736 struct AsnDecodeSequenceItem items
[] = {
2737 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2738 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2739 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2740 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2741 CRYPT_AsnDecodePKCSAttributeValue
,
2742 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2743 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2745 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2747 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2748 pvStructInfo
, *pcbStructInfo
);
2750 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2751 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2752 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2753 TRACE("returning %d\n", ret
);
2757 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2758 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2759 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2763 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2764 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2770 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2771 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2775 *pcbStructInfo
= bytesNeeded
;
2776 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2777 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2779 PCRYPT_ATTRIBUTE attr
;
2781 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2782 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2783 attr
= pvStructInfo
;
2784 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2785 sizeof(CRYPT_ATTRIBUTE
));
2786 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2787 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2789 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2790 CRYPT_FreeSpace(pDecodePara
, attr
);
2796 SetLastError(STATUS_ACCESS_VIOLATION
);
2799 TRACE("returning %d\n", ret
);
2803 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2804 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2807 struct AsnArrayDescriptor arrayDesc
= { 0,
2808 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2809 sizeof(CRYPT_ATTRIBUTES
),
2810 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2811 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2814 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2815 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2819 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2820 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2821 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2825 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2826 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2830 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2831 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2832 sizeof(CRYPT_ATTRIBUTES
),
2833 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2834 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2836 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2837 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2841 SetLastError(STATUS_ACCESS_VIOLATION
);
2844 TRACE("returning %d\n", ret
);
2848 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2849 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2851 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2853 struct AsnDecodeSequenceItem items
[] = {
2854 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2855 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2856 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2857 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2858 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2859 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2862 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2863 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2865 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2866 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2867 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2868 if (ret
&& pvStructInfo
)
2870 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2871 debugstr_a(algo
->pszObjId
));
2876 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2877 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2881 struct AsnDecodeSequenceItem items
[] = {
2882 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2883 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2884 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2885 Algorithm
.pszObjId
) },
2886 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2887 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2888 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2890 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2892 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2893 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2894 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2898 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2899 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2900 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2908 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2909 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2912 *pcbStructInfo
= bytesNeeded
;
2913 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2914 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2916 PCERT_PUBLIC_KEY_INFO info
;
2918 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2919 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2920 info
= pvStructInfo
;
2921 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2922 sizeof(CERT_PUBLIC_KEY_INFO
);
2923 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2924 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2925 &bytesNeeded
, NULL
);
2926 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2927 CRYPT_FreeSpace(pDecodePara
, info
);
2933 SetLastError(STATUS_ACCESS_VIOLATION
);
2940 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2941 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2947 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2950 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2952 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2955 if (pbEncoded
[1] > 1)
2957 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2964 *pcbStructInfo
= sizeof(BOOL
);
2967 else if (*pcbStructInfo
< sizeof(BOOL
))
2969 *pcbStructInfo
= sizeof(BOOL
);
2970 SetLastError(ERROR_MORE_DATA
);
2975 *pcbStructInfo
= sizeof(BOOL
);
2976 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2979 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2983 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2984 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2986 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2987 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2990 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2991 pvStructInfo
, *pcbStructInfo
);
2995 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2998 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2999 if (1 + lenBytes
> cbEncoded
)
3001 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3004 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3006 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3008 case 1: /* rfc822Name */
3009 case 2: /* dNSName */
3010 case 6: /* uniformResourceIdentifier */
3011 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
3013 SetLastError(CRYPT_E_ASN1_RULE
);
3017 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3019 case 4: /* directoryName */
3020 case 7: /* iPAddress */
3021 bytesNeeded
+= dataLen
;
3023 case 8: /* registeredID */
3024 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3028 /* FIXME: ugly, shouldn't need to know internals of OID decode
3029 * function to use it.
3031 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3034 case 0: /* otherName */
3035 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3036 SetLastError(CRYPT_E_ASN1_BADTAG
);
3039 case 3: /* x400Address, unimplemented */
3040 case 5: /* ediPartyName, unimplemented */
3041 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3042 SetLastError(CRYPT_E_ASN1_BADTAG
);
3046 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3047 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3053 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3055 *pcbStructInfo
= bytesNeeded
;
3056 else if (*pcbStructInfo
< bytesNeeded
)
3058 *pcbStructInfo
= bytesNeeded
;
3059 SetLastError(ERROR_MORE_DATA
);
3064 *pcbStructInfo
= bytesNeeded
;
3065 /* MS used values one greater than the asn1 ones.. sigh */
3066 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3067 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3069 case 1: /* rfc822Name */
3070 case 2: /* dNSName */
3071 case 6: /* uniformResourceIdentifier */
3075 for (i
= 0; i
< dataLen
; i
++)
3076 entry
->u
.pwszURL
[i
] =
3077 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3078 entry
->u
.pwszURL
[i
] = 0;
3079 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3080 debugstr_w(entry
->u
.pwszURL
));
3083 case 4: /* directoryName */
3084 /* The data are memory-equivalent with the IPAddress case,
3087 case 7: /* iPAddress */
3088 /* The next data pointer is in the pwszURL spot, that is,
3089 * the first 4 bytes. Need to move it to the next spot.
3091 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3092 entry
->u
.IPAddress
.cbData
= dataLen
;
3093 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3096 case 8: /* registeredID */
3097 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3098 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3107 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3108 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3112 struct AsnArrayDescriptor arrayDesc
= { 0,
3113 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3114 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3115 sizeof(CERT_ALT_NAME_INFO
),
3116 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3117 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3119 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3120 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3122 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3123 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3127 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3128 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3129 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3135 struct AsnDecodeSequenceItem items
[] = {
3136 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3137 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3138 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3139 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3140 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3141 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3142 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3143 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3144 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3145 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3146 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3149 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3150 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3151 pcbStructInfo
, NULL
, NULL
);
3155 SetLastError(STATUS_ACCESS_VIOLATION
);
3162 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3163 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3164 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3170 struct AsnDecodeSequenceItem items
[] = {
3171 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3172 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3173 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3174 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3175 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3176 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3177 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3178 AuthorityCertIssuer
.rgAltEntry
), 0 },
3179 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3180 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3181 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3182 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3183 AuthorityCertSerialNumber
.pbData
), 0 },
3186 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3187 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3188 pcbStructInfo
, NULL
, NULL
);
3192 SetLastError(STATUS_ACCESS_VIOLATION
);
3199 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3200 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3203 struct AsnDecodeSequenceItem items
[] = {
3204 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3205 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3206 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3207 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3208 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3209 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3211 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3213 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3214 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3215 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3218 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3219 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3220 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3224 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3225 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3229 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3230 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3231 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3232 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3233 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3234 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3236 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3237 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3241 SetLastError(STATUS_ACCESS_VIOLATION
);
3248 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3249 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3254 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3255 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3257 /* The caller has already checked the tag, no need to check it again.
3258 * Check the outer length is valid:
3260 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3262 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3265 pbEncoded
+= 1 + lenBytes
;
3266 cbEncoded
-= 1 + lenBytes
;
3267 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3268 cbEncoded
-= 2; /* space for 0 TLV */
3269 /* Check the inner length is valid: */
3270 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3274 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3275 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3276 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3278 if (*(pbEncoded
+ decodedLen
) != 0 ||
3279 *(pbEncoded
+ decodedLen
+ 1) != 0)
3281 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3282 *(pbEncoded
+ decodedLen
),
3283 *(pbEncoded
+ decodedLen
+ 1));
3284 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3290 if (ret
&& pcbDecoded
)
3292 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3293 TRACE("decoded %d bytes\n", *pcbDecoded
);
3300 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3301 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3304 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3305 struct AsnDecodeSequenceItem items
[] = {
3306 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3307 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3308 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3309 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3310 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3311 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3312 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3316 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3317 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3319 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3320 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3321 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3325 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3326 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3327 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3331 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3332 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3336 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3337 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3338 if (ret
&& pvStructInfo
)
3340 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3341 pcbStructInfo
, *pcbStructInfo
);
3344 CRYPT_CONTENT_INFO
*info
;
3346 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3347 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3348 info
= pvStructInfo
;
3349 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3350 sizeof(CRYPT_CONTENT_INFO
));
3351 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3352 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3353 pcbStructInfo
, NULL
);
3354 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3355 CRYPT_FreeSpace(pDecodePara
, info
);
3361 SetLastError(STATUS_ACCESS_VIOLATION
);
3367 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3368 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3369 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3372 struct AsnDecodeSequenceItem items
[] = {
3373 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3374 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3375 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3376 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3377 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3379 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3380 CRYPT_AsnDecodePKCSContentInfoInternal
,
3381 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3382 ContentInfo
.pszObjId
), 0 },
3383 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3384 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3385 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3388 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3389 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3394 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3395 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3396 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3400 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3401 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3407 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3408 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3411 *pcbStructInfo
= bytesNeeded
;
3412 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3413 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3415 CERT_ALT_NAME_INFO
*name
;
3417 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3418 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3419 name
= pvStructInfo
;
3420 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3421 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3422 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3423 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3424 &bytesNeeded
, NULL
);
3425 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3426 CRYPT_FreeSpace(pDecodePara
, name
);
3432 SetLastError(STATUS_ACCESS_VIOLATION
);
3439 struct PATH_LEN_CONSTRAINT
3441 BOOL fPathLenConstraint
;
3442 DWORD dwPathLenConstraint
;
3445 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3446 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3450 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3452 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3453 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3457 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3459 *pcbStructInfo
= bytesNeeded
;
3461 else if (*pcbStructInfo
< bytesNeeded
)
3463 SetLastError(ERROR_MORE_DATA
);
3464 *pcbStructInfo
= bytesNeeded
;
3469 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3471 *pcbStructInfo
= bytesNeeded
;
3472 size
= sizeof(constraint
->dwPathLenConstraint
);
3473 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3474 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3476 constraint
->fPathLenConstraint
= TRUE
;
3477 TRACE("got an int, dwPathLenConstraint is %d\n",
3478 constraint
->dwPathLenConstraint
);
3480 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3484 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3485 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3489 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3490 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3491 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3492 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3493 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3494 offsetof(CERT_NAME_BLOB
, pbData
) };
3496 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3497 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3499 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3500 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3501 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3505 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3506 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3507 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3513 struct AsnDecodeSequenceItem items
[] = {
3514 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3515 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3516 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3517 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3518 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3519 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3520 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3521 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3522 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3524 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3527 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3528 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3529 pcbStructInfo
, NULL
, NULL
);
3533 SetLastError(STATUS_ACCESS_VIOLATION
);
3540 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3541 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3542 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3548 struct AsnDecodeSequenceItem items
[] = {
3549 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3550 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3551 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3552 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3553 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3556 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3557 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3558 pcbStructInfo
, NULL
, NULL
);
3562 SetLastError(STATUS_ACCESS_VIOLATION
);
3569 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3570 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3573 struct AsnDecodeSequenceItem items
[] = {
3574 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3575 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3576 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3578 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3579 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3580 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3583 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3585 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3586 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3588 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3589 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3590 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3594 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3595 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3599 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3600 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3601 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3602 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3603 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3604 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3606 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3607 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3609 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3610 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3611 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3615 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3616 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3618 struct AsnDecodeSequenceItem items
[] = {
3619 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3620 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3621 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3622 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3623 CRYPT_AsnDecodePolicyQualifiers
,
3624 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3625 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3627 CERT_POLICY_INFO
*info
= pvStructInfo
;
3630 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3631 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3633 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3634 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3635 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3639 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3640 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3641 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3645 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3646 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3650 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3651 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3652 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3653 sizeof(CERT_POLICIES_INFO
),
3654 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3655 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3657 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3658 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3662 SetLastError(STATUS_ACCESS_VIOLATION
);
3668 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3669 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3672 struct AsnDecodeSequenceItem items
[] = {
3673 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3674 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3675 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3676 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3677 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3678 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3680 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3683 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3684 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3686 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3687 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3688 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3692 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3693 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3694 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3698 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3699 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3703 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3704 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3705 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3706 sizeof(CERT_POLICY_MAPPING
),
3707 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3708 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3710 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3711 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3715 SetLastError(STATUS_ACCESS_VIOLATION
);
3721 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3722 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3726 DWORD skip
, size
= sizeof(skip
);
3730 SetLastError(CRYPT_E_ASN1_EOD
);
3733 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3735 SetLastError(CRYPT_E_ASN1_BADTAG
);
3738 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3739 &skip
, &size
, pcbDecoded
)))
3741 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3742 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3745 *pcbStructInfo
= bytesNeeded
;
3746 else if (*pcbStructInfo
< bytesNeeded
)
3748 *pcbStructInfo
= bytesNeeded
;
3749 SetLastError(ERROR_MORE_DATA
);
3754 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3755 CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
);
3757 *pcbStructInfo
= bytesNeeded
;
3758 /* The BOOL is implicit: if the integer is present, then it's
3761 info
->fRequireExplicitPolicy
= TRUE
;
3762 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3768 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3769 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3773 DWORD skip
, size
= sizeof(skip
);
3777 SetLastError(CRYPT_E_ASN1_EOD
);
3780 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3782 SetLastError(CRYPT_E_ASN1_BADTAG
);
3785 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3786 &skip
, &size
, pcbDecoded
)))
3788 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3789 fInhibitPolicyMapping
);
3792 *pcbStructInfo
= bytesNeeded
;
3793 else if (*pcbStructInfo
< bytesNeeded
)
3795 *pcbStructInfo
= bytesNeeded
;
3796 SetLastError(ERROR_MORE_DATA
);
3801 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3802 CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
);
3804 *pcbStructInfo
= bytesNeeded
;
3805 /* The BOOL is implicit: if the integer is present, then it's
3808 info
->fInhibitPolicyMapping
= TRUE
;
3809 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3815 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3816 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3817 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3818 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3822 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3823 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3827 struct AsnDecodeSequenceItem items
[] = {
3829 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3830 CRYPT_AsnDecodeRequireExplicit
,
3831 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3832 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3834 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3835 CRYPT_AsnDecodeInhibitMapping
,
3836 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3837 TRUE
, FALSE
, 0, 0 },
3840 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3841 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3842 pcbStructInfo
, NULL
, NULL
);
3846 SetLastError(STATUS_ACCESS_VIOLATION
);
3852 #define RSA1_MAGIC 0x31415352
3854 struct DECODED_RSA_PUB_KEY
3857 CRYPT_INTEGER_BLOB modulus
;
3860 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3861 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3862 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3868 struct AsnDecodeSequenceItem items
[] = {
3869 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3870 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3871 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3873 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3874 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3876 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3879 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3880 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3884 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3885 decodedKey
->modulus
.cbData
;
3889 *pcbStructInfo
= bytesNeeded
;
3892 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3893 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3896 RSAPUBKEY
*rsaPubKey
;
3898 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3899 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3901 hdr
->bType
= PUBLICKEYBLOB
;
3902 hdr
->bVersion
= CUR_BLOB_VERSION
;
3904 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3905 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3906 sizeof(BLOBHEADER
));
3907 rsaPubKey
->magic
= RSA1_MAGIC
;
3908 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3909 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3910 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3911 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3912 decodedKey
->modulus
.cbData
);
3914 LocalFree(decodedKey
);
3919 SetLastError(STATUS_ACCESS_VIOLATION
);
3926 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3927 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3931 DWORD bytesNeeded
, dataLen
;
3933 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3934 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3936 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3938 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3940 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3941 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3943 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3945 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3947 *pcbStructInfo
= bytesNeeded
;
3948 else if (*pcbStructInfo
< bytesNeeded
)
3950 SetLastError(ERROR_MORE_DATA
);
3951 *pcbStructInfo
= bytesNeeded
;
3956 CRYPT_DATA_BLOB
*blob
;
3958 *pcbStructInfo
= bytesNeeded
;
3959 blob
= pvStructInfo
;
3960 blob
->cbData
= dataLen
;
3961 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3962 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3965 assert(blob
->pbData
);
3967 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3975 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3976 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3977 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3981 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3982 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3990 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3993 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
3995 SetLastError(CRYPT_E_ASN1_BADTAG
);
3998 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3999 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4002 *pcbStructInfo
= bytesNeeded
;
4003 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4004 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4006 CRYPT_DATA_BLOB
*blob
;
4008 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4009 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4010 blob
= pvStructInfo
;
4011 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4012 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
4013 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4014 &bytesNeeded
, NULL
);
4015 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4016 CRYPT_FreeSpace(pDecodePara
, blob
);
4022 SetLastError(STATUS_ACCESS_VIOLATION
);
4029 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4030 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4033 DWORD bytesNeeded
, dataLen
;
4034 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4036 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4037 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4039 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4041 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4042 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4044 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4046 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4048 *pcbStructInfo
= bytesNeeded
;
4049 else if (*pcbStructInfo
< bytesNeeded
)
4051 *pcbStructInfo
= bytesNeeded
;
4052 SetLastError(ERROR_MORE_DATA
);
4057 CRYPT_BIT_BLOB
*blob
;
4059 *pcbStructInfo
= bytesNeeded
;
4060 blob
= pvStructInfo
;
4061 blob
->cbData
= dataLen
- 1;
4062 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4063 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4065 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4069 assert(blob
->pbData
);
4072 BYTE mask
= 0xff << blob
->cUnusedBits
;
4074 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4076 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4084 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4085 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4086 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4090 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4091 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4099 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4102 else if (pbEncoded
[0] != ASN_BITSTRING
)
4104 SetLastError(CRYPT_E_ASN1_BADTAG
);
4107 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4108 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4111 *pcbStructInfo
= bytesNeeded
;
4112 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4113 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4115 CRYPT_BIT_BLOB
*blob
;
4117 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4118 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4119 blob
= pvStructInfo
;
4120 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4121 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4122 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4123 &bytesNeeded
, NULL
);
4124 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4125 CRYPT_FreeSpace(pDecodePara
, blob
);
4131 SetLastError(STATUS_ACCESS_VIOLATION
);
4135 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4139 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4140 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4141 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4146 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4148 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4151 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4152 if (dataLen
> sizeof(int))
4154 SetLastError(CRYPT_E_ASN1_LARGE
);
4157 else if (!pvStructInfo
)
4158 *pcbStructInfo
= sizeof(int);
4159 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4163 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4165 /* initialize to a negative value to sign-extend */
4170 for (i
= 0; i
< dataLen
; i
++)
4173 val
|= pbEncoded
[1 + lenBytes
+ i
];
4175 memcpy(pvStructInfo
, &val
, sizeof(int));
4181 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4182 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4183 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4193 SetLastError(CRYPT_E_ASN1_EOD
);
4196 else if (pbEncoded
[0] != ASN_INTEGER
)
4198 SetLastError(CRYPT_E_ASN1_BADTAG
);
4202 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4203 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4207 *pcbStructInfo
= bytesNeeded
;
4208 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4209 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4211 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4212 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4213 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4214 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4215 &bytesNeeded
, NULL
);
4216 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4217 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4223 SetLastError(STATUS_ACCESS_VIOLATION
);
4230 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4231 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4235 DWORD bytesNeeded
, dataLen
;
4237 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4239 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4241 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4243 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4245 *pcbStructInfo
= bytesNeeded
;
4246 else if (*pcbStructInfo
< bytesNeeded
)
4248 *pcbStructInfo
= bytesNeeded
;
4249 SetLastError(ERROR_MORE_DATA
);
4254 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4256 *pcbStructInfo
= bytesNeeded
;
4257 blob
->cbData
= dataLen
;
4258 assert(blob
->pbData
);
4263 for (i
= 0; i
< blob
->cbData
; i
++)
4265 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4274 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4275 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4276 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4284 if (pbEncoded
[0] != ASN_INTEGER
)
4286 SetLastError(CRYPT_E_ASN1_BADTAG
);
4290 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4291 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4295 *pcbStructInfo
= bytesNeeded
;
4296 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4297 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4299 CRYPT_INTEGER_BLOB
*blob
;
4301 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4302 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4303 blob
= pvStructInfo
;
4304 blob
->pbData
= (BYTE
*)pvStructInfo
+
4305 sizeof(CRYPT_INTEGER_BLOB
);
4306 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4307 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4308 &bytesNeeded
, NULL
);
4309 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4310 CRYPT_FreeSpace(pDecodePara
, blob
);
4316 SetLastError(STATUS_ACCESS_VIOLATION
);
4323 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4324 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4329 if (pbEncoded
[0] == ASN_INTEGER
)
4331 DWORD bytesNeeded
, dataLen
;
4333 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4335 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4338 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4339 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4341 *pcbStructInfo
= bytesNeeded
;
4342 else if (*pcbStructInfo
< bytesNeeded
)
4344 *pcbStructInfo
= bytesNeeded
;
4345 SetLastError(ERROR_MORE_DATA
);
4350 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4352 *pcbStructInfo
= bytesNeeded
;
4353 blob
->cbData
= dataLen
;
4354 assert(blob
->pbData
);
4355 /* remove leading zero byte if it exists */
4356 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4365 for (i
= 0; i
< blob
->cbData
; i
++)
4367 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4376 SetLastError(CRYPT_E_ASN1_BADTAG
);
4382 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4383 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4384 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4392 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4393 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4396 *pcbStructInfo
= bytesNeeded
;
4397 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4398 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4400 CRYPT_INTEGER_BLOB
*blob
;
4402 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4403 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4404 blob
= pvStructInfo
;
4405 blob
->pbData
= (BYTE
*)pvStructInfo
+
4406 sizeof(CRYPT_INTEGER_BLOB
);
4407 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4408 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4409 &bytesNeeded
, NULL
);
4410 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4411 CRYPT_FreeSpace(pDecodePara
, blob
);
4417 SetLastError(STATUS_ACCESS_VIOLATION
);
4424 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4425 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4426 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4432 *pcbStructInfo
= sizeof(int);
4437 if (pbEncoded
[0] == ASN_ENUMERATED
)
4439 unsigned int val
= 0, i
;
4443 SetLastError(CRYPT_E_ASN1_EOD
);
4446 else if (pbEncoded
[1] == 0)
4448 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4453 /* A little strange looking, but we have to accept a sign byte:
4454 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4455 * assuming a small length is okay here, it has to be in short
4458 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4460 SetLastError(CRYPT_E_ASN1_LARGE
);
4463 for (i
= 0; i
< pbEncoded
[1]; i
++)
4466 val
|= pbEncoded
[2 + i
];
4468 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4469 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4471 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4472 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4473 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4479 SetLastError(CRYPT_E_ASN1_BADTAG
);
4485 SetLastError(STATUS_ACCESS_VIOLATION
);
4492 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4495 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4500 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4502 if (!isdigit(*(pbEncoded))) \
4504 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4510 (word) += *(pbEncoded)++ - '0'; \
4515 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4516 SYSTEMTIME
*sysTime
)
4520 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4522 WORD hours
, minutes
= 0;
4523 BYTE sign
= *pbEncoded
++;
4526 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4527 if (ret
&& hours
>= 24)
4529 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4534 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4535 if (ret
&& minutes
>= 60)
4537 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4545 sysTime
->wHour
+= hours
;
4546 sysTime
->wMinute
+= minutes
;
4550 if (hours
> sysTime
->wHour
)
4553 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4556 sysTime
->wHour
-= hours
;
4557 if (minutes
> sysTime
->wMinute
)
4560 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4563 sysTime
->wMinute
-= minutes
;
4570 #define MIN_ENCODED_TIME_LENGTH 10
4572 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4573 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4578 if (pbEncoded
[0] == ASN_UTCTIME
)
4581 SetLastError(CRYPT_E_ASN1_EOD
);
4582 else if (pbEncoded
[1] > 0x7f)
4584 /* long-form date strings really can't be valid */
4585 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4589 SYSTEMTIME sysTime
= { 0 };
4590 BYTE len
= pbEncoded
[1];
4592 if (len
< MIN_ENCODED_TIME_LENGTH
)
4593 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4598 *pcbDecoded
= 2 + len
;
4600 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4601 if (sysTime
.wYear
>= 50)
4602 sysTime
.wYear
+= 1900;
4604 sysTime
.wYear
+= 2000;
4605 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4606 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4607 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4608 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4611 if (len
>= 2 && isdigit(*pbEncoded
) &&
4612 isdigit(*(pbEncoded
+ 1)))
4613 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4615 else if (isdigit(*pbEncoded
))
4616 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4619 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4625 *pcbStructInfo
= sizeof(FILETIME
);
4626 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4628 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4634 SetLastError(CRYPT_E_ASN1_BADTAG
);
4638 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4639 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4640 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4648 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4649 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4653 *pcbStructInfo
= bytesNeeded
;
4654 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4655 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4657 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4658 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4659 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4660 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4661 &bytesNeeded
, NULL
);
4662 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4663 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4669 SetLastError(STATUS_ACCESS_VIOLATION
);
4675 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4676 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4681 if (pbEncoded
[0] == ASN_GENERALTIME
)
4684 SetLastError(CRYPT_E_ASN1_EOD
);
4685 else if (pbEncoded
[1] > 0x7f)
4687 /* long-form date strings really can't be valid */
4688 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4692 BYTE len
= pbEncoded
[1];
4694 if (len
< MIN_ENCODED_TIME_LENGTH
)
4695 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4698 SYSTEMTIME sysTime
= { 0 };
4702 *pcbDecoded
= 2 + len
;
4704 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4705 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4706 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4707 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4710 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4713 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4715 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4722 /* workaround macro weirdness */
4723 digits
= min(len
, 3);
4724 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4725 sysTime
.wMilliseconds
);
4728 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4734 *pcbStructInfo
= sizeof(FILETIME
);
4735 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4737 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4743 SetLastError(CRYPT_E_ASN1_BADTAG
);
4747 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4748 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4752 InternalDecodeFunc decode
= NULL
;
4754 if (pbEncoded
[0] == ASN_UTCTIME
)
4755 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4756 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4757 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4759 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4760 pcbStructInfo
, pcbDecoded
);
4763 SetLastError(CRYPT_E_ASN1_BADTAG
);
4769 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4770 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4771 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4779 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4780 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4784 *pcbStructInfo
= bytesNeeded
;
4785 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4786 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4788 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4789 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4790 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4791 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4792 &bytesNeeded
, NULL
);
4793 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4794 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4800 SetLastError(STATUS_ACCESS_VIOLATION
);
4807 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4808 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4809 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4815 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4817 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4819 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4824 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4825 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4827 ptr
= pbEncoded
+ 1 + lenBytes
;
4828 remainingLen
= dataLen
;
4829 while (ret
&& remainingLen
)
4833 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4836 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4838 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4839 ptr
+= 1 + nextLenBytes
+ nextLen
;
4840 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4841 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4842 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4848 CRYPT_SEQUENCE_OF_ANY
*seq
;
4853 *pcbStructInfo
= bytesNeeded
;
4854 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4855 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4857 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4858 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4860 seq
->cValue
= cValue
;
4861 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4863 nextPtr
= (BYTE
*)seq
->rgValue
+
4864 cValue
* sizeof(CRYPT_DER_BLOB
);
4865 ptr
= pbEncoded
+ 1 + lenBytes
;
4866 remainingLen
= dataLen
;
4868 while (ret
&& remainingLen
)
4872 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4875 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4877 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4879 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4880 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4883 seq
->rgValue
[i
].pbData
= nextPtr
;
4884 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4886 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4888 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4889 ptr
+= 1 + nextLenBytes
+ nextLen
;
4893 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4894 CRYPT_FreeSpace(pDecodePara
, seq
);
4901 SetLastError(CRYPT_E_ASN1_BADTAG
);
4907 SetLastError(STATUS_ACCESS_VIOLATION
);
4914 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4915 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4920 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4922 DWORD bytesNeeded
, dataLen
;
4924 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4926 struct AsnArrayDescriptor arrayDesc
= {
4927 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4928 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
4929 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
4930 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
4931 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4932 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4933 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4938 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4939 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4940 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
4941 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4942 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
4945 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4947 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4949 *pcbStructInfo
= bytesNeeded
;
4950 else if (*pcbStructInfo
< bytesNeeded
)
4952 *pcbStructInfo
= bytesNeeded
;
4953 SetLastError(ERROR_MORE_DATA
);
4958 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
4960 *pcbStructInfo
= bytesNeeded
;
4963 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4964 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4965 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4966 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
4970 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4976 SetLastError(CRYPT_E_ASN1_BADTAG
);
4982 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4983 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4985 struct AsnDecodeSequenceItem items
[] = {
4986 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4987 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4988 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4989 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4990 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4991 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4992 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4993 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4994 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4995 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4997 CRL_DIST_POINT
*point
= pvStructInfo
;
5000 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5001 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5002 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5006 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5007 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5008 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5012 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5013 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5017 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5018 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
5019 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
5020 sizeof(CRL_DIST_POINTS_INFO
),
5021 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5022 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5024 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5025 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5029 SetLastError(STATUS_ACCESS_VIOLATION
);
5036 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5037 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5038 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5042 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5043 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5047 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5048 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5049 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5050 sizeof(CERT_ENHKEY_USAGE
),
5051 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5053 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5054 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5058 SetLastError(STATUS_ACCESS_VIOLATION
);
5065 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5066 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5067 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5071 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5072 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5076 struct AsnDecodeSequenceItem items
[] = {
5077 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5078 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5079 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5080 offsetof(CRL_ISSUING_DIST_POINT
,
5081 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5082 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5083 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5085 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5086 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5088 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5089 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5090 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5091 OnlySomeReasonFlags
.pbData
), 0 },
5092 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5093 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5096 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5097 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5098 pcbStructInfo
, NULL
, NULL
);
5102 SetLastError(STATUS_ACCESS_VIOLATION
);
5109 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5110 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5114 DWORD max
, size
= sizeof(max
);
5116 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5117 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5121 SetLastError(CRYPT_E_ASN1_EOD
);
5124 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5126 SetLastError(CRYPT_E_ASN1_BADTAG
);
5129 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5130 &max
, &size
, pcbDecoded
)))
5132 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5135 *pcbStructInfo
= bytesNeeded
;
5136 else if (*pcbStructInfo
< bytesNeeded
)
5138 *pcbStructInfo
= bytesNeeded
;
5139 SetLastError(ERROR_MORE_DATA
);
5144 CERT_GENERAL_SUBTREE
*subtree
= CONTAINING_RECORD(pvStructInfo
,
5145 CERT_GENERAL_SUBTREE
, fMaximum
);
5147 *pcbStructInfo
= bytesNeeded
;
5148 /* The BOOL is implicit: if the integer is present, then it's
5151 subtree
->fMaximum
= TRUE
;
5152 subtree
->dwMaximum
= max
;
5155 TRACE("returning %d\n", ret
);
5159 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5160 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5164 struct AsnDecodeSequenceItem items
[] = {
5165 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5166 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5167 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5168 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5169 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5170 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5171 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5172 TRUE
, FALSE
, 0, 0 },
5174 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5176 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5177 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5179 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5180 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5181 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5184 TRACE("%d\n", *pcbDecoded
);
5185 if (*pcbDecoded
< cbEncoded
)
5186 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5187 *(pbEncoded
+ *pcbDecoded
+ 1));
5189 TRACE("returning %d\n", ret
);
5193 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5194 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5198 struct AsnArrayDescriptor arrayDesc
= { 0,
5199 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5200 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5201 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5203 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5204 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5206 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5207 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5209 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5210 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5214 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5215 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5219 struct AsnArrayDescriptor arrayDesc
= { 0,
5220 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5221 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5222 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5223 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5224 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5226 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5227 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5229 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5230 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5234 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5235 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5236 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5240 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5241 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5245 struct AsnDecodeSequenceItem items
[] = {
5246 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5247 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5248 CRYPT_AsnDecodePermittedSubtree
,
5249 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5250 cExcludedSubtree
), TRUE
, TRUE
,
5251 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5252 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5253 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5254 CRYPT_AsnDecodeExcludedSubtree
,
5255 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5257 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5260 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5261 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5262 pcbStructInfo
, NULL
, NULL
);
5266 SetLastError(STATUS_ACCESS_VIOLATION
);
5272 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5273 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5277 struct AsnDecodeSequenceItem items
[] = {
5278 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5279 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5281 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5282 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5283 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5285 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5287 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5288 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5290 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5291 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5292 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5293 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5295 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5298 TRACE("returning %d\n", ret
);
5302 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5303 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5306 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5307 struct AsnDecodeSequenceItem items
[] = {
5308 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5309 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5310 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5311 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5312 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5313 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5314 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5315 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5316 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5317 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5318 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5319 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5320 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5321 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5322 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5323 HashEncryptionAlgorithm
.pszObjId
), 0 },
5324 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5325 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5326 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5327 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5328 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5329 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5330 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5334 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5335 pvStructInfo
, *pcbStructInfo
);
5337 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5338 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5339 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5343 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5344 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5345 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5349 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5350 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5354 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5355 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5356 if (ret
&& pvStructInfo
)
5358 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5359 pcbStructInfo
, *pcbStructInfo
);
5362 CMSG_SIGNER_INFO
*info
;
5364 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5365 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5366 info
= pvStructInfo
;
5367 info
->Issuer
.pbData
= ((BYTE
*)info
+
5368 sizeof(CMSG_SIGNER_INFO
));
5369 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5370 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5371 pcbStructInfo
, NULL
);
5372 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5373 CRYPT_FreeSpace(pDecodePara
, info
);
5379 SetLastError(STATUS_ACCESS_VIOLATION
);
5382 TRACE("returning %d\n", ret
);
5386 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5387 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5391 struct AsnArrayDescriptor arrayDesc
= { 0,
5392 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5393 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5394 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5395 CRYPT_AsnDecodeCopyBytes
,
5396 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5398 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5399 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5401 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5402 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5406 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5407 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5411 struct AsnArrayDescriptor arrayDesc
= { 0,
5412 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5413 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5414 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5415 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5416 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5418 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5419 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5421 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5422 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5426 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5427 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5430 CERT_ID
*id
= pvStructInfo
;
5433 if (*pbEncoded
== ASN_SEQUENCEOF
)
5435 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5436 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5440 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5441 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5442 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5443 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5445 *pcbStructInfo
= sizeof(CERT_ID
);
5448 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5450 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5451 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5455 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5456 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5457 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5458 sizeof(CRYPT_DATA_BLOB
);
5460 *pcbStructInfo
= sizeof(CERT_ID
);
5464 SetLastError(CRYPT_E_ASN1_BADTAG
);
5468 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5469 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5472 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5473 struct AsnDecodeSequenceItem items
[] = {
5474 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5475 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5476 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5477 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5478 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5479 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5480 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5481 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5482 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5483 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5484 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5485 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5486 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5487 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5488 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5489 HashEncryptionAlgorithm
.pszObjId
), 0 },
5490 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5491 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5492 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5493 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5494 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5495 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5496 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5500 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5501 pvStructInfo
, *pcbStructInfo
);
5503 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5504 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5505 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5509 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5510 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5511 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5515 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5516 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5520 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5521 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5522 if (ret
&& pvStructInfo
)
5524 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5525 pcbStructInfo
, *pcbStructInfo
);
5528 CMSG_CMS_SIGNER_INFO
*info
;
5530 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5531 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5532 info
= pvStructInfo
;
5533 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5534 sizeof(CMSG_CMS_SIGNER_INFO
));
5535 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5536 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5537 pcbStructInfo
, NULL
);
5538 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5539 CRYPT_FreeSpace(pDecodePara
, info
);
5545 SetLastError(STATUS_ACCESS_VIOLATION
);
5548 TRACE("returning %d\n", ret
);
5552 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5553 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5556 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5557 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5558 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5559 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5560 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5561 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5563 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5564 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5566 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5567 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5571 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5572 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5573 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5576 struct AsnDecodeSequenceItem items
[] = {
5577 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5578 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5579 /* Placeholder for the hash algorithms - redundant with those in the
5580 * signers, so just ignore them.
5582 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5583 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5584 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5585 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5586 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5587 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5588 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5589 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5590 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5591 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5592 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5593 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5594 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5595 CRYPT_DecodeSignerArray
,
5596 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5597 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5600 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5601 pDecodePara
, signedInfo
, *pcbSignedInfo
);
5603 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5604 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5606 TRACE("returning %d\n", ret
);
5610 static BOOL
CRYPT_AsnDecodeRecipientInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5611 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5614 CMSG_KEY_TRANS_RECIPIENT_INFO
*info
= pvStructInfo
;
5615 struct AsnDecodeSequenceItem items
[] = {
5616 { ASN_INTEGER
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, dwVersion
),
5617 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5618 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5619 RecipientId
.u
.IssuerSerialNumber
), CRYPT_AsnDecodeIssuerSerialNumber
,
5620 sizeof(CERT_ISSUER_SERIAL_NUMBER
), FALSE
, TRUE
,
5621 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5622 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
), 0 },
5623 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5624 KeyEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5625 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5626 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5627 KeyEncryptionAlgorithm
.pszObjId
), 0 },
5628 { ASN_OCTETSTRING
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
),
5629 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
5630 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
.pbData
), 0 },
5633 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5634 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5636 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5637 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5638 pcbDecoded
, info
? info
->RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
:
5641 info
->RecipientId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5642 TRACE("returning %d\n", ret
);
5646 static BOOL
CRYPT_DecodeRecipientInfoArray(const BYTE
*pbEncoded
,
5647 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5651 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5652 offsetof(CRYPT_ENVELOPED_DATA
, cRecipientInfo
),
5653 offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
),
5654 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5655 CRYPT_AsnDecodeRecipientInfo
, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO
), TRUE
,
5656 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5657 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
) };
5659 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5660 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5662 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5663 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5664 TRACE("returning %d\n", ret
);
5668 static BOOL
CRYPT_AsnDecodeEncryptedContentInfo(const BYTE
*pbEncoded
,
5669 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5673 CRYPT_ENCRYPTED_CONTENT_INFO
*info
= pvStructInfo
;
5674 struct AsnDecodeSequenceItem items
[] = {
5675 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5676 contentType
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
5677 FALSE
, TRUE
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5679 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5680 contentEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5681 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5682 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5683 contentEncryptionAlgorithm
.pszObjId
), 0 },
5684 { ASN_CONTEXT
| 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5685 encryptedContent
), CRYPT_AsnDecodeOctetsInternal
,
5686 sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
5687 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
, encryptedContent
.pbData
) },
5690 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5691 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5693 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5694 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5695 pcbDecoded
, info
? info
->contentType
: NULL
);
5696 TRACE("returning %d\n", ret
);
5700 BOOL
CRYPT_AsnDecodePKCSEnvelopedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5701 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5702 CRYPT_ENVELOPED_DATA
*envelopedData
, DWORD
*pcbEnvelopedData
)
5705 struct AsnDecodeSequenceItem items
[] = {
5706 { ASN_INTEGER
, offsetof(CRYPT_ENVELOPED_DATA
, version
),
5707 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5708 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ENVELOPED_DATA
,
5709 cRecipientInfo
), CRYPT_DecodeRecipientInfoArray
,
5710 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5711 FALSE
, TRUE
, offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
), 0 },
5712 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
),
5713 CRYPT_AsnDecodeEncryptedContentInfo
,
5714 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO
), FALSE
, TRUE
,
5715 offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
.contentType
), 0 },
5718 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5719 pDecodePara
, envelopedData
, *pcbEnvelopedData
);
5721 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5722 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, envelopedData
,
5723 pcbEnvelopedData
, NULL
, NULL
);
5724 TRACE("returning %d\n", ret
);
5728 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5729 LPCSTR lpszStructType
)
5731 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5733 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5734 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5736 SetLastError(ERROR_FILE_NOT_FOUND
);
5739 if (IS_INTOID(lpszStructType
))
5741 switch (LOWORD(lpszStructType
))
5743 case LOWORD(X509_CERT
):
5744 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5746 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5747 decodeFunc
= CRYPT_AsnDecodeCert
;
5749 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5750 decodeFunc
= CRYPT_AsnDecodeCRL
;
5752 case LOWORD(X509_EXTENSIONS
):
5753 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5755 case LOWORD(X509_NAME_VALUE
):
5756 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5758 case LOWORD(X509_NAME
):
5759 decodeFunc
= CRYPT_AsnDecodeName
;
5761 case LOWORD(X509_PUBLIC_KEY_INFO
):
5762 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5764 case LOWORD(X509_AUTHORITY_KEY_ID
):
5765 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5767 case LOWORD(X509_ALTERNATE_NAME
):
5768 decodeFunc
= CRYPT_AsnDecodeAltName
;
5770 case LOWORD(X509_BASIC_CONSTRAINTS
):
5771 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5773 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5774 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5776 case LOWORD(X509_CERT_POLICIES
):
5777 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5779 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5780 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5782 case LOWORD(X509_UNICODE_NAME
):
5783 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5785 case LOWORD(PKCS_ATTRIBUTE
):
5786 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5788 case LOWORD(X509_UNICODE_NAME_VALUE
):
5789 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5791 case LOWORD(X509_OCTET_STRING
):
5792 decodeFunc
= CRYPT_AsnDecodeOctets
;
5794 case LOWORD(X509_BITS
):
5795 case LOWORD(X509_KEY_USAGE
):
5796 decodeFunc
= CRYPT_AsnDecodeBits
;
5798 case LOWORD(X509_INTEGER
):
5799 decodeFunc
= CRYPT_AsnDecodeInt
;
5801 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5802 decodeFunc
= CRYPT_AsnDecodeInteger
;
5804 case LOWORD(X509_MULTI_BYTE_UINT
):
5805 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5807 case LOWORD(X509_ENUMERATED
):
5808 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5810 case LOWORD(X509_CHOICE_OF_TIME
):
5811 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5813 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5814 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5816 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5817 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5819 case LOWORD(PKCS_CONTENT_INFO
):
5820 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5822 case LOWORD(X509_SEQUENCE_OF_ANY
):
5823 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5825 case LOWORD(PKCS_UTC_TIME
):
5826 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5828 case LOWORD(X509_CRL_DIST_POINTS
):
5829 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5831 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5832 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5834 case LOWORD(PKCS_CTL
):
5835 decodeFunc
= CRYPT_AsnDecodeCTL
;
5837 case LOWORD(PKCS_SMIME_CAPABILITIES
):
5838 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5840 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
5841 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5843 case LOWORD(PKCS_ATTRIBUTES
):
5844 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
5846 case LOWORD(X509_ISSUING_DIST_POINT
):
5847 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5849 case LOWORD(X509_NAME_CONSTRAINTS
):
5850 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5852 case LOWORD(X509_POLICY_MAPPINGS
):
5853 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5855 case LOWORD(X509_POLICY_CONSTRAINTS
):
5856 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5858 case LOWORD(PKCS7_SIGNER_INFO
):
5859 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
5861 case LOWORD(CMS_SIGNER_INFO
):
5862 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
5866 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
5867 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5868 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
5869 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5870 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
5871 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5872 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
5873 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5874 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
5875 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5876 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
5877 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5878 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
5879 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5880 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
5881 decodeFunc
= CRYPT_AsnDecodeBits
;
5882 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
5883 decodeFunc
= CRYPT_AsnDecodeOctets
;
5884 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
5885 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5886 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
5887 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5888 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
5889 decodeFunc
= CRYPT_AsnDecodeAltName
;
5890 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
5891 decodeFunc
= CRYPT_AsnDecodeAltName
;
5892 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
5893 decodeFunc
= CRYPT_AsnDecodeAltName
;
5894 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
5895 decodeFunc
= CRYPT_AsnDecodeAltName
;
5896 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
5897 decodeFunc
= CRYPT_AsnDecodeAltName
;
5898 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
5899 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5900 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
5901 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5902 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
5903 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5904 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
5905 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5906 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
5907 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5908 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
5909 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5910 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
5911 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5912 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
5913 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5914 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
5915 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5916 else if (!strcmp(lpszStructType
, szOID_CTL
))
5917 decodeFunc
= CRYPT_AsnDecodeCTL
;
5921 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
5922 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5924 static HCRYPTOIDFUNCSET set
= NULL
;
5925 CryptDecodeObjectFunc decodeFunc
= NULL
;
5928 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
5929 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5930 (void **)&decodeFunc
, hFunc
);
5934 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
5935 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5937 static HCRYPTOIDFUNCSET set
= NULL
;
5938 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5941 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
5942 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5943 (void **)&decodeFunc
, hFunc
);
5947 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5948 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
5949 DWORD
*pcbStructInfo
)
5952 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
5953 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
5954 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5956 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
5957 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
5958 pvStructInfo
, pcbStructInfo
);
5960 if (!pvStructInfo
&& !pcbStructInfo
)
5962 SetLastError(ERROR_INVALID_PARAMETER
);
5965 if (cbEncoded
> MAX_ENCODED_LEN
)
5967 SetLastError(CRYPT_E_ASN1_LARGE
);
5971 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
5974 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5975 debugstr_a(lpszStructType
));
5976 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
5977 lpszStructType
, &hFunc
);
5978 if (!pCryptDecodeObject
)
5979 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
5980 lpszStructType
, &hFunc
);
5982 if (pCryptDecodeObject
)
5983 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5984 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5985 else if (pCryptDecodeObjectEx
)
5986 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
5987 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5988 pvStructInfo
, pcbStructInfo
);
5990 CryptFreeOIDFunctionAddress(hFunc
, 0);
5991 TRACE_(crypt
)("returning %d\n", ret
);
5995 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5996 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5997 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6000 CryptDecodeObjectExFunc decodeFunc
;
6001 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6003 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6004 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
6005 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6007 if (!pvStructInfo
&& !pcbStructInfo
)
6009 SetLastError(ERROR_INVALID_PARAMETER
);
6012 if (cbEncoded
> MAX_ENCODED_LEN
)
6014 SetLastError(CRYPT_E_ASN1_LARGE
);
6018 SetLastError(NOERROR
);
6019 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6023 SetLastError(ERROR_INVALID_PARAMETER
);
6026 *(BYTE
**)pvStructInfo
= NULL
;
6028 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
6031 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6032 debugstr_a(lpszStructType
));
6033 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
6037 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
6038 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6041 CryptDecodeObjectFunc pCryptDecodeObject
=
6042 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
6044 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6045 * directly, as that could cause an infinite loop.
6047 if (pCryptDecodeObject
)
6049 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6051 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6052 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
6053 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
6054 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
6056 ret
= pCryptDecodeObject(dwCertEncodingType
,
6057 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
6058 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
6060 CRYPT_FreeSpace(pDecodePara
, *(BYTE
**)pvStructInfo
);
6064 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6065 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6069 CryptFreeOIDFunctionAddress(hFunc
, 0);
6070 TRACE_(crypt
)("returning %d\n", ret
);
6074 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
6078 TRACE_(crypt
)("(%p)\n", pPFX
);
6080 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6081 * version integer of length 1 (3 encoded byes) and at least one other
6082 * datum (two encoded bytes), plus at least two bytes for the outer
6083 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6085 if (pPFX
->cbData
< 7)
6087 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
6091 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
6093 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
6095 /* Need at least three bytes for the integer version */
6096 if (pPFX
->cbData
< 1 + lenLen
+ 3)
6098 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
6099 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
6100 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
6109 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6112 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);
6116 BOOL WINAPI
PFXVerifyPassword(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6119 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);