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(LPTR
, 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
, ARRAY_SIZE(items
),
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
, ARRAY_SIZE(items
),
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
, ARRAY_SIZE(items
),
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
, ARRAY_SIZE(items
),
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
, ARRAY_SIZE(items
), pbEncoded
, cbEncoded
, dwFlags
,
1240 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1242 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1246 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1247 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1248 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1252 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1253 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1259 /* Unless told not to, first try to decode it as a signed crl. */
1260 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1262 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1264 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1265 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1270 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1271 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1272 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1273 pvStructInfo
, pcbStructInfo
);
1274 LocalFree(signedCrl
);
1277 /* Failing that, try it as an unsigned crl */
1281 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1282 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1283 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1288 SetLastError(STATUS_ACCESS_VIOLATION
);
1292 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1296 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1297 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1302 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1303 pvStructInfo
, *pcbStructInfo
);
1305 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1307 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1308 DWORD bytesNeeded
= sizeof(LPSTR
);
1315 snprintf(str
, sizeof(str
), "%d.%d",
1316 pbEncoded
[1 + lenBytes
] / 40,
1317 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1319 bytesNeeded
+= strlen(str
) + 1;
1320 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1321 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1325 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1332 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1335 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1342 snprintf(str
, sizeof(str
), ".%d", val
);
1343 bytesNeeded
+= strlen(str
);
1348 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1350 *pcbStructInfo
= bytesNeeded
;
1351 else if (*pcbStructInfo
< bytesNeeded
)
1353 *pcbStructInfo
= bytesNeeded
;
1354 SetLastError(ERROR_MORE_DATA
);
1362 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1365 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1366 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1368 pszObjId
+= strlen(pszObjId
);
1369 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1370 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1374 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1383 sprintf(pszObjId
, ".%d", val
);
1384 pszObjId
+= strlen(pszObjId
);
1388 *(LPSTR
*)pvStructInfo
= NULL
;
1389 *pcbStructInfo
= bytesNeeded
;
1395 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1396 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1400 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1401 pvStructInfo
, *pcbStructInfo
);
1403 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1404 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1405 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1408 SetLastError(CRYPT_E_ASN1_BADTAG
);
1414 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1415 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1417 struct AsnDecodeSequenceItem items
[] = {
1418 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1419 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1420 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1421 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1422 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1423 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1424 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1425 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1428 PCERT_EXTENSION ext
= pvStructInfo
;
1430 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1434 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1435 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1436 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1437 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1439 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1440 debugstr_a(ext
->pszObjId
));
1441 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1445 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1446 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1447 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1451 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1452 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1456 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1457 offsetof(CERT_EXTENSIONS
, cExtension
),
1458 offsetof(CERT_EXTENSIONS
, rgExtension
),
1459 sizeof(CERT_EXTENSIONS
),
1460 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1461 offsetof(CERT_EXTENSION
, pszObjId
) };
1462 CERT_EXTENSIONS
*exts
= pvStructInfo
;
1464 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1465 exts
->rgExtension
= (CERT_EXTENSION
*)(exts
+ 1);
1466 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1467 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1471 SetLastError(STATUS_ACCESS_VIOLATION
);
1478 /* Warning: this assumes the address of value->Value.pbData is already set, in
1479 * order to avoid overwriting memory. (In some cases, it may change it, if it
1480 * doesn't copy anything to memory.) Be sure to set it correctly!
1482 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1483 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1488 CERT_NAME_VALUE
*value
= pvStructInfo
;
1490 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1492 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1493 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1495 switch (pbEncoded
[0])
1497 case ASN_OCTETSTRING
:
1498 valueType
= CERT_RDN_OCTET_STRING
;
1499 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1500 bytesNeeded
+= dataLen
;
1502 case ASN_NUMERICSTRING
:
1503 valueType
= CERT_RDN_NUMERIC_STRING
;
1504 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1505 bytesNeeded
+= dataLen
;
1507 case ASN_PRINTABLESTRING
:
1508 valueType
= CERT_RDN_PRINTABLE_STRING
;
1509 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1510 bytesNeeded
+= dataLen
;
1513 valueType
= CERT_RDN_IA5_STRING
;
1514 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1515 bytesNeeded
+= dataLen
;
1518 valueType
= CERT_RDN_T61_STRING
;
1519 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1520 bytesNeeded
+= dataLen
;
1522 case ASN_VIDEOTEXSTRING
:
1523 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1524 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1525 bytesNeeded
+= dataLen
;
1527 case ASN_GRAPHICSTRING
:
1528 valueType
= CERT_RDN_GRAPHIC_STRING
;
1529 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1530 bytesNeeded
+= dataLen
;
1532 case ASN_VISIBLESTRING
:
1533 valueType
= CERT_RDN_VISIBLE_STRING
;
1534 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1535 bytesNeeded
+= dataLen
;
1537 case ASN_GENERALSTRING
:
1538 valueType
= CERT_RDN_GENERAL_STRING
;
1539 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1540 bytesNeeded
+= dataLen
;
1542 case ASN_UNIVERSALSTRING
:
1543 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1544 SetLastError(CRYPT_E_ASN1_BADTAG
);
1547 valueType
= CERT_RDN_BMP_STRING
;
1548 bytesNeeded
+= dataLen
;
1550 case ASN_UTF8STRING
:
1551 valueType
= CERT_RDN_UTF8_STRING
;
1552 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1553 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1556 SetLastError(CRYPT_E_ASN1_BADTAG
);
1561 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1563 *pcbStructInfo
= bytesNeeded
;
1564 else if (*pcbStructInfo
< bytesNeeded
)
1566 *pcbStructInfo
= bytesNeeded
;
1567 SetLastError(ERROR_MORE_DATA
);
1572 *pcbStructInfo
= bytesNeeded
;
1573 value
->dwValueType
= valueType
;
1578 assert(value
->Value
.pbData
);
1579 switch (pbEncoded
[0])
1581 case ASN_OCTETSTRING
:
1582 case ASN_NUMERICSTRING
:
1583 case ASN_PRINTABLESTRING
:
1586 case ASN_VIDEOTEXSTRING
:
1587 case ASN_GRAPHICSTRING
:
1588 case ASN_VISIBLESTRING
:
1589 case ASN_GENERALSTRING
:
1590 value
->Value
.cbData
= dataLen
;
1593 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1594 memcpy(value
->Value
.pbData
,
1595 pbEncoded
+ 1 + lenBytes
, dataLen
);
1597 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1603 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1605 value
->Value
.cbData
= dataLen
;
1606 for (i
= 0; i
< dataLen
/ 2; i
++)
1607 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1608 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1611 case ASN_UTF8STRING
:
1613 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1615 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1616 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1617 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1624 value
->Value
.cbData
= 0;
1625 value
->Value
.pbData
= NULL
;
1632 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1633 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1634 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1640 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1641 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1642 if (ret
&& pvStructInfo
)
1644 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1645 pcbStructInfo
, *pcbStructInfo
);
1648 CERT_NAME_VALUE
*value
;
1650 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1651 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1652 value
= pvStructInfo
;
1653 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1654 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1655 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1656 pcbStructInfo
, NULL
);
1657 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1658 CRYPT_FreeSpace(pDecodePara
, value
);
1664 SetLastError(STATUS_ACCESS_VIOLATION
);
1671 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1672 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1677 CERT_NAME_VALUE
*value
= pvStructInfo
;
1679 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1681 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1682 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1684 switch (pbEncoded
[0])
1686 case ASN_NUMERICSTRING
:
1687 valueType
= CERT_RDN_NUMERIC_STRING
;
1689 bytesNeeded
+= (dataLen
+ 1) * 2;
1691 case ASN_PRINTABLESTRING
:
1692 valueType
= CERT_RDN_PRINTABLE_STRING
;
1694 bytesNeeded
+= (dataLen
+ 1) * 2;
1697 valueType
= CERT_RDN_IA5_STRING
;
1699 bytesNeeded
+= (dataLen
+ 1) * 2;
1702 valueType
= CERT_RDN_T61_STRING
;
1704 bytesNeeded
+= (dataLen
+ 1) * 2;
1706 case ASN_VIDEOTEXSTRING
:
1707 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1709 bytesNeeded
+= (dataLen
+ 1) * 2;
1711 case ASN_GRAPHICSTRING
:
1712 valueType
= CERT_RDN_GRAPHIC_STRING
;
1714 bytesNeeded
+= (dataLen
+ 1) * 2;
1716 case ASN_VISIBLESTRING
:
1717 valueType
= CERT_RDN_VISIBLE_STRING
;
1719 bytesNeeded
+= (dataLen
+ 1) * 2;
1721 case ASN_GENERALSTRING
:
1722 valueType
= CERT_RDN_GENERAL_STRING
;
1724 bytesNeeded
+= (dataLen
+ 1) * 2;
1726 case ASN_UNIVERSALSTRING
:
1727 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1729 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1732 valueType
= CERT_RDN_BMP_STRING
;
1734 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1736 case ASN_UTF8STRING
:
1737 valueType
= CERT_RDN_UTF8_STRING
;
1739 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1740 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1743 SetLastError(CRYPT_E_ASN1_BADTAG
);
1748 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1750 *pcbStructInfo
= bytesNeeded
;
1751 else if (*pcbStructInfo
< bytesNeeded
)
1753 *pcbStructInfo
= bytesNeeded
;
1754 SetLastError(ERROR_MORE_DATA
);
1759 *pcbStructInfo
= bytesNeeded
;
1760 value
->dwValueType
= valueType
;
1764 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1766 assert(value
->Value
.pbData
);
1767 switch (pbEncoded
[0])
1769 case ASN_NUMERICSTRING
:
1770 case ASN_PRINTABLESTRING
:
1773 case ASN_VIDEOTEXSTRING
:
1774 case ASN_GRAPHICSTRING
:
1775 case ASN_VISIBLESTRING
:
1776 case ASN_GENERALSTRING
:
1777 value
->Value
.cbData
= dataLen
* 2;
1778 for (i
= 0; i
< dataLen
; i
++)
1779 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1782 case ASN_UNIVERSALSTRING
:
1783 value
->Value
.cbData
= dataLen
/ 2;
1784 for (i
= 0; i
< dataLen
/ 4; i
++)
1785 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1786 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1790 value
->Value
.cbData
= dataLen
;
1791 for (i
= 0; i
< dataLen
/ 2; i
++)
1792 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1793 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1796 case ASN_UTF8STRING
:
1797 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1798 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1799 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1800 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1801 value
->Value
.cbData
+= sizeof(WCHAR
);
1807 value
->Value
.cbData
= 0;
1808 value
->Value
.pbData
= NULL
;
1815 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1816 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1817 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1823 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1824 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1825 if (ret
&& pvStructInfo
)
1827 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1828 pcbStructInfo
, *pcbStructInfo
);
1831 CERT_NAME_VALUE
*value
;
1833 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1834 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1835 value
= pvStructInfo
;
1836 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1837 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1838 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1839 pcbStructInfo
, NULL
);
1840 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1841 CRYPT_FreeSpace(pDecodePara
, value
);
1847 SetLastError(STATUS_ACCESS_VIOLATION
);
1854 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1855 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1858 struct AsnDecodeSequenceItem items
[] = {
1859 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1860 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1861 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1862 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1863 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1864 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1866 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1868 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1869 pvStructInfo
, *pcbStructInfo
);
1872 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1873 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1874 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1875 attr
? attr
->pszObjId
: NULL
);
1878 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1879 debugstr_a(attr
->pszObjId
));
1880 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1882 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1886 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1887 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1890 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1891 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1893 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1894 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1896 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1897 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1901 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1902 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1903 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1909 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1910 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1911 sizeof(CERT_NAME_INFO
),
1912 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1913 offsetof(CERT_RDN
, rgRDNAttr
) };
1914 DWORD bytesNeeded
= 0;
1916 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1917 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1922 *pcbStructInfo
= bytesNeeded
;
1923 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1924 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1926 CERT_NAME_INFO
*info
;
1928 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1929 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1930 info
= pvStructInfo
;
1931 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1932 sizeof(CERT_NAME_INFO
));
1933 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1934 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1935 &bytesNeeded
, NULL
);
1936 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1937 CRYPT_FreeSpace(pDecodePara
, info
);
1943 SetLastError(STATUS_ACCESS_VIOLATION
);
1950 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1951 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1955 struct AsnDecodeSequenceItem items
[] = {
1956 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1957 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1958 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1959 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1960 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1961 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1963 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1965 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1966 pvStructInfo
, *pcbStructInfo
);
1969 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1970 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1971 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1972 attr
? attr
->pszObjId
: NULL
);
1975 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1976 debugstr_a(attr
->pszObjId
));
1977 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1979 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1983 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1984 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1987 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1988 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1990 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1991 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1993 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1994 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1998 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1999 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2000 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2006 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2007 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2008 sizeof(CERT_NAME_INFO
),
2009 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2010 offsetof(CERT_RDN
, rgRDNAttr
) };
2011 DWORD bytesNeeded
= 0;
2013 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2014 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2019 *pcbStructInfo
= bytesNeeded
;
2020 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2021 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2023 CERT_NAME_INFO
*info
;
2025 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2026 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2027 info
= pvStructInfo
;
2028 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2029 sizeof(CERT_NAME_INFO
));
2030 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2031 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2032 &bytesNeeded
, NULL
);
2033 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2034 CRYPT_FreeSpace(pDecodePara
, info
);
2040 SetLastError(STATUS_ACCESS_VIOLATION
);
2047 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2050 BOOL ret
= TRUE
, done
= FALSE
;
2051 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2053 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2060 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2063 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2065 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2067 indefiniteNestingLevels
++;
2068 pbEncoded
+= 1 + lenBytes
;
2069 cbEncoded
-= 1 + lenBytes
;
2070 decoded
+= 1 + lenBytes
;
2071 TRACE("indefiniteNestingLevels = %d\n",
2072 indefiniteNestingLevels
);
2076 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2077 indefiniteNestingLevels
)
2079 indefiniteNestingLevels
--;
2080 TRACE("indefiniteNestingLevels = %d\n",
2081 indefiniteNestingLevels
);
2083 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2084 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2085 decoded
+= 1 + lenBytes
+ dataLen
;
2086 if (!indefiniteNestingLevels
)
2090 } while (ret
&& !done
);
2091 /* If we haven't found all 0 TLVs, we haven't found the end */
2092 if (ret
&& indefiniteNestingLevels
)
2094 SetLastError(CRYPT_E_ASN1_EOD
);
2098 *pcbDecoded
= decoded
;
2099 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2103 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2104 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2108 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2110 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2111 pvStructInfo
, *pcbStructInfo
);
2113 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2115 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2116 bytesNeeded
+= encodedLen
;
2118 *pcbStructInfo
= bytesNeeded
;
2119 else if (*pcbStructInfo
< bytesNeeded
)
2121 SetLastError(ERROR_MORE_DATA
);
2122 *pcbStructInfo
= bytesNeeded
;
2127 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2129 *pcbStructInfo
= bytesNeeded
;
2130 blob
->cbData
= encodedLen
;
2133 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2134 blob
->pbData
= (LPBYTE
)pbEncoded
;
2137 assert(blob
->pbData
);
2138 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2142 blob
->pbData
= NULL
;
2145 *pcbDecoded
= encodedLen
;
2150 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2151 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2154 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2155 offsetof(CTL_USAGE
, cUsageIdentifier
),
2156 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2158 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2160 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2161 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2165 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2166 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2169 struct AsnArrayDescriptor arrayDesc
= { 0,
2170 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2171 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2172 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2173 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2176 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2177 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2181 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2182 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2184 struct AsnDecodeSequenceItem items
[] = {
2185 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2186 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2187 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2188 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2189 CRYPT_AsnDecodeCTLEntryAttributes
,
2190 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2191 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2194 CTL_ENTRY
*entry
= pvStructInfo
;
2196 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2199 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2200 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2201 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2205 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2206 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2209 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2210 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2211 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2212 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2213 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2215 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2216 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2218 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2219 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2223 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2224 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2228 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2229 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2230 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2231 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2232 offsetof(CERT_EXTENSION
, pszObjId
) };
2234 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2235 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2237 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2238 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2242 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2243 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2249 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2251 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2253 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2254 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2255 if (ret
&& pcbDecoded
)
2256 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2261 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2262 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2263 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2267 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2268 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2272 struct AsnDecodeSequenceItem items
[] = {
2273 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2274 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2275 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2276 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2277 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2278 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2279 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2280 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2281 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2282 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2283 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2284 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2285 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2287 { 0, offsetof(CTL_INFO
, NextUpdate
),
2288 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2290 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2291 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2292 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2293 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2294 CRYPT_AsnDecodeCTLEntries
,
2295 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2296 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2297 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2298 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2299 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2302 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2303 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2304 pcbStructInfo
, NULL
, NULL
);
2308 SetLastError(STATUS_ACCESS_VIOLATION
);
2314 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2315 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2319 struct AsnDecodeSequenceItem items
[] = {
2320 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2321 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2322 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2323 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2324 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2325 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2327 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2329 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2330 pvStructInfo
, *pcbStructInfo
);
2332 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2333 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2334 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2335 TRACE("returning %d\n", ret
);
2339 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2340 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2341 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2345 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2346 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2350 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2351 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2352 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2353 sizeof(CRYPT_SMIME_CAPABILITIES
),
2354 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2355 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2356 CRYPT_SMIME_CAPABILITIES
*capabilities
= pvStructInfo
;
2358 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2359 capabilities
->rgCapability
= (CRYPT_SMIME_CAPABILITY
*)(capabilities
+ 1);
2360 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2361 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2365 SetLastError(STATUS_ACCESS_VIOLATION
);
2368 TRACE("returning %d\n", ret
);
2372 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2373 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2378 LPSTR
*pStr
= pvStructInfo
;
2380 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2382 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2383 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2385 if (pbEncoded
[0] != ASN_IA5STRING
)
2387 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2392 bytesNeeded
+= dataLen
;
2394 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2396 *pcbStructInfo
= bytesNeeded
;
2397 else if (*pcbStructInfo
< bytesNeeded
)
2399 *pcbStructInfo
= bytesNeeded
;
2400 SetLastError(ERROR_MORE_DATA
);
2405 *pcbStructInfo
= bytesNeeded
;
2411 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2422 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2423 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2426 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2427 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2428 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2429 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2430 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2433 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2434 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2436 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2437 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2438 TRACE("returning %d\n", ret
);
2442 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2443 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2447 struct AsnDecodeSequenceItem items
[] = {
2448 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2449 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2450 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2451 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2452 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2453 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2454 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2455 rgNoticeNumbers
), 0 },
2457 DWORD bytesNeeded
= 0;
2459 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2460 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2462 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2463 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2467 /* The caller is expecting a pointer to a
2468 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2469 * CRYPT_AsnDecodeSequence is decoding a
2470 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2471 * needed, and decode again if the requisite space is available.
2473 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2475 *pcbStructInfo
= bytesNeeded
;
2476 else if (*pcbStructInfo
< bytesNeeded
)
2478 *pcbStructInfo
= bytesNeeded
;
2479 SetLastError(ERROR_MORE_DATA
);
2484 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2486 *pcbStructInfo
= bytesNeeded
;
2487 /* The pointer (pvStructInfo) passed in points to the first dynamic
2488 * pointer, so use it as the pointer to the
2489 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2490 * appropriate offset for the first dynamic pointer within the
2491 * notice reference by pointing to the first memory location past
2492 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2495 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2496 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2497 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2498 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
), pbEncoded
, cbEncoded
, dwFlags
,
2499 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
, noticeRef
->pszOrganization
);
2502 TRACE("returning %d\n", ret
);
2506 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2507 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2513 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2515 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2516 DWORD bytesNeeded
= sizeof(LPWSTR
);
2518 switch (pbEncoded
[0])
2520 case ASN_NUMERICSTRING
:
2522 bytesNeeded
+= (dataLen
+ 1) * 2;
2524 case ASN_PRINTABLESTRING
:
2526 bytesNeeded
+= (dataLen
+ 1) * 2;
2530 bytesNeeded
+= (dataLen
+ 1) * 2;
2534 bytesNeeded
+= (dataLen
+ 1) * 2;
2536 case ASN_VIDEOTEXSTRING
:
2538 bytesNeeded
+= (dataLen
+ 1) * 2;
2540 case ASN_GRAPHICSTRING
:
2542 bytesNeeded
+= (dataLen
+ 1) * 2;
2544 case ASN_VISIBLESTRING
:
2546 bytesNeeded
+= (dataLen
+ 1) * 2;
2548 case ASN_GENERALSTRING
:
2550 bytesNeeded
+= (dataLen
+ 1) * 2;
2552 case ASN_UNIVERSALSTRING
:
2554 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2558 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2560 case ASN_UTF8STRING
:
2562 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2563 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2566 SetLastError(CRYPT_E_ASN1_BADTAG
);
2571 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2573 *pcbStructInfo
= bytesNeeded
;
2574 else if (*pcbStructInfo
< bytesNeeded
)
2576 *pcbStructInfo
= bytesNeeded
;
2577 SetLastError(ERROR_MORE_DATA
);
2582 LPWSTR
*pStr
= pvStructInfo
;
2584 *pcbStructInfo
= bytesNeeded
;
2588 LPWSTR str
= *(LPWSTR
*)pStr
;
2591 switch (pbEncoded
[0])
2593 case ASN_NUMERICSTRING
:
2594 case ASN_PRINTABLESTRING
:
2597 case ASN_VIDEOTEXSTRING
:
2598 case ASN_GRAPHICSTRING
:
2599 case ASN_VISIBLESTRING
:
2600 case ASN_GENERALSTRING
:
2601 for (i
= 0; i
< dataLen
; i
++)
2602 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2605 case ASN_UNIVERSALSTRING
:
2606 for (i
= 0; i
< dataLen
/ 4; i
++)
2607 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2608 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2612 for (i
= 0; i
< dataLen
/ 2; i
++)
2613 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2614 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2617 case ASN_UTF8STRING
:
2619 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2620 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2621 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2634 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2635 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2636 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2639 struct AsnDecodeSequenceItem items
[] = {
2640 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2641 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2642 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2643 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2644 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2645 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2646 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2648 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2650 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2651 pvStructInfo
, *pcbStructInfo
);
2653 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2654 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2655 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2656 TRACE("returning %d\n", ret
);
2660 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2661 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2662 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2663 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2667 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2668 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2672 DWORD bytesNeeded
= 0;
2674 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2675 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2680 *pcbStructInfo
= bytesNeeded
;
2681 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2682 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2684 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2686 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2687 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2688 notice
= pvStructInfo
;
2689 notice
->pNoticeReference
=
2690 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2691 ((BYTE
*)pvStructInfo
+
2692 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2693 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2694 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2695 pvStructInfo
, &bytesNeeded
, NULL
);
2696 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2697 CRYPT_FreeSpace(pDecodePara
, notice
);
2703 SetLastError(STATUS_ACCESS_VIOLATION
);
2706 TRACE("returning %d\n", ret
);
2710 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2711 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2715 struct AsnArrayDescriptor arrayDesc
= { 0,
2716 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2717 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2718 CRYPT_AsnDecodeCopyBytes
,
2719 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2721 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2722 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2724 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2725 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2729 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2730 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2734 struct AsnDecodeSequenceItem items
[] = {
2735 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2736 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2737 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2738 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2739 CRYPT_AsnDecodePKCSAttributeValue
,
2740 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2741 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2743 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2745 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2746 pvStructInfo
, *pcbStructInfo
);
2748 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2749 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2750 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2751 TRACE("returning %d\n", ret
);
2755 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2756 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2757 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2761 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2762 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2766 DWORD bytesNeeded
= 0;
2768 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2769 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2773 *pcbStructInfo
= bytesNeeded
;
2774 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2775 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2777 PCRYPT_ATTRIBUTE attr
;
2779 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2780 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2781 attr
= pvStructInfo
;
2782 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2783 sizeof(CRYPT_ATTRIBUTE
));
2784 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2785 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2787 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2788 CRYPT_FreeSpace(pDecodePara
, attr
);
2794 SetLastError(STATUS_ACCESS_VIOLATION
);
2797 TRACE("returning %d\n", ret
);
2801 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2802 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2805 struct AsnArrayDescriptor arrayDesc
= { 0,
2806 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2807 sizeof(CRYPT_ATTRIBUTES
),
2808 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2809 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2812 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2813 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2817 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2818 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2819 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2823 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2824 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2828 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2829 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2830 sizeof(CRYPT_ATTRIBUTES
),
2831 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2832 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2833 CRYPT_ATTRIBUTES
*attrs
= pvStructInfo
;
2835 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2836 attrs
->rgAttr
= (CRYPT_ATTRIBUTE
*)(attrs
+ 1);
2837 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2838 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2842 SetLastError(STATUS_ACCESS_VIOLATION
);
2845 TRACE("returning %d\n", ret
);
2849 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2850 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2852 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2854 struct AsnDecodeSequenceItem items
[] = {
2855 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2856 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2857 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2858 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2859 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2860 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2863 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2864 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2866 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2867 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2868 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2869 if (ret
&& pvStructInfo
)
2871 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2872 debugstr_a(algo
->pszObjId
));
2877 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2878 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2882 struct AsnDecodeSequenceItem items
[] = {
2883 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2884 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2885 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2886 Algorithm
.pszObjId
) },
2887 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2888 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2889 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2891 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2893 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2894 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2895 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2899 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2900 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2901 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2907 DWORD bytesNeeded
= 0;
2909 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2910 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2913 *pcbStructInfo
= bytesNeeded
;
2914 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2915 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2917 PCERT_PUBLIC_KEY_INFO info
;
2919 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2920 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2921 info
= pvStructInfo
;
2922 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2923 sizeof(CERT_PUBLIC_KEY_INFO
);
2924 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2925 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2926 &bytesNeeded
, NULL
);
2927 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2928 CRYPT_FreeSpace(pDecodePara
, info
);
2934 SetLastError(STATUS_ACCESS_VIOLATION
);
2941 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2942 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2948 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2951 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2953 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2956 if (pbEncoded
[1] > 1)
2958 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2965 *pcbStructInfo
= sizeof(BOOL
);
2968 else if (*pcbStructInfo
< sizeof(BOOL
))
2970 *pcbStructInfo
= sizeof(BOOL
);
2971 SetLastError(ERROR_MORE_DATA
);
2976 *pcbStructInfo
= sizeof(BOOL
);
2977 *(BOOL
*)pvStructInfo
= pbEncoded
[2] != 0;
2980 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2984 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2985 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2987 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2988 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2991 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2992 pvStructInfo
, *pcbStructInfo
);
2996 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2999 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3000 if (1 + lenBytes
> cbEncoded
)
3002 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3005 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3007 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3009 case 1: /* rfc822Name */
3010 case 2: /* dNSName */
3011 case 6: /* uniformResourceIdentifier */
3012 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
3014 SetLastError(CRYPT_E_ASN1_RULE
);
3018 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3020 case 4: /* directoryName */
3021 case 7: /* iPAddress */
3022 bytesNeeded
+= dataLen
;
3024 case 8: /* registeredID */
3025 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3029 /* FIXME: ugly, shouldn't need to know internals of OID decode
3030 * function to use it.
3032 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3035 case 0: /* otherName */
3036 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3037 SetLastError(CRYPT_E_ASN1_BADTAG
);
3040 case 3: /* x400Address, unimplemented */
3041 case 5: /* ediPartyName, unimplemented */
3042 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3043 SetLastError(CRYPT_E_ASN1_BADTAG
);
3047 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3048 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3054 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3056 *pcbStructInfo
= bytesNeeded
;
3057 else if (*pcbStructInfo
< bytesNeeded
)
3059 *pcbStructInfo
= bytesNeeded
;
3060 SetLastError(ERROR_MORE_DATA
);
3065 *pcbStructInfo
= bytesNeeded
;
3066 /* MS used values one greater than the asn1 ones.. sigh */
3067 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3068 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3070 case 1: /* rfc822Name */
3071 case 2: /* dNSName */
3072 case 6: /* uniformResourceIdentifier */
3076 for (i
= 0; i
< dataLen
; i
++)
3077 entry
->u
.pwszURL
[i
] =
3078 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3079 entry
->u
.pwszURL
[i
] = 0;
3080 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3081 debugstr_w(entry
->u
.pwszURL
));
3084 case 4: /* directoryName */
3085 /* The data are memory-equivalent with the IPAddress case,
3088 case 7: /* iPAddress */
3089 /* The next data pointer is in the pwszURL spot, that is,
3090 * the first 4 bytes. Need to move it to the next spot.
3092 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3093 entry
->u
.IPAddress
.cbData
= dataLen
;
3094 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3097 case 8: /* registeredID */
3098 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3099 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3108 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3109 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3113 struct AsnArrayDescriptor arrayDesc
= { 0,
3114 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3115 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3116 sizeof(CERT_ALT_NAME_INFO
),
3117 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3118 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3120 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3121 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3123 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3124 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3128 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3129 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3130 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3136 struct AsnDecodeSequenceItem items
[] = {
3137 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3138 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3139 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3140 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3141 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3142 CRYPT_AsnDecodeOctets
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3143 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3144 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3145 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3146 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3147 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3150 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3151 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3152 pcbStructInfo
, NULL
, NULL
);
3156 SetLastError(STATUS_ACCESS_VIOLATION
);
3163 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3164 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3165 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3171 struct AsnDecodeSequenceItem items
[] = {
3172 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3173 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3174 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3175 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3176 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3177 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3178 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3179 AuthorityCertIssuer
.rgAltEntry
), 0 },
3180 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3181 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3182 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3183 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3184 AuthorityCertSerialNumber
.pbData
), 0 },
3187 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3188 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3189 pcbStructInfo
, NULL
, NULL
);
3193 SetLastError(STATUS_ACCESS_VIOLATION
);
3200 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3201 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3204 struct AsnDecodeSequenceItem items
[] = {
3205 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3206 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3207 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3208 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3209 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3210 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3212 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3214 return CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3215 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3216 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3219 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3220 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3221 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3225 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3226 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3230 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3231 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3232 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3233 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3234 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3235 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3236 CERT_AUTHORITY_INFO_ACCESS
*info
= pvStructInfo
;
3238 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3239 info
->rgAccDescr
= (CERT_ACCESS_DESCRIPTION
*)(info
+ 1);
3240 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3241 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3245 SetLastError(STATUS_ACCESS_VIOLATION
);
3252 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3253 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3258 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3259 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3261 /* The caller has already checked the tag, no need to check it again.
3262 * Check the outer length is valid:
3264 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3266 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3269 pbEncoded
+= 1 + lenBytes
;
3270 cbEncoded
-= 1 + lenBytes
;
3271 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3272 cbEncoded
-= 2; /* space for 0 TLV */
3273 /* Check the inner length is valid: */
3274 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3278 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3279 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3280 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3282 if (*(pbEncoded
+ decodedLen
) != 0 ||
3283 *(pbEncoded
+ decodedLen
+ 1) != 0)
3285 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3286 *(pbEncoded
+ decodedLen
),
3287 *(pbEncoded
+ decodedLen
+ 1));
3288 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3294 if (ret
&& pcbDecoded
)
3296 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3297 TRACE("decoded %d bytes\n", *pcbDecoded
);
3304 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3305 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3308 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3309 struct AsnDecodeSequenceItem items
[] = {
3310 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3311 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3312 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3313 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3314 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3315 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3316 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3320 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3321 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3323 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3324 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3325 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3329 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3330 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3331 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3335 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3336 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3340 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3341 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3342 if (ret
&& pvStructInfo
)
3344 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3345 pcbStructInfo
, *pcbStructInfo
);
3348 CRYPT_CONTENT_INFO
*info
;
3350 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3351 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3352 info
= pvStructInfo
;
3353 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3354 sizeof(CRYPT_CONTENT_INFO
));
3355 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3356 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3357 pcbStructInfo
, NULL
);
3358 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3359 CRYPT_FreeSpace(pDecodePara
, info
);
3365 SetLastError(STATUS_ACCESS_VIOLATION
);
3371 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3372 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3373 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3376 struct AsnDecodeSequenceItem items
[] = {
3377 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3378 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3379 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3380 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3381 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3383 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3384 CRYPT_AsnDecodePKCSContentInfoInternal
,
3385 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3386 ContentInfo
.pszObjId
), 0 },
3387 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3388 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3389 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3392 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3393 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3398 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3399 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3400 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3404 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3405 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3409 DWORD bytesNeeded
= 0;
3411 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3412 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3415 *pcbStructInfo
= bytesNeeded
;
3416 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3417 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3419 CERT_ALT_NAME_INFO
*name
;
3421 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3422 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3423 name
= pvStructInfo
;
3424 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3425 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3426 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3427 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3428 &bytesNeeded
, NULL
);
3429 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3430 CRYPT_FreeSpace(pDecodePara
, name
);
3436 SetLastError(STATUS_ACCESS_VIOLATION
);
3443 struct PATH_LEN_CONSTRAINT
3445 BOOL fPathLenConstraint
;
3446 DWORD dwPathLenConstraint
;
3449 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3450 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3454 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3456 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3457 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3461 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3463 *pcbStructInfo
= bytesNeeded
;
3465 else if (*pcbStructInfo
< bytesNeeded
)
3467 SetLastError(ERROR_MORE_DATA
);
3468 *pcbStructInfo
= bytesNeeded
;
3473 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3475 *pcbStructInfo
= bytesNeeded
;
3476 size
= sizeof(constraint
->dwPathLenConstraint
);
3477 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3478 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3480 constraint
->fPathLenConstraint
= TRUE
;
3481 TRACE("got an int, dwPathLenConstraint is %d\n",
3482 constraint
->dwPathLenConstraint
);
3484 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3488 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3489 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3493 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3494 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3495 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3496 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3497 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3498 offsetof(CERT_NAME_BLOB
, pbData
) };
3500 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3501 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3503 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3504 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3505 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3509 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3510 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3511 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3517 struct AsnDecodeSequenceItem items
[] = {
3518 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3519 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3520 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3521 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3522 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3523 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3524 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3525 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3526 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3528 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3531 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3532 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3533 pcbStructInfo
, NULL
, NULL
);
3537 SetLastError(STATUS_ACCESS_VIOLATION
);
3544 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3545 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3546 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3552 struct AsnDecodeSequenceItem items
[] = {
3553 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3554 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3555 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3556 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3557 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3560 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3561 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3562 pcbStructInfo
, NULL
, NULL
);
3566 SetLastError(STATUS_ACCESS_VIOLATION
);
3573 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3574 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3577 struct AsnDecodeSequenceItem items
[] = {
3578 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3579 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3580 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3582 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3583 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3584 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3587 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3589 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3590 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3592 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3593 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3594 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3598 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3599 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3603 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3604 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3605 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3606 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3607 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3608 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3610 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3611 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3613 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3614 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3615 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3619 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3620 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3622 struct AsnDecodeSequenceItem items
[] = {
3623 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3624 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3625 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3626 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3627 CRYPT_AsnDecodePolicyQualifiers
,
3628 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3629 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3631 CERT_POLICY_INFO
*info
= pvStructInfo
;
3634 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3635 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3637 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3638 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3639 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3643 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3644 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3645 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3649 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3650 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3654 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3655 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3656 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3657 sizeof(CERT_POLICIES_INFO
),
3658 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3659 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3660 CERT_POLICIES_INFO
*info
= pvStructInfo
;
3662 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3663 info
->rgPolicyInfo
= (CERT_POLICY_INFO
*)(info
+ 1);
3665 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3666 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3670 SetLastError(STATUS_ACCESS_VIOLATION
);
3676 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3677 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3680 struct AsnDecodeSequenceItem items
[] = {
3681 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3682 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3683 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3684 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3685 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3686 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3688 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3691 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3692 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3694 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3695 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3696 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3700 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3701 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3702 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3706 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3707 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3711 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3712 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3713 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3714 sizeof(CERT_POLICY_MAPPING
),
3715 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3716 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3717 CERT_POLICY_MAPPINGS_INFO
*info
= pvStructInfo
;
3719 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3720 info
->rgPolicyMapping
= (CERT_POLICY_MAPPING
*)(info
+ 1);
3721 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3722 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3726 SetLastError(STATUS_ACCESS_VIOLATION
);
3732 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3733 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3737 DWORD skip
, size
= sizeof(skip
);
3741 SetLastError(CRYPT_E_ASN1_EOD
);
3744 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3746 SetLastError(CRYPT_E_ASN1_BADTAG
);
3749 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3750 &skip
, &size
, pcbDecoded
)))
3752 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3753 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3756 *pcbStructInfo
= bytesNeeded
;
3757 else if (*pcbStructInfo
< bytesNeeded
)
3759 *pcbStructInfo
= bytesNeeded
;
3760 SetLastError(ERROR_MORE_DATA
);
3765 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3766 CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
);
3768 *pcbStructInfo
= bytesNeeded
;
3769 /* The BOOL is implicit: if the integer is present, then it's
3772 info
->fRequireExplicitPolicy
= TRUE
;
3773 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3779 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3780 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3784 DWORD skip
, size
= sizeof(skip
);
3788 SetLastError(CRYPT_E_ASN1_EOD
);
3791 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3793 SetLastError(CRYPT_E_ASN1_BADTAG
);
3796 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3797 &skip
, &size
, pcbDecoded
)))
3799 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3800 fInhibitPolicyMapping
);
3803 *pcbStructInfo
= bytesNeeded
;
3804 else if (*pcbStructInfo
< bytesNeeded
)
3806 *pcbStructInfo
= bytesNeeded
;
3807 SetLastError(ERROR_MORE_DATA
);
3812 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3813 CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
);
3815 *pcbStructInfo
= bytesNeeded
;
3816 /* The BOOL is implicit: if the integer is present, then it's
3819 info
->fInhibitPolicyMapping
= TRUE
;
3820 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3826 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3827 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3828 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3829 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3833 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3834 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3838 struct AsnDecodeSequenceItem items
[] = {
3840 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3841 CRYPT_AsnDecodeRequireExplicit
,
3842 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3843 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3845 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3846 CRYPT_AsnDecodeInhibitMapping
,
3847 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3848 TRUE
, FALSE
, 0, 0 },
3851 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3852 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3853 pcbStructInfo
, NULL
, NULL
);
3857 SetLastError(STATUS_ACCESS_VIOLATION
);
3863 #define RSA1_MAGIC 0x31415352
3865 struct DECODED_RSA_PUB_KEY
3868 CRYPT_INTEGER_BLOB modulus
;
3871 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3872 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3873 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3879 struct AsnDecodeSequenceItem items
[] = {
3880 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3881 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3882 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3884 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3885 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3887 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3890 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3891 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3895 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3896 decodedKey
->modulus
.cbData
;
3900 *pcbStructInfo
= bytesNeeded
;
3903 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3904 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3907 RSAPUBKEY
*rsaPubKey
;
3909 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3910 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3912 hdr
->bType
= PUBLICKEYBLOB
;
3913 hdr
->bVersion
= CUR_BLOB_VERSION
;
3915 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3916 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3917 sizeof(BLOBHEADER
));
3918 rsaPubKey
->magic
= RSA1_MAGIC
;
3919 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3920 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3921 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3922 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3923 decodedKey
->modulus
.cbData
);
3925 LocalFree(decodedKey
);
3930 SetLastError(STATUS_ACCESS_VIOLATION
);
3937 #define RSA2_MAGIC 0x32415352
3939 struct DECODED_RSA_PRIV_KEY
3943 CRYPT_INTEGER_BLOB modulus
;
3944 CRYPT_INTEGER_BLOB privexp
;
3945 CRYPT_INTEGER_BLOB prime1
;
3946 CRYPT_INTEGER_BLOB prime2
;
3947 CRYPT_INTEGER_BLOB exponent1
;
3948 CRYPT_INTEGER_BLOB exponent2
;
3949 CRYPT_INTEGER_BLOB coefficient
;
3952 static BOOL WINAPI
CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType
,
3953 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3954 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3961 struct AsnDecodeSequenceItem items
[] = {
3962 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, version
),
3963 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3964 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
),
3965 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3966 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
.pbData
),
3968 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, pubexp
),
3969 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3970 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
),
3971 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3972 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
.pbData
),
3974 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
),
3975 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3976 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
.pbData
),
3978 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
),
3979 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3980 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
.pbData
),
3982 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
),
3983 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3984 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
.pbData
),
3986 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
),
3987 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3988 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
.pbData
),
3990 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
),
3991 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3992 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
.pbData
),
3995 struct DECODED_RSA_PRIV_KEY
*decodedKey
= NULL
;
3998 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3999 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
4003 halflen
= decodedKey
->prime1
.cbData
;
4004 if (halflen
< decodedKey
->prime2
.cbData
)
4005 halflen
= decodedKey
->prime2
.cbData
;
4006 if (halflen
< decodedKey
->exponent1
.cbData
)
4007 halflen
= decodedKey
->exponent1
.cbData
;
4008 if (halflen
< decodedKey
->exponent2
.cbData
)
4009 halflen
= decodedKey
->exponent2
.cbData
;
4010 if (halflen
< decodedKey
->coefficient
.cbData
)
4011 halflen
= decodedKey
->coefficient
.cbData
;
4012 if (halflen
* 2 < decodedKey
->modulus
.cbData
)
4013 halflen
= decodedKey
->modulus
.cbData
/ 2 + decodedKey
->modulus
.cbData
% 2;
4014 if (halflen
* 2 < decodedKey
->privexp
.cbData
)
4015 halflen
= decodedKey
->privexp
.cbData
/ 2 + decodedKey
->privexp
.cbData
% 2;
4019 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
4024 *pcbStructInfo
= bytesNeeded
;
4027 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4028 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4031 RSAPUBKEY
*rsaPubKey
;
4034 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4035 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4038 hdr
->bType
= PRIVATEKEYBLOB
;
4039 hdr
->bVersion
= CUR_BLOB_VERSION
;
4041 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
4043 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
4044 sizeof(BLOBHEADER
));
4045 rsaPubKey
->magic
= RSA2_MAGIC
;
4046 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
4047 rsaPubKey
->bitlen
= halflen
* 16;
4049 vardata
= (BYTE
*)(rsaPubKey
+ 1);
4050 memset(vardata
, 0, halflen
* 9);
4052 decodedKey
->modulus
.pbData
, decodedKey
->modulus
.cbData
);
4053 memcpy(vardata
+ halflen
* 2,
4054 decodedKey
->prime1
.pbData
, decodedKey
->prime1
.cbData
);
4055 memcpy(vardata
+ halflen
* 3,
4056 decodedKey
->prime2
.pbData
, decodedKey
->prime2
.cbData
);
4057 memcpy(vardata
+ halflen
* 4,
4058 decodedKey
->exponent1
.pbData
, decodedKey
->exponent1
.cbData
);
4059 memcpy(vardata
+ halflen
* 5,
4060 decodedKey
->exponent2
.pbData
, decodedKey
->exponent2
.cbData
);
4061 memcpy(vardata
+ halflen
* 6,
4062 decodedKey
->coefficient
.pbData
, decodedKey
->coefficient
.cbData
);
4063 memcpy(vardata
+ halflen
* 7,
4064 decodedKey
->privexp
.pbData
, decodedKey
->privexp
.cbData
);
4068 LocalFree(decodedKey
);
4073 SetLastError(STATUS_ACCESS_VIOLATION
);
4080 static BOOL
CRYPT_AsnDecodeOctets(const BYTE
*pbEncoded
,
4081 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4085 DWORD bytesNeeded
, dataLen
;
4087 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4088 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4090 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4092 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4094 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4095 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
4097 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
4099 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4101 *pcbStructInfo
= bytesNeeded
;
4102 else if (*pcbStructInfo
< bytesNeeded
)
4104 SetLastError(ERROR_MORE_DATA
);
4105 *pcbStructInfo
= bytesNeeded
;
4110 CRYPT_DATA_BLOB
*blob
;
4112 *pcbStructInfo
= bytesNeeded
;
4113 blob
= pvStructInfo
;
4114 blob
->cbData
= dataLen
;
4115 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4116 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
4119 assert(blob
->pbData
);
4121 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
4129 static BOOL
CRYPT_AsnDecodeOctetStringInternal(const BYTE
*encoded
, DWORD encoded_size
,
4130 DWORD flags
, void *buf
, DWORD
*buf_size
, DWORD
*ret_decoded
)
4132 DWORD decoded
= 0, indefinite_len_depth
= 0, len_size
, len
, bytes_needed
;
4133 CRYPT_DATA_BLOB
*blob
;
4136 while (encoded
[0] == (ASN_CONSTRUCTOR
| ASN_OCTETSTRING
))
4138 if (!CRYPT_GetLengthIndefinite(encoded
, encoded_size
, &len
))
4141 len_size
= GET_LEN_BYTES(encoded
[1]);
4142 encoded
+= 1 + len_size
;
4143 encoded_size
-= 1 + len_size
;
4144 decoded
+= 1 + len_size
;
4146 if (len
== CMSG_INDEFINITE_LENGTH
)
4148 indefinite_len_depth
++;
4149 if (encoded_size
< 2)
4151 SetLastError(CRYPT_E_ASN1_EOD
);
4159 if (encoded
[0] != ASN_OCTETSTRING
)
4161 WARN("Unexpected tag %02x\n", encoded
[0]);
4162 SetLastError(CRYPT_E_ASN1_BADTAG
);
4166 if (!CRYPT_GetLen(encoded
, encoded_size
, &len
))
4168 len_size
= GET_LEN_BYTES(encoded
[1]);
4169 decoded
+= 1 + len_size
+ len
;
4170 encoded_size
-= 1 + len_size
;
4172 if (len
> encoded_size
)
4174 SetLastError(CRYPT_E_ASN1_EOD
);
4178 *ret_decoded
= decoded
;
4180 encoded
+= 1 + len_size
;
4184 while (indefinite_len_depth
--)
4186 if (encoded
[0] || encoded
[1])
4188 TRACE("expected 0 TLV, got %02x %02x\n", encoded
[0], encoded
[1]);
4189 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4194 bytes_needed
= sizeof(*blob
);
4195 if (!(flags
& CRYPT_DECODE_NOCOPY_FLAG
)) bytes_needed
+= len
;
4198 *buf_size
= bytes_needed
;
4201 if (*buf_size
< bytes_needed
)
4203 SetLastError(ERROR_MORE_DATA
);
4204 *buf_size
= bytes_needed
;
4208 *buf_size
= bytes_needed
;
4211 if (flags
& CRYPT_DECODE_NOCOPY_FLAG
)
4212 blob
->pbData
= (BYTE
*)string
;
4213 else if (blob
->cbData
)
4214 memcpy(blob
->pbData
, string
, blob
->cbData
);
4217 *ret_decoded
= decoded
;
4221 static BOOL WINAPI
CRYPT_AsnDecodeOctetString(DWORD dwCertEncodingType
,
4222 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4223 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4227 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4228 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4232 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4238 DWORD bytesNeeded
= 0;
4240 if ((ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4241 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4244 *pcbStructInfo
= bytesNeeded
;
4245 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4246 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4248 CRYPT_DATA_BLOB
*blob
;
4250 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4251 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4252 blob
= pvStructInfo
;
4253 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4254 ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4255 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4256 &bytesNeeded
, NULL
);
4257 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4258 CRYPT_FreeSpace(pDecodePara
, blob
);
4264 SetLastError(STATUS_ACCESS_VIOLATION
);
4271 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4272 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4275 DWORD bytesNeeded
, dataLen
;
4276 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4278 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4279 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4281 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4283 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4284 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4286 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4288 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4290 *pcbStructInfo
= bytesNeeded
;
4291 else if (*pcbStructInfo
< bytesNeeded
)
4293 *pcbStructInfo
= bytesNeeded
;
4294 SetLastError(ERROR_MORE_DATA
);
4299 CRYPT_BIT_BLOB
*blob
;
4301 *pcbStructInfo
= bytesNeeded
;
4302 blob
= pvStructInfo
;
4303 blob
->cbData
= dataLen
- 1;
4304 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4305 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4307 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4311 assert(blob
->pbData
);
4314 BYTE mask
= 0xff << blob
->cUnusedBits
;
4316 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4318 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4326 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4327 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4328 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4332 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4333 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4337 DWORD bytesNeeded
= 0;
4341 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4344 else if (pbEncoded
[0] != ASN_BITSTRING
)
4346 SetLastError(CRYPT_E_ASN1_BADTAG
);
4349 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4350 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4353 *pcbStructInfo
= bytesNeeded
;
4354 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4355 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4357 CRYPT_BIT_BLOB
*blob
;
4359 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4360 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4361 blob
= pvStructInfo
;
4362 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4363 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4364 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4365 &bytesNeeded
, NULL
);
4366 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4367 CRYPT_FreeSpace(pDecodePara
, blob
);
4373 SetLastError(STATUS_ACCESS_VIOLATION
);
4377 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4381 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4382 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4383 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4388 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4390 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4393 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4394 if (dataLen
> sizeof(int))
4396 SetLastError(CRYPT_E_ASN1_LARGE
);
4399 else if (!pvStructInfo
)
4400 *pcbStructInfo
= sizeof(int);
4401 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4405 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4407 /* initialize to a negative value to sign-extend */
4412 for (i
= 0; i
< dataLen
; i
++)
4415 val
|= pbEncoded
[1 + lenBytes
+ i
];
4417 memcpy(pvStructInfo
, &val
, sizeof(int));
4423 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4424 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4425 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4431 DWORD bytesNeeded
= 0;
4435 SetLastError(CRYPT_E_ASN1_EOD
);
4438 else if (pbEncoded
[0] != ASN_INTEGER
)
4440 SetLastError(CRYPT_E_ASN1_BADTAG
);
4444 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4445 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4449 *pcbStructInfo
= bytesNeeded
;
4450 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4451 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4453 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4454 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4455 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4456 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4457 &bytesNeeded
, NULL
);
4458 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4459 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4465 SetLastError(STATUS_ACCESS_VIOLATION
);
4472 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4473 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4477 DWORD bytesNeeded
, dataLen
;
4479 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4481 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4483 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4485 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4487 *pcbStructInfo
= bytesNeeded
;
4488 else if (*pcbStructInfo
< bytesNeeded
)
4490 *pcbStructInfo
= bytesNeeded
;
4491 SetLastError(ERROR_MORE_DATA
);
4496 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4498 *pcbStructInfo
= bytesNeeded
;
4499 blob
->cbData
= dataLen
;
4500 assert(blob
->pbData
);
4505 for (i
= 0; i
< blob
->cbData
; i
++)
4507 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4516 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4517 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4518 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4524 DWORD bytesNeeded
= 0;
4526 if (pbEncoded
[0] != ASN_INTEGER
)
4528 SetLastError(CRYPT_E_ASN1_BADTAG
);
4532 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4533 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4537 *pcbStructInfo
= bytesNeeded
;
4538 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4539 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4541 CRYPT_INTEGER_BLOB
*blob
;
4543 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4544 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4545 blob
= pvStructInfo
;
4546 blob
->pbData
= (BYTE
*)pvStructInfo
+
4547 sizeof(CRYPT_INTEGER_BLOB
);
4548 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4549 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4550 &bytesNeeded
, NULL
);
4551 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4552 CRYPT_FreeSpace(pDecodePara
, blob
);
4558 SetLastError(STATUS_ACCESS_VIOLATION
);
4565 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4566 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4571 if (pbEncoded
[0] == ASN_INTEGER
)
4573 DWORD bytesNeeded
, dataLen
;
4575 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4577 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4580 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4581 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4583 *pcbStructInfo
= bytesNeeded
;
4584 else if (*pcbStructInfo
< bytesNeeded
)
4586 *pcbStructInfo
= bytesNeeded
;
4587 SetLastError(ERROR_MORE_DATA
);
4592 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4594 *pcbStructInfo
= bytesNeeded
;
4595 blob
->cbData
= dataLen
;
4596 assert(blob
->pbData
);
4597 /* remove leading zero byte if it exists */
4598 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4607 for (i
= 0; i
< blob
->cbData
; i
++)
4609 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4618 SetLastError(CRYPT_E_ASN1_BADTAG
);
4624 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4625 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4626 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4632 DWORD bytesNeeded
= 0;
4634 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4635 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4638 *pcbStructInfo
= bytesNeeded
;
4639 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4640 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4642 CRYPT_INTEGER_BLOB
*blob
;
4644 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4645 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4646 blob
= pvStructInfo
;
4647 blob
->pbData
= (BYTE
*)pvStructInfo
+
4648 sizeof(CRYPT_INTEGER_BLOB
);
4649 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4650 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4651 &bytesNeeded
, NULL
);
4652 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4653 CRYPT_FreeSpace(pDecodePara
, blob
);
4659 SetLastError(STATUS_ACCESS_VIOLATION
);
4666 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4667 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4668 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4674 *pcbStructInfo
= sizeof(int);
4679 if (pbEncoded
[0] == ASN_ENUMERATED
)
4681 unsigned int val
= 0, i
;
4685 SetLastError(CRYPT_E_ASN1_EOD
);
4688 else if (pbEncoded
[1] == 0)
4690 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4695 /* A little strange looking, but we have to accept a sign byte:
4696 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4697 * assuming a small length is okay here, it has to be in short
4700 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4702 SetLastError(CRYPT_E_ASN1_LARGE
);
4705 for (i
= 0; i
< pbEncoded
[1]; i
++)
4708 val
|= pbEncoded
[2 + i
];
4710 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4711 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4713 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4714 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4715 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4721 SetLastError(CRYPT_E_ASN1_BADTAG
);
4727 SetLastError(STATUS_ACCESS_VIOLATION
);
4734 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4737 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4742 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4744 if (!isdigit(*(pbEncoded))) \
4746 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4752 (word) += *(pbEncoded)++ - '0'; \
4757 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4758 SYSTEMTIME
*sysTime
)
4762 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4764 WORD hours
, minutes
= 0;
4765 BYTE sign
= *pbEncoded
++;
4768 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4769 if (ret
&& hours
>= 24)
4771 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4776 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4777 if (ret
&& minutes
>= 60)
4779 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4787 sysTime
->wHour
+= hours
;
4788 sysTime
->wMinute
+= minutes
;
4792 if (hours
> sysTime
->wHour
)
4795 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4798 sysTime
->wHour
-= hours
;
4799 if (minutes
> sysTime
->wMinute
)
4802 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4805 sysTime
->wMinute
-= minutes
;
4812 #define MIN_ENCODED_TIME_LENGTH 10
4814 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4815 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4820 if (pbEncoded
[0] == ASN_UTCTIME
)
4823 SetLastError(CRYPT_E_ASN1_EOD
);
4824 else if (pbEncoded
[1] > 0x7f)
4826 /* long-form date strings really can't be valid */
4827 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4831 SYSTEMTIME sysTime
= { 0 };
4832 BYTE len
= pbEncoded
[1];
4834 if (len
< MIN_ENCODED_TIME_LENGTH
)
4835 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4840 *pcbDecoded
= 2 + len
;
4842 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4843 if (sysTime
.wYear
>= 50)
4844 sysTime
.wYear
+= 1900;
4846 sysTime
.wYear
+= 2000;
4847 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4848 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4849 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4850 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4853 if (len
>= 2 && isdigit(*pbEncoded
) &&
4854 isdigit(*(pbEncoded
+ 1)))
4855 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4857 else if (isdigit(*pbEncoded
))
4858 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4861 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4867 *pcbStructInfo
= sizeof(FILETIME
);
4868 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4870 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4876 SetLastError(CRYPT_E_ASN1_BADTAG
);
4880 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4881 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4882 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4888 DWORD bytesNeeded
= 0;
4890 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4891 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4895 *pcbStructInfo
= bytesNeeded
;
4896 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4897 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4899 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4900 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4901 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4902 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4903 &bytesNeeded
, NULL
);
4904 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4905 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4911 SetLastError(STATUS_ACCESS_VIOLATION
);
4917 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4918 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4923 if (pbEncoded
[0] == ASN_GENERALTIME
)
4926 SetLastError(CRYPT_E_ASN1_EOD
);
4927 else if (pbEncoded
[1] > 0x7f)
4929 /* long-form date strings really can't be valid */
4930 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4934 BYTE len
= pbEncoded
[1];
4936 if (len
< MIN_ENCODED_TIME_LENGTH
)
4937 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4940 SYSTEMTIME sysTime
= { 0 };
4944 *pcbDecoded
= 2 + len
;
4946 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4947 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4948 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4949 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4952 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4955 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4957 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4964 /* workaround macro weirdness */
4965 digits
= min(len
, 3);
4966 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4967 sysTime
.wMilliseconds
);
4970 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4976 *pcbStructInfo
= sizeof(FILETIME
);
4977 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4979 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4985 SetLastError(CRYPT_E_ASN1_BADTAG
);
4989 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4990 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4994 InternalDecodeFunc decode
= NULL
;
4996 if (pbEncoded
[0] == ASN_UTCTIME
)
4997 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4998 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4999 decode
= CRYPT_AsnDecodeGeneralizedTime
;
5001 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
5002 pcbStructInfo
, pcbDecoded
);
5005 SetLastError(CRYPT_E_ASN1_BADTAG
);
5011 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
5012 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5013 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5019 DWORD bytesNeeded
= 0;
5021 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5022 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
5026 *pcbStructInfo
= bytesNeeded
;
5027 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5028 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5030 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5031 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5032 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5033 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5034 &bytesNeeded
, NULL
);
5035 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5036 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
5042 SetLastError(STATUS_ACCESS_VIOLATION
);
5049 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
5050 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5051 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5057 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
5059 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
5061 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5066 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5067 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
5069 ptr
= pbEncoded
+ 1 + lenBytes
;
5070 remainingLen
= dataLen
;
5071 while (ret
&& remainingLen
)
5075 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5078 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5080 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5081 ptr
+= 1 + nextLenBytes
+ nextLen
;
5082 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
5083 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
5084 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
5090 CRYPT_SEQUENCE_OF_ANY
*seq
;
5095 *pcbStructInfo
= bytesNeeded
;
5096 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5097 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5099 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5100 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5102 seq
->cValue
= cValue
;
5103 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
5105 nextPtr
= (BYTE
*)seq
->rgValue
+
5106 cValue
* sizeof(CRYPT_DER_BLOB
);
5107 ptr
= pbEncoded
+ 1 + lenBytes
;
5108 remainingLen
= dataLen
;
5110 while (ret
&& remainingLen
)
5114 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5117 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5119 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
5121 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
5122 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
5125 seq
->rgValue
[i
].pbData
= nextPtr
;
5126 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
5128 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
5130 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5131 ptr
+= 1 + nextLenBytes
+ nextLen
;
5135 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5136 CRYPT_FreeSpace(pDecodePara
, seq
);
5143 SetLastError(CRYPT_E_ASN1_BADTAG
);
5149 SetLastError(STATUS_ACCESS_VIOLATION
);
5156 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
5157 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5162 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
5164 DWORD bytesNeeded
= 0, dataLen
;
5166 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5168 struct AsnArrayDescriptor arrayDesc
= {
5169 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5170 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
5171 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
5172 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
5173 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
5174 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
5175 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5180 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5181 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5182 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
5183 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
5184 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
5187 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
5189 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
5191 *pcbStructInfo
= bytesNeeded
;
5192 else if (*pcbStructInfo
< bytesNeeded
)
5194 *pcbStructInfo
= bytesNeeded
;
5195 SetLastError(ERROR_MORE_DATA
);
5200 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
5202 *pcbStructInfo
= bytesNeeded
;
5205 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
5206 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5207 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5208 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
5212 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
5218 SetLastError(CRYPT_E_ASN1_BADTAG
);
5224 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5225 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5227 struct AsnDecodeSequenceItem items
[] = {
5228 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
5229 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5230 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
5231 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5232 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
5233 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
5234 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
5235 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
5236 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
5237 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
5239 CRL_DIST_POINT
*point
= pvStructInfo
;
5242 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5243 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5244 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5248 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5249 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5250 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5254 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5255 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5259 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5260 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
5261 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
5262 sizeof(CRL_DIST_POINTS_INFO
),
5263 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5264 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5265 CRL_DIST_POINTS_INFO
*info
= pvStructInfo
;
5267 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5268 info
->rgDistPoint
= (CRL_DIST_POINT
*)(info
+ 1);
5269 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5270 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5274 SetLastError(STATUS_ACCESS_VIOLATION
);
5281 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5282 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5283 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5287 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5288 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5292 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5293 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5294 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5295 sizeof(CERT_ENHKEY_USAGE
),
5296 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5297 CERT_ENHKEY_USAGE
*usage
= pvStructInfo
;
5299 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5300 usage
->rgpszUsageIdentifier
= (LPSTR
*)(usage
+ 1);
5301 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5302 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5306 SetLastError(STATUS_ACCESS_VIOLATION
);
5313 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5314 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5315 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5319 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5320 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5324 struct AsnDecodeSequenceItem items
[] = {
5325 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5326 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5327 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5328 offsetof(CRL_ISSUING_DIST_POINT
,
5329 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5330 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5331 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5333 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5334 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5336 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5337 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5338 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5339 OnlySomeReasonFlags
.pbData
), 0 },
5340 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5341 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5344 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5345 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5346 pcbStructInfo
, NULL
, NULL
);
5350 SetLastError(STATUS_ACCESS_VIOLATION
);
5357 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5358 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5362 DWORD max
, size
= sizeof(max
);
5364 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5365 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5369 SetLastError(CRYPT_E_ASN1_EOD
);
5372 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5374 SetLastError(CRYPT_E_ASN1_BADTAG
);
5377 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5378 &max
, &size
, pcbDecoded
)))
5380 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5383 *pcbStructInfo
= bytesNeeded
;
5384 else if (*pcbStructInfo
< bytesNeeded
)
5386 *pcbStructInfo
= bytesNeeded
;
5387 SetLastError(ERROR_MORE_DATA
);
5392 CERT_GENERAL_SUBTREE
*subtree
= CONTAINING_RECORD(pvStructInfo
,
5393 CERT_GENERAL_SUBTREE
, fMaximum
);
5395 *pcbStructInfo
= bytesNeeded
;
5396 /* The BOOL is implicit: if the integer is present, then it's
5399 subtree
->fMaximum
= TRUE
;
5400 subtree
->dwMaximum
= max
;
5403 TRACE("returning %d\n", ret
);
5407 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5408 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5412 struct AsnDecodeSequenceItem items
[] = {
5413 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5414 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5415 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5416 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5417 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5418 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5419 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5420 TRUE
, FALSE
, 0, 0 },
5422 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5424 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5425 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5427 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5428 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5429 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5432 TRACE("%d\n", *pcbDecoded
);
5433 if (*pcbDecoded
< cbEncoded
)
5434 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5435 *(pbEncoded
+ *pcbDecoded
+ 1));
5437 TRACE("returning %d\n", ret
);
5441 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5442 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5446 struct AsnArrayDescriptor arrayDesc
= { 0,
5447 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5448 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5449 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5451 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5452 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5454 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5455 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5457 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5458 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5462 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5463 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5467 struct AsnArrayDescriptor arrayDesc
= { 0,
5468 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5469 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5470 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5471 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5472 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5474 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5475 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5477 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5478 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5482 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5483 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5484 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5488 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5489 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5493 struct AsnDecodeSequenceItem items
[] = {
5494 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5495 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5496 CRYPT_AsnDecodePermittedSubtree
,
5497 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5498 cExcludedSubtree
), TRUE
, TRUE
,
5499 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5500 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5501 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5502 CRYPT_AsnDecodeExcludedSubtree
,
5503 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5505 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5508 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5509 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5510 pcbStructInfo
, NULL
, NULL
);
5514 SetLastError(STATUS_ACCESS_VIOLATION
);
5520 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5521 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5525 struct AsnDecodeSequenceItem items
[] = {
5526 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5527 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5529 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5530 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5531 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5533 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5535 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5536 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5538 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5539 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5540 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5541 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5543 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5546 TRACE("returning %d\n", ret
);
5550 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5551 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5554 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5555 struct AsnDecodeSequenceItem items
[] = {
5556 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5557 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5558 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5559 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5560 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5561 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5562 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5563 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5564 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5565 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5566 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5567 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5568 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5569 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5570 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5571 HashEncryptionAlgorithm
.pszObjId
), 0 },
5572 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5573 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5574 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5575 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5576 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5577 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5578 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5582 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5583 pvStructInfo
, *pcbStructInfo
);
5585 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5586 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5587 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5591 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5592 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5593 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5597 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5598 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5602 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5603 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5604 if (ret
&& pvStructInfo
)
5606 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5607 pcbStructInfo
, *pcbStructInfo
);
5610 CMSG_SIGNER_INFO
*info
;
5612 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5613 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5614 info
= pvStructInfo
;
5615 info
->Issuer
.pbData
= ((BYTE
*)info
+
5616 sizeof(CMSG_SIGNER_INFO
));
5617 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5618 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5619 pcbStructInfo
, NULL
);
5620 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5621 CRYPT_FreeSpace(pDecodePara
, info
);
5627 SetLastError(STATUS_ACCESS_VIOLATION
);
5630 TRACE("returning %d\n", ret
);
5634 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5635 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5639 struct AsnArrayDescriptor arrayDesc
= { 0,
5640 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5641 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5642 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5643 CRYPT_AsnDecodeCopyBytes
,
5644 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5646 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5647 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5649 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5650 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5654 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5655 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5659 struct AsnArrayDescriptor arrayDesc
= { 0,
5660 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5661 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5662 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5663 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5664 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5666 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5667 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5669 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5670 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5674 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5675 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5678 CERT_ID
*id
= pvStructInfo
;
5681 if (*pbEncoded
== ASN_SEQUENCEOF
)
5683 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5684 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5688 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5689 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5690 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5691 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5693 *pcbStructInfo
= sizeof(CERT_ID
);
5696 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5698 ret
= CRYPT_AsnDecodeOctets(pbEncoded
, cbEncoded
, dwFlags
,
5699 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5703 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5704 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5705 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5706 sizeof(CRYPT_DATA_BLOB
);
5708 *pcbStructInfo
= sizeof(CERT_ID
);
5712 SetLastError(CRYPT_E_ASN1_BADTAG
);
5716 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5717 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5720 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5721 struct AsnDecodeSequenceItem items
[] = {
5722 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5723 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5724 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5725 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5726 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5727 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5728 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5729 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5730 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5731 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5732 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5733 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5734 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5735 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5736 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5737 HashEncryptionAlgorithm
.pszObjId
), 0 },
5738 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5739 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5740 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5741 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5742 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5743 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5744 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5748 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5749 pvStructInfo
, *pcbStructInfo
);
5751 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5752 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5753 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5757 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5758 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5759 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5763 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5764 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5768 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5769 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5770 if (ret
&& pvStructInfo
)
5772 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5773 pcbStructInfo
, *pcbStructInfo
);
5776 CMSG_CMS_SIGNER_INFO
*info
;
5778 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5779 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5780 info
= pvStructInfo
;
5781 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5782 sizeof(CMSG_CMS_SIGNER_INFO
));
5783 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5784 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5785 pcbStructInfo
, NULL
);
5786 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5787 CRYPT_FreeSpace(pDecodePara
, info
);
5793 SetLastError(STATUS_ACCESS_VIOLATION
);
5796 TRACE("returning %d\n", ret
);
5800 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5801 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5804 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5805 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5806 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5807 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5808 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5809 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5811 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5812 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5814 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5815 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5819 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5820 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5821 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5824 struct AsnDecodeSequenceItem items
[] = {
5825 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5826 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5827 /* Placeholder for the hash algorithms - redundant with those in the
5828 * signers, so just ignore them.
5830 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5831 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5832 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5833 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5834 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5835 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5836 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5837 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5838 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5839 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5840 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5841 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5842 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5843 CRYPT_DecodeSignerArray
,
5844 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5845 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5848 TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5849 pDecodePara
, signedInfo
, pcbSignedInfo
);
5851 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5852 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5854 TRACE("returning %d\n", ret
);
5858 static BOOL
CRYPT_AsnDecodeRecipientInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5859 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5862 CMSG_KEY_TRANS_RECIPIENT_INFO
*info
= pvStructInfo
;
5863 struct AsnDecodeSequenceItem items
[] = {
5864 { ASN_INTEGER
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, dwVersion
),
5865 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5866 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5867 RecipientId
.u
.IssuerSerialNumber
), CRYPT_AsnDecodeIssuerSerialNumber
,
5868 sizeof(CERT_ISSUER_SERIAL_NUMBER
), FALSE
, TRUE
,
5869 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5870 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
), 0 },
5871 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5872 KeyEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5873 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5874 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5875 KeyEncryptionAlgorithm
.pszObjId
), 0 },
5876 { ASN_OCTETSTRING
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
),
5877 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
5878 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
.pbData
), 0 },
5881 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5882 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5884 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5885 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5886 pcbDecoded
, info
? info
->RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
:
5889 info
->RecipientId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5890 TRACE("returning %d\n", ret
);
5894 static BOOL
CRYPT_DecodeRecipientInfoArray(const BYTE
*pbEncoded
,
5895 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5899 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5900 offsetof(CRYPT_ENVELOPED_DATA
, cRecipientInfo
),
5901 offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
),
5902 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5903 CRYPT_AsnDecodeRecipientInfo
, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO
), TRUE
,
5904 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5905 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
) };
5907 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5908 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5910 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5911 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5912 TRACE("returning %d\n", ret
);
5916 static BOOL
CRYPT_AsnDecodeEncryptedContentInfo(const BYTE
*pbEncoded
,
5917 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5921 CRYPT_ENCRYPTED_CONTENT_INFO
*info
= pvStructInfo
;
5922 struct AsnDecodeSequenceItem items
[] = {
5923 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5924 contentType
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
5925 FALSE
, TRUE
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5927 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5928 contentEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5929 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5930 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5931 contentEncryptionAlgorithm
.pszObjId
), 0 },
5932 { ASN_CONTEXT
| 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5933 encryptedContent
), CRYPT_AsnDecodeOctets
,
5934 sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
5935 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
, encryptedContent
.pbData
) },
5938 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5939 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5941 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5942 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5943 pcbDecoded
, info
? info
->contentType
: NULL
);
5944 TRACE("returning %d\n", ret
);
5948 BOOL
CRYPT_AsnDecodePKCSEnvelopedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5949 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5950 CRYPT_ENVELOPED_DATA
*envelopedData
, DWORD
*pcbEnvelopedData
)
5953 struct AsnDecodeSequenceItem items
[] = {
5954 { ASN_INTEGER
, offsetof(CRYPT_ENVELOPED_DATA
, version
),
5955 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5956 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ENVELOPED_DATA
,
5957 cRecipientInfo
), CRYPT_DecodeRecipientInfoArray
,
5958 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5959 FALSE
, TRUE
, offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
), 0 },
5960 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
),
5961 CRYPT_AsnDecodeEncryptedContentInfo
,
5962 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO
), FALSE
, TRUE
,
5963 offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
.contentType
), 0 },
5966 TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5967 pDecodePara
, envelopedData
, pcbEnvelopedData
);
5969 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5970 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, envelopedData
,
5971 pcbEnvelopedData
, NULL
, NULL
);
5972 TRACE("returning %d\n", ret
);
5976 static BOOL WINAPI
CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType
,
5977 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5978 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5980 DWORD bytesNeeded
= 0;
5985 ret
= CRYPT_AsnDecodeOidInternal(pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
5986 NULL
, &bytesNeeded
, NULL
);
5990 *pcbStructInfo
= bytesNeeded
;
5991 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5995 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5996 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5998 info
= pvStructInfo
;
5999 *info
= (void *)((BYTE
*)info
+ sizeof(*info
));
6000 ret
= CRYPT_AsnDecodeOidInternal(pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
6001 pvStructInfo
, &bytesNeeded
, NULL
);
6002 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
6003 CRYPT_FreeSpace(pDecodePara
, info
);
6009 SetLastError(STATUS_ACCESS_VIOLATION
);
6016 static BOOL WINAPI
CRYPT_AsnDecodeEccSignature(DWORD dwCertEncodingType
,
6017 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6018 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6021 struct AsnDecodeSequenceItem items
[] = {
6022 { ASN_INTEGER
, offsetof(CERT_ECC_SIGNATURE
, r
),
6023 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_UINT_BLOB
), FALSE
,
6024 TRUE
, offsetof(CERT_ECC_SIGNATURE
, r
.pbData
), 0 },
6025 { ASN_INTEGER
, offsetof(CERT_ECC_SIGNATURE
, s
),
6026 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_UINT_BLOB
), FALSE
,
6027 TRUE
, offsetof(CERT_ECC_SIGNATURE
, s
.pbData
), 0 },
6032 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6033 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
6034 pcbStructInfo
, NULL
, NULL
);
6038 SetLastError(STATUS_ACCESS_VIOLATION
);
6045 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
6046 LPCSTR lpszStructType
)
6048 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6050 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
6051 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
6053 SetLastError(ERROR_FILE_NOT_FOUND
);
6056 if (IS_INTOID(lpszStructType
))
6058 switch (LOWORD(lpszStructType
))
6060 case LOWORD(X509_CERT
):
6061 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
6063 case LOWORD(X509_CERT_TO_BE_SIGNED
):
6064 decodeFunc
= CRYPT_AsnDecodeCert
;
6066 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
6067 decodeFunc
= CRYPT_AsnDecodeCRL
;
6069 case LOWORD(X509_EXTENSIONS
):
6070 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6072 case LOWORD(X509_NAME_VALUE
):
6073 decodeFunc
= CRYPT_AsnDecodeNameValue
;
6075 case LOWORD(X509_NAME
):
6076 decodeFunc
= CRYPT_AsnDecodeName
;
6078 case LOWORD(X509_PUBLIC_KEY_INFO
):
6079 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
6081 case LOWORD(X509_AUTHORITY_KEY_ID
):
6082 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6084 case LOWORD(X509_ALTERNATE_NAME
):
6085 decodeFunc
= CRYPT_AsnDecodeAltName
;
6087 case LOWORD(X509_BASIC_CONSTRAINTS
):
6088 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6090 case LOWORD(X509_BASIC_CONSTRAINTS2
):
6091 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6093 case LOWORD(X509_CERT_POLICIES
):
6094 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6096 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
6097 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
6099 case LOWORD(PKCS_RSA_PRIVATE_KEY
):
6100 decodeFunc
= CRYPT_AsnDecodeRsaPrivKey
;
6102 case LOWORD(X509_UNICODE_NAME
):
6103 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
6105 case LOWORD(PKCS_ATTRIBUTE
):
6106 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
6108 case LOWORD(X509_UNICODE_NAME_VALUE
):
6109 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
6111 case LOWORD(X509_OCTET_STRING
):
6112 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6114 case LOWORD(X509_BITS
):
6115 case LOWORD(X509_KEY_USAGE
):
6116 decodeFunc
= CRYPT_AsnDecodeBits
;
6118 case LOWORD(X509_INTEGER
):
6119 decodeFunc
= CRYPT_AsnDecodeInt
;
6121 case LOWORD(X509_MULTI_BYTE_INTEGER
):
6122 decodeFunc
= CRYPT_AsnDecodeInteger
;
6124 case LOWORD(X509_MULTI_BYTE_UINT
):
6125 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
6127 case LOWORD(X509_ENUMERATED
):
6128 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6130 case LOWORD(X509_CHOICE_OF_TIME
):
6131 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
6133 case LOWORD(X509_AUTHORITY_KEY_ID2
):
6134 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6136 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
6137 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6139 case LOWORD(PKCS_CONTENT_INFO
):
6140 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
6142 case LOWORD(X509_SEQUENCE_OF_ANY
):
6143 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
6145 case LOWORD(PKCS_UTC_TIME
):
6146 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6148 case LOWORD(X509_CRL_DIST_POINTS
):
6149 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6151 case LOWORD(X509_ENHANCED_KEY_USAGE
):
6152 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6154 case LOWORD(PKCS_CTL
):
6155 decodeFunc
= CRYPT_AsnDecodeCTL
;
6157 case LOWORD(PKCS_SMIME_CAPABILITIES
):
6158 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6160 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
6161 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6163 case LOWORD(PKCS_ATTRIBUTES
):
6164 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
6166 case LOWORD(X509_ISSUING_DIST_POINT
):
6167 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6169 case LOWORD(X509_NAME_CONSTRAINTS
):
6170 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6172 case LOWORD(X509_POLICY_MAPPINGS
):
6173 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6175 case LOWORD(X509_POLICY_CONSTRAINTS
):
6176 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6178 case LOWORD(PKCS7_SIGNER_INFO
):
6179 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
6181 case LOWORD(CMS_SIGNER_INFO
):
6182 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
6184 case LOWORD(X509_OBJECT_IDENTIFIER
):
6185 decodeFunc
= CRYPT_AsnDecodeObjectIdentifier
;
6187 case LOWORD(X509_ECC_SIGNATURE
):
6188 decodeFunc
= CRYPT_AsnDecodeEccSignature
;
6192 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
6193 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6194 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
6195 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6196 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
6197 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6198 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
6199 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6200 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
6201 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6202 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
6203 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6204 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
6205 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6206 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
6207 decodeFunc
= CRYPT_AsnDecodeBits
;
6208 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
6209 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6210 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
6211 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6212 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
6213 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6214 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
6215 decodeFunc
= CRYPT_AsnDecodeAltName
;
6216 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
6217 decodeFunc
= CRYPT_AsnDecodeAltName
;
6218 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
6219 decodeFunc
= CRYPT_AsnDecodeAltName
;
6220 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
6221 decodeFunc
= CRYPT_AsnDecodeAltName
;
6222 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
6223 decodeFunc
= CRYPT_AsnDecodeAltName
;
6224 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
6225 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6226 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
6227 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6228 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
6229 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6230 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
6231 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6232 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
6233 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6234 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
6235 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6236 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
6237 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6238 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
6239 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6240 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
6241 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6242 else if (!strcmp(lpszStructType
, szOID_CTL
))
6243 decodeFunc
= CRYPT_AsnDecodeCTL
;
6244 else if (!strcmp(lpszStructType
, szOID_ECC_PUBLIC_KEY
))
6245 decodeFunc
= CRYPT_AsnDecodeObjectIdentifier
;
6249 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
6250 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6252 static HCRYPTOIDFUNCSET set
= NULL
;
6253 CryptDecodeObjectFunc decodeFunc
= NULL
;
6256 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
6257 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6258 (void **)&decodeFunc
, hFunc
);
6262 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
6263 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6265 static HCRYPTOIDFUNCSET set
= NULL
;
6266 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6269 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
6270 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6271 (void **)&decodeFunc
, hFunc
);
6275 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6276 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
6277 DWORD
*pcbStructInfo
)
6279 return CryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
6280 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
);
6283 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6284 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6285 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6288 CryptDecodeObjectExFunc decodeFunc
;
6289 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6291 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6292 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
6293 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6295 if (!pvStructInfo
&& !pcbStructInfo
)
6297 SetLastError(ERROR_INVALID_PARAMETER
);
6300 if (cbEncoded
> MAX_ENCODED_LEN
)
6302 SetLastError(CRYPT_E_ASN1_LARGE
);
6306 SetLastError(NOERROR
);
6307 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6311 SetLastError(ERROR_INVALID_PARAMETER
);
6314 *(BYTE
**)pvStructInfo
= NULL
;
6316 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
6319 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6320 debugstr_a(lpszStructType
));
6321 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
6325 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
6326 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6329 CryptDecodeObjectFunc pCryptDecodeObject
=
6330 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
6332 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6333 * directly, as that could cause an infinite loop.
6335 if (pCryptDecodeObject
)
6337 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6339 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6340 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
6341 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
6342 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
6344 ret
= pCryptDecodeObject(dwCertEncodingType
,
6345 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
6346 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
6348 CRYPT_FreeSpace(pDecodePara
, *(BYTE
**)pvStructInfo
);
6352 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6353 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6357 CryptFreeOIDFunctionAddress(hFunc
, 0);
6358 TRACE_(crypt
)("returning %d\n", ret
);
6362 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
6366 TRACE_(crypt
)("(%p)\n", pPFX
);
6368 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6369 * version integer of length 1 (3 encoded byes) and at least one other
6370 * datum (two encoded bytes), plus at least two bytes for the outer
6371 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6373 if (pPFX
->cbData
< 7)
6375 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
6379 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
6381 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
6383 /* Need at least three bytes for the integer version */
6384 if (pPFX
->cbData
< 1 + lenLen
+ 3)
6386 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
6387 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
6388 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
6397 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6400 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);
6404 BOOL WINAPI
PFXVerifyPassword(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
6407 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);