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_AsnDecodeOctets(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
)
484 else if (cbEncoded
< dataLen
)
486 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
488 SetLastError(CRYPT_E_ASN1_CORRUPT
);
493 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
494 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
495 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
497 if (cbDecoded
> cbEncoded
- 2)
499 /* Not enough space for 0 TLV */
500 SetLastError(CRYPT_E_ASN1_CORRUPT
);
503 else if (*(ptr
+ cbDecoded
) != 0 ||
504 *(ptr
+ cbDecoded
+ 1) != 0)
506 TRACE("expected 0 TLV\n");
507 SetLastError(CRYPT_E_ASN1_CORRUPT
);
514 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
516 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
518 SetLastError(CRYPT_E_ASN1_CORRUPT
);
523 DWORD i
, bytesNeeded
= 0, structSize
= 0;
525 for (i
= 0; i
< cItem
; i
++)
527 if (items
[i
].size
> items
[i
].minSize
)
528 bytesNeeded
+= items
[i
].size
- items
[i
].minSize
;
529 structSize
= max( structSize
, items
[i
].offset
+ items
[i
].minSize
);
531 bytesNeeded
+= structSize
;
533 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
535 *pcbStructInfo
= bytesNeeded
;
536 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
537 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
541 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
542 pvStructInfo
= *(BYTE
**)pvStructInfo
;
544 nextData
= startingPointer
;
546 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
547 memset(pvStructInfo
, 0, structSize
);
548 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
549 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
551 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
552 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
559 SetLastError(CRYPT_E_ASN1_BADTAG
);
562 TRACE("returning %d (%08x)\n", ret
, GetLastError());
567 * The expected tag of the entire encoded array (usually a variant
568 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
569 * regardless of the tag seen.
571 * The offset within the outer structure at which the count exists.
572 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
573 * while CRYPT_ATTRIBUTE has countOffset ==
574 * offsetof(CRYPT_ATTRIBUTE, cValue).
576 * The offset within the outer structure at which the array pointer exists.
577 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
578 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
580 * The minimum size of the decoded array. On WIN32, this is always 8:
581 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
584 * used to decode each item in the array
586 * is the minimum size of each decoded item
588 * indicates whether each item has a dynamic pointer
590 * indicates the offset within itemSize at which the pointer exists
592 struct AsnArrayDescriptor
598 InternalDecodeFunc decodeFunc
;
604 struct AsnArrayItemSize
610 /* Decodes an array of like types into a structure described by a struct
611 * AsnArrayDescriptor.
613 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
614 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
615 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
620 TRACE("%p, %p, %d, %p, %d\n", arrayDesc
, pbEncoded
,
621 cbEncoded
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
625 SetLastError(CRYPT_E_ASN1_EOD
);
628 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
632 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
634 DWORD bytesNeeded
= arrayDesc
->minArraySize
, cItems
= 0, decoded
;
635 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
636 /* There can be arbitrarily many items, but there is often only one.
638 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
640 decoded
= 1 + lenBytes
;
644 BOOL doneDecoding
= FALSE
;
646 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
648 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
655 SetLastError(CRYPT_E_ASN1_CORRUPT
);
662 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
666 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
668 /* Each item decoded may not tolerate extraneous bytes,
669 * so get the length of the next element if known.
671 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
672 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
674 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
675 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
677 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
681 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
682 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
687 if (itemSizes
!= &itemSize
)
688 itemSizes
= CryptMemRealloc(itemSizes
,
689 cItems
* sizeof(struct AsnArrayItemSize
));
694 cItems
* sizeof(struct AsnArrayItemSize
));
696 *itemSizes
= itemSize
;
700 decoded
+= itemDecoded
;
701 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
702 itemSizes
[cItems
- 1].size
= size
;
715 *pcbDecoded
= decoded
;
717 *pcbStructInfo
= bytesNeeded
;
718 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
719 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
726 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
727 pvStructInfo
= *(void **)pvStructInfo
;
728 pcItems
= pvStructInfo
;
730 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
732 rgItems
= (BYTE
*)pvStructInfo
+
733 arrayDesc
->minArraySize
;
734 *(void **)((BYTE
*)pcItems
-
735 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
) =
739 rgItems
= *(void **)((BYTE
*)pcItems
-
740 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
);
741 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
742 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
743 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
748 if (arrayDesc
->hasPointer
)
749 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
750 + arrayDesc
->pointerOffset
) = nextData
;
751 ret
= arrayDesc
->decodeFunc(ptr
,
752 itemSizes
[i
].encodedLen
,
753 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
754 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
755 &itemSizes
[i
].size
, &itemDecoded
);
758 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
762 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
763 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
766 if (itemSizes
!= &itemSize
)
767 CryptMemFree(itemSizes
);
772 SetLastError(CRYPT_E_ASN1_BADTAG
);
778 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
779 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
780 * to CRYPT_E_ASN1_CORRUPT.
781 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
784 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
785 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
790 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
792 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
793 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
795 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
796 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
799 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
801 *pcbStructInfo
= bytesNeeded
;
802 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
804 CRYPT_DER_BLOB
*blob
;
806 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
807 pvStructInfo
= *(BYTE
**)pvStructInfo
;
809 blob
->cbData
= 1 + lenBytes
+ dataLen
;
812 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
813 blob
->pbData
= (BYTE
*)pbEncoded
;
816 assert(blob
->pbData
);
817 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
822 SetLastError(CRYPT_E_ASN1_CORRUPT
);
830 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
831 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
832 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
837 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
838 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
840 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
843 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
844 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
846 if (ret
&& pvStructInfo
)
848 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
855 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
857 temp
= blob
->pbData
[i
];
858 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
859 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
863 TRACE("returning %d (%08x)\n", ret
, GetLastError());
867 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
868 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
869 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
873 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
874 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
878 struct AsnDecodeSequenceItem items
[] = {
879 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
880 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
881 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
882 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
883 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
884 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
885 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
886 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
887 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
888 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
891 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
892 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
893 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
894 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
895 pcbStructInfo
, NULL
, NULL
);
899 SetLastError(STATUS_ACCESS_VIOLATION
);
904 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
908 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
909 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
914 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
916 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
918 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
919 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
921 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
926 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
927 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
931 struct AsnDecodeSequenceItem items
[] = {
932 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
933 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
934 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
935 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
938 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
939 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
944 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
945 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
949 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
950 offsetof(CERT_INFO
, cExtension
), offsetof(CERT_INFO
, rgExtension
),
951 FINALMEMBERSIZE(CERT_INFO
, cExtension
),
952 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
953 offsetof(CERT_EXTENSION
, pszObjId
) };
955 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
956 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
958 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
959 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
963 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
964 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
970 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
972 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
974 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
975 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
976 if (ret
&& pcbDecoded
)
977 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
982 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
983 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
984 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
987 struct AsnDecodeSequenceItem items
[] = {
988 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
989 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
990 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
991 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
992 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
993 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
994 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
995 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
996 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
997 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
999 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
1000 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
1002 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
1003 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1005 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
1006 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
1007 FALSE
, TRUE
, offsetof(CERT_INFO
,
1008 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
1009 { ASN_CONTEXT
| 1, offsetof(CERT_INFO
, IssuerUniqueId
),
1010 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1011 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
1012 { ASN_CONTEXT
| 2, offsetof(CERT_INFO
, SubjectUniqueId
),
1013 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1014 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
1015 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
1016 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
1017 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1020 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1021 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1023 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1024 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1026 if (ret
&& pvStructInfo
)
1030 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1031 info
= *(CERT_INFO
**)pvStructInfo
;
1033 info
= pvStructInfo
;
1034 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1035 !info
->Subject
.cbData
)
1037 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1038 /* Don't need to deallocate, because it should have failed on the
1039 * first pass (and no memory was allocated.)
1045 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1049 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1050 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1051 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1055 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1056 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1062 /* Unless told not to, first try to decode it as a signed cert. */
1063 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1065 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1067 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1068 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1069 &signedCert
, &size
);
1073 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1074 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1075 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1076 pvStructInfo
, pcbStructInfo
);
1077 LocalFree(signedCert
);
1080 /* Failing that, try it as an unsigned cert */
1084 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1085 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1086 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1091 SetLastError(STATUS_ACCESS_VIOLATION
);
1095 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1099 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1100 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1104 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1105 offsetof(CRL_ENTRY
, cExtension
), offsetof(CRL_ENTRY
, rgExtension
),
1106 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
),
1107 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1108 offsetof(CERT_EXTENSION
, pszObjId
) };
1110 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1111 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1113 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1114 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1118 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1119 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1122 struct AsnDecodeSequenceItem items
[] = {
1123 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1124 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1125 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1126 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1127 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1128 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1129 CRYPT_AsnDecodeCRLEntryExtensions
,
1130 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1131 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1133 PCRL_ENTRY entry
= pvStructInfo
;
1135 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1138 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1139 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1140 entry
? entry
->SerialNumber
.pbData
: NULL
);
1141 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1143 WARN("empty CRL entry serial number\n");
1144 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1150 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1151 * whose rgCRLEntry member has been set prior to calling.
1153 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1154 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1157 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1158 offsetof(CRL_INFO
, cCRLEntry
), offsetof(CRL_INFO
, rgCRLEntry
),
1159 MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1160 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1161 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1163 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1164 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1166 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1167 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1168 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1172 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1173 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1177 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1178 offsetof(CRL_INFO
, cExtension
), offsetof(CRL_INFO
, rgExtension
),
1179 FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1180 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1181 offsetof(CERT_EXTENSION
, pszObjId
) };
1183 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1184 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1186 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1187 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1191 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1192 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1198 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1200 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1202 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1203 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1204 if (ret
&& pcbDecoded
)
1205 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1210 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1211 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1212 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1214 struct AsnDecodeSequenceItem items
[] = {
1215 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1216 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1217 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1218 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1219 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1220 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1221 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1223 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1224 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1225 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1226 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1227 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1228 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1229 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1230 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1231 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1232 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1236 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1237 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1239 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1240 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1243 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1247 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1248 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1249 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1253 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1254 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1260 /* Unless told not to, first try to decode it as a signed crl. */
1261 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1263 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1265 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1266 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1271 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1272 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1273 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1274 pvStructInfo
, pcbStructInfo
);
1275 LocalFree(signedCrl
);
1278 /* Failing that, try it as an unsigned crl */
1282 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1283 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1284 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1289 SetLastError(STATUS_ACCESS_VIOLATION
);
1293 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1297 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1298 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1303 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1304 pvStructInfo
, *pcbStructInfo
);
1306 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1308 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1309 DWORD bytesNeeded
= sizeof(LPSTR
);
1316 snprintf(str
, sizeof(str
), "%d.%d",
1317 pbEncoded
[1 + lenBytes
] / 40,
1318 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1320 bytesNeeded
+= strlen(str
) + 1;
1321 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1322 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1326 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1333 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1336 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1343 snprintf(str
, sizeof(str
), ".%d", val
);
1344 bytesNeeded
+= strlen(str
);
1349 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1351 *pcbStructInfo
= bytesNeeded
;
1352 else if (*pcbStructInfo
< bytesNeeded
)
1354 *pcbStructInfo
= bytesNeeded
;
1355 SetLastError(ERROR_MORE_DATA
);
1363 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1366 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1367 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1369 pszObjId
+= strlen(pszObjId
);
1370 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1371 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1375 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1384 sprintf(pszObjId
, ".%d", val
);
1385 pszObjId
+= strlen(pszObjId
);
1389 *(LPSTR
*)pvStructInfo
= NULL
;
1390 *pcbStructInfo
= bytesNeeded
;
1396 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1397 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1401 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1402 pvStructInfo
, *pcbStructInfo
);
1404 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1405 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1406 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1409 SetLastError(CRYPT_E_ASN1_BADTAG
);
1415 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1416 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1418 struct AsnDecodeSequenceItem items
[] = {
1419 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1420 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1421 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1422 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1423 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1424 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1425 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1426 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1429 PCERT_EXTENSION ext
= pvStructInfo
;
1431 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1435 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1436 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1437 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1438 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1440 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1441 debugstr_a(ext
->pszObjId
));
1442 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1446 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1447 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1448 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1452 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1453 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1457 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1458 offsetof(CERT_EXTENSIONS
, cExtension
),
1459 offsetof(CERT_EXTENSIONS
, rgExtension
),
1460 sizeof(CERT_EXTENSIONS
),
1461 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1462 offsetof(CERT_EXTENSION
, pszObjId
) };
1463 CERT_EXTENSIONS
*exts
= pvStructInfo
;
1465 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1466 exts
->rgExtension
= (CERT_EXTENSION
*)(exts
+ 1);
1467 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1468 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1472 SetLastError(STATUS_ACCESS_VIOLATION
);
1479 /* Warning: this assumes the address of value->Value.pbData is already set, in
1480 * order to avoid overwriting memory. (In some cases, it may change it, if it
1481 * doesn't copy anything to memory.) Be sure to set it correctly!
1483 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1484 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1489 CERT_NAME_VALUE
*value
= pvStructInfo
;
1491 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1493 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1494 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1496 switch (pbEncoded
[0])
1498 case ASN_OCTETSTRING
:
1499 valueType
= CERT_RDN_OCTET_STRING
;
1500 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1501 bytesNeeded
+= dataLen
;
1503 case ASN_NUMERICSTRING
:
1504 valueType
= CERT_RDN_NUMERIC_STRING
;
1505 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1506 bytesNeeded
+= dataLen
;
1508 case ASN_PRINTABLESTRING
:
1509 valueType
= CERT_RDN_PRINTABLE_STRING
;
1510 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1511 bytesNeeded
+= dataLen
;
1514 valueType
= CERT_RDN_IA5_STRING
;
1515 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1516 bytesNeeded
+= dataLen
;
1519 valueType
= CERT_RDN_T61_STRING
;
1520 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1521 bytesNeeded
+= dataLen
;
1523 case ASN_VIDEOTEXSTRING
:
1524 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1525 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1526 bytesNeeded
+= dataLen
;
1528 case ASN_GRAPHICSTRING
:
1529 valueType
= CERT_RDN_GRAPHIC_STRING
;
1530 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1531 bytesNeeded
+= dataLen
;
1533 case ASN_VISIBLESTRING
:
1534 valueType
= CERT_RDN_VISIBLE_STRING
;
1535 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1536 bytesNeeded
+= dataLen
;
1538 case ASN_GENERALSTRING
:
1539 valueType
= CERT_RDN_GENERAL_STRING
;
1540 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1541 bytesNeeded
+= dataLen
;
1543 case ASN_UNIVERSALSTRING
:
1544 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1545 SetLastError(CRYPT_E_ASN1_BADTAG
);
1548 valueType
= CERT_RDN_BMP_STRING
;
1549 bytesNeeded
+= dataLen
;
1551 case ASN_UTF8STRING
:
1552 valueType
= CERT_RDN_UTF8_STRING
;
1553 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1554 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1557 SetLastError(CRYPT_E_ASN1_BADTAG
);
1562 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1564 *pcbStructInfo
= bytesNeeded
;
1565 else if (*pcbStructInfo
< bytesNeeded
)
1567 *pcbStructInfo
= bytesNeeded
;
1568 SetLastError(ERROR_MORE_DATA
);
1573 *pcbStructInfo
= bytesNeeded
;
1574 value
->dwValueType
= valueType
;
1579 assert(value
->Value
.pbData
);
1580 switch (pbEncoded
[0])
1582 case ASN_OCTETSTRING
:
1583 case ASN_NUMERICSTRING
:
1584 case ASN_PRINTABLESTRING
:
1587 case ASN_VIDEOTEXSTRING
:
1588 case ASN_GRAPHICSTRING
:
1589 case ASN_VISIBLESTRING
:
1590 case ASN_GENERALSTRING
:
1591 value
->Value
.cbData
= dataLen
;
1594 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1595 memcpy(value
->Value
.pbData
,
1596 pbEncoded
+ 1 + lenBytes
, dataLen
);
1598 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1604 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1606 value
->Value
.cbData
= dataLen
;
1607 for (i
= 0; i
< dataLen
/ 2; i
++)
1608 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1609 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1612 case ASN_UTF8STRING
:
1614 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1616 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1617 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1618 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1625 value
->Value
.cbData
= 0;
1626 value
->Value
.pbData
= NULL
;
1633 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1634 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1635 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1641 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1642 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1643 if (ret
&& pvStructInfo
)
1645 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1646 pcbStructInfo
, *pcbStructInfo
);
1649 CERT_NAME_VALUE
*value
;
1651 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1652 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1653 value
= pvStructInfo
;
1654 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1655 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1656 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1657 pcbStructInfo
, NULL
);
1658 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1659 CRYPT_FreeSpace(pDecodePara
, value
);
1665 SetLastError(STATUS_ACCESS_VIOLATION
);
1672 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1673 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1678 CERT_NAME_VALUE
*value
= pvStructInfo
;
1680 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1682 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1683 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1685 switch (pbEncoded
[0])
1687 case ASN_NUMERICSTRING
:
1688 valueType
= CERT_RDN_NUMERIC_STRING
;
1690 bytesNeeded
+= (dataLen
+ 1) * 2;
1692 case ASN_PRINTABLESTRING
:
1693 valueType
= CERT_RDN_PRINTABLE_STRING
;
1695 bytesNeeded
+= (dataLen
+ 1) * 2;
1698 valueType
= CERT_RDN_IA5_STRING
;
1700 bytesNeeded
+= (dataLen
+ 1) * 2;
1703 valueType
= CERT_RDN_T61_STRING
;
1705 bytesNeeded
+= (dataLen
+ 1) * 2;
1707 case ASN_VIDEOTEXSTRING
:
1708 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1710 bytesNeeded
+= (dataLen
+ 1) * 2;
1712 case ASN_GRAPHICSTRING
:
1713 valueType
= CERT_RDN_GRAPHIC_STRING
;
1715 bytesNeeded
+= (dataLen
+ 1) * 2;
1717 case ASN_VISIBLESTRING
:
1718 valueType
= CERT_RDN_VISIBLE_STRING
;
1720 bytesNeeded
+= (dataLen
+ 1) * 2;
1722 case ASN_GENERALSTRING
:
1723 valueType
= CERT_RDN_GENERAL_STRING
;
1725 bytesNeeded
+= (dataLen
+ 1) * 2;
1727 case ASN_UNIVERSALSTRING
:
1728 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1730 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1733 valueType
= CERT_RDN_BMP_STRING
;
1735 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1737 case ASN_UTF8STRING
:
1738 valueType
= CERT_RDN_UTF8_STRING
;
1740 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1741 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1744 SetLastError(CRYPT_E_ASN1_BADTAG
);
1749 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1751 *pcbStructInfo
= bytesNeeded
;
1752 else if (*pcbStructInfo
< bytesNeeded
)
1754 *pcbStructInfo
= bytesNeeded
;
1755 SetLastError(ERROR_MORE_DATA
);
1760 *pcbStructInfo
= bytesNeeded
;
1761 value
->dwValueType
= valueType
;
1765 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1767 assert(value
->Value
.pbData
);
1768 switch (pbEncoded
[0])
1770 case ASN_NUMERICSTRING
:
1771 case ASN_PRINTABLESTRING
:
1774 case ASN_VIDEOTEXSTRING
:
1775 case ASN_GRAPHICSTRING
:
1776 case ASN_VISIBLESTRING
:
1777 case ASN_GENERALSTRING
:
1778 value
->Value
.cbData
= dataLen
* 2;
1779 for (i
= 0; i
< dataLen
; i
++)
1780 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1783 case ASN_UNIVERSALSTRING
:
1784 value
->Value
.cbData
= dataLen
/ 2;
1785 for (i
= 0; i
< dataLen
/ 4; i
++)
1786 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1787 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1791 value
->Value
.cbData
= dataLen
;
1792 for (i
= 0; i
< dataLen
/ 2; i
++)
1793 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1794 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1797 case ASN_UTF8STRING
:
1798 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1799 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1800 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1801 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1802 value
->Value
.cbData
+= sizeof(WCHAR
);
1808 value
->Value
.cbData
= 0;
1809 value
->Value
.pbData
= NULL
;
1816 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1817 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1818 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1824 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1825 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1826 if (ret
&& pvStructInfo
)
1828 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1829 pcbStructInfo
, *pcbStructInfo
);
1832 CERT_NAME_VALUE
*value
;
1834 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1835 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1836 value
= pvStructInfo
;
1837 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1838 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1839 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1840 pcbStructInfo
, NULL
);
1841 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1842 CRYPT_FreeSpace(pDecodePara
, value
);
1848 SetLastError(STATUS_ACCESS_VIOLATION
);
1855 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1856 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1859 struct AsnDecodeSequenceItem items
[] = {
1860 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1861 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1862 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1863 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1864 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1865 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1867 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1869 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1870 pvStructInfo
, *pcbStructInfo
);
1873 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1874 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1875 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1876 attr
? attr
->pszObjId
: NULL
);
1879 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1880 debugstr_a(attr
->pszObjId
));
1881 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1883 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1887 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1888 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1891 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1892 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1894 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1895 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1897 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1898 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1902 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1903 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1904 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1910 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1911 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1912 sizeof(CERT_NAME_INFO
),
1913 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1914 offsetof(CERT_RDN
, rgRDNAttr
) };
1915 DWORD bytesNeeded
= 0;
1917 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1918 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1923 *pcbStructInfo
= bytesNeeded
;
1924 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1925 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1927 CERT_NAME_INFO
*info
;
1929 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1930 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1931 info
= pvStructInfo
;
1932 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1933 sizeof(CERT_NAME_INFO
));
1934 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1935 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1936 &bytesNeeded
, NULL
);
1937 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1938 CRYPT_FreeSpace(pDecodePara
, info
);
1944 SetLastError(STATUS_ACCESS_VIOLATION
);
1951 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1952 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1956 struct AsnDecodeSequenceItem items
[] = {
1957 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1958 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1959 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1960 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1961 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1962 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1964 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1966 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1967 pvStructInfo
, *pcbStructInfo
);
1970 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1971 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1972 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1973 attr
? attr
->pszObjId
: NULL
);
1976 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1977 debugstr_a(attr
->pszObjId
));
1978 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1980 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1984 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1985 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1988 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1989 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1991 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1992 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1994 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1995 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1999 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
2000 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2001 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2007 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2008 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2009 sizeof(CERT_NAME_INFO
),
2010 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2011 offsetof(CERT_RDN
, rgRDNAttr
) };
2012 DWORD bytesNeeded
= 0;
2014 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2015 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2020 *pcbStructInfo
= bytesNeeded
;
2021 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2022 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2024 CERT_NAME_INFO
*info
;
2026 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2027 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2028 info
= pvStructInfo
;
2029 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2030 sizeof(CERT_NAME_INFO
));
2031 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2032 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2033 &bytesNeeded
, NULL
);
2034 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2035 CRYPT_FreeSpace(pDecodePara
, info
);
2041 SetLastError(STATUS_ACCESS_VIOLATION
);
2048 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2051 BOOL ret
= TRUE
, done
= FALSE
;
2052 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2054 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2061 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2064 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2066 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2068 indefiniteNestingLevels
++;
2069 pbEncoded
+= 1 + lenBytes
;
2070 cbEncoded
-= 1 + lenBytes
;
2071 decoded
+= 1 + lenBytes
;
2072 TRACE("indefiniteNestingLevels = %d\n",
2073 indefiniteNestingLevels
);
2077 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2078 indefiniteNestingLevels
)
2080 indefiniteNestingLevels
--;
2081 TRACE("indefiniteNestingLevels = %d\n",
2082 indefiniteNestingLevels
);
2084 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2085 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2086 decoded
+= 1 + lenBytes
+ dataLen
;
2087 if (!indefiniteNestingLevels
)
2091 } while (ret
&& !done
);
2092 /* If we haven't found all 0 TLVs, we haven't found the end */
2093 if (ret
&& indefiniteNestingLevels
)
2095 SetLastError(CRYPT_E_ASN1_EOD
);
2099 *pcbDecoded
= decoded
;
2100 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2104 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2105 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2109 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2111 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2112 pvStructInfo
, *pcbStructInfo
);
2114 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2116 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2117 bytesNeeded
+= encodedLen
;
2119 *pcbStructInfo
= bytesNeeded
;
2120 else if (*pcbStructInfo
< bytesNeeded
)
2122 SetLastError(ERROR_MORE_DATA
);
2123 *pcbStructInfo
= bytesNeeded
;
2128 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2130 *pcbStructInfo
= bytesNeeded
;
2131 blob
->cbData
= encodedLen
;
2134 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2135 blob
->pbData
= (LPBYTE
)pbEncoded
;
2138 assert(blob
->pbData
);
2139 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2143 blob
->pbData
= NULL
;
2146 *pcbDecoded
= encodedLen
;
2151 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2152 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2155 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2156 offsetof(CTL_USAGE
, cUsageIdentifier
),
2157 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2159 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2161 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2162 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2166 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2167 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2170 struct AsnArrayDescriptor arrayDesc
= { 0,
2171 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2172 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2173 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2174 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2177 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2178 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2182 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2183 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2185 struct AsnDecodeSequenceItem items
[] = {
2186 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2187 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2188 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2189 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2190 CRYPT_AsnDecodeCTLEntryAttributes
,
2191 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2192 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2195 CTL_ENTRY
*entry
= pvStructInfo
;
2197 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2200 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2201 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2202 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2206 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2207 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2210 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2211 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2212 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2213 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2214 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2216 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2217 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2219 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2220 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2224 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2225 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2229 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2230 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2231 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2232 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2233 offsetof(CERT_EXTENSION
, pszObjId
) };
2235 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2236 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2238 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2239 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2243 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2244 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2250 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2252 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2254 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2255 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2256 if (ret
&& pcbDecoded
)
2257 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2262 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2263 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2264 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2268 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2269 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2273 struct AsnDecodeSequenceItem items
[] = {
2274 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2275 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2276 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2277 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2278 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2279 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2280 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2281 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2282 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2283 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2284 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2285 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2286 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2288 { 0, offsetof(CTL_INFO
, NextUpdate
),
2289 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2291 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2292 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2293 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2294 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2295 CRYPT_AsnDecodeCTLEntries
,
2296 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2297 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2298 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2299 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2300 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2303 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2304 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2305 pcbStructInfo
, NULL
, NULL
);
2309 SetLastError(STATUS_ACCESS_VIOLATION
);
2315 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2316 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2320 struct AsnDecodeSequenceItem items
[] = {
2321 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2322 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2323 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2324 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2325 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2326 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2328 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2330 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2331 pvStructInfo
, *pcbStructInfo
);
2333 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2334 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2335 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2336 TRACE("returning %d\n", ret
);
2340 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2341 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2342 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2346 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2347 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2351 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2352 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2353 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2354 sizeof(CRYPT_SMIME_CAPABILITIES
),
2355 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2356 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2357 CRYPT_SMIME_CAPABILITIES
*capabilities
= pvStructInfo
;
2359 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2360 capabilities
->rgCapability
= (CRYPT_SMIME_CAPABILITY
*)(capabilities
+ 1);
2361 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2362 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2366 SetLastError(STATUS_ACCESS_VIOLATION
);
2369 TRACE("returning %d\n", ret
);
2373 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2374 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2379 LPSTR
*pStr
= pvStructInfo
;
2381 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2383 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2384 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2386 if (pbEncoded
[0] != ASN_IA5STRING
)
2388 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2393 bytesNeeded
+= dataLen
;
2395 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2397 *pcbStructInfo
= bytesNeeded
;
2398 else if (*pcbStructInfo
< bytesNeeded
)
2400 *pcbStructInfo
= bytesNeeded
;
2401 SetLastError(ERROR_MORE_DATA
);
2406 *pcbStructInfo
= bytesNeeded
;
2412 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2423 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2424 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2427 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2428 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2429 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2430 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2431 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2434 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2435 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2437 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2438 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2439 TRACE("returning %d\n", ret
);
2443 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2444 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2448 struct AsnDecodeSequenceItem items
[] = {
2449 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2450 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2451 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2452 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2453 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2454 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2455 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2456 rgNoticeNumbers
), 0 },
2458 DWORD bytesNeeded
= 0;
2460 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2461 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2463 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2464 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2468 /* The caller is expecting a pointer to a
2469 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2470 * CRYPT_AsnDecodeSequence is decoding a
2471 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2472 * needed, and decode again if the requisite space is available.
2474 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2476 *pcbStructInfo
= bytesNeeded
;
2477 else if (*pcbStructInfo
< bytesNeeded
)
2479 *pcbStructInfo
= bytesNeeded
;
2480 SetLastError(ERROR_MORE_DATA
);
2485 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2487 *pcbStructInfo
= bytesNeeded
;
2488 /* The pointer (pvStructInfo) passed in points to the first dynamic
2489 * pointer, so use it as the pointer to the
2490 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2491 * appropriate offset for the first dynamic pointer within the
2492 * notice reference by pointing to the first memory location past
2493 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2496 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2497 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2498 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2499 ret
= CRYPT_AsnDecodeSequence(items
,
2500 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2501 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2502 noticeRef
->pszOrganization
);
2505 TRACE("returning %d\n", ret
);
2509 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2510 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2516 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2518 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2519 DWORD bytesNeeded
= sizeof(LPWSTR
);
2521 switch (pbEncoded
[0])
2523 case ASN_NUMERICSTRING
:
2525 bytesNeeded
+= (dataLen
+ 1) * 2;
2527 case ASN_PRINTABLESTRING
:
2529 bytesNeeded
+= (dataLen
+ 1) * 2;
2533 bytesNeeded
+= (dataLen
+ 1) * 2;
2537 bytesNeeded
+= (dataLen
+ 1) * 2;
2539 case ASN_VIDEOTEXSTRING
:
2541 bytesNeeded
+= (dataLen
+ 1) * 2;
2543 case ASN_GRAPHICSTRING
:
2545 bytesNeeded
+= (dataLen
+ 1) * 2;
2547 case ASN_VISIBLESTRING
:
2549 bytesNeeded
+= (dataLen
+ 1) * 2;
2551 case ASN_GENERALSTRING
:
2553 bytesNeeded
+= (dataLen
+ 1) * 2;
2555 case ASN_UNIVERSALSTRING
:
2557 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2561 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2563 case ASN_UTF8STRING
:
2565 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2566 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2569 SetLastError(CRYPT_E_ASN1_BADTAG
);
2574 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2576 *pcbStructInfo
= bytesNeeded
;
2577 else if (*pcbStructInfo
< bytesNeeded
)
2579 *pcbStructInfo
= bytesNeeded
;
2580 SetLastError(ERROR_MORE_DATA
);
2585 LPWSTR
*pStr
= pvStructInfo
;
2587 *pcbStructInfo
= bytesNeeded
;
2591 LPWSTR str
= *(LPWSTR
*)pStr
;
2594 switch (pbEncoded
[0])
2596 case ASN_NUMERICSTRING
:
2597 case ASN_PRINTABLESTRING
:
2600 case ASN_VIDEOTEXSTRING
:
2601 case ASN_GRAPHICSTRING
:
2602 case ASN_VISIBLESTRING
:
2603 case ASN_GENERALSTRING
:
2604 for (i
= 0; i
< dataLen
; i
++)
2605 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2608 case ASN_UNIVERSALSTRING
:
2609 for (i
= 0; i
< dataLen
/ 4; i
++)
2610 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2611 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2615 for (i
= 0; i
< dataLen
/ 2; i
++)
2616 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2617 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2620 case ASN_UTF8STRING
:
2622 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2623 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2624 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2637 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2638 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2639 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2642 struct AsnDecodeSequenceItem items
[] = {
2643 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2644 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2645 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2646 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2647 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2648 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2649 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2651 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2653 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2654 pvStructInfo
, *pcbStructInfo
);
2656 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2657 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2658 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2659 TRACE("returning %d\n", ret
);
2663 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2664 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2665 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2666 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2670 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2671 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2675 DWORD bytesNeeded
= 0;
2677 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2678 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2683 *pcbStructInfo
= bytesNeeded
;
2684 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2685 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2687 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2689 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2690 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2691 notice
= pvStructInfo
;
2692 notice
->pNoticeReference
=
2693 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2694 ((BYTE
*)pvStructInfo
+
2695 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2696 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2697 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2698 pvStructInfo
, &bytesNeeded
, NULL
);
2699 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2700 CRYPT_FreeSpace(pDecodePara
, notice
);
2706 SetLastError(STATUS_ACCESS_VIOLATION
);
2709 TRACE("returning %d\n", ret
);
2713 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2714 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2718 struct AsnArrayDescriptor arrayDesc
= { 0,
2719 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2720 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2721 CRYPT_AsnDecodeCopyBytes
,
2722 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2724 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2725 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2727 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2728 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2732 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2733 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2737 struct AsnDecodeSequenceItem items
[] = {
2738 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2739 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2740 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2741 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2742 CRYPT_AsnDecodePKCSAttributeValue
,
2743 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2744 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2746 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2748 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2749 pvStructInfo
, *pcbStructInfo
);
2751 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2752 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2753 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2754 TRACE("returning %d\n", ret
);
2758 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2759 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2760 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2764 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2765 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2769 DWORD bytesNeeded
= 0;
2771 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2772 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2776 *pcbStructInfo
= bytesNeeded
;
2777 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2778 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2780 PCRYPT_ATTRIBUTE attr
;
2782 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2783 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2784 attr
= pvStructInfo
;
2785 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2786 sizeof(CRYPT_ATTRIBUTE
));
2787 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2788 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2790 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2791 CRYPT_FreeSpace(pDecodePara
, attr
);
2797 SetLastError(STATUS_ACCESS_VIOLATION
);
2800 TRACE("returning %d\n", ret
);
2804 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2805 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2808 struct AsnArrayDescriptor arrayDesc
= { 0,
2809 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2810 sizeof(CRYPT_ATTRIBUTES
),
2811 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2812 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2815 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2816 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2820 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2821 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2822 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2826 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2827 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2831 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2832 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2833 sizeof(CRYPT_ATTRIBUTES
),
2834 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2835 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2836 CRYPT_ATTRIBUTES
*attrs
= pvStructInfo
;
2838 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2839 attrs
->rgAttr
= (CRYPT_ATTRIBUTE
*)(attrs
+ 1);
2840 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2841 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2845 SetLastError(STATUS_ACCESS_VIOLATION
);
2848 TRACE("returning %d\n", ret
);
2852 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2853 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2855 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2857 struct AsnDecodeSequenceItem items
[] = {
2858 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2859 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2860 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2861 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2862 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2863 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2866 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2867 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2869 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2870 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2871 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2872 if (ret
&& pvStructInfo
)
2874 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2875 debugstr_a(algo
->pszObjId
));
2880 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2881 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2885 struct AsnDecodeSequenceItem items
[] = {
2886 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2887 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2888 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2889 Algorithm
.pszObjId
) },
2890 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2891 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2892 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2894 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2896 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2897 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2898 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2902 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2903 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2904 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2910 DWORD bytesNeeded
= 0;
2912 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2913 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2916 *pcbStructInfo
= bytesNeeded
;
2917 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2918 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2920 PCERT_PUBLIC_KEY_INFO info
;
2922 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2923 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2924 info
= pvStructInfo
;
2925 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2926 sizeof(CERT_PUBLIC_KEY_INFO
);
2927 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2928 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2929 &bytesNeeded
, NULL
);
2930 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2931 CRYPT_FreeSpace(pDecodePara
, info
);
2937 SetLastError(STATUS_ACCESS_VIOLATION
);
2944 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2945 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2951 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2954 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2956 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2959 if (pbEncoded
[1] > 1)
2961 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2968 *pcbStructInfo
= sizeof(BOOL
);
2971 else if (*pcbStructInfo
< sizeof(BOOL
))
2973 *pcbStructInfo
= sizeof(BOOL
);
2974 SetLastError(ERROR_MORE_DATA
);
2979 *pcbStructInfo
= sizeof(BOOL
);
2980 *(BOOL
*)pvStructInfo
= pbEncoded
[2] != 0;
2983 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2987 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2988 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2990 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2991 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2994 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2995 pvStructInfo
, *pcbStructInfo
);
2999 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3002 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3003 if (1 + lenBytes
> cbEncoded
)
3005 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3008 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3010 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3012 case 1: /* rfc822Name */
3013 case 2: /* dNSName */
3014 case 6: /* uniformResourceIdentifier */
3015 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
3017 SetLastError(CRYPT_E_ASN1_RULE
);
3021 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3023 case 4: /* directoryName */
3024 case 7: /* iPAddress */
3025 bytesNeeded
+= dataLen
;
3027 case 8: /* registeredID */
3028 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3032 /* FIXME: ugly, shouldn't need to know internals of OID decode
3033 * function to use it.
3035 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3038 case 0: /* otherName */
3039 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3040 SetLastError(CRYPT_E_ASN1_BADTAG
);
3043 case 3: /* x400Address, unimplemented */
3044 case 5: /* ediPartyName, unimplemented */
3045 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3046 SetLastError(CRYPT_E_ASN1_BADTAG
);
3050 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3051 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3057 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3059 *pcbStructInfo
= bytesNeeded
;
3060 else if (*pcbStructInfo
< bytesNeeded
)
3062 *pcbStructInfo
= bytesNeeded
;
3063 SetLastError(ERROR_MORE_DATA
);
3068 *pcbStructInfo
= bytesNeeded
;
3069 /* MS used values one greater than the asn1 ones.. sigh */
3070 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3071 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3073 case 1: /* rfc822Name */
3074 case 2: /* dNSName */
3075 case 6: /* uniformResourceIdentifier */
3079 for (i
= 0; i
< dataLen
; i
++)
3080 entry
->u
.pwszURL
[i
] =
3081 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3082 entry
->u
.pwszURL
[i
] = 0;
3083 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3084 debugstr_w(entry
->u
.pwszURL
));
3087 case 4: /* directoryName */
3088 /* The data are memory-equivalent with the IPAddress case,
3091 case 7: /* iPAddress */
3092 /* The next data pointer is in the pwszURL spot, that is,
3093 * the first 4 bytes. Need to move it to the next spot.
3095 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3096 entry
->u
.IPAddress
.cbData
= dataLen
;
3097 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3100 case 8: /* registeredID */
3101 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3102 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3111 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3112 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3116 struct AsnArrayDescriptor arrayDesc
= { 0,
3117 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3118 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3119 sizeof(CERT_ALT_NAME_INFO
),
3120 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3121 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3123 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3124 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3126 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3127 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3131 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3132 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3133 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3139 struct AsnDecodeSequenceItem items
[] = {
3140 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3141 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3142 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3143 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3144 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3145 CRYPT_AsnDecodeOctets
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3146 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3147 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3148 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3149 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3150 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3153 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3154 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3155 pcbStructInfo
, NULL
, NULL
);
3159 SetLastError(STATUS_ACCESS_VIOLATION
);
3166 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3167 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3168 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3174 struct AsnDecodeSequenceItem items
[] = {
3175 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3176 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3177 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3178 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3179 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3180 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3181 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3182 AuthorityCertIssuer
.rgAltEntry
), 0 },
3183 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3184 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3185 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3186 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3187 AuthorityCertSerialNumber
.pbData
), 0 },
3190 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3191 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3192 pcbStructInfo
, NULL
, NULL
);
3196 SetLastError(STATUS_ACCESS_VIOLATION
);
3203 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3204 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3207 struct AsnDecodeSequenceItem items
[] = {
3208 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3209 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3210 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3211 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3212 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3213 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3215 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3217 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3218 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3219 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3222 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3223 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3224 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3228 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3229 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3233 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3234 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3235 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3236 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3237 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3238 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3239 CERT_AUTHORITY_INFO_ACCESS
*info
= pvStructInfo
;
3241 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3242 info
->rgAccDescr
= (CERT_ACCESS_DESCRIPTION
*)(info
+ 1);
3243 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3244 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3248 SetLastError(STATUS_ACCESS_VIOLATION
);
3255 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3256 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3261 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3262 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3264 /* The caller has already checked the tag, no need to check it again.
3265 * Check the outer length is valid:
3267 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3269 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3272 pbEncoded
+= 1 + lenBytes
;
3273 cbEncoded
-= 1 + lenBytes
;
3274 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3275 cbEncoded
-= 2; /* space for 0 TLV */
3276 /* Check the inner length is valid: */
3277 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3281 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3282 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3283 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3285 if (*(pbEncoded
+ decodedLen
) != 0 ||
3286 *(pbEncoded
+ decodedLen
+ 1) != 0)
3288 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3289 *(pbEncoded
+ decodedLen
),
3290 *(pbEncoded
+ decodedLen
+ 1));
3291 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3297 if (ret
&& pcbDecoded
)
3299 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3300 TRACE("decoded %d bytes\n", *pcbDecoded
);
3307 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3308 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3311 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3312 struct AsnDecodeSequenceItem items
[] = {
3313 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3314 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3315 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3316 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3317 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3318 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3319 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3323 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3324 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3326 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3327 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3328 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3332 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3333 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3334 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3338 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3339 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3343 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3344 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3345 if (ret
&& pvStructInfo
)
3347 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3348 pcbStructInfo
, *pcbStructInfo
);
3351 CRYPT_CONTENT_INFO
*info
;
3353 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3354 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3355 info
= pvStructInfo
;
3356 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3357 sizeof(CRYPT_CONTENT_INFO
));
3358 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3359 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3360 pcbStructInfo
, NULL
);
3361 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3362 CRYPT_FreeSpace(pDecodePara
, info
);
3368 SetLastError(STATUS_ACCESS_VIOLATION
);
3374 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3375 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3376 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3379 struct AsnDecodeSequenceItem items
[] = {
3380 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3381 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3382 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3383 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3384 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3386 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3387 CRYPT_AsnDecodePKCSContentInfoInternal
,
3388 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3389 ContentInfo
.pszObjId
), 0 },
3390 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3391 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3392 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3395 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3396 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3401 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3402 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3403 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3407 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3408 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3412 DWORD bytesNeeded
= 0;
3414 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3415 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3418 *pcbStructInfo
= bytesNeeded
;
3419 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3420 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3422 CERT_ALT_NAME_INFO
*name
;
3424 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3425 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3426 name
= pvStructInfo
;
3427 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3428 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3429 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3430 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3431 &bytesNeeded
, NULL
);
3432 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3433 CRYPT_FreeSpace(pDecodePara
, name
);
3439 SetLastError(STATUS_ACCESS_VIOLATION
);
3446 struct PATH_LEN_CONSTRAINT
3448 BOOL fPathLenConstraint
;
3449 DWORD dwPathLenConstraint
;
3452 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3453 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3457 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3459 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3460 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3464 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3466 *pcbStructInfo
= bytesNeeded
;
3468 else if (*pcbStructInfo
< bytesNeeded
)
3470 SetLastError(ERROR_MORE_DATA
);
3471 *pcbStructInfo
= bytesNeeded
;
3476 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3478 *pcbStructInfo
= bytesNeeded
;
3479 size
= sizeof(constraint
->dwPathLenConstraint
);
3480 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3481 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3483 constraint
->fPathLenConstraint
= TRUE
;
3484 TRACE("got an int, dwPathLenConstraint is %d\n",
3485 constraint
->dwPathLenConstraint
);
3487 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3491 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3492 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3496 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3497 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3498 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3499 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3500 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3501 offsetof(CERT_NAME_BLOB
, pbData
) };
3503 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3504 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3506 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3507 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3508 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3512 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3513 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3514 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3520 struct AsnDecodeSequenceItem items
[] = {
3521 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3522 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3523 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3524 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3525 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3526 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3527 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3528 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3529 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3531 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3534 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3535 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3536 pcbStructInfo
, NULL
, NULL
);
3540 SetLastError(STATUS_ACCESS_VIOLATION
);
3547 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3548 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3549 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3555 struct AsnDecodeSequenceItem items
[] = {
3556 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3557 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3558 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3559 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3560 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3563 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3564 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3565 pcbStructInfo
, NULL
, NULL
);
3569 SetLastError(STATUS_ACCESS_VIOLATION
);
3576 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3577 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3580 struct AsnDecodeSequenceItem items
[] = {
3581 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3582 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3583 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3585 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3586 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3587 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3590 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3592 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3593 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3595 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3596 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3597 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3601 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3602 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3606 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3607 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3608 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3609 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3610 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3611 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3613 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3614 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3616 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3617 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3618 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3622 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3623 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3625 struct AsnDecodeSequenceItem items
[] = {
3626 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3627 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3628 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3629 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3630 CRYPT_AsnDecodePolicyQualifiers
,
3631 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3632 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3634 CERT_POLICY_INFO
*info
= pvStructInfo
;
3637 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3638 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3640 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3641 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3642 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3646 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3647 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3648 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3652 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3653 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3657 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3658 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3659 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3660 sizeof(CERT_POLICIES_INFO
),
3661 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3662 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3663 CERT_POLICIES_INFO
*info
= pvStructInfo
;
3665 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3666 info
->rgPolicyInfo
= (CERT_POLICY_INFO
*)(info
+ 1);
3668 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3669 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3673 SetLastError(STATUS_ACCESS_VIOLATION
);
3679 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3680 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3683 struct AsnDecodeSequenceItem items
[] = {
3684 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3685 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3686 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3687 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3688 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3689 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3691 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3694 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3695 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3697 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3698 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3699 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3703 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3704 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3705 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3709 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3710 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3714 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3715 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3716 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3717 sizeof(CERT_POLICY_MAPPING
),
3718 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3719 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3720 CERT_POLICY_MAPPINGS_INFO
*info
= pvStructInfo
;
3722 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3723 info
->rgPolicyMapping
= (CERT_POLICY_MAPPING
*)(info
+ 1);
3724 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3725 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3729 SetLastError(STATUS_ACCESS_VIOLATION
);
3735 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3736 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3740 DWORD skip
, size
= sizeof(skip
);
3744 SetLastError(CRYPT_E_ASN1_EOD
);
3747 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3749 SetLastError(CRYPT_E_ASN1_BADTAG
);
3752 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3753 &skip
, &size
, pcbDecoded
)))
3755 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3756 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3759 *pcbStructInfo
= bytesNeeded
;
3760 else if (*pcbStructInfo
< bytesNeeded
)
3762 *pcbStructInfo
= bytesNeeded
;
3763 SetLastError(ERROR_MORE_DATA
);
3768 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3769 CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
);
3771 *pcbStructInfo
= bytesNeeded
;
3772 /* The BOOL is implicit: if the integer is present, then it's
3775 info
->fRequireExplicitPolicy
= TRUE
;
3776 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3782 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3783 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3787 DWORD skip
, size
= sizeof(skip
);
3791 SetLastError(CRYPT_E_ASN1_EOD
);
3794 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3796 SetLastError(CRYPT_E_ASN1_BADTAG
);
3799 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3800 &skip
, &size
, pcbDecoded
)))
3802 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3803 fInhibitPolicyMapping
);
3806 *pcbStructInfo
= bytesNeeded
;
3807 else if (*pcbStructInfo
< bytesNeeded
)
3809 *pcbStructInfo
= bytesNeeded
;
3810 SetLastError(ERROR_MORE_DATA
);
3815 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3816 CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
);
3818 *pcbStructInfo
= bytesNeeded
;
3819 /* The BOOL is implicit: if the integer is present, then it's
3822 info
->fInhibitPolicyMapping
= TRUE
;
3823 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3829 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3830 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3831 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3832 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3836 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3837 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3841 struct AsnDecodeSequenceItem items
[] = {
3843 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3844 CRYPT_AsnDecodeRequireExplicit
,
3845 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3846 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3848 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3849 CRYPT_AsnDecodeInhibitMapping
,
3850 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3851 TRUE
, FALSE
, 0, 0 },
3854 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3855 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3856 pcbStructInfo
, NULL
, NULL
);
3860 SetLastError(STATUS_ACCESS_VIOLATION
);
3866 #define RSA1_MAGIC 0x31415352
3868 struct DECODED_RSA_PUB_KEY
3871 CRYPT_INTEGER_BLOB modulus
;
3874 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3875 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3876 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3882 struct AsnDecodeSequenceItem items
[] = {
3883 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3884 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3885 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3887 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3888 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3890 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3893 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3894 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3898 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3899 decodedKey
->modulus
.cbData
;
3903 *pcbStructInfo
= bytesNeeded
;
3906 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3907 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3910 RSAPUBKEY
*rsaPubKey
;
3912 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3913 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3915 hdr
->bType
= PUBLICKEYBLOB
;
3916 hdr
->bVersion
= CUR_BLOB_VERSION
;
3918 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3919 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3920 sizeof(BLOBHEADER
));
3921 rsaPubKey
->magic
= RSA1_MAGIC
;
3922 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3923 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3924 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3925 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3926 decodedKey
->modulus
.cbData
);
3928 LocalFree(decodedKey
);
3933 SetLastError(STATUS_ACCESS_VIOLATION
);
3940 #define RSA2_MAGIC 0x32415352
3942 struct DECODED_RSA_PRIV_KEY
3946 CRYPT_INTEGER_BLOB modulus
;
3947 CRYPT_INTEGER_BLOB privexp
;
3948 CRYPT_INTEGER_BLOB prime1
;
3949 CRYPT_INTEGER_BLOB prime2
;
3950 CRYPT_INTEGER_BLOB exponent1
;
3951 CRYPT_INTEGER_BLOB exponent2
;
3952 CRYPT_INTEGER_BLOB coefficient
;
3955 static BOOL WINAPI
CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType
,
3956 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3957 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3964 struct AsnDecodeSequenceItem items
[] = {
3965 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, version
),
3966 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3967 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
),
3968 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3969 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
.pbData
),
3971 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, pubexp
),
3972 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3973 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
),
3974 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3975 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
.pbData
),
3977 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
),
3978 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3979 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
.pbData
),
3981 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
),
3982 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3983 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
.pbData
),
3985 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
),
3986 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3987 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
.pbData
),
3989 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
),
3990 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3991 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
.pbData
),
3993 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
),
3994 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3995 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
.pbData
),
3998 struct DECODED_RSA_PRIV_KEY
*decodedKey
= NULL
;
4001 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4002 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
4006 halflen
= decodedKey
->prime1
.cbData
;
4007 if (halflen
< decodedKey
->prime2
.cbData
)
4008 halflen
= decodedKey
->prime2
.cbData
;
4009 if (halflen
< decodedKey
->exponent1
.cbData
)
4010 halflen
= decodedKey
->exponent1
.cbData
;
4011 if (halflen
< decodedKey
->exponent2
.cbData
)
4012 halflen
= decodedKey
->exponent2
.cbData
;
4013 if (halflen
< decodedKey
->coefficient
.cbData
)
4014 halflen
= decodedKey
->coefficient
.cbData
;
4015 if (halflen
* 2 < decodedKey
->modulus
.cbData
)
4016 halflen
= decodedKey
->modulus
.cbData
/ 2 + decodedKey
->modulus
.cbData
% 2;
4017 if (halflen
* 2 < decodedKey
->privexp
.cbData
)
4018 halflen
= decodedKey
->privexp
.cbData
/ 2 + decodedKey
->privexp
.cbData
% 2;
4022 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
4027 *pcbStructInfo
= bytesNeeded
;
4030 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4031 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4034 RSAPUBKEY
*rsaPubKey
;
4037 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4038 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4041 hdr
->bType
= PRIVATEKEYBLOB
;
4042 hdr
->bVersion
= CUR_BLOB_VERSION
;
4044 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
4046 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
4047 sizeof(BLOBHEADER
));
4048 rsaPubKey
->magic
= RSA2_MAGIC
;
4049 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
4050 rsaPubKey
->bitlen
= halflen
* 16;
4052 vardata
= (BYTE
*)(rsaPubKey
+ 1);
4053 memset(vardata
, 0, halflen
* 9);
4055 decodedKey
->modulus
.pbData
, decodedKey
->modulus
.cbData
);
4056 memcpy(vardata
+ halflen
* 2,
4057 decodedKey
->prime1
.pbData
, decodedKey
->prime1
.cbData
);
4058 memcpy(vardata
+ halflen
* 3,
4059 decodedKey
->prime2
.pbData
, decodedKey
->prime2
.cbData
);
4060 memcpy(vardata
+ halflen
* 4,
4061 decodedKey
->exponent1
.pbData
, decodedKey
->exponent1
.cbData
);
4062 memcpy(vardata
+ halflen
* 5,
4063 decodedKey
->exponent2
.pbData
, decodedKey
->exponent2
.cbData
);
4064 memcpy(vardata
+ halflen
* 6,
4065 decodedKey
->coefficient
.pbData
, decodedKey
->coefficient
.cbData
);
4066 memcpy(vardata
+ halflen
* 7,
4067 decodedKey
->privexp
.pbData
, decodedKey
->privexp
.cbData
);
4071 LocalFree(decodedKey
);
4076 SetLastError(STATUS_ACCESS_VIOLATION
);
4083 static BOOL
CRYPT_AsnDecodeOctets(const BYTE
*pbEncoded
,
4084 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4088 DWORD bytesNeeded
, dataLen
;
4090 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4091 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4093 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4095 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4097 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4098 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
4100 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
4102 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4104 *pcbStructInfo
= bytesNeeded
;
4105 else if (*pcbStructInfo
< bytesNeeded
)
4107 SetLastError(ERROR_MORE_DATA
);
4108 *pcbStructInfo
= bytesNeeded
;
4113 CRYPT_DATA_BLOB
*blob
;
4115 *pcbStructInfo
= bytesNeeded
;
4116 blob
= pvStructInfo
;
4117 blob
->cbData
= dataLen
;
4118 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4119 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
4122 assert(blob
->pbData
);
4124 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
4132 static BOOL
CRYPT_AsnDecodeOctetStringInternal(const BYTE
*encoded
, DWORD encoded_size
,
4133 DWORD flags
, void *buf
, DWORD
*buf_size
, DWORD
*ret_decoded
)
4135 DWORD decoded
= 0, indefinite_len_depth
= 0, len_size
, len
, bytes_needed
;
4136 CRYPT_DATA_BLOB
*blob
;
4139 while (encoded
[0] == (ASN_CONSTRUCTOR
| ASN_OCTETSTRING
))
4141 if (!CRYPT_GetLengthIndefinite(encoded
, encoded_size
, &len
))
4144 len_size
= GET_LEN_BYTES(encoded
[1]);
4145 encoded
+= 1 + len_size
;
4146 encoded_size
-= 1 + len_size
;
4147 decoded
+= 1 + len_size
;
4149 if (len
== CMSG_INDEFINITE_LENGTH
)
4151 indefinite_len_depth
++;
4152 if (encoded_size
< 2)
4154 SetLastError(CRYPT_E_ASN1_EOD
);
4162 if (encoded
[0] != ASN_OCTETSTRING
)
4164 WARN("Unexpected tag %02x\n", encoded
[0]);
4165 SetLastError(CRYPT_E_ASN1_BADTAG
);
4169 if (!CRYPT_GetLen(encoded
, encoded_size
, &len
))
4171 len_size
= GET_LEN_BYTES(encoded
[1]);
4172 decoded
+= 1 + len_size
+ len
;
4173 encoded_size
-= 1 + len_size
;
4175 if (len
> encoded_size
)
4177 SetLastError(CRYPT_E_ASN1_EOD
);
4181 *ret_decoded
= decoded
;
4183 encoded
+= 1 + len_size
;
4187 while (indefinite_len_depth
--)
4189 if (encoded
[0] || encoded
[1])
4191 TRACE("expected 0 TLV, got %02x %02x\n", encoded
[0], encoded
[1]);
4192 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4197 bytes_needed
= sizeof(*blob
);
4198 if (!(flags
& CRYPT_DECODE_NOCOPY_FLAG
)) bytes_needed
+= len
;
4201 *buf_size
= bytes_needed
;
4204 if (*buf_size
< bytes_needed
)
4206 SetLastError(ERROR_MORE_DATA
);
4207 *buf_size
= bytes_needed
;
4211 *buf_size
= bytes_needed
;
4214 if (flags
& CRYPT_DECODE_NOCOPY_FLAG
)
4215 blob
->pbData
= (BYTE
*)string
;
4216 else if (blob
->cbData
)
4217 memcpy(blob
->pbData
, string
, blob
->cbData
);
4220 *ret_decoded
= decoded
;
4224 static BOOL WINAPI
CRYPT_AsnDecodeOctetString(DWORD dwCertEncodingType
,
4225 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4226 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4230 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4231 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4235 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4241 DWORD bytesNeeded
= 0;
4243 if ((ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4244 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4247 *pcbStructInfo
= bytesNeeded
;
4248 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4249 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4251 CRYPT_DATA_BLOB
*blob
;
4253 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4254 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4255 blob
= pvStructInfo
;
4256 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4257 ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4258 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4259 &bytesNeeded
, NULL
);
4260 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4261 CRYPT_FreeSpace(pDecodePara
, blob
);
4267 SetLastError(STATUS_ACCESS_VIOLATION
);
4274 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4275 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4278 DWORD bytesNeeded
, dataLen
;
4279 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4281 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4282 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4284 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4286 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4287 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4289 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4291 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4293 *pcbStructInfo
= bytesNeeded
;
4294 else if (*pcbStructInfo
< bytesNeeded
)
4296 *pcbStructInfo
= bytesNeeded
;
4297 SetLastError(ERROR_MORE_DATA
);
4302 CRYPT_BIT_BLOB
*blob
;
4304 *pcbStructInfo
= bytesNeeded
;
4305 blob
= pvStructInfo
;
4306 blob
->cbData
= dataLen
- 1;
4307 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4308 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4310 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4314 assert(blob
->pbData
);
4317 BYTE mask
= 0xff << blob
->cUnusedBits
;
4319 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4321 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4329 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4330 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4331 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4335 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4336 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4340 DWORD bytesNeeded
= 0;
4344 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4347 else if (pbEncoded
[0] != ASN_BITSTRING
)
4349 SetLastError(CRYPT_E_ASN1_BADTAG
);
4352 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4353 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4356 *pcbStructInfo
= bytesNeeded
;
4357 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4358 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4360 CRYPT_BIT_BLOB
*blob
;
4362 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4363 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4364 blob
= pvStructInfo
;
4365 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4366 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4367 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4368 &bytesNeeded
, NULL
);
4369 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4370 CRYPT_FreeSpace(pDecodePara
, blob
);
4376 SetLastError(STATUS_ACCESS_VIOLATION
);
4380 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4384 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4385 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4386 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4391 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4393 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4396 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4397 if (dataLen
> sizeof(int))
4399 SetLastError(CRYPT_E_ASN1_LARGE
);
4402 else if (!pvStructInfo
)
4403 *pcbStructInfo
= sizeof(int);
4404 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4408 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4410 /* initialize to a negative value to sign-extend */
4415 for (i
= 0; i
< dataLen
; i
++)
4418 val
|= pbEncoded
[1 + lenBytes
+ i
];
4420 memcpy(pvStructInfo
, &val
, sizeof(int));
4426 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4427 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4428 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4434 DWORD bytesNeeded
= 0;
4438 SetLastError(CRYPT_E_ASN1_EOD
);
4441 else if (pbEncoded
[0] != ASN_INTEGER
)
4443 SetLastError(CRYPT_E_ASN1_BADTAG
);
4447 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4448 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4452 *pcbStructInfo
= bytesNeeded
;
4453 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4454 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4456 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4457 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4458 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4459 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4460 &bytesNeeded
, NULL
);
4461 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4462 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4468 SetLastError(STATUS_ACCESS_VIOLATION
);
4475 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4476 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4480 DWORD bytesNeeded
, dataLen
;
4482 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4484 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4486 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4488 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4490 *pcbStructInfo
= bytesNeeded
;
4491 else if (*pcbStructInfo
< bytesNeeded
)
4493 *pcbStructInfo
= bytesNeeded
;
4494 SetLastError(ERROR_MORE_DATA
);
4499 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4501 *pcbStructInfo
= bytesNeeded
;
4502 blob
->cbData
= dataLen
;
4503 assert(blob
->pbData
);
4508 for (i
= 0; i
< blob
->cbData
; i
++)
4510 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4519 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4520 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4521 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4527 DWORD bytesNeeded
= 0;
4529 if (pbEncoded
[0] != ASN_INTEGER
)
4531 SetLastError(CRYPT_E_ASN1_BADTAG
);
4535 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4536 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4540 *pcbStructInfo
= bytesNeeded
;
4541 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4542 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4544 CRYPT_INTEGER_BLOB
*blob
;
4546 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4547 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4548 blob
= pvStructInfo
;
4549 blob
->pbData
= (BYTE
*)pvStructInfo
+
4550 sizeof(CRYPT_INTEGER_BLOB
);
4551 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4552 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4553 &bytesNeeded
, NULL
);
4554 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4555 CRYPT_FreeSpace(pDecodePara
, blob
);
4561 SetLastError(STATUS_ACCESS_VIOLATION
);
4568 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4569 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4574 if (pbEncoded
[0] == ASN_INTEGER
)
4576 DWORD bytesNeeded
, dataLen
;
4578 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4580 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4583 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4584 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4586 *pcbStructInfo
= bytesNeeded
;
4587 else if (*pcbStructInfo
< bytesNeeded
)
4589 *pcbStructInfo
= bytesNeeded
;
4590 SetLastError(ERROR_MORE_DATA
);
4595 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4597 *pcbStructInfo
= bytesNeeded
;
4598 blob
->cbData
= dataLen
;
4599 assert(blob
->pbData
);
4600 /* remove leading zero byte if it exists */
4601 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4610 for (i
= 0; i
< blob
->cbData
; i
++)
4612 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4621 SetLastError(CRYPT_E_ASN1_BADTAG
);
4627 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4628 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4629 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4635 DWORD bytesNeeded
= 0;
4637 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4638 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4641 *pcbStructInfo
= bytesNeeded
;
4642 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4643 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4645 CRYPT_INTEGER_BLOB
*blob
;
4647 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4648 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4649 blob
= pvStructInfo
;
4650 blob
->pbData
= (BYTE
*)pvStructInfo
+
4651 sizeof(CRYPT_INTEGER_BLOB
);
4652 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4653 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4654 &bytesNeeded
, NULL
);
4655 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4656 CRYPT_FreeSpace(pDecodePara
, blob
);
4662 SetLastError(STATUS_ACCESS_VIOLATION
);
4669 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4670 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4671 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4677 *pcbStructInfo
= sizeof(int);
4682 if (pbEncoded
[0] == ASN_ENUMERATED
)
4684 unsigned int val
= 0, i
;
4688 SetLastError(CRYPT_E_ASN1_EOD
);
4691 else if (pbEncoded
[1] == 0)
4693 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4698 /* A little strange looking, but we have to accept a sign byte:
4699 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4700 * assuming a small length is okay here, it has to be in short
4703 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4705 SetLastError(CRYPT_E_ASN1_LARGE
);
4708 for (i
= 0; i
< pbEncoded
[1]; i
++)
4711 val
|= pbEncoded
[2 + i
];
4713 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4714 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4716 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4717 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4718 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4724 SetLastError(CRYPT_E_ASN1_BADTAG
);
4730 SetLastError(STATUS_ACCESS_VIOLATION
);
4737 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4740 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4745 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4747 if (!isdigit(*(pbEncoded))) \
4749 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4755 (word) += *(pbEncoded)++ - '0'; \
4760 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4761 SYSTEMTIME
*sysTime
)
4765 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4767 WORD hours
, minutes
= 0;
4768 BYTE sign
= *pbEncoded
++;
4771 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4772 if (ret
&& hours
>= 24)
4774 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4779 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4780 if (ret
&& minutes
>= 60)
4782 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4790 sysTime
->wHour
+= hours
;
4791 sysTime
->wMinute
+= minutes
;
4795 if (hours
> sysTime
->wHour
)
4798 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4801 sysTime
->wHour
-= hours
;
4802 if (minutes
> sysTime
->wMinute
)
4805 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4808 sysTime
->wMinute
-= minutes
;
4815 #define MIN_ENCODED_TIME_LENGTH 10
4817 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4818 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4823 if (pbEncoded
[0] == ASN_UTCTIME
)
4826 SetLastError(CRYPT_E_ASN1_EOD
);
4827 else if (pbEncoded
[1] > 0x7f)
4829 /* long-form date strings really can't be valid */
4830 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4834 SYSTEMTIME sysTime
= { 0 };
4835 BYTE len
= pbEncoded
[1];
4837 if (len
< MIN_ENCODED_TIME_LENGTH
)
4838 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4843 *pcbDecoded
= 2 + len
;
4845 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4846 if (sysTime
.wYear
>= 50)
4847 sysTime
.wYear
+= 1900;
4849 sysTime
.wYear
+= 2000;
4850 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4851 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4852 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4853 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4856 if (len
>= 2 && isdigit(*pbEncoded
) &&
4857 isdigit(*(pbEncoded
+ 1)))
4858 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4860 else if (isdigit(*pbEncoded
))
4861 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4864 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4870 *pcbStructInfo
= sizeof(FILETIME
);
4871 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4873 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4879 SetLastError(CRYPT_E_ASN1_BADTAG
);
4883 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4884 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4885 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4891 DWORD bytesNeeded
= 0;
4893 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4894 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4898 *pcbStructInfo
= bytesNeeded
;
4899 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4900 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4902 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4903 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4904 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4905 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4906 &bytesNeeded
, NULL
);
4907 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4908 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4914 SetLastError(STATUS_ACCESS_VIOLATION
);
4920 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4921 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4926 if (pbEncoded
[0] == ASN_GENERALTIME
)
4929 SetLastError(CRYPT_E_ASN1_EOD
);
4930 else if (pbEncoded
[1] > 0x7f)
4932 /* long-form date strings really can't be valid */
4933 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4937 BYTE len
= pbEncoded
[1];
4939 if (len
< MIN_ENCODED_TIME_LENGTH
)
4940 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4943 SYSTEMTIME sysTime
= { 0 };
4947 *pcbDecoded
= 2 + len
;
4949 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4950 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4951 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4952 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4955 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4958 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4960 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4967 /* workaround macro weirdness */
4968 digits
= min(len
, 3);
4969 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4970 sysTime
.wMilliseconds
);
4973 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4979 *pcbStructInfo
= sizeof(FILETIME
);
4980 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4982 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4988 SetLastError(CRYPT_E_ASN1_BADTAG
);
4992 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4993 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4997 InternalDecodeFunc decode
= NULL
;
4999 if (pbEncoded
[0] == ASN_UTCTIME
)
5000 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
5001 else if (pbEncoded
[0] == ASN_GENERALTIME
)
5002 decode
= CRYPT_AsnDecodeGeneralizedTime
;
5004 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
5005 pcbStructInfo
, pcbDecoded
);
5008 SetLastError(CRYPT_E_ASN1_BADTAG
);
5014 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
5015 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5016 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5022 DWORD bytesNeeded
= 0;
5024 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5025 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
5029 *pcbStructInfo
= bytesNeeded
;
5030 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5031 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5033 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5034 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5035 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5036 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5037 &bytesNeeded
, NULL
);
5038 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5039 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
5045 SetLastError(STATUS_ACCESS_VIOLATION
);
5052 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
5053 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5054 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5060 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
5062 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
5064 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5069 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5070 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
5072 ptr
= pbEncoded
+ 1 + lenBytes
;
5073 remainingLen
= dataLen
;
5074 while (ret
&& remainingLen
)
5078 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5081 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5083 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5084 ptr
+= 1 + nextLenBytes
+ nextLen
;
5085 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
5086 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
5087 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
5093 CRYPT_SEQUENCE_OF_ANY
*seq
;
5098 *pcbStructInfo
= bytesNeeded
;
5099 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5100 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5102 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5103 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5105 seq
->cValue
= cValue
;
5106 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
5108 nextPtr
= (BYTE
*)seq
->rgValue
+
5109 cValue
* sizeof(CRYPT_DER_BLOB
);
5110 ptr
= pbEncoded
+ 1 + lenBytes
;
5111 remainingLen
= dataLen
;
5113 while (ret
&& remainingLen
)
5117 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5120 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5122 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
5124 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
5125 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
5128 seq
->rgValue
[i
].pbData
= nextPtr
;
5129 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
5131 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
5133 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5134 ptr
+= 1 + nextLenBytes
+ nextLen
;
5138 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5139 CRYPT_FreeSpace(pDecodePara
, seq
);
5146 SetLastError(CRYPT_E_ASN1_BADTAG
);
5152 SetLastError(STATUS_ACCESS_VIOLATION
);
5159 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
5160 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5165 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
5167 DWORD bytesNeeded
= 0, dataLen
;
5169 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5171 struct AsnArrayDescriptor arrayDesc
= {
5172 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5173 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
5174 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
5175 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
5176 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
5177 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
5178 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5183 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5184 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5185 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
5186 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
5187 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
5190 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
5192 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
5194 *pcbStructInfo
= bytesNeeded
;
5195 else if (*pcbStructInfo
< bytesNeeded
)
5197 *pcbStructInfo
= bytesNeeded
;
5198 SetLastError(ERROR_MORE_DATA
);
5203 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
5205 *pcbStructInfo
= bytesNeeded
;
5208 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
5209 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5210 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5211 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
5215 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
5221 SetLastError(CRYPT_E_ASN1_BADTAG
);
5227 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5228 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5230 struct AsnDecodeSequenceItem items
[] = {
5231 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
5232 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5233 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
5234 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5235 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
5236 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
5237 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
5238 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
5239 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
5240 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
5242 CRL_DIST_POINT
*point
= pvStructInfo
;
5245 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5246 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5247 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5251 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5252 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5253 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5257 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5258 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5262 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5263 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
5264 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
5265 sizeof(CRL_DIST_POINTS_INFO
),
5266 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5267 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5268 CRL_DIST_POINTS_INFO
*info
= pvStructInfo
;
5270 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5271 info
->rgDistPoint
= (CRL_DIST_POINT
*)(info
+ 1);
5272 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5273 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5277 SetLastError(STATUS_ACCESS_VIOLATION
);
5284 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5285 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5286 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5290 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5291 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5295 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5296 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5297 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5298 sizeof(CERT_ENHKEY_USAGE
),
5299 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5300 CERT_ENHKEY_USAGE
*usage
= pvStructInfo
;
5302 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5303 usage
->rgpszUsageIdentifier
= (LPSTR
*)(usage
+ 1);
5304 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5305 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5309 SetLastError(STATUS_ACCESS_VIOLATION
);
5316 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5317 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5318 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5322 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5323 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5327 struct AsnDecodeSequenceItem items
[] = {
5328 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5329 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5330 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5331 offsetof(CRL_ISSUING_DIST_POINT
,
5332 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5333 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5334 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5336 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5337 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5339 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5340 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5341 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5342 OnlySomeReasonFlags
.pbData
), 0 },
5343 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5344 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5347 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5348 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5349 pcbStructInfo
, NULL
, NULL
);
5353 SetLastError(STATUS_ACCESS_VIOLATION
);
5360 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5361 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5365 DWORD max
, size
= sizeof(max
);
5367 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5368 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5372 SetLastError(CRYPT_E_ASN1_EOD
);
5375 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5377 SetLastError(CRYPT_E_ASN1_BADTAG
);
5380 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5381 &max
, &size
, pcbDecoded
)))
5383 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5386 *pcbStructInfo
= bytesNeeded
;
5387 else if (*pcbStructInfo
< bytesNeeded
)
5389 *pcbStructInfo
= bytesNeeded
;
5390 SetLastError(ERROR_MORE_DATA
);
5395 CERT_GENERAL_SUBTREE
*subtree
= CONTAINING_RECORD(pvStructInfo
,
5396 CERT_GENERAL_SUBTREE
, fMaximum
);
5398 *pcbStructInfo
= bytesNeeded
;
5399 /* The BOOL is implicit: if the integer is present, then it's
5402 subtree
->fMaximum
= TRUE
;
5403 subtree
->dwMaximum
= max
;
5406 TRACE("returning %d\n", ret
);
5410 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5411 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5415 struct AsnDecodeSequenceItem items
[] = {
5416 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5417 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5418 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5419 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5420 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5421 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5422 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5423 TRUE
, FALSE
, 0, 0 },
5425 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5427 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5428 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5430 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5431 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5432 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5435 TRACE("%d\n", *pcbDecoded
);
5436 if (*pcbDecoded
< cbEncoded
)
5437 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5438 *(pbEncoded
+ *pcbDecoded
+ 1));
5440 TRACE("returning %d\n", ret
);
5444 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5445 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5449 struct AsnArrayDescriptor arrayDesc
= { 0,
5450 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5451 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5452 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5454 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5455 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5457 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5458 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5460 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5461 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5465 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5466 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5470 struct AsnArrayDescriptor arrayDesc
= { 0,
5471 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5472 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5473 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5474 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5475 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5477 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5478 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5480 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5481 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5485 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5486 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5487 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5491 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5492 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5496 struct AsnDecodeSequenceItem items
[] = {
5497 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5498 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5499 CRYPT_AsnDecodePermittedSubtree
,
5500 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5501 cExcludedSubtree
), TRUE
, TRUE
,
5502 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5503 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5504 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5505 CRYPT_AsnDecodeExcludedSubtree
,
5506 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5508 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5511 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5512 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5513 pcbStructInfo
, NULL
, NULL
);
5517 SetLastError(STATUS_ACCESS_VIOLATION
);
5523 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5524 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5528 struct AsnDecodeSequenceItem items
[] = {
5529 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5530 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5532 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5533 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5534 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5536 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5538 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5539 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5541 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5542 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5543 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5544 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5546 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5549 TRACE("returning %d\n", ret
);
5553 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5554 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5557 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5558 struct AsnDecodeSequenceItem items
[] = {
5559 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5560 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5561 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5562 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5563 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5564 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5565 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5566 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5567 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5568 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5569 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5570 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5571 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5572 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5573 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5574 HashEncryptionAlgorithm
.pszObjId
), 0 },
5575 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5576 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5577 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5578 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5579 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5580 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5581 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5585 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5586 pvStructInfo
, *pcbStructInfo
);
5588 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5589 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5590 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5594 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5595 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5596 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5600 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5601 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5605 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5606 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5607 if (ret
&& pvStructInfo
)
5609 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5610 pcbStructInfo
, *pcbStructInfo
);
5613 CMSG_SIGNER_INFO
*info
;
5615 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5616 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5617 info
= pvStructInfo
;
5618 info
->Issuer
.pbData
= ((BYTE
*)info
+
5619 sizeof(CMSG_SIGNER_INFO
));
5620 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5621 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5622 pcbStructInfo
, NULL
);
5623 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5624 CRYPT_FreeSpace(pDecodePara
, info
);
5630 SetLastError(STATUS_ACCESS_VIOLATION
);
5633 TRACE("returning %d\n", ret
);
5637 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5638 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5642 struct AsnArrayDescriptor arrayDesc
= { 0,
5643 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5644 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5645 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5646 CRYPT_AsnDecodeCopyBytes
,
5647 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5649 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5650 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5652 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5653 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5657 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5658 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5662 struct AsnArrayDescriptor arrayDesc
= { 0,
5663 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5664 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5665 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5666 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5667 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5669 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5670 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5672 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5673 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5677 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5678 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5681 CERT_ID
*id
= pvStructInfo
;
5684 if (*pbEncoded
== ASN_SEQUENCEOF
)
5686 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5687 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5691 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5692 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5693 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5694 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5696 *pcbStructInfo
= sizeof(CERT_ID
);
5699 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5701 ret
= CRYPT_AsnDecodeOctets(pbEncoded
, cbEncoded
, dwFlags
,
5702 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5706 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5707 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5708 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5709 sizeof(CRYPT_DATA_BLOB
);
5711 *pcbStructInfo
= sizeof(CERT_ID
);
5715 SetLastError(CRYPT_E_ASN1_BADTAG
);
5719 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5720 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5723 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5724 struct AsnDecodeSequenceItem items
[] = {
5725 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5726 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5727 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5728 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5729 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5730 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5731 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5732 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5733 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5734 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5735 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5736 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5737 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5738 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5739 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5740 HashEncryptionAlgorithm
.pszObjId
), 0 },
5741 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5742 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5743 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5744 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5745 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5746 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5747 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5751 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5752 pvStructInfo
, *pcbStructInfo
);
5754 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5755 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5756 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5760 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5761 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5762 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5766 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5767 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5771 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5772 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5773 if (ret
&& pvStructInfo
)
5775 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5776 pcbStructInfo
, *pcbStructInfo
);
5779 CMSG_CMS_SIGNER_INFO
*info
;
5781 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5782 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5783 info
= pvStructInfo
;
5784 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5785 sizeof(CMSG_CMS_SIGNER_INFO
));
5786 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5787 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5788 pcbStructInfo
, NULL
);
5789 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5790 CRYPT_FreeSpace(pDecodePara
, info
);
5796 SetLastError(STATUS_ACCESS_VIOLATION
);
5799 TRACE("returning %d\n", ret
);
5803 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5804 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5807 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5808 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5809 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5810 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5811 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5812 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5814 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5815 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5817 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5818 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5822 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5823 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5824 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5827 struct AsnDecodeSequenceItem items
[] = {
5828 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5829 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5830 /* Placeholder for the hash algorithms - redundant with those in the
5831 * signers, so just ignore them.
5833 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5834 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5835 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5836 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5837 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5838 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5839 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5840 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5841 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5842 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5843 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5844 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5845 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5846 CRYPT_DecodeSignerArray
,
5847 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5848 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5851 TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5852 pDecodePara
, signedInfo
, pcbSignedInfo
);
5854 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5855 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5857 TRACE("returning %d\n", ret
);
5861 static BOOL
CRYPT_AsnDecodeRecipientInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5862 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5865 CMSG_KEY_TRANS_RECIPIENT_INFO
*info
= pvStructInfo
;
5866 struct AsnDecodeSequenceItem items
[] = {
5867 { ASN_INTEGER
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, dwVersion
),
5868 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5869 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5870 RecipientId
.u
.IssuerSerialNumber
), CRYPT_AsnDecodeIssuerSerialNumber
,
5871 sizeof(CERT_ISSUER_SERIAL_NUMBER
), FALSE
, TRUE
,
5872 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5873 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
), 0 },
5874 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5875 KeyEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5876 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5877 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5878 KeyEncryptionAlgorithm
.pszObjId
), 0 },
5879 { ASN_OCTETSTRING
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
),
5880 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
5881 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
.pbData
), 0 },
5884 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5885 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5887 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5888 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5889 pcbDecoded
, info
? info
->RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
:
5892 info
->RecipientId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5893 TRACE("returning %d\n", ret
);
5897 static BOOL
CRYPT_DecodeRecipientInfoArray(const BYTE
*pbEncoded
,
5898 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5902 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5903 offsetof(CRYPT_ENVELOPED_DATA
, cRecipientInfo
),
5904 offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
),
5905 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5906 CRYPT_AsnDecodeRecipientInfo
, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO
), TRUE
,
5907 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5908 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
) };
5910 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5911 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5913 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5914 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5915 TRACE("returning %d\n", ret
);
5919 static BOOL
CRYPT_AsnDecodeEncryptedContentInfo(const BYTE
*pbEncoded
,
5920 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5924 CRYPT_ENCRYPTED_CONTENT_INFO
*info
= pvStructInfo
;
5925 struct AsnDecodeSequenceItem items
[] = {
5926 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5927 contentType
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
5928 FALSE
, TRUE
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5930 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5931 contentEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5932 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5933 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5934 contentEncryptionAlgorithm
.pszObjId
), 0 },
5935 { ASN_CONTEXT
| 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5936 encryptedContent
), CRYPT_AsnDecodeOctets
,
5937 sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
5938 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
, encryptedContent
.pbData
) },
5941 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5942 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5944 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5945 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5946 pcbDecoded
, info
? info
->contentType
: NULL
);
5947 TRACE("returning %d\n", ret
);
5951 BOOL
CRYPT_AsnDecodePKCSEnvelopedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5952 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5953 CRYPT_ENVELOPED_DATA
*envelopedData
, DWORD
*pcbEnvelopedData
)
5956 struct AsnDecodeSequenceItem items
[] = {
5957 { ASN_INTEGER
, offsetof(CRYPT_ENVELOPED_DATA
, version
),
5958 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5959 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ENVELOPED_DATA
,
5960 cRecipientInfo
), CRYPT_DecodeRecipientInfoArray
,
5961 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5962 FALSE
, TRUE
, offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
), 0 },
5963 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
),
5964 CRYPT_AsnDecodeEncryptedContentInfo
,
5965 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO
), FALSE
, TRUE
,
5966 offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
.contentType
), 0 },
5969 TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5970 pDecodePara
, envelopedData
, pcbEnvelopedData
);
5972 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5973 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, envelopedData
,
5974 pcbEnvelopedData
, NULL
, NULL
);
5975 TRACE("returning %d\n", ret
);
5979 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5980 LPCSTR lpszStructType
)
5982 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5984 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5985 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5987 SetLastError(ERROR_FILE_NOT_FOUND
);
5990 if (IS_INTOID(lpszStructType
))
5992 switch (LOWORD(lpszStructType
))
5994 case LOWORD(X509_CERT
):
5995 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5997 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5998 decodeFunc
= CRYPT_AsnDecodeCert
;
6000 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
6001 decodeFunc
= CRYPT_AsnDecodeCRL
;
6003 case LOWORD(X509_EXTENSIONS
):
6004 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6006 case LOWORD(X509_NAME_VALUE
):
6007 decodeFunc
= CRYPT_AsnDecodeNameValue
;
6009 case LOWORD(X509_NAME
):
6010 decodeFunc
= CRYPT_AsnDecodeName
;
6012 case LOWORD(X509_PUBLIC_KEY_INFO
):
6013 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
6015 case LOWORD(X509_AUTHORITY_KEY_ID
):
6016 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6018 case LOWORD(X509_ALTERNATE_NAME
):
6019 decodeFunc
= CRYPT_AsnDecodeAltName
;
6021 case LOWORD(X509_BASIC_CONSTRAINTS
):
6022 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6024 case LOWORD(X509_BASIC_CONSTRAINTS2
):
6025 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6027 case LOWORD(X509_CERT_POLICIES
):
6028 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6030 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
6031 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
6033 case LOWORD(PKCS_RSA_PRIVATE_KEY
):
6034 decodeFunc
= CRYPT_AsnDecodeRsaPrivKey
;
6036 case LOWORD(X509_UNICODE_NAME
):
6037 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
6039 case LOWORD(PKCS_ATTRIBUTE
):
6040 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
6042 case LOWORD(X509_UNICODE_NAME_VALUE
):
6043 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
6045 case LOWORD(X509_OCTET_STRING
):
6046 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6048 case LOWORD(X509_BITS
):
6049 case LOWORD(X509_KEY_USAGE
):
6050 decodeFunc
= CRYPT_AsnDecodeBits
;
6052 case LOWORD(X509_INTEGER
):
6053 decodeFunc
= CRYPT_AsnDecodeInt
;
6055 case LOWORD(X509_MULTI_BYTE_INTEGER
):
6056 decodeFunc
= CRYPT_AsnDecodeInteger
;
6058 case LOWORD(X509_MULTI_BYTE_UINT
):
6059 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
6061 case LOWORD(X509_ENUMERATED
):
6062 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6064 case LOWORD(X509_CHOICE_OF_TIME
):
6065 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
6067 case LOWORD(X509_AUTHORITY_KEY_ID2
):
6068 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6070 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
6071 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6073 case LOWORD(PKCS_CONTENT_INFO
):
6074 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
6076 case LOWORD(X509_SEQUENCE_OF_ANY
):
6077 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
6079 case LOWORD(PKCS_UTC_TIME
):
6080 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6082 case LOWORD(X509_CRL_DIST_POINTS
):
6083 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6085 case LOWORD(X509_ENHANCED_KEY_USAGE
):
6086 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6088 case LOWORD(PKCS_CTL
):
6089 decodeFunc
= CRYPT_AsnDecodeCTL
;
6091 case LOWORD(PKCS_SMIME_CAPABILITIES
):
6092 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6094 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
6095 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6097 case LOWORD(PKCS_ATTRIBUTES
):
6098 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
6100 case LOWORD(X509_ISSUING_DIST_POINT
):
6101 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6103 case LOWORD(X509_NAME_CONSTRAINTS
):
6104 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6106 case LOWORD(X509_POLICY_MAPPINGS
):
6107 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6109 case LOWORD(X509_POLICY_CONSTRAINTS
):
6110 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6112 case LOWORD(PKCS7_SIGNER_INFO
):
6113 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
6115 case LOWORD(CMS_SIGNER_INFO
):
6116 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
6120 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
6121 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6122 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
6123 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6124 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
6125 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6126 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
6127 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6128 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
6129 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6130 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
6131 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6132 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
6133 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6134 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
6135 decodeFunc
= CRYPT_AsnDecodeBits
;
6136 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
6137 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6138 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
6139 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6140 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
6141 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6142 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
6143 decodeFunc
= CRYPT_AsnDecodeAltName
;
6144 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
6145 decodeFunc
= CRYPT_AsnDecodeAltName
;
6146 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
6147 decodeFunc
= CRYPT_AsnDecodeAltName
;
6148 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
6149 decodeFunc
= CRYPT_AsnDecodeAltName
;
6150 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
6151 decodeFunc
= CRYPT_AsnDecodeAltName
;
6152 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
6153 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6154 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
6155 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6156 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
6157 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6158 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
6159 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6160 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
6161 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6162 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
6163 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6164 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
6165 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6166 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
6167 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6168 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
6169 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6170 else if (!strcmp(lpszStructType
, szOID_CTL
))
6171 decodeFunc
= CRYPT_AsnDecodeCTL
;
6175 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
6176 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6178 static HCRYPTOIDFUNCSET set
= NULL
;
6179 CryptDecodeObjectFunc decodeFunc
= NULL
;
6182 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
6183 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6184 (void **)&decodeFunc
, hFunc
);
6188 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
6189 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6191 static HCRYPTOIDFUNCSET set
= NULL
;
6192 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6195 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
6196 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6197 (void **)&decodeFunc
, hFunc
);
6201 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6202 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
6203 DWORD
*pcbStructInfo
)
6206 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
6207 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
6208 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6210 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
6211 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
6212 pvStructInfo
, pcbStructInfo
);
6214 if (!pvStructInfo
&& !pcbStructInfo
)
6216 SetLastError(ERROR_INVALID_PARAMETER
);
6219 if (cbEncoded
> MAX_ENCODED_LEN
)
6221 SetLastError(CRYPT_E_ASN1_LARGE
);
6225 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
6228 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6229 debugstr_a(lpszStructType
));
6230 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
6231 lpszStructType
, &hFunc
);
6232 if (!pCryptDecodeObject
)
6233 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
6234 lpszStructType
, &hFunc
);
6236 if (pCryptDecodeObject
)
6237 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6238 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6239 else if (pCryptDecodeObjectEx
)
6240 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
6241 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
6242 pvStructInfo
, pcbStructInfo
);
6244 CryptFreeOIDFunctionAddress(hFunc
, 0);
6245 TRACE_(crypt
)("returning %d\n", ret
);
6249 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6250 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6251 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6254 CryptDecodeObjectExFunc decodeFunc
;
6255 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6257 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6258 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
6259 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6261 if (!pvStructInfo
&& !pcbStructInfo
)
6263 SetLastError(ERROR_INVALID_PARAMETER
);
6266 if (cbEncoded
> MAX_ENCODED_LEN
)
6268 SetLastError(CRYPT_E_ASN1_LARGE
);
6272 SetLastError(NOERROR
);
6273 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6277 SetLastError(ERROR_INVALID_PARAMETER
);
6280 *(BYTE
**)pvStructInfo
= NULL
;
6282 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
6285 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6286 debugstr_a(lpszStructType
));
6287 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
6291 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
6292 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6295 CryptDecodeObjectFunc pCryptDecodeObject
=
6296 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
6298 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6299 * directly, as that could cause an infinite loop.
6301 if (pCryptDecodeObject
)
6303 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6305 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6306 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
6307 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
6308 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
6310 ret
= pCryptDecodeObject(dwCertEncodingType
,
6311 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
6312 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
6314 CRYPT_FreeSpace(pDecodePara
, *(BYTE
**)pvStructInfo
);
6318 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6319 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6323 CryptFreeOIDFunctionAddress(hFunc
, 0);
6324 TRACE_(crypt
)("returning %d\n", ret
);
6328 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
6332 TRACE_(crypt
)("(%p)\n", pPFX
);
6334 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6335 * version integer of length 1 (3 encoded byes) and at least one other
6336 * datum (two encoded bytes), plus at least two bytes for the outer
6337 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6339 if (pPFX
->cbData
< 7)
6341 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
6345 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
6347 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
6349 /* Need at least three bytes for the integer version */
6350 if (pPFX
->cbData
< 1 + lenLen
+ 3)
6352 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
6353 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
6354 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
6363 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6366 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);
6370 BOOL WINAPI
PFXVerifyPassword(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6373 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);