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"
43 #include "wine/debug.h"
44 #include "wine/exception.h"
45 #include "crypt32_private.h"
47 /* This is a bit arbitrary, but to set some limit: */
48 #define MAX_ENCODED_LEN 0x04000000
50 #define ASN_FLAGS_MASK 0xe0
51 #define ASN_TYPE_MASK 0x1f
53 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
54 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
56 void CRYPT_CopyReversed(BYTE
*dst
, const BYTE
*src
, size_t len
)
59 for (i
= 0; i
< len
; i
++) {
60 dst
[len
- i
- 1] = src
[i
];
64 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
65 DWORD
, DWORD
, void *, DWORD
*);
66 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
67 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
69 /* Internal decoders don't do memory allocation or exception handling, and
70 * they report how many bytes they decoded.
72 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
73 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
75 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
76 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
78 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
79 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
81 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
83 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
84 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
85 /* Assumes algo->Parameters.pbData is set ahead of time. */
86 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
87 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
88 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
89 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
90 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
91 static BOOL
CRYPT_AsnDecodeOctets(const BYTE
*pbEncoded
,
92 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
94 /* Doesn't check the tag, assumes the caller does so */
95 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
96 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
97 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
98 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
99 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
100 * member has been initialized, doesn't do exception handling, and doesn't do
101 * memory allocation. Also doesn't check tag, assumes the caller has checked
104 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
105 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
107 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
108 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
109 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
111 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
112 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
115 /* Gets the number of length bytes from the given (leading) length byte */
116 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
118 /* Helper function to get the encoded length of the data starting at pbEncoded,
119 * where pbEncoded[0] is the tag. If the data are too short to contain a
120 * length or if the length is too large for cbEncoded, sets an appropriate
121 * error code and returns FALSE. If the encoded length is unknown due to
122 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
124 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
131 SetLastError(CRYPT_E_ASN1_CORRUPT
);
134 else if (pbEncoded
[1] <= 0x7f)
136 if (pbEncoded
[1] + 1 > cbEncoded
)
138 SetLastError(CRYPT_E_ASN1_EOD
);
147 else if (pbEncoded
[1] == 0x80)
149 *len
= CMSG_INDEFINITE_LENGTH
;
154 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
156 if (lenLen
> sizeof(DWORD
) + 1)
158 SetLastError(CRYPT_E_ASN1_LARGE
);
161 else if (lenLen
+ 2 > cbEncoded
)
163 SetLastError(CRYPT_E_ASN1_CORRUPT
);
176 if (out
+ lenLen
+ 1 > cbEncoded
)
178 SetLastError(CRYPT_E_ASN1_EOD
);
191 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
192 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
196 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
197 *len
== CMSG_INDEFINITE_LENGTH
)
199 SetLastError(CRYPT_E_ASN1_CORRUPT
);
205 /* Helper function to check *pcbStructInfo, set it to the required size, and
206 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
207 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
208 * pointer to the newly allocated memory.
210 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
211 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
216 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
218 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
219 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
221 *(BYTE
**)pvStructInfo
= LocalAlloc(LPTR
, bytesNeeded
);
222 if (!*(BYTE
**)pvStructInfo
)
225 *pcbStructInfo
= bytesNeeded
;
227 else if (*pcbStructInfo
< bytesNeeded
)
229 *pcbStructInfo
= bytesNeeded
;
230 SetLastError(ERROR_MORE_DATA
);
234 *pcbStructInfo
= bytesNeeded
;
238 static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA
*pDecodePara
, LPVOID pv
)
240 if (pDecodePara
&& pDecodePara
->pfnFree
)
241 pDecodePara
->pfnFree(pv
);
246 /* Helper function to check *pcbStructInfo and set it to the required size.
247 * Assumes pvStructInfo is not NULL.
249 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
253 if (*pcbStructInfo
< bytesNeeded
)
255 *pcbStructInfo
= bytesNeeded
;
256 SetLastError(ERROR_MORE_DATA
);
261 *pcbStructInfo
= bytesNeeded
;
268 * The expected tag of the item. If tag is 0, decodeFunc is called
269 * regardless of the tag value seen.
271 * A sequence is decoded into a struct. The offset member is the
272 * offset of this item within that struct.
274 * The decoder function to use. If this is NULL, then the member isn't
275 * decoded, but minSize space is reserved for it.
277 * The minimum amount of space occupied after decoding. You must set this.
279 * If true, and the tag doesn't match the expected tag for this item,
280 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
281 * filled with 0 for this member.
282 * hasPointer, pointerOffset:
283 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
284 * the offset within the struct of the data pointer (or to the
285 * first data pointer, if more than one exist).
287 * Used by CRYPT_AsnDecodeSequence, not for your use.
289 struct AsnDecodeSequenceItem
293 InternalDecodeFunc decodeFunc
;
301 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
302 #define MEMBERSIZE(s, member, nextmember) \
303 (offsetof(s, nextmember) - offsetof(s, member))
305 /* Decodes the items in a sequence, where the items are described in items,
306 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
307 * pvStructInfo. nextData is a pointer to the memory location at which the
308 * first decoded item with a dynamic pointer should point.
309 * Upon decoding, *cbDecoded is the total number of bytes decoded.
310 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
312 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
313 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
314 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
317 DWORD i
, decoded
= 0;
318 const BYTE
*ptr
= pbEncoded
;
320 TRACE("%p, %ld, %p, %ld, %08lx, %p, %p, %p\n", items
, cItem
, pbEncoded
,
321 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
323 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
325 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
329 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
330 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
332 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
334 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
336 DWORD itemEncodedLen
;
338 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
339 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
341 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
342 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
344 TRACE("Setting next pointer to %p\n",
346 *(BYTE
**)((BYTE
*)pvStructInfo
+
347 items
[i
].pointerOffset
) = nextData
;
349 if (items
[i
].decodeFunc
)
354 TRACE("decoding item %ld\n", i
);
356 TRACE("sizing item %ld\n", i
);
357 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
358 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
359 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
360 : NULL
, &items
[i
].size
, &itemDecoded
);
363 if (items
[i
].size
< items
[i
].minSize
)
364 items
[i
].size
= items
[i
].minSize
;
365 else if (items
[i
].size
> items
[i
].minSize
)
367 /* Account for alignment padding */
368 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
370 TRACE("item %ld size: %ld\n", i
, items
[i
].size
);
371 if (nextData
&& items
[i
].hasPointer
&&
372 items
[i
].size
> items
[i
].minSize
)
373 nextData
+= items
[i
].size
- items
[i
].minSize
;
374 if (itemDecoded
> itemEncodedLen
)
376 WARN("decoded length %ld exceeds encoded %ld\n",
377 itemDecoded
, itemEncodedLen
);
378 SetLastError(CRYPT_E_ASN1_CORRUPT
);
384 decoded
+= itemDecoded
;
385 TRACE("item %ld: decoded %ld bytes\n", i
,
389 else if (items
[i
].optional
&&
390 GetLastError() == CRYPT_E_ASN1_BADTAG
)
392 TRACE("skipping optional item %ld\n", i
);
393 items
[i
].size
= items
[i
].minSize
;
394 SetLastError(NOERROR
);
398 TRACE("item %ld failed: %08lx\n", i
,
401 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
403 ERR("can't use indefinite length encoding without a decoder\n");
404 SetLastError(CRYPT_E_ASN1_CORRUPT
);
409 TRACE("item %ld: decoded %ld bytes\n", i
, itemEncodedLen
);
410 ptr
+= itemEncodedLen
;
411 decoded
+= itemEncodedLen
;
412 items
[i
].size
= items
[i
].minSize
;
415 else if (items
[i
].optional
)
417 TRACE("skipping optional item %ld\n", i
);
418 items
[i
].size
= items
[i
].minSize
;
422 TRACE("item %ld: tag %02x doesn't match expected %02x\n",
423 i
, ptr
[0], items
[i
].tag
);
424 SetLastError(CRYPT_E_ASN1_BADTAG
);
429 else if (items
[i
].optional
)
431 TRACE("missing optional item %ld, skipping\n", i
);
432 items
[i
].size
= items
[i
].minSize
;
436 TRACE("not enough bytes for item %ld, failing\n", i
);
437 SetLastError(CRYPT_E_ASN1_CORRUPT
);
442 *cbDecoded
= decoded
;
443 TRACE("returning %d\n", ret
);
447 /* This decodes an arbitrary sequence into a contiguous block of memory
448 * (basically, a struct.) Each element being decoded is described by a struct
449 * AsnDecodeSequenceItem, see above.
450 * startingPointer is an optional pointer to the first place where dynamic
451 * data will be stored. If you know the starting offset, you may pass it
452 * here. Otherwise, pass NULL, and one will be inferred from the items.
454 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
455 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
456 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
457 DWORD
*pcbDecoded
, void *startingPointer
)
461 TRACE("%p, %ld, %p, %ld, %08lx, %p, %p, %ld, %p\n", items
, cItem
, pbEncoded
,
462 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
467 SetLastError(CRYPT_E_ASN1_EOD
);
470 if (pbEncoded
[0] == ASN_SEQUENCE
)
474 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
476 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
477 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
478 BOOL indefinite
= FALSE
;
480 cbEncoded
-= 1 + lenBytes
;
481 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
487 else if (cbEncoded
< dataLen
)
489 TRACE("dataLen %ld exceeds cbEncoded %ld, failing\n", dataLen
,
491 SetLastError(CRYPT_E_ASN1_CORRUPT
);
496 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
497 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
498 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
500 if (cbDecoded
> cbEncoded
- 2)
502 /* Not enough space for 0 TLV */
503 SetLastError(CRYPT_E_ASN1_CORRUPT
);
506 else if (*(ptr
+ cbDecoded
) != 0 ||
507 *(ptr
+ cbDecoded
+ 1) != 0)
509 TRACE("expected 0 TLV\n");
510 SetLastError(CRYPT_E_ASN1_CORRUPT
);
517 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
519 TRACE("expected %ld decoded, got %ld, failing\n", dataLen
,
521 SetLastError(CRYPT_E_ASN1_CORRUPT
);
526 DWORD i
, bytesNeeded
= 0, structSize
= 0;
528 for (i
= 0; i
< cItem
; i
++)
530 if (items
[i
].size
> items
[i
].minSize
)
531 bytesNeeded
+= items
[i
].size
- items
[i
].minSize
;
532 structSize
= max( structSize
, items
[i
].offset
+ items
[i
].minSize
);
534 bytesNeeded
+= structSize
;
536 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
538 *pcbStructInfo
= bytesNeeded
;
539 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
540 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
544 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
545 pvStructInfo
= *(BYTE
**)pvStructInfo
;
547 nextData
= startingPointer
;
549 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
550 memset(pvStructInfo
, 0, structSize
);
551 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
552 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
554 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
555 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
562 SetLastError(CRYPT_E_ASN1_BADTAG
);
565 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
570 * The expected tag of the entire encoded array (usually a variant
571 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
572 * regardless of the tag seen.
574 * The offset within the outer structure at which the count exists.
575 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
576 * while CRYPT_ATTRIBUTE has countOffset ==
577 * offsetof(CRYPT_ATTRIBUTE, cValue).
579 * The offset within the outer structure at which the array pointer exists.
580 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
581 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
583 * The minimum size of the decoded array. On WIN32, this is always 8:
584 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
587 * used to decode each item in the array
589 * is the minimum size of each decoded item
591 * indicates whether each item has a dynamic pointer
593 * indicates the offset within itemSize at which the pointer exists
595 struct AsnArrayDescriptor
601 InternalDecodeFunc decodeFunc
;
607 struct AsnArrayItemSize
613 /* Decodes an array of like types into a structure described by a struct
614 * AsnArrayDescriptor.
616 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
617 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
618 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
623 TRACE("%p, %p, %ld, %p, %ld\n", arrayDesc
, pbEncoded
,
624 cbEncoded
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
628 SetLastError(CRYPT_E_ASN1_EOD
);
631 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
635 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
637 DWORD bytesNeeded
= arrayDesc
->minArraySize
, cItems
= 0, capacity
= 0, decoded
;
638 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
639 /* There can be arbitrarily many items, but there is often only one.
641 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
643 decoded
= 1 + lenBytes
;
647 BOOL doneDecoding
= FALSE
;
649 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
651 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
658 SetLastError(CRYPT_E_ASN1_CORRUPT
);
665 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
669 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
671 /* Each item decoded may not tolerate extraneous bytes,
672 * so get the length of the next element if known.
674 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
675 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
677 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
678 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
680 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
684 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
685 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
689 /* Ignore an item that failed to decode but the decoder doesn't want to fail the whole process */
697 itemSizes
= &itemSize
;
698 else if (itemSizes
== &itemSize
)
701 itemSizes
= CryptMemAlloc(capacity
* sizeof(struct AsnArrayItemSize
));
702 if (itemSizes
) *itemSizes
= itemSize
;
704 else if (cItems
> capacity
)
706 capacity
= capacity
* 3 / 2;
707 itemSizes
= CryptMemRealloc(itemSizes
, capacity
* sizeof(struct AsnArrayItemSize
));
711 decoded
+= itemDecoded
;
712 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
713 itemSizes
[cItems
- 1].size
= size
;
726 *pcbDecoded
= decoded
;
728 *pcbStructInfo
= bytesNeeded
;
729 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
730 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
737 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
738 pvStructInfo
= *(void **)pvStructInfo
;
739 pcItems
= pvStructInfo
;
741 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
743 rgItems
= (BYTE
*)pvStructInfo
+
744 arrayDesc
->minArraySize
;
745 *(void **)((BYTE
*)pcItems
-
746 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
) =
750 rgItems
= *(void **)((BYTE
*)pcItems
-
751 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
);
752 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
753 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
754 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
759 if (arrayDesc
->hasPointer
)
760 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
761 + arrayDesc
->pointerOffset
) = nextData
;
762 ret
= arrayDesc
->decodeFunc(ptr
,
763 itemSizes
[i
].encodedLen
,
764 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
765 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
766 &itemSizes
[i
].size
, &itemDecoded
);
769 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
773 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
774 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
777 if (itemSizes
!= &itemSize
)
778 CryptMemFree(itemSizes
);
783 SetLastError(CRYPT_E_ASN1_BADTAG
);
789 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
790 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
791 * to CRYPT_E_ASN1_CORRUPT.
792 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
795 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
796 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
801 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
803 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
804 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
806 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
807 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
810 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
812 *pcbStructInfo
= bytesNeeded
;
813 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
815 CRYPT_DER_BLOB
*blob
;
817 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
818 pvStructInfo
= *(BYTE
**)pvStructInfo
;
820 blob
->cbData
= 1 + lenBytes
+ dataLen
;
823 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
824 blob
->pbData
= (BYTE
*)pbEncoded
;
827 assert(blob
->pbData
);
828 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
833 SetLastError(CRYPT_E_ASN1_CORRUPT
);
841 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
842 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
843 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
848 TRACE("(%p, %ld, 0x%08lx, %p, %ld, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
849 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
851 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
854 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
855 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
857 if (ret
&& pvStructInfo
)
859 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
866 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
868 temp
= blob
->pbData
[i
];
869 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
870 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
874 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
878 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
879 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
880 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
884 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
885 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
889 struct AsnDecodeSequenceItem items
[] = {
890 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
891 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
892 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
893 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
894 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
895 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
896 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
897 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
898 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
899 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
902 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
903 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
904 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
905 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
906 pcbStructInfo
, NULL
, NULL
);
910 SetLastError(STATUS_ACCESS_VIOLATION
);
915 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
919 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
920 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
925 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
927 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
929 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
930 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
932 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
937 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
938 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
942 struct AsnDecodeSequenceItem items
[] = {
943 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
944 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
945 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
946 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
949 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
950 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
955 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
956 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
960 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
961 offsetof(CERT_INFO
, cExtension
), offsetof(CERT_INFO
, rgExtension
),
962 FINALMEMBERSIZE(CERT_INFO
, cExtension
),
963 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
964 offsetof(CERT_EXTENSION
, pszObjId
) };
966 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
967 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
969 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
970 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
974 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
975 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
981 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
983 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
985 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
986 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
987 if (ret
&& pcbDecoded
)
988 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
993 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
994 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
995 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
998 struct AsnDecodeSequenceItem items
[] = {
999 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
1000 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1001 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
1002 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
1003 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
1004 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
1005 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1006 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1007 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1008 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1010 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
1011 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
1013 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
1014 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1016 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
1017 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
1018 FALSE
, TRUE
, offsetof(CERT_INFO
,
1019 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
1020 { ASN_CONTEXT
| 1, offsetof(CERT_INFO
, IssuerUniqueId
),
1021 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1022 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
1023 { ASN_CONTEXT
| 2, offsetof(CERT_INFO
, SubjectUniqueId
),
1024 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1025 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
1026 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
1027 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
1028 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1031 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1032 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1034 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1035 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1037 if (ret
&& pvStructInfo
)
1041 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1042 info
= *(CERT_INFO
**)pvStructInfo
;
1044 info
= pvStructInfo
;
1045 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1046 !info
->Subject
.cbData
)
1048 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1049 /* Don't need to deallocate, because it should have failed on the
1050 * first pass (and no memory was allocated.)
1056 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1060 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1061 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1062 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1066 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1067 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1073 /* Unless told not to, first try to decode it as a signed cert. */
1074 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1076 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1078 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1079 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1080 &signedCert
, &size
);
1084 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1085 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1086 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1087 pvStructInfo
, pcbStructInfo
);
1088 LocalFree(signedCert
);
1091 /* Failing that, try it as an unsigned cert */
1095 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1096 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1097 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1102 SetLastError(STATUS_ACCESS_VIOLATION
);
1106 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1110 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1111 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1115 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1116 offsetof(CRL_ENTRY
, cExtension
), offsetof(CRL_ENTRY
, rgExtension
),
1117 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
),
1118 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1119 offsetof(CERT_EXTENSION
, pszObjId
) };
1121 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1122 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1124 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1125 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1129 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1130 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1133 struct AsnDecodeSequenceItem items
[] = {
1134 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1135 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1136 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1137 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1138 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1139 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1140 CRYPT_AsnDecodeCRLEntryExtensions
,
1141 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1142 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1144 PCRL_ENTRY entry
= pvStructInfo
;
1146 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1149 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1150 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1151 entry
? entry
->SerialNumber
.pbData
: NULL
);
1152 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1154 WARN("empty CRL entry serial number\n");
1155 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1161 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1162 * whose rgCRLEntry member has been set prior to calling.
1164 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1165 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1168 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1169 offsetof(CRL_INFO
, cCRLEntry
), offsetof(CRL_INFO
, rgCRLEntry
),
1170 MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1171 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1172 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1174 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1175 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1177 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1178 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1179 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1183 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1184 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1188 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1189 offsetof(CRL_INFO
, cExtension
), offsetof(CRL_INFO
, rgExtension
),
1190 FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1191 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1192 offsetof(CERT_EXTENSION
, pszObjId
) };
1194 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1195 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1197 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1198 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1202 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1203 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1209 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1211 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1213 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1214 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1215 if (ret
&& pcbDecoded
)
1216 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1221 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1222 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1223 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1225 struct AsnDecodeSequenceItem items
[] = {
1226 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1227 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1228 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1229 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1230 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1231 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1232 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1234 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1235 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1236 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1237 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1238 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1239 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1240 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1241 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1242 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1243 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1247 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1248 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1250 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
), pbEncoded
, cbEncoded
, dwFlags
,
1251 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1253 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1257 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1258 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1259 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1263 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1264 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1270 /* Unless told not to, first try to decode it as a signed crl. */
1271 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1273 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1275 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1276 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1281 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1282 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1283 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1284 pvStructInfo
, pcbStructInfo
);
1285 LocalFree(signedCrl
);
1288 /* Failing that, try it as an unsigned crl */
1292 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1293 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1294 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1299 SetLastError(STATUS_ACCESS_VIOLATION
);
1303 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1307 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1308 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1313 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1314 pvStructInfo
, *pcbStructInfo
);
1316 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1318 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1319 DWORD bytesNeeded
= sizeof(LPSTR
);
1326 snprintf(str
, sizeof(str
), "%d.%d",
1327 pbEncoded
[1 + lenBytes
] / 40,
1328 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1330 bytesNeeded
+= strlen(str
) + 1;
1331 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1332 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1336 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1343 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1346 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1353 snprintf(str
, sizeof(str
), ".%d", val
);
1354 bytesNeeded
+= strlen(str
);
1359 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1361 *pcbStructInfo
= bytesNeeded
;
1362 else if (*pcbStructInfo
< bytesNeeded
)
1364 *pcbStructInfo
= bytesNeeded
;
1365 SetLastError(ERROR_MORE_DATA
);
1373 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1376 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1377 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1379 pszObjId
+= strlen(pszObjId
);
1380 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1381 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1385 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1394 sprintf(pszObjId
, ".%d", val
);
1395 pszObjId
+= strlen(pszObjId
);
1399 *(LPSTR
*)pvStructInfo
= NULL
;
1400 *pcbStructInfo
= bytesNeeded
;
1406 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1407 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1411 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1412 pvStructInfo
, *pcbStructInfo
);
1414 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1415 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1416 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1419 SetLastError(CRYPT_E_ASN1_BADTAG
);
1425 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1426 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1428 struct AsnDecodeSequenceItem items
[] = {
1429 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1430 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1431 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1432 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1433 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1434 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1435 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1436 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1439 PCERT_EXTENSION ext
= pvStructInfo
;
1441 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1445 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1446 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1447 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1448 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1450 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1451 debugstr_a(ext
->pszObjId
));
1452 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1456 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1457 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1458 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1462 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1463 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1467 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1468 offsetof(CERT_EXTENSIONS
, cExtension
),
1469 offsetof(CERT_EXTENSIONS
, rgExtension
),
1470 sizeof(CERT_EXTENSIONS
),
1471 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1472 offsetof(CERT_EXTENSION
, pszObjId
) };
1473 CERT_EXTENSIONS
*exts
= pvStructInfo
;
1475 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1476 exts
->rgExtension
= (CERT_EXTENSION
*)(exts
+ 1);
1477 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1478 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1482 SetLastError(STATUS_ACCESS_VIOLATION
);
1489 /* Warning: this assumes the address of value->Value.pbData is already set, in
1490 * order to avoid overwriting memory. (In some cases, it may change it, if it
1491 * doesn't copy anything to memory.) Be sure to set it correctly!
1493 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1494 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1499 CERT_NAME_VALUE
*value
= pvStructInfo
;
1501 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1503 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1504 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1506 switch (pbEncoded
[0])
1508 case ASN_OCTETSTRING
:
1509 valueType
= CERT_RDN_OCTET_STRING
;
1510 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1511 bytesNeeded
+= dataLen
;
1513 case ASN_NUMERICSTRING
:
1514 valueType
= CERT_RDN_NUMERIC_STRING
;
1515 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1516 bytesNeeded
+= dataLen
;
1518 case ASN_PRINTABLESTRING
:
1519 valueType
= CERT_RDN_PRINTABLE_STRING
;
1520 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1521 bytesNeeded
+= dataLen
;
1524 valueType
= CERT_RDN_IA5_STRING
;
1525 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1526 bytesNeeded
+= dataLen
;
1529 valueType
= CERT_RDN_T61_STRING
;
1530 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1531 bytesNeeded
+= dataLen
;
1533 case ASN_VIDEOTEXSTRING
:
1534 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1535 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1536 bytesNeeded
+= dataLen
;
1538 case ASN_GRAPHICSTRING
:
1539 valueType
= CERT_RDN_GRAPHIC_STRING
;
1540 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1541 bytesNeeded
+= dataLen
;
1543 case ASN_VISIBLESTRING
:
1544 valueType
= CERT_RDN_VISIBLE_STRING
;
1545 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1546 bytesNeeded
+= dataLen
;
1548 case ASN_GENERALSTRING
:
1549 valueType
= CERT_RDN_GENERAL_STRING
;
1550 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1551 bytesNeeded
+= dataLen
;
1553 case ASN_UNIVERSALSTRING
:
1554 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1555 SetLastError(CRYPT_E_ASN1_BADTAG
);
1558 valueType
= CERT_RDN_BMP_STRING
;
1559 bytesNeeded
+= dataLen
;
1561 case ASN_UTF8STRING
:
1562 valueType
= CERT_RDN_UTF8_STRING
;
1563 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1564 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * sizeof(WCHAR
);
1567 SetLastError(CRYPT_E_ASN1_BADTAG
);
1572 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1574 *pcbStructInfo
= bytesNeeded
;
1575 else if (*pcbStructInfo
< bytesNeeded
)
1577 *pcbStructInfo
= bytesNeeded
;
1578 SetLastError(ERROR_MORE_DATA
);
1583 *pcbStructInfo
= bytesNeeded
;
1584 value
->dwValueType
= valueType
;
1589 assert(value
->Value
.pbData
);
1590 switch (pbEncoded
[0])
1592 case ASN_OCTETSTRING
:
1593 case ASN_NUMERICSTRING
:
1594 case ASN_PRINTABLESTRING
:
1597 case ASN_VIDEOTEXSTRING
:
1598 case ASN_GRAPHICSTRING
:
1599 case ASN_VISIBLESTRING
:
1600 case ASN_GENERALSTRING
:
1601 value
->Value
.cbData
= dataLen
;
1602 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1603 memcpy(value
->Value
.pbData
,
1604 pbEncoded
+ 1 + lenBytes
, dataLen
);
1606 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1611 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1613 value
->Value
.cbData
= dataLen
;
1614 for (i
= 0; i
< dataLen
/ 2; i
++)
1615 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1616 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1619 case ASN_UTF8STRING
:
1621 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1623 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1624 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1625 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1632 value
->Value
.cbData
= 0;
1633 value
->Value
.pbData
= NULL
;
1640 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1641 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1642 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1648 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1649 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1650 if (ret
&& pvStructInfo
)
1652 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1653 pcbStructInfo
, *pcbStructInfo
);
1656 CERT_NAME_VALUE
*value
;
1658 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1659 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1660 value
= pvStructInfo
;
1661 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1662 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1663 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1664 pcbStructInfo
, NULL
);
1665 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1666 CRYPT_FreeSpace(pDecodePara
, value
);
1672 SetLastError(STATUS_ACCESS_VIOLATION
);
1679 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1680 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1685 CERT_NAME_VALUE
*value
= pvStructInfo
;
1687 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1689 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1690 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1692 switch (pbEncoded
[0])
1694 case ASN_NUMERICSTRING
:
1695 valueType
= CERT_RDN_NUMERIC_STRING
;
1697 bytesNeeded
+= (dataLen
+ 1) * 2;
1699 case ASN_PRINTABLESTRING
:
1700 valueType
= CERT_RDN_PRINTABLE_STRING
;
1702 bytesNeeded
+= (dataLen
+ 1) * 2;
1705 valueType
= CERT_RDN_IA5_STRING
;
1707 bytesNeeded
+= (dataLen
+ 1) * 2;
1710 valueType
= CERT_RDN_T61_STRING
;
1712 bytesNeeded
+= (dataLen
+ 1) * 2;
1714 case ASN_VIDEOTEXSTRING
:
1715 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1717 bytesNeeded
+= (dataLen
+ 1) * 2;
1719 case ASN_GRAPHICSTRING
:
1720 valueType
= CERT_RDN_GRAPHIC_STRING
;
1722 bytesNeeded
+= (dataLen
+ 1) * 2;
1724 case ASN_VISIBLESTRING
:
1725 valueType
= CERT_RDN_VISIBLE_STRING
;
1727 bytesNeeded
+= (dataLen
+ 1) * 2;
1729 case ASN_GENERALSTRING
:
1730 valueType
= CERT_RDN_GENERAL_STRING
;
1732 bytesNeeded
+= (dataLen
+ 1) * 2;
1734 case ASN_UNIVERSALSTRING
:
1735 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1737 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1740 valueType
= CERT_RDN_BMP_STRING
;
1742 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1744 case ASN_UTF8STRING
:
1745 valueType
= CERT_RDN_UTF8_STRING
;
1747 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1748 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1751 SetLastError(CRYPT_E_ASN1_BADTAG
);
1756 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1758 *pcbStructInfo
= bytesNeeded
;
1759 else if (*pcbStructInfo
< bytesNeeded
)
1761 *pcbStructInfo
= bytesNeeded
;
1762 SetLastError(ERROR_MORE_DATA
);
1767 *pcbStructInfo
= bytesNeeded
;
1768 value
->dwValueType
= valueType
;
1772 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1774 assert(value
->Value
.pbData
);
1775 switch (pbEncoded
[0])
1777 case ASN_NUMERICSTRING
:
1778 case ASN_PRINTABLESTRING
:
1781 case ASN_VIDEOTEXSTRING
:
1782 case ASN_GRAPHICSTRING
:
1783 case ASN_VISIBLESTRING
:
1784 case ASN_GENERALSTRING
:
1785 value
->Value
.cbData
= dataLen
* 2;
1786 for (i
= 0; i
< dataLen
; i
++)
1787 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1790 case ASN_UNIVERSALSTRING
:
1791 value
->Value
.cbData
= dataLen
/ 2;
1792 for (i
= 0; i
< dataLen
/ 4; i
++)
1793 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1794 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1798 value
->Value
.cbData
= dataLen
;
1799 for (i
= 0; i
< dataLen
/ 2; i
++)
1800 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1801 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1804 case ASN_UTF8STRING
:
1805 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1806 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1807 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1808 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1809 value
->Value
.cbData
+= sizeof(WCHAR
);
1815 value
->Value
.cbData
= 0;
1816 value
->Value
.pbData
= NULL
;
1823 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1824 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1825 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1831 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1832 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1833 if (ret
&& pvStructInfo
)
1835 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1836 pcbStructInfo
, *pcbStructInfo
);
1839 CERT_NAME_VALUE
*value
;
1841 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1842 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1843 value
= pvStructInfo
;
1844 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1845 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1846 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1847 pcbStructInfo
, NULL
);
1848 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1849 CRYPT_FreeSpace(pDecodePara
, value
);
1855 SetLastError(STATUS_ACCESS_VIOLATION
);
1862 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1863 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1866 struct AsnDecodeSequenceItem items
[] = {
1867 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1868 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1869 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1870 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1871 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1872 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1874 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1876 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1877 pvStructInfo
, *pcbStructInfo
);
1880 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1881 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1882 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1883 attr
? attr
->pszObjId
: NULL
);
1886 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1887 debugstr_a(attr
->pszObjId
));
1888 TRACE("attr->dwValueType is %ld\n", attr
->dwValueType
);
1890 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1894 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1895 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1898 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1899 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1901 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1902 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1904 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1905 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1909 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1910 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1911 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1917 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1918 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1919 sizeof(CERT_NAME_INFO
),
1920 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1921 offsetof(CERT_RDN
, rgRDNAttr
) };
1922 DWORD bytesNeeded
= 0;
1924 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1925 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1930 *pcbStructInfo
= bytesNeeded
;
1931 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1932 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1934 CERT_NAME_INFO
*info
;
1936 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1937 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1938 info
= pvStructInfo
;
1939 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1940 sizeof(CERT_NAME_INFO
));
1941 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1942 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1943 &bytesNeeded
, NULL
);
1944 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1945 CRYPT_FreeSpace(pDecodePara
, info
);
1951 SetLastError(STATUS_ACCESS_VIOLATION
);
1958 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1959 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1963 struct AsnDecodeSequenceItem items
[] = {
1964 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1965 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1966 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1967 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1968 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1969 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1971 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1973 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1974 pvStructInfo
, *pcbStructInfo
);
1977 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1978 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1979 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1980 attr
? attr
->pszObjId
: NULL
);
1983 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1984 debugstr_a(attr
->pszObjId
));
1985 TRACE("attr->dwValueType is %ld\n", attr
->dwValueType
);
1987 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1991 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1992 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1995 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1996 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1998 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1999 offsetof(CERT_RDN_ATTR
, pszObjId
) };
2001 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2002 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2006 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
2007 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2008 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2014 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2015 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2016 sizeof(CERT_NAME_INFO
),
2017 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2018 offsetof(CERT_RDN
, rgRDNAttr
) };
2019 DWORD bytesNeeded
= 0;
2021 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2022 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2027 *pcbStructInfo
= bytesNeeded
;
2028 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2029 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2031 CERT_NAME_INFO
*info
;
2033 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2034 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2035 info
= pvStructInfo
;
2036 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2037 sizeof(CERT_NAME_INFO
));
2038 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2039 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2040 &bytesNeeded
, NULL
);
2041 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2042 CRYPT_FreeSpace(pDecodePara
, info
);
2048 SetLastError(STATUS_ACCESS_VIOLATION
);
2055 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2058 BOOL ret
= TRUE
, done
= FALSE
;
2059 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2061 TRACE("(%p, %ld)\n", pbEncoded
, cbEncoded
);
2068 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2071 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2073 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2075 indefiniteNestingLevels
++;
2076 pbEncoded
+= 1 + lenBytes
;
2077 cbEncoded
-= 1 + lenBytes
;
2078 decoded
+= 1 + lenBytes
;
2079 TRACE("indefiniteNestingLevels = %ld\n",
2080 indefiniteNestingLevels
);
2084 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2085 indefiniteNestingLevels
)
2087 indefiniteNestingLevels
--;
2088 TRACE("indefiniteNestingLevels = %ld\n",
2089 indefiniteNestingLevels
);
2091 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2092 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2093 decoded
+= 1 + lenBytes
+ dataLen
;
2094 if (!indefiniteNestingLevels
)
2098 } while (ret
&& !done
);
2099 /* If we haven't found all 0 TLVs, we haven't found the end */
2100 if (ret
&& indefiniteNestingLevels
)
2102 SetLastError(CRYPT_E_ASN1_EOD
);
2106 *pcbDecoded
= decoded
;
2107 TRACE("returning %d (%ld)\n", ret
, ret
? *pcbDecoded
: 0);
2111 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2112 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2116 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2118 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2119 pvStructInfo
, *pcbStructInfo
);
2121 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2123 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2124 bytesNeeded
+= encodedLen
;
2126 *pcbStructInfo
= bytesNeeded
;
2127 else if (*pcbStructInfo
< bytesNeeded
)
2129 SetLastError(ERROR_MORE_DATA
);
2130 *pcbStructInfo
= bytesNeeded
;
2135 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2137 *pcbStructInfo
= bytesNeeded
;
2138 blob
->cbData
= encodedLen
;
2141 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2142 blob
->pbData
= (LPBYTE
)pbEncoded
;
2145 assert(blob
->pbData
);
2146 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2150 blob
->pbData
= NULL
;
2153 *pcbDecoded
= encodedLen
;
2158 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2159 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2162 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2163 offsetof(CTL_USAGE
, cUsageIdentifier
),
2164 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2166 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2168 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2169 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2173 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2174 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2177 struct AsnArrayDescriptor arrayDesc
= { 0,
2178 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2179 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2180 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2181 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2184 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2185 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2189 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2190 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2192 struct AsnDecodeSequenceItem items
[] = {
2193 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2194 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2195 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2196 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2197 CRYPT_AsnDecodeCTLEntryAttributes
,
2198 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2199 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2202 CTL_ENTRY
*entry
= pvStructInfo
;
2204 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2207 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2208 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2209 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2213 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2214 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2217 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2218 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2219 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2220 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2221 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2223 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2224 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2226 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2227 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2231 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2232 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2236 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2237 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2238 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2239 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2240 offsetof(CERT_EXTENSION
, pszObjId
) };
2242 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2243 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2245 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2246 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2250 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2251 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2257 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2259 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2261 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2262 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2263 if (ret
&& pcbDecoded
)
2264 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2269 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2270 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2271 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2275 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2276 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2280 struct AsnDecodeSequenceItem items
[] = {
2281 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2282 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2283 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2284 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2285 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2286 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2287 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2288 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2289 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2290 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2291 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2292 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2293 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2295 { 0, offsetof(CTL_INFO
, NextUpdate
),
2296 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2298 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2299 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2300 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2301 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2302 CRYPT_AsnDecodeCTLEntries
,
2303 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2304 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2305 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2306 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2307 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2310 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2311 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2312 pcbStructInfo
, NULL
, NULL
);
2316 SetLastError(STATUS_ACCESS_VIOLATION
);
2322 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2323 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2327 struct AsnDecodeSequenceItem items
[] = {
2328 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2329 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2330 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2331 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2332 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2333 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2335 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2337 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2338 pvStructInfo
, *pcbStructInfo
);
2340 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2341 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2342 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2343 TRACE("returning %d\n", ret
);
2347 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2348 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2349 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2353 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2354 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2358 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2359 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2360 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2361 sizeof(CRYPT_SMIME_CAPABILITIES
),
2362 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2363 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2364 CRYPT_SMIME_CAPABILITIES
*capabilities
= pvStructInfo
;
2366 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2367 capabilities
->rgCapability
= (CRYPT_SMIME_CAPABILITY
*)(capabilities
+ 1);
2368 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2369 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2373 SetLastError(STATUS_ACCESS_VIOLATION
);
2376 TRACE("returning %d\n", ret
);
2380 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2381 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2386 LPSTR
*pStr
= pvStructInfo
;
2388 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2390 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2391 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2393 if (pbEncoded
[0] != ASN_IA5STRING
)
2395 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2400 bytesNeeded
+= dataLen
;
2402 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2404 *pcbStructInfo
= bytesNeeded
;
2405 else if (*pcbStructInfo
< bytesNeeded
)
2407 *pcbStructInfo
= bytesNeeded
;
2408 SetLastError(ERROR_MORE_DATA
);
2413 *pcbStructInfo
= bytesNeeded
;
2419 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2430 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2431 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2434 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2435 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2436 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2437 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2438 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2441 TRACE("(%p, %ld, %08lx, %p, %ld)\n", pbEncoded
, cbEncoded
, dwFlags
,
2442 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2444 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2445 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2446 TRACE("returning %d\n", ret
);
2450 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2451 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2455 struct AsnDecodeSequenceItem items
[] = {
2456 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2457 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2458 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2459 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2460 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2461 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2462 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2463 rgNoticeNumbers
), 0 },
2465 DWORD bytesNeeded
= 0;
2467 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2468 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2470 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2471 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2475 /* The caller is expecting a pointer to a
2476 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2477 * CRYPT_AsnDecodeSequence is decoding a
2478 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2479 * needed, and decode again if the requisite space is available.
2481 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2483 *pcbStructInfo
= bytesNeeded
;
2484 else if (*pcbStructInfo
< bytesNeeded
)
2486 *pcbStructInfo
= bytesNeeded
;
2487 SetLastError(ERROR_MORE_DATA
);
2492 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2494 *pcbStructInfo
= bytesNeeded
;
2495 /* The pointer (pvStructInfo) passed in points to the first dynamic
2496 * pointer, so use it as the pointer to the
2497 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2498 * appropriate offset for the first dynamic pointer within the
2499 * notice reference by pointing to the first memory location past
2500 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2503 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2504 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2505 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2506 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
), pbEncoded
, cbEncoded
, dwFlags
,
2507 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
, noticeRef
->pszOrganization
);
2510 TRACE("returning %d\n", ret
);
2514 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2515 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2521 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2523 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2524 DWORD bytesNeeded
= sizeof(LPWSTR
);
2526 switch (pbEncoded
[0])
2528 case ASN_NUMERICSTRING
:
2530 bytesNeeded
+= (dataLen
+ 1) * 2;
2532 case ASN_PRINTABLESTRING
:
2534 bytesNeeded
+= (dataLen
+ 1) * 2;
2538 bytesNeeded
+= (dataLen
+ 1) * 2;
2542 bytesNeeded
+= (dataLen
+ 1) * 2;
2544 case ASN_VIDEOTEXSTRING
:
2546 bytesNeeded
+= (dataLen
+ 1) * 2;
2548 case ASN_GRAPHICSTRING
:
2550 bytesNeeded
+= (dataLen
+ 1) * 2;
2552 case ASN_VISIBLESTRING
:
2554 bytesNeeded
+= (dataLen
+ 1) * 2;
2556 case ASN_GENERALSTRING
:
2558 bytesNeeded
+= (dataLen
+ 1) * 2;
2560 case ASN_UNIVERSALSTRING
:
2562 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2566 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2568 case ASN_UTF8STRING
:
2570 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2571 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2574 SetLastError(CRYPT_E_ASN1_BADTAG
);
2579 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2581 *pcbStructInfo
= bytesNeeded
;
2582 else if (*pcbStructInfo
< bytesNeeded
)
2584 *pcbStructInfo
= bytesNeeded
;
2585 SetLastError(ERROR_MORE_DATA
);
2590 LPWSTR
*pStr
= pvStructInfo
;
2592 *pcbStructInfo
= bytesNeeded
;
2599 switch (pbEncoded
[0])
2601 case ASN_NUMERICSTRING
:
2602 case ASN_PRINTABLESTRING
:
2605 case ASN_VIDEOTEXSTRING
:
2606 case ASN_GRAPHICSTRING
:
2607 case ASN_VISIBLESTRING
:
2608 case ASN_GENERALSTRING
:
2609 for (i
= 0; i
< dataLen
; i
++)
2610 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2613 case ASN_UNIVERSALSTRING
:
2614 for (i
= 0; i
< dataLen
/ 4; i
++)
2615 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2616 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2620 for (i
= 0; i
< dataLen
/ 2; i
++)
2621 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2622 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2625 case ASN_UTF8STRING
:
2627 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2628 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2629 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2642 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2643 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2644 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2647 struct AsnDecodeSequenceItem items
[] = {
2648 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2649 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2650 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2651 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2652 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2653 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2654 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2656 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2658 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2659 pvStructInfo
, *pcbStructInfo
);
2661 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2662 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2663 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2664 TRACE("returning %d\n", ret
);
2668 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2669 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2670 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2671 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2675 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2676 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2680 DWORD bytesNeeded
= 0;
2682 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2683 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2688 *pcbStructInfo
= bytesNeeded
;
2689 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2690 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2692 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2694 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2695 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2696 notice
= pvStructInfo
;
2697 notice
->pNoticeReference
=
2698 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2699 ((BYTE
*)pvStructInfo
+
2700 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2701 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2702 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2703 pvStructInfo
, &bytesNeeded
, NULL
);
2704 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2705 CRYPT_FreeSpace(pDecodePara
, notice
);
2711 SetLastError(STATUS_ACCESS_VIOLATION
);
2714 TRACE("returning %d\n", ret
);
2718 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2719 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2723 struct AsnArrayDescriptor arrayDesc
= { 0,
2724 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2725 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2726 CRYPT_AsnDecodeCopyBytes
,
2727 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2729 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2730 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2732 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2733 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2737 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2738 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2742 struct AsnDecodeSequenceItem items
[] = {
2743 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2744 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2745 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2746 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2747 CRYPT_AsnDecodePKCSAttributeValue
,
2748 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2749 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2751 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2753 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2754 pvStructInfo
, *pcbStructInfo
);
2756 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2757 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2758 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2759 TRACE("returning %d\n", ret
);
2763 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2764 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2765 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2769 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2770 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2774 DWORD bytesNeeded
= 0;
2776 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2777 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2781 *pcbStructInfo
= bytesNeeded
;
2782 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2783 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2785 PCRYPT_ATTRIBUTE attr
;
2787 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2788 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2789 attr
= pvStructInfo
;
2790 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2791 sizeof(CRYPT_ATTRIBUTE
));
2792 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2793 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2795 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2796 CRYPT_FreeSpace(pDecodePara
, attr
);
2802 SetLastError(STATUS_ACCESS_VIOLATION
);
2805 TRACE("returning %d\n", ret
);
2809 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2810 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2813 struct AsnArrayDescriptor arrayDesc
= { 0,
2814 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2815 sizeof(CRYPT_ATTRIBUTES
),
2816 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2817 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2820 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2821 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2825 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2826 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2827 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2831 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2832 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2836 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2837 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2838 sizeof(CRYPT_ATTRIBUTES
),
2839 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2840 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2841 CRYPT_ATTRIBUTES
*attrs
= pvStructInfo
;
2843 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2844 attrs
->rgAttr
= (CRYPT_ATTRIBUTE
*)(attrs
+ 1);
2845 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2846 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2850 SetLastError(STATUS_ACCESS_VIOLATION
);
2853 TRACE("returning %d\n", ret
);
2857 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2858 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2860 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2862 struct AsnDecodeSequenceItem items
[] = {
2863 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2864 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2865 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2866 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2867 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2868 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2871 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2872 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2874 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2875 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2876 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2877 if (ret
&& pvStructInfo
)
2879 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2880 debugstr_a(algo
->pszObjId
));
2885 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2886 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2890 struct AsnDecodeSequenceItem items
[] = {
2891 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2892 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2893 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2894 Algorithm
.pszObjId
) },
2895 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2896 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2897 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2899 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2901 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2902 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2903 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2907 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2908 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2909 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2915 DWORD bytesNeeded
= 0;
2917 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2918 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2921 *pcbStructInfo
= bytesNeeded
;
2922 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2923 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2925 PCERT_PUBLIC_KEY_INFO info
;
2927 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2928 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2929 info
= pvStructInfo
;
2930 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2931 sizeof(CERT_PUBLIC_KEY_INFO
);
2932 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2933 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2934 &bytesNeeded
, NULL
);
2935 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2936 CRYPT_FreeSpace(pDecodePara
, info
);
2942 SetLastError(STATUS_ACCESS_VIOLATION
);
2949 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2950 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2956 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2959 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2961 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2964 if (pbEncoded
[1] > 1)
2966 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2973 *pcbStructInfo
= sizeof(BOOL
);
2976 else if (*pcbStructInfo
< sizeof(BOOL
))
2978 *pcbStructInfo
= sizeof(BOOL
);
2979 SetLastError(ERROR_MORE_DATA
);
2984 *pcbStructInfo
= sizeof(BOOL
);
2985 *(BOOL
*)pvStructInfo
= pbEncoded
[2] != 0;
2988 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
2992 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2993 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2995 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2996 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2999 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3000 pvStructInfo
, *pcbStructInfo
);
3004 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3007 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3008 if (1 + lenBytes
> cbEncoded
)
3010 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3013 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3015 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3017 case 1: /* rfc822Name */
3018 case 2: /* dNSName */
3019 case 6: /* uniformResourceIdentifier */
3020 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
3022 SetLastError(CRYPT_E_ASN1_RULE
);
3026 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3028 case 4: /* directoryName */
3029 case 7: /* iPAddress */
3030 bytesNeeded
+= dataLen
;
3032 case 8: /* registeredID */
3033 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3037 /* FIXME: ugly, shouldn't need to know internals of OID decode
3038 * function to use it.
3040 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3043 case 0: /* otherName */
3044 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3045 SetLastError(CRYPT_E_ASN1_BADTAG
);
3048 case 3: /* x400Address, unimplemented */
3049 case 5: /* ediPartyName, unimplemented */
3050 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3051 SetLastError(CRYPT_E_ASN1_BADTAG
);
3055 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3056 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3062 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3064 *pcbStructInfo
= bytesNeeded
;
3065 else if (*pcbStructInfo
< bytesNeeded
)
3067 *pcbStructInfo
= bytesNeeded
;
3068 SetLastError(ERROR_MORE_DATA
);
3073 *pcbStructInfo
= bytesNeeded
;
3074 /* MS used values one greater than the asn1 ones.. sigh */
3075 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3076 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3078 case 1: /* rfc822Name */
3079 case 2: /* dNSName */
3080 case 6: /* uniformResourceIdentifier */
3084 for (i
= 0; i
< dataLen
; i
++)
3085 entry
->pwszURL
[i
] = (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3086 entry
->pwszURL
[i
] = 0;
3087 TRACE("URL is %p (%s)\n", entry
->pwszURL
,
3088 debugstr_w(entry
->pwszURL
));
3091 case 4: /* directoryName */
3092 /* The data are memory-equivalent with the IPAddress case,
3095 case 7: /* iPAddress */
3096 /* The next data pointer is in the pwszURL spot, that is,
3097 * the first 4 bytes. Need to move it to the next spot.
3099 entry
->IPAddress
.pbData
= (LPBYTE
)entry
->pwszURL
;
3100 entry
->IPAddress
.cbData
= dataLen
;
3101 memcpy(entry
->IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3104 case 8: /* registeredID */
3105 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3106 &entry
->pszRegisteredID
, &dataLen
, NULL
);
3115 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3116 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3120 struct AsnArrayDescriptor arrayDesc
= { 0,
3121 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3122 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3123 sizeof(CERT_ALT_NAME_INFO
),
3124 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3125 offsetof(CERT_ALT_NAME_ENTRY
, pwszURL
) };
3127 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3128 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3130 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3131 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3135 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3136 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3137 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3143 struct AsnDecodeSequenceItem items
[] = {
3144 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3145 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3146 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3147 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3148 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3149 CRYPT_AsnDecodeOctets
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3150 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3151 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3152 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3153 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3154 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3157 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3158 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3159 pcbStructInfo
, NULL
, NULL
);
3163 SetLastError(STATUS_ACCESS_VIOLATION
);
3170 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3171 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3172 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3178 struct AsnDecodeSequenceItem items
[] = {
3179 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3180 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3181 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3182 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3183 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3184 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3185 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3186 AuthorityCertIssuer
.rgAltEntry
), 0 },
3187 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3188 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3189 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3190 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3191 AuthorityCertSerialNumber
.pbData
), 0 },
3194 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3195 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3196 pcbStructInfo
, NULL
, NULL
);
3200 SetLastError(STATUS_ACCESS_VIOLATION
);
3207 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3208 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3211 struct AsnDecodeSequenceItem items
[] = {
3212 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3213 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3214 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3215 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3216 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3217 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.pwszURL
), 0 },
3219 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3221 return CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3222 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3223 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3226 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3227 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3228 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3232 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3233 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3237 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3238 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3239 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3240 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3241 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3242 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3243 CERT_AUTHORITY_INFO_ACCESS
*info
= pvStructInfo
;
3245 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3246 info
->rgAccDescr
= (CERT_ACCESS_DESCRIPTION
*)(info
+ 1);
3247 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3248 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3252 SetLastError(STATUS_ACCESS_VIOLATION
);
3259 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3260 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3265 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3266 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3268 /* The caller has already checked the tag, no need to check it again.
3269 * Check the outer length is valid:
3271 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3273 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3276 pbEncoded
+= 1 + lenBytes
;
3277 cbEncoded
-= 1 + lenBytes
;
3278 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3279 cbEncoded
-= 2; /* space for 0 TLV */
3280 /* Check the inner length is valid: */
3281 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3285 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3286 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3287 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3289 if (*(pbEncoded
+ decodedLen
) != 0 ||
3290 *(pbEncoded
+ decodedLen
+ 1) != 0)
3292 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3293 *(pbEncoded
+ decodedLen
),
3294 *(pbEncoded
+ decodedLen
+ 1));
3295 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3301 if (ret
&& pcbDecoded
)
3303 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3304 TRACE("decoded %ld bytes\n", *pcbDecoded
);
3311 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3312 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3315 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3316 struct AsnDecodeSequenceItem items
[] = {
3317 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3318 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3319 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3320 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3321 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3322 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3323 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3327 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3328 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3330 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3331 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3332 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3336 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3337 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3338 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3342 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3343 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3347 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3348 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3349 if (ret
&& pvStructInfo
)
3351 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3352 pcbStructInfo
, *pcbStructInfo
);
3355 CRYPT_CONTENT_INFO
*info
;
3357 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3358 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3359 info
= pvStructInfo
;
3360 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3361 sizeof(CRYPT_CONTENT_INFO
));
3362 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3363 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3364 pcbStructInfo
, NULL
);
3365 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3366 CRYPT_FreeSpace(pDecodePara
, info
);
3372 SetLastError(STATUS_ACCESS_VIOLATION
);
3378 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3379 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3380 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3383 struct AsnDecodeSequenceItem items
[] = {
3384 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3385 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3386 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3387 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3388 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3390 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3391 CRYPT_AsnDecodePKCSContentInfoInternal
,
3392 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3393 ContentInfo
.pszObjId
), 0 },
3394 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3395 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3396 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3399 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3400 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3405 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3406 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3407 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3411 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3412 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3416 DWORD bytesNeeded
= 0;
3418 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3419 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3422 *pcbStructInfo
= bytesNeeded
;
3423 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3424 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3426 CERT_ALT_NAME_INFO
*name
;
3428 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3429 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3430 name
= pvStructInfo
;
3431 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3432 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3433 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3434 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3435 &bytesNeeded
, NULL
);
3436 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3437 CRYPT_FreeSpace(pDecodePara
, name
);
3443 SetLastError(STATUS_ACCESS_VIOLATION
);
3450 struct PATH_LEN_CONSTRAINT
3452 BOOL fPathLenConstraint
;
3453 DWORD dwPathLenConstraint
;
3456 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3457 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3461 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3463 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3464 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3468 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3470 *pcbStructInfo
= bytesNeeded
;
3472 else if (*pcbStructInfo
< bytesNeeded
)
3474 SetLastError(ERROR_MORE_DATA
);
3475 *pcbStructInfo
= bytesNeeded
;
3480 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3482 *pcbStructInfo
= bytesNeeded
;
3483 size
= sizeof(constraint
->dwPathLenConstraint
);
3484 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3485 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3487 constraint
->fPathLenConstraint
= TRUE
;
3488 TRACE("got an int, dwPathLenConstraint is %ld\n",
3489 constraint
->dwPathLenConstraint
);
3491 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
3495 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3496 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3500 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3501 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3502 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3503 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3504 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3505 offsetof(CERT_NAME_BLOB
, pbData
) };
3507 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3508 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3510 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3511 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3512 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
3516 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3517 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3518 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3524 struct AsnDecodeSequenceItem items
[] = {
3525 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3526 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3527 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3528 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3529 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3530 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3531 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3532 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3533 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3535 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3538 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3539 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3540 pcbStructInfo
, NULL
, NULL
);
3544 SetLastError(STATUS_ACCESS_VIOLATION
);
3551 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3552 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3553 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3559 struct AsnDecodeSequenceItem items
[] = {
3560 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3561 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3562 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3563 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3564 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3567 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3568 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3569 pcbStructInfo
, NULL
, NULL
);
3573 SetLastError(STATUS_ACCESS_VIOLATION
);
3580 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3581 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3584 struct AsnDecodeSequenceItem items
[] = {
3585 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3586 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3587 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3589 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3590 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3591 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3594 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3596 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3597 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3599 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3600 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3601 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3605 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3606 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3610 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3611 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3612 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3613 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3614 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3615 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3617 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3618 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3620 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3621 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3622 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
3626 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3627 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3629 struct AsnDecodeSequenceItem items
[] = {
3630 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3631 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3632 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3633 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3634 CRYPT_AsnDecodePolicyQualifiers
,
3635 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3636 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3638 CERT_POLICY_INFO
*info
= pvStructInfo
;
3641 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3642 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3644 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3645 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3646 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3650 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3651 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3652 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3656 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3657 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3661 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3662 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3663 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3664 sizeof(CERT_POLICIES_INFO
),
3665 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3666 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3667 CERT_POLICIES_INFO
*info
= pvStructInfo
;
3669 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3670 info
->rgPolicyInfo
= (CERT_POLICY_INFO
*)(info
+ 1);
3672 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3673 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3677 SetLastError(STATUS_ACCESS_VIOLATION
);
3683 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3684 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3687 struct AsnDecodeSequenceItem items
[] = {
3688 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3689 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3690 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3691 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3692 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3693 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3695 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3698 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3699 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3701 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3702 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3703 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3707 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3708 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3709 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3713 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3714 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3718 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3719 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3720 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3721 sizeof(CERT_POLICY_MAPPING
),
3722 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3723 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3724 CERT_POLICY_MAPPINGS_INFO
*info
= pvStructInfo
;
3726 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3727 info
->rgPolicyMapping
= (CERT_POLICY_MAPPING
*)(info
+ 1);
3728 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3729 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3733 SetLastError(STATUS_ACCESS_VIOLATION
);
3739 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3740 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3744 DWORD skip
, size
= sizeof(skip
);
3748 SetLastError(CRYPT_E_ASN1_EOD
);
3751 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3753 SetLastError(CRYPT_E_ASN1_BADTAG
);
3756 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3757 &skip
, &size
, pcbDecoded
)))
3759 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3760 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3763 *pcbStructInfo
= bytesNeeded
;
3764 else if (*pcbStructInfo
< bytesNeeded
)
3766 *pcbStructInfo
= bytesNeeded
;
3767 SetLastError(ERROR_MORE_DATA
);
3772 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3773 CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
);
3775 *pcbStructInfo
= bytesNeeded
;
3776 /* The BOOL is implicit: if the integer is present, then it's
3779 info
->fRequireExplicitPolicy
= TRUE
;
3780 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3786 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3787 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3791 DWORD skip
, size
= sizeof(skip
);
3795 SetLastError(CRYPT_E_ASN1_EOD
);
3798 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3800 SetLastError(CRYPT_E_ASN1_BADTAG
);
3803 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3804 &skip
, &size
, pcbDecoded
)))
3806 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3807 fInhibitPolicyMapping
);
3810 *pcbStructInfo
= bytesNeeded
;
3811 else if (*pcbStructInfo
< bytesNeeded
)
3813 *pcbStructInfo
= bytesNeeded
;
3814 SetLastError(ERROR_MORE_DATA
);
3819 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3820 CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
);
3822 *pcbStructInfo
= bytesNeeded
;
3823 /* The BOOL is implicit: if the integer is present, then it's
3826 info
->fInhibitPolicyMapping
= TRUE
;
3827 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3833 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3834 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3835 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3836 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3840 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3841 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3845 struct AsnDecodeSequenceItem items
[] = {
3847 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3848 CRYPT_AsnDecodeRequireExplicit
,
3849 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3850 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3852 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3853 CRYPT_AsnDecodeInhibitMapping
,
3854 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3855 TRUE
, FALSE
, 0, 0 },
3858 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3859 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3860 pcbStructInfo
, NULL
, NULL
);
3864 SetLastError(STATUS_ACCESS_VIOLATION
);
3870 #define RSA1_MAGIC 0x31415352
3872 struct DECODED_RSA_PUB_KEY
3874 CRYPT_INTEGER_BLOB pubexp
;
3875 CRYPT_INTEGER_BLOB modulus
;
3878 /* Helper function to decode an ASN.1 DER encoded RSA public key, writing the decoded
3879 * key into 'decodedKey', and the length into 'size'. The memory
3880 * for 'decodedKey' is allocated with 'CRYPT_DECODE_ALLOC_FLAG'
3882 static BOOL
CRYPT_raw_decode_rsa_pub_key(struct DECODED_RSA_PUB_KEY
**decodedKey
,
3883 DWORD
*size
, const BYTE
*pbEncoded
, DWORD cbEncoded
)
3887 struct AsnDecodeSequenceItem items
[] = {
3888 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3889 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3890 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3892 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3893 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3894 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
.pbData
),
3898 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3899 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, decodedKey
,
3902 if (ret
&& (*decodedKey
)->pubexp
.cbData
> sizeof(DWORD
))
3904 WARN("Unexpected exponent length %lu.\n", (*decodedKey
)->pubexp
.cbData
);
3905 LocalFree(*decodedKey
);
3906 SetLastError(CRYPT_E_ASN1_LARGE
);
3913 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey_Bcrypt(DWORD dwCertEncodingType
,
3914 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3915 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3921 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3924 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
3925 pvStructInfo
, *pcbStructInfo
);
3927 ret
= CRYPT_raw_decode_rsa_pub_key(&decodedKey
, &size
, pbEncoded
, cbEncoded
);
3930 /* Header, exponent, and modulus */
3931 DWORD bytesNeeded
= sizeof(BCRYPT_RSAKEY_BLOB
) + decodedKey
->pubexp
.cbData
+
3932 decodedKey
->modulus
.cbData
;
3936 *pcbStructInfo
= bytesNeeded
;
3939 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3940 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3942 BCRYPT_RSAKEY_BLOB
*hdr
;
3944 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3945 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3948 hdr
->Magic
= BCRYPT_RSAPUBLIC_MAGIC
;
3949 hdr
->BitLength
= decodedKey
->modulus
.cbData
* 8;
3950 hdr
->cbPublicExp
= decodedKey
->pubexp
.cbData
;
3951 hdr
->cbModulus
= decodedKey
->modulus
.cbData
;
3954 /* CNG_RSA_PUBLIC_KEY_BLOB always stores the exponent and modulus
3955 * in big-endian format, so we need to convert from little-endian
3957 CRYPT_CopyReversed((BYTE
*)pvStructInfo
+ sizeof(BCRYPT_RSAKEY_BLOB
),
3958 decodedKey
->pubexp
.pbData
, hdr
->cbPublicExp
);
3959 CRYPT_CopyReversed((BYTE
*)pvStructInfo
+ sizeof(BCRYPT_RSAKEY_BLOB
) +
3960 hdr
->cbPublicExp
, decodedKey
->modulus
.pbData
,
3961 decodedKey
->modulus
.cbData
);
3963 LocalFree(decodedKey
);
3968 SetLastError(STATUS_ACCESS_VIOLATION
);
3976 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3977 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3978 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3984 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3986 ret
= CRYPT_raw_decode_rsa_pub_key(&decodedKey
, &size
, pbEncoded
, cbEncoded
);
3989 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3990 decodedKey
->modulus
.cbData
;
3994 *pcbStructInfo
= bytesNeeded
;
3996 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3997 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4000 RSAPUBKEY
*rsaPubKey
;
4003 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4004 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4006 hdr
->bType
= PUBLICKEYBLOB
;
4007 hdr
->bVersion
= CUR_BLOB_VERSION
;
4009 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
4010 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
4011 sizeof(BLOBHEADER
));
4012 rsaPubKey
->magic
= RSA1_MAGIC
;
4013 rsaPubKey
->pubexp
= 0;
4014 assert(decodedKey
->pubexp
.cbData
<= sizeof(rsaPubKey
->pubexp
));
4015 for (i
= 0; i
< decodedKey
->pubexp
.cbData
; ++i
)
4016 rsaPubKey
->pubexp
|= decodedKey
->pubexp
.pbData
[i
] << (i
* 8);
4018 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
4019 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
4020 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
4021 decodedKey
->modulus
.cbData
);
4023 LocalFree(decodedKey
);
4028 SetLastError(STATUS_ACCESS_VIOLATION
);
4035 #define RSA2_MAGIC 0x32415352
4037 struct DECODED_RSA_PRIV_KEY
4041 CRYPT_INTEGER_BLOB modulus
;
4042 CRYPT_INTEGER_BLOB privexp
;
4043 CRYPT_INTEGER_BLOB prime1
;
4044 CRYPT_INTEGER_BLOB prime2
;
4045 CRYPT_INTEGER_BLOB exponent1
;
4046 CRYPT_INTEGER_BLOB exponent2
;
4047 CRYPT_INTEGER_BLOB coefficient
;
4050 static BOOL WINAPI
CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType
,
4051 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4052 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4059 struct AsnDecodeSequenceItem items
[] = {
4060 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, version
),
4061 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4062 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
),
4063 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4064 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
.pbData
),
4066 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, pubexp
),
4067 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4068 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
),
4069 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4070 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
.pbData
),
4072 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
),
4073 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4074 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
.pbData
),
4076 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
),
4077 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4078 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
.pbData
),
4080 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
),
4081 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4082 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
.pbData
),
4084 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
),
4085 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4086 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
.pbData
),
4088 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
),
4089 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
4090 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
.pbData
),
4093 struct DECODED_RSA_PRIV_KEY
*decodedKey
= NULL
;
4096 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
4097 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
4101 halflen
= decodedKey
->prime1
.cbData
;
4102 if (halflen
< decodedKey
->prime2
.cbData
)
4103 halflen
= decodedKey
->prime2
.cbData
;
4104 if (halflen
< decodedKey
->exponent1
.cbData
)
4105 halflen
= decodedKey
->exponent1
.cbData
;
4106 if (halflen
< decodedKey
->exponent2
.cbData
)
4107 halflen
= decodedKey
->exponent2
.cbData
;
4108 if (halflen
< decodedKey
->coefficient
.cbData
)
4109 halflen
= decodedKey
->coefficient
.cbData
;
4110 if (halflen
* 2 < decodedKey
->modulus
.cbData
)
4111 halflen
= decodedKey
->modulus
.cbData
/ 2 + decodedKey
->modulus
.cbData
% 2;
4112 if (halflen
* 2 < decodedKey
->privexp
.cbData
)
4113 halflen
= decodedKey
->privexp
.cbData
/ 2 + decodedKey
->privexp
.cbData
% 2;
4117 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
4122 *pcbStructInfo
= bytesNeeded
;
4125 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4126 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4129 RSAPUBKEY
*rsaPubKey
;
4132 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4133 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4136 hdr
->bType
= PRIVATEKEYBLOB
;
4137 hdr
->bVersion
= CUR_BLOB_VERSION
;
4139 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
4141 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
4142 sizeof(BLOBHEADER
));
4143 rsaPubKey
->magic
= RSA2_MAGIC
;
4144 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
4145 rsaPubKey
->bitlen
= halflen
* 16;
4147 vardata
= (BYTE
*)(rsaPubKey
+ 1);
4148 memset(vardata
, 0, halflen
* 9);
4150 decodedKey
->modulus
.pbData
, decodedKey
->modulus
.cbData
);
4151 memcpy(vardata
+ halflen
* 2,
4152 decodedKey
->prime1
.pbData
, decodedKey
->prime1
.cbData
);
4153 memcpy(vardata
+ halflen
* 3,
4154 decodedKey
->prime2
.pbData
, decodedKey
->prime2
.cbData
);
4155 memcpy(vardata
+ halflen
* 4,
4156 decodedKey
->exponent1
.pbData
, decodedKey
->exponent1
.cbData
);
4157 memcpy(vardata
+ halflen
* 5,
4158 decodedKey
->exponent2
.pbData
, decodedKey
->exponent2
.cbData
);
4159 memcpy(vardata
+ halflen
* 6,
4160 decodedKey
->coefficient
.pbData
, decodedKey
->coefficient
.cbData
);
4161 memcpy(vardata
+ halflen
* 7,
4162 decodedKey
->privexp
.pbData
, decodedKey
->privexp
.cbData
);
4166 LocalFree(decodedKey
);
4171 SetLastError(STATUS_ACCESS_VIOLATION
);
4178 static BOOL
CRYPT_AsnDecodeOctets(const BYTE
*pbEncoded
,
4179 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4183 DWORD bytesNeeded
, dataLen
;
4185 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4186 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4188 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4190 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4192 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4193 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
4195 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
4197 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4199 *pcbStructInfo
= bytesNeeded
;
4200 else if (*pcbStructInfo
< bytesNeeded
)
4202 SetLastError(ERROR_MORE_DATA
);
4203 *pcbStructInfo
= bytesNeeded
;
4208 CRYPT_DATA_BLOB
*blob
;
4210 *pcbStructInfo
= bytesNeeded
;
4211 blob
= pvStructInfo
;
4212 blob
->cbData
= dataLen
;
4213 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4214 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
4217 assert(blob
->pbData
);
4219 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
4227 static BOOL
CRYPT_AsnDecodeOctetStringInternal(const BYTE
*encoded
, DWORD encoded_size
,
4228 DWORD flags
, void *buf
, DWORD
*buf_size
, DWORD
*ret_decoded
)
4230 DWORD decoded
= 0, indefinite_len_depth
= 0, len_size
, len
, bytes_needed
;
4231 CRYPT_DATA_BLOB
*blob
;
4234 while (encoded
[0] == (ASN_CONSTRUCTOR
| ASN_OCTETSTRING
))
4236 if (!CRYPT_GetLengthIndefinite(encoded
, encoded_size
, &len
))
4239 len_size
= GET_LEN_BYTES(encoded
[1]);
4240 encoded
+= 1 + len_size
;
4241 encoded_size
-= 1 + len_size
;
4242 decoded
+= 1 + len_size
;
4244 if (len
== CMSG_INDEFINITE_LENGTH
)
4246 indefinite_len_depth
++;
4247 if (encoded_size
< 2)
4249 SetLastError(CRYPT_E_ASN1_EOD
);
4257 if (encoded
[0] != ASN_OCTETSTRING
)
4259 WARN("Unexpected tag %02x\n", encoded
[0]);
4260 SetLastError(CRYPT_E_ASN1_BADTAG
);
4264 if (!CRYPT_GetLen(encoded
, encoded_size
, &len
))
4266 len_size
= GET_LEN_BYTES(encoded
[1]);
4267 decoded
+= 1 + len_size
+ len
;
4268 encoded_size
-= 1 + len_size
;
4270 if (len
> encoded_size
)
4272 SetLastError(CRYPT_E_ASN1_EOD
);
4276 *ret_decoded
= decoded
;
4278 encoded
+= 1 + len_size
;
4282 while (indefinite_len_depth
--)
4284 if (encoded
[0] || encoded
[1])
4286 TRACE("expected 0 TLV, got %02x %02x\n", encoded
[0], encoded
[1]);
4287 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4292 bytes_needed
= sizeof(*blob
);
4293 if (!(flags
& CRYPT_DECODE_NOCOPY_FLAG
)) bytes_needed
+= len
;
4296 *buf_size
= bytes_needed
;
4299 if (*buf_size
< bytes_needed
)
4301 SetLastError(ERROR_MORE_DATA
);
4302 *buf_size
= bytes_needed
;
4306 *buf_size
= bytes_needed
;
4309 if (flags
& CRYPT_DECODE_NOCOPY_FLAG
)
4310 blob
->pbData
= (BYTE
*)string
;
4311 else if (blob
->cbData
)
4312 memcpy(blob
->pbData
, string
, blob
->cbData
);
4315 *ret_decoded
= decoded
;
4319 static BOOL WINAPI
CRYPT_AsnDecodeOctetString(DWORD dwCertEncodingType
,
4320 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4321 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4325 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
4326 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4330 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4336 DWORD bytesNeeded
= 0;
4338 if ((ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4339 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4342 *pcbStructInfo
= bytesNeeded
;
4343 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4344 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4346 CRYPT_DATA_BLOB
*blob
;
4348 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4349 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4350 blob
= pvStructInfo
;
4351 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4352 ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4353 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4354 &bytesNeeded
, NULL
);
4355 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4356 CRYPT_FreeSpace(pDecodePara
, blob
);
4362 SetLastError(STATUS_ACCESS_VIOLATION
);
4369 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4370 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4373 DWORD bytesNeeded
, dataLen
;
4374 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4376 TRACE("(%p, %ld, 0x%08lx, %p, %ld, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4377 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4379 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4381 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4382 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4384 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4386 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4388 *pcbStructInfo
= bytesNeeded
;
4389 else if (*pcbStructInfo
< bytesNeeded
)
4391 *pcbStructInfo
= bytesNeeded
;
4392 SetLastError(ERROR_MORE_DATA
);
4397 CRYPT_BIT_BLOB
*blob
;
4399 *pcbStructInfo
= bytesNeeded
;
4400 blob
= pvStructInfo
;
4401 blob
->cbData
= dataLen
- 1;
4402 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4403 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4405 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4409 assert(blob
->pbData
);
4412 BYTE mask
= 0xff << blob
->cUnusedBits
;
4414 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4416 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4424 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4425 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4426 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4430 TRACE("(%p, %ld, 0x%08lx, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4431 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4435 DWORD bytesNeeded
= 0;
4439 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4442 else if (pbEncoded
[0] != ASN_BITSTRING
)
4444 SetLastError(CRYPT_E_ASN1_BADTAG
);
4447 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4448 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4451 *pcbStructInfo
= bytesNeeded
;
4452 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4453 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4455 CRYPT_BIT_BLOB
*blob
;
4457 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4458 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4459 blob
= pvStructInfo
;
4460 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4461 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4462 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4463 &bytesNeeded
, NULL
);
4464 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4465 CRYPT_FreeSpace(pDecodePara
, blob
);
4471 SetLastError(STATUS_ACCESS_VIOLATION
);
4475 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
4479 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4480 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4481 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4486 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4488 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4491 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4492 if (dataLen
> sizeof(int))
4494 SetLastError(CRYPT_E_ASN1_LARGE
);
4497 else if (!pvStructInfo
)
4498 *pcbStructInfo
= sizeof(int);
4499 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4503 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4505 /* initialize to a negative value to sign-extend */
4510 for (i
= 0; i
< dataLen
; i
++)
4513 val
|= pbEncoded
[1 + lenBytes
+ i
];
4515 memcpy(pvStructInfo
, &val
, sizeof(int));
4521 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4522 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4523 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4529 DWORD bytesNeeded
= 0;
4533 SetLastError(CRYPT_E_ASN1_EOD
);
4536 else if (pbEncoded
[0] != ASN_INTEGER
)
4538 SetLastError(CRYPT_E_ASN1_BADTAG
);
4542 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4543 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4547 *pcbStructInfo
= bytesNeeded
;
4548 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4549 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4551 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4552 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4553 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4554 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4555 &bytesNeeded
, NULL
);
4556 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4557 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4563 SetLastError(STATUS_ACCESS_VIOLATION
);
4570 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4571 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4575 DWORD bytesNeeded
, dataLen
;
4577 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4579 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4581 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4583 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4585 *pcbStructInfo
= bytesNeeded
;
4586 else if (*pcbStructInfo
< bytesNeeded
)
4588 *pcbStructInfo
= bytesNeeded
;
4589 SetLastError(ERROR_MORE_DATA
);
4594 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4596 *pcbStructInfo
= bytesNeeded
;
4597 blob
->cbData
= dataLen
;
4598 assert(blob
->pbData
);
4603 for (i
= 0; i
< blob
->cbData
; i
++)
4605 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4614 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4615 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4616 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4622 DWORD bytesNeeded
= 0;
4624 if (pbEncoded
[0] != ASN_INTEGER
)
4626 SetLastError(CRYPT_E_ASN1_BADTAG
);
4630 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4631 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4635 *pcbStructInfo
= bytesNeeded
;
4636 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4637 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4639 CRYPT_INTEGER_BLOB
*blob
;
4641 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4642 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4643 blob
= pvStructInfo
;
4644 blob
->pbData
= (BYTE
*)pvStructInfo
+
4645 sizeof(CRYPT_INTEGER_BLOB
);
4646 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4647 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4648 &bytesNeeded
, NULL
);
4649 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4650 CRYPT_FreeSpace(pDecodePara
, blob
);
4656 SetLastError(STATUS_ACCESS_VIOLATION
);
4663 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4664 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4669 if (pbEncoded
[0] == ASN_INTEGER
)
4671 DWORD bytesNeeded
, dataLen
;
4673 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4675 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4678 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4679 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4681 *pcbStructInfo
= bytesNeeded
;
4682 else if (*pcbStructInfo
< bytesNeeded
)
4684 *pcbStructInfo
= bytesNeeded
;
4685 SetLastError(ERROR_MORE_DATA
);
4690 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4692 *pcbStructInfo
= bytesNeeded
;
4693 blob
->cbData
= dataLen
;
4694 assert(blob
->pbData
);
4695 /* remove leading zero byte if it exists */
4696 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4705 for (i
= 0; i
< blob
->cbData
; i
++)
4707 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4716 SetLastError(CRYPT_E_ASN1_BADTAG
);
4722 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4723 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4724 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4730 DWORD bytesNeeded
= 0;
4732 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4733 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4736 *pcbStructInfo
= bytesNeeded
;
4737 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4738 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4740 CRYPT_INTEGER_BLOB
*blob
;
4742 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4743 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4744 blob
= pvStructInfo
;
4745 blob
->pbData
= (BYTE
*)pvStructInfo
+
4746 sizeof(CRYPT_INTEGER_BLOB
);
4747 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4748 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4749 &bytesNeeded
, NULL
);
4750 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4751 CRYPT_FreeSpace(pDecodePara
, blob
);
4757 SetLastError(STATUS_ACCESS_VIOLATION
);
4764 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4765 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4766 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4772 *pcbStructInfo
= sizeof(int);
4777 if (pbEncoded
[0] == ASN_ENUMERATED
)
4779 unsigned int val
= 0, i
;
4783 SetLastError(CRYPT_E_ASN1_EOD
);
4786 else if (pbEncoded
[1] == 0)
4788 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4793 /* A little strange looking, but we have to accept a sign byte:
4794 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4795 * assuming a small length is okay here, it has to be in short
4798 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4800 SetLastError(CRYPT_E_ASN1_LARGE
);
4803 for (i
= 0; i
< pbEncoded
[1]; i
++)
4806 val
|= pbEncoded
[2 + i
];
4808 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4809 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4811 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4812 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4813 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4819 SetLastError(CRYPT_E_ASN1_BADTAG
);
4825 SetLastError(STATUS_ACCESS_VIOLATION
);
4832 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4835 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4840 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4842 if (!isdigit(*(pbEncoded))) \
4844 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4850 (word) += *(pbEncoded)++ - '0'; \
4855 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4856 SYSTEMTIME
*sysTime
)
4860 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4862 WORD hours
, minutes
= 0;
4863 BYTE sign
= *pbEncoded
++;
4866 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4867 if (ret
&& hours
>= 24)
4869 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4874 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4875 if (ret
&& minutes
>= 60)
4877 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4885 sysTime
->wHour
+= hours
;
4886 sysTime
->wMinute
+= minutes
;
4890 if (hours
> sysTime
->wHour
)
4893 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4896 sysTime
->wHour
-= hours
;
4897 if (minutes
> sysTime
->wMinute
)
4900 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4903 sysTime
->wMinute
-= minutes
;
4910 #define MIN_ENCODED_TIME_LENGTH 10
4912 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4913 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4918 if (pbEncoded
[0] == ASN_UTCTIME
)
4921 SetLastError(CRYPT_E_ASN1_EOD
);
4922 else if (pbEncoded
[1] > 0x7f)
4924 /* long-form date strings really can't be valid */
4925 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4929 SYSTEMTIME sysTime
= { 0 };
4930 BYTE len
= pbEncoded
[1];
4932 if (len
< MIN_ENCODED_TIME_LENGTH
)
4933 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4938 *pcbDecoded
= 2 + len
;
4940 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4941 if (sysTime
.wYear
>= 50)
4942 sysTime
.wYear
+= 1900;
4944 sysTime
.wYear
+= 2000;
4945 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4946 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4947 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4948 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4951 if (len
>= 2 && isdigit(*pbEncoded
) &&
4952 isdigit(*(pbEncoded
+ 1)))
4953 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4955 else if (isdigit(*pbEncoded
))
4956 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4959 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4965 *pcbStructInfo
= sizeof(FILETIME
);
4966 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4968 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4974 SetLastError(CRYPT_E_ASN1_BADTAG
);
4978 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4979 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4980 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4986 DWORD bytesNeeded
= 0;
4988 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4989 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4993 *pcbStructInfo
= bytesNeeded
;
4994 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4995 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4997 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4998 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4999 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
5000 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5001 &bytesNeeded
, NULL
);
5002 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5003 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
5009 SetLastError(STATUS_ACCESS_VIOLATION
);
5015 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
5016 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5021 if (pbEncoded
[0] == ASN_GENERALTIME
)
5024 SetLastError(CRYPT_E_ASN1_EOD
);
5025 else if (pbEncoded
[1] > 0x7f)
5027 /* long-form date strings really can't be valid */
5028 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5032 BYTE len
= pbEncoded
[1];
5034 if (len
< MIN_ENCODED_TIME_LENGTH
)
5035 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5038 SYSTEMTIME sysTime
= { 0 };
5042 *pcbDecoded
= 2 + len
;
5044 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
5045 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
5046 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
5047 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
5050 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
5053 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
5055 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
5062 /* workaround macro weirdness */
5063 digits
= min(len
, 3);
5064 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
5065 sysTime
.wMilliseconds
);
5068 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
5074 *pcbStructInfo
= sizeof(FILETIME
);
5075 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
5077 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
5083 SetLastError(CRYPT_E_ASN1_BADTAG
);
5087 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
5088 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5092 InternalDecodeFunc decode
= NULL
;
5094 if (pbEncoded
[0] == ASN_UTCTIME
)
5095 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
5096 else if (pbEncoded
[0] == ASN_GENERALTIME
)
5097 decode
= CRYPT_AsnDecodeGeneralizedTime
;
5099 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
5100 pcbStructInfo
, pcbDecoded
);
5103 SetLastError(CRYPT_E_ASN1_BADTAG
);
5109 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
5110 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5111 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5117 DWORD bytesNeeded
= 0;
5119 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5120 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
5124 *pcbStructInfo
= bytesNeeded
;
5125 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5126 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5128 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5129 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5130 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5131 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5132 &bytesNeeded
, NULL
);
5133 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5134 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
5140 SetLastError(STATUS_ACCESS_VIOLATION
);
5147 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
5148 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5149 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5155 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
5157 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
5159 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5164 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5165 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
5167 ptr
= pbEncoded
+ 1 + lenBytes
;
5168 remainingLen
= dataLen
;
5169 while (ret
&& remainingLen
)
5173 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5176 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5178 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5179 ptr
+= 1 + nextLenBytes
+ nextLen
;
5180 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
5181 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
5182 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
5188 CRYPT_SEQUENCE_OF_ANY
*seq
;
5193 *pcbStructInfo
= bytesNeeded
;
5194 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5195 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5197 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5198 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5200 seq
->cValue
= cValue
;
5201 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
5203 nextPtr
= (BYTE
*)seq
->rgValue
+
5204 cValue
* sizeof(CRYPT_DER_BLOB
);
5205 ptr
= pbEncoded
+ 1 + lenBytes
;
5206 remainingLen
= dataLen
;
5208 while (ret
&& remainingLen
)
5212 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5215 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5217 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
5219 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
5220 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
5223 seq
->rgValue
[i
].pbData
= nextPtr
;
5224 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
5226 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
5228 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5229 ptr
+= 1 + nextLenBytes
+ nextLen
;
5233 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5234 CRYPT_FreeSpace(pDecodePara
, seq
);
5241 SetLastError(CRYPT_E_ASN1_BADTAG
);
5247 SetLastError(STATUS_ACCESS_VIOLATION
);
5254 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
5255 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5260 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
5262 DWORD bytesNeeded
= 0, dataLen
;
5264 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5266 struct AsnArrayDescriptor arrayDesc
= {
5267 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5268 offsetof(CRL_DIST_POINT_NAME
, FullName
.cAltEntry
),
5269 offsetof(CRL_DIST_POINT_NAME
, FullName
.rgAltEntry
),
5270 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, FullName
),
5271 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
5272 offsetof(CERT_ALT_NAME_ENTRY
, pwszURL
) };
5273 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5278 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5279 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5280 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
5281 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
5282 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, FullName
);
5285 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
5287 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
5289 *pcbStructInfo
= bytesNeeded
;
5290 else if (*pcbStructInfo
< bytesNeeded
)
5292 *pcbStructInfo
= bytesNeeded
;
5293 SetLastError(ERROR_MORE_DATA
);
5298 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
5300 *pcbStructInfo
= bytesNeeded
;
5303 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
5304 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5305 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5306 dwFlags
, NULL
, &name
->FullName
.cAltEntry
, &nameLen
,
5310 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
5316 SetLastError(CRYPT_E_ASN1_BADTAG
);
5322 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5323 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5325 struct AsnDecodeSequenceItem items
[] = {
5326 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
5327 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5328 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
5329 DistPointName
.FullName
.rgAltEntry
), 0 },
5330 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
5331 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
5332 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
5333 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
5334 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
5335 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
5337 CRL_DIST_POINT
*point
= pvStructInfo
;
5340 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5341 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5342 pcbDecoded
, point
? point
->DistPointName
.FullName
.rgAltEntry
: NULL
);
5346 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5347 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5348 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5352 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5353 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5357 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5358 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
5359 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
5360 sizeof(CRL_DIST_POINTS_INFO
),
5361 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5362 offsetof(CRL_DIST_POINT
, DistPointName
.FullName
.rgAltEntry
) };
5363 CRL_DIST_POINTS_INFO
*info
= pvStructInfo
;
5365 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5366 info
->rgDistPoint
= (CRL_DIST_POINT
*)(info
+ 1);
5367 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5368 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5372 SetLastError(STATUS_ACCESS_VIOLATION
);
5379 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5380 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5381 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5385 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5386 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5390 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5391 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5392 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5393 sizeof(CERT_ENHKEY_USAGE
),
5394 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5395 CERT_ENHKEY_USAGE
*usage
= pvStructInfo
;
5397 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5398 usage
->rgpszUsageIdentifier
= (LPSTR
*)(usage
+ 1);
5399 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5400 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5404 SetLastError(STATUS_ACCESS_VIOLATION
);
5411 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5412 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5413 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5417 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5418 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5422 struct AsnDecodeSequenceItem items
[] = {
5423 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5424 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5425 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5426 offsetof(CRL_ISSUING_DIST_POINT
,
5427 DistPointName
.FullName
.rgAltEntry
), 0 },
5428 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5429 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5431 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5432 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5434 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5435 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5436 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5437 OnlySomeReasonFlags
.pbData
), 0 },
5438 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5439 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5442 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5443 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5444 pcbStructInfo
, NULL
, NULL
);
5448 SetLastError(STATUS_ACCESS_VIOLATION
);
5455 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5456 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5460 DWORD max
, size
= sizeof(max
);
5462 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5463 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5467 SetLastError(CRYPT_E_ASN1_EOD
);
5470 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5472 SetLastError(CRYPT_E_ASN1_BADTAG
);
5475 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5476 &max
, &size
, pcbDecoded
)))
5478 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5481 *pcbStructInfo
= bytesNeeded
;
5482 else if (*pcbStructInfo
< bytesNeeded
)
5484 *pcbStructInfo
= bytesNeeded
;
5485 SetLastError(ERROR_MORE_DATA
);
5490 CERT_GENERAL_SUBTREE
*subtree
= CONTAINING_RECORD(pvStructInfo
,
5491 CERT_GENERAL_SUBTREE
, fMaximum
);
5493 *pcbStructInfo
= bytesNeeded
;
5494 /* The BOOL is implicit: if the integer is present, then it's
5497 subtree
->fMaximum
= TRUE
;
5498 subtree
->dwMaximum
= max
;
5501 TRACE("returning %d\n", ret
);
5505 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5506 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5510 struct AsnDecodeSequenceItem items
[] = {
5511 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5512 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5513 offsetof(CERT_ALT_NAME_ENTRY
, pwszURL
), 0 },
5514 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5515 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5516 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5517 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5518 TRUE
, FALSE
, 0, 0 },
5520 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5522 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5523 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5525 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5526 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5527 pcbDecoded
, subtree
? subtree
->Base
.pwszURL
: NULL
);
5530 TRACE("%ld\n", *pcbDecoded
);
5531 if (*pcbDecoded
< cbEncoded
)
5532 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5533 *(pbEncoded
+ *pcbDecoded
+ 1));
5535 TRACE("returning %d\n", ret
);
5539 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5540 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5544 struct AsnArrayDescriptor arrayDesc
= { 0,
5545 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5546 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5547 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5549 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5550 offsetof(CERT_GENERAL_SUBTREE
, Base
.pwszURL
) };
5552 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5553 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5555 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5556 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5560 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5561 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5565 struct AsnArrayDescriptor arrayDesc
= { 0,
5566 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5567 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5568 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5569 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5570 offsetof(CERT_GENERAL_SUBTREE
, Base
.pwszURL
) };
5572 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5573 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5575 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5576 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5580 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5581 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5582 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5586 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5587 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5591 struct AsnDecodeSequenceItem items
[] = {
5592 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5593 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5594 CRYPT_AsnDecodePermittedSubtree
,
5595 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5596 cExcludedSubtree
), TRUE
, TRUE
,
5597 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5598 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5599 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5600 CRYPT_AsnDecodeExcludedSubtree
,
5601 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5603 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5606 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5607 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5608 pcbStructInfo
, NULL
, NULL
);
5612 SetLastError(STATUS_ACCESS_VIOLATION
);
5618 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5619 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5623 struct AsnDecodeSequenceItem items
[] = {
5624 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5625 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5627 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5628 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5629 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5631 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5633 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5634 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5636 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5637 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5638 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5639 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5641 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5644 TRACE("returning %d\n", ret
);
5648 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5649 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5652 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5653 struct AsnDecodeSequenceItem items
[] = {
5654 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5655 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5656 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5657 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5658 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5659 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5660 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5661 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5662 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5663 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5664 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5665 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5666 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5667 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5668 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5669 HashEncryptionAlgorithm
.pszObjId
), 0 },
5670 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5671 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5672 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5673 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5674 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5675 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5676 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5680 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5681 pvStructInfo
, *pcbStructInfo
);
5683 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5684 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5685 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5689 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5690 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5691 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5695 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5696 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5700 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5701 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5702 if (ret
&& pvStructInfo
)
5704 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5705 pcbStructInfo
, *pcbStructInfo
);
5708 CMSG_SIGNER_INFO
*info
;
5710 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5711 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5712 info
= pvStructInfo
;
5713 info
->Issuer
.pbData
= ((BYTE
*)info
+
5714 sizeof(CMSG_SIGNER_INFO
));
5715 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5716 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5717 pcbStructInfo
, NULL
);
5718 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5719 CRYPT_FreeSpace(pDecodePara
, info
);
5725 SetLastError(STATUS_ACCESS_VIOLATION
);
5728 TRACE("returning %d\n", ret
);
5732 static BOOL
verify_and_copy_certificate(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5733 void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5735 PCCERT_CONTEXT cert
;
5737 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, pbEncoded
, cbEncoded
);
5740 WARN("CertCreateCertificateContext error %#lx\n", GetLastError());
5746 CertFreeCertificateContext(cert
);
5748 return CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5751 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5752 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5756 struct AsnArrayDescriptor arrayDesc
= { 0,
5757 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5758 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5759 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5760 verify_and_copy_certificate
,
5761 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5763 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5764 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5766 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5767 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5771 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5772 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5776 struct AsnArrayDescriptor arrayDesc
= { 0,
5777 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5778 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5779 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5780 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5781 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5783 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5784 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5786 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5787 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5791 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5792 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5795 CERT_ID
*id
= pvStructInfo
;
5798 if (*pbEncoded
== ASN_SEQUENCEOF
)
5800 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5801 id
? &id
->IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5805 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5806 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5807 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5808 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5810 *pcbStructInfo
= sizeof(CERT_ID
);
5813 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5815 ret
= CRYPT_AsnDecodeOctets(pbEncoded
, cbEncoded
, dwFlags
,
5816 id
? &id
->KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5820 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5821 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5822 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5823 sizeof(CRYPT_DATA_BLOB
);
5825 *pcbStructInfo
= sizeof(CERT_ID
);
5829 SetLastError(CRYPT_E_ASN1_BADTAG
);
5833 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5834 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5837 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5838 struct AsnDecodeSequenceItem items
[] = {
5839 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5840 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5841 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5842 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5843 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.KeyId
.pbData
), 0 },
5844 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5845 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5846 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5847 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5848 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5849 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5850 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5851 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5852 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5853 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5854 HashEncryptionAlgorithm
.pszObjId
), 0 },
5855 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5856 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5857 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5858 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5859 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5860 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5861 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5865 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5866 pvStructInfo
, *pcbStructInfo
);
5868 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5869 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5870 pcbDecoded
, info
? info
->SignerId
.KeyId
.pbData
: NULL
);
5874 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5875 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5876 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5880 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
5881 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5885 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5886 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5887 if (ret
&& pvStructInfo
)
5889 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5890 pcbStructInfo
, *pcbStructInfo
);
5893 CMSG_CMS_SIGNER_INFO
*info
;
5895 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5896 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5897 info
= pvStructInfo
;
5898 info
->SignerId
.KeyId
.pbData
= ((BYTE
*)info
+
5899 sizeof(CMSG_CMS_SIGNER_INFO
));
5900 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5901 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5902 pcbStructInfo
, NULL
);
5903 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5904 CRYPT_FreeSpace(pDecodePara
, info
);
5910 SetLastError(STATUS_ACCESS_VIOLATION
);
5913 TRACE("returning %d\n", ret
);
5917 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5918 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5921 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5922 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5923 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5924 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5925 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5926 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.KeyId
.pbData
) };
5928 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5929 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5931 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5932 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5936 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5937 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5938 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5941 struct AsnDecodeSequenceItem items
[] = {
5942 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5943 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5944 /* Placeholder for the hash algorithms - redundant with those in the
5945 * signers, so just ignore them.
5947 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5948 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5949 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5950 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5951 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5952 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5953 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5954 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5955 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5956 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5957 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5958 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5959 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5960 CRYPT_DecodeSignerArray
,
5961 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5962 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5965 TRACE("%p, %ld, %08lx, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5966 pDecodePara
, signedInfo
, pcbSignedInfo
);
5968 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5969 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5971 TRACE("returning %d\n", ret
);
5975 static BOOL
CRYPT_AsnDecodeRecipientInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5976 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5979 CMSG_KEY_TRANS_RECIPIENT_INFO
*info
= pvStructInfo
;
5980 struct AsnDecodeSequenceItem items
[] = {
5981 { ASN_INTEGER
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, dwVersion
),
5982 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5983 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5984 RecipientId
.IssuerSerialNumber
), CRYPT_AsnDecodeIssuerSerialNumber
,
5985 sizeof(CERT_ISSUER_SERIAL_NUMBER
), FALSE
, TRUE
,
5986 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5987 RecipientId
.IssuerSerialNumber
.Issuer
.pbData
), 0 },
5988 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5989 KeyEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5990 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5991 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5992 KeyEncryptionAlgorithm
.pszObjId
), 0 },
5993 { ASN_OCTETSTRING
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
),
5994 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
5995 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
.pbData
), 0 },
5998 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5999 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
6001 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6002 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
6003 pcbDecoded
, info
? info
->RecipientId
.IssuerSerialNumber
.Issuer
.pbData
:
6006 info
->RecipientId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
6007 TRACE("returning %d\n", ret
);
6011 static BOOL
CRYPT_DecodeRecipientInfoArray(const BYTE
*pbEncoded
,
6012 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6016 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
6017 offsetof(CRYPT_ENVELOPED_DATA
, cRecipientInfo
),
6018 offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
),
6019 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
6020 CRYPT_AsnDecodeRecipientInfo
, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO
), TRUE
,
6021 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
6022 RecipientId
.IssuerSerialNumber
.Issuer
.pbData
) };
6024 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
6025 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
6027 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
6028 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
6029 TRACE("returning %d\n", ret
);
6033 static BOOL
CRYPT_AsnDecodeEncryptedContentInfo(const BYTE
*pbEncoded
,
6034 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6038 CRYPT_ENCRYPTED_CONTENT_INFO
*info
= pvStructInfo
;
6039 struct AsnDecodeSequenceItem items
[] = {
6040 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
6041 contentType
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
6042 FALSE
, TRUE
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
6044 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
6045 contentEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
6046 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
6047 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
6048 contentEncryptionAlgorithm
.pszObjId
), 0 },
6049 { ASN_CONTEXT
| 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
6050 encryptedContent
), CRYPT_AsnDecodeOctets
,
6051 sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
6052 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
, encryptedContent
.pbData
) },
6055 TRACE("%p, %ld, %08lx, %p, %ld, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
6056 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
6058 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6059 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
6060 pcbDecoded
, info
? info
->contentType
: NULL
);
6061 TRACE("returning %d\n", ret
);
6065 BOOL
CRYPT_AsnDecodePKCSEnvelopedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
6066 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
6067 CRYPT_ENVELOPED_DATA
*envelopedData
, DWORD
*pcbEnvelopedData
)
6070 struct AsnDecodeSequenceItem items
[] = {
6071 { ASN_INTEGER
, offsetof(CRYPT_ENVELOPED_DATA
, version
),
6072 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
6073 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ENVELOPED_DATA
,
6074 cRecipientInfo
), CRYPT_DecodeRecipientInfoArray
,
6075 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
6076 FALSE
, TRUE
, offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
), 0 },
6077 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
),
6078 CRYPT_AsnDecodeEncryptedContentInfo
,
6079 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO
), FALSE
, TRUE
,
6080 offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
.contentType
), 0 },
6083 TRACE("%p, %ld, %08lx, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
6084 pDecodePara
, envelopedData
, pcbEnvelopedData
);
6086 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6087 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, envelopedData
,
6088 pcbEnvelopedData
, NULL
, NULL
);
6089 TRACE("returning %d\n", ret
);
6093 static BOOL WINAPI
CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType
,
6094 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6095 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6097 DWORD bytesNeeded
= 0;
6102 ret
= CRYPT_AsnDecodeOidInternal(pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
6103 NULL
, &bytesNeeded
, NULL
);
6107 *pcbStructInfo
= bytesNeeded
;
6108 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
6112 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6113 pvStructInfo
= *(BYTE
**)pvStructInfo
;
6115 info
= pvStructInfo
;
6116 *info
= (void *)((BYTE
*)info
+ sizeof(*info
));
6117 ret
= CRYPT_AsnDecodeOidInternal(pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
6118 pvStructInfo
, &bytesNeeded
, NULL
);
6119 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
6120 CRYPT_FreeSpace(pDecodePara
, info
);
6126 SetLastError(STATUS_ACCESS_VIOLATION
);
6133 static BOOL WINAPI
CRYPT_AsnDecodeEccSignature(DWORD dwCertEncodingType
,
6134 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6135 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6138 struct AsnDecodeSequenceItem items
[] = {
6139 { ASN_INTEGER
, offsetof(CERT_ECC_SIGNATURE
, r
),
6140 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_UINT_BLOB
), FALSE
,
6141 TRUE
, offsetof(CERT_ECC_SIGNATURE
, r
.pbData
), 0 },
6142 { ASN_INTEGER
, offsetof(CERT_ECC_SIGNATURE
, s
),
6143 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_UINT_BLOB
), FALSE
,
6144 TRUE
, offsetof(CERT_ECC_SIGNATURE
, s
.pbData
), 0 },
6149 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6150 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
6151 pcbStructInfo
, NULL
, NULL
);
6155 SetLastError(STATUS_ACCESS_VIOLATION
);
6162 static BOOL
CRYPT_AsnDecodeOCSPResponseStatus(const BYTE
*pbEncoded
,
6163 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6168 SetLastError(CRYPT_E_ASN1_EOD
);
6171 if (pbEncoded
[0] != ASN_ENUMERATED
)
6173 SetLastError(CRYPT_E_ASN1_BADTAG
);
6177 return CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
6178 pcbStructInfo
, pcbDecoded
);
6181 static BOOL
CRYPT_AsnDecodeOCSPResponseBytes(const BYTE
*pbEncoded
,
6182 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6190 SetLastError(CRYPT_E_ASN1_EOD
);
6193 if (pbEncoded
[0] != (ASN_CONTEXT
| ASN_CONSTRUCTOR
))
6195 SetLastError(CRYPT_E_ASN1_BADTAG
);
6199 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
6201 struct AsnDecodeSequenceItem items
[] = {
6202 { ASN_OBJECTIDENTIFIER
, 0,
6203 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
6205 { ASN_OCTETSTRING
, sizeof(LPSTR
),
6206 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
6207 sizeof(LPSTR
) + offsetof(CRYPT_OBJID_BLOB
, pbData
), 0 },
6209 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6214 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6215 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
, dwFlags
, NULL
,
6216 pvStructInfo
, pcbStructInfo
, &bytesNeeded
, NULL
);
6217 if (ret
) *pcbDecoded
= bytesNeeded
+ lenBytes
+ 1;
6223 static BOOL WINAPI
CRYPT_AsnDecodeOCSPResponse(DWORD dwCertEncodingType
,
6224 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6225 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6228 struct AsnDecodeSequenceItem items
[] = {
6229 { ASN_ENUMERATED
, offsetof(OCSP_RESPONSE_INFO
, dwStatus
),
6230 CRYPT_AsnDecodeOCSPResponseStatus
, sizeof(DWORD
), FALSE
, FALSE
,
6232 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(OCSP_RESPONSE_INFO
, pszObjId
),
6233 CRYPT_AsnDecodeOCSPResponseBytes
, sizeof(LPSTR
) + sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
6234 offsetof(OCSP_RESPONSE_INFO
, pszObjId
), 0 },
6239 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6240 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
6241 pcbStructInfo
, NULL
, NULL
);
6245 SetLastError(STATUS_ACCESS_VIOLATION
);
6252 static BOOL
CRYPT_AsnDecodeOCSPSignatureInfoCertEncoded(const BYTE
*pbEncoded
,
6253 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6257 DWORD data_len
, len_bytes
;
6258 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCE
,
6259 offsetof(OCSP_SIGNATURE_INFO
, cCertEncoded
), offsetof(OCSP_SIGNATURE_INFO
, rgCertEncoded
),
6260 FINALMEMBERSIZE(OCSP_SIGNATURE_INFO
, cCertEncoded
), verify_and_copy_certificate
,
6261 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
6263 if (pbEncoded
[0] != (ASN_CONTEXT
| ASN_CONSTRUCTOR
))
6265 WARN("Unexpected tag %#x.\n", pbEncoded
[0]);
6266 SetLastError(CRYPT_E_ASN1_BADTAG
);
6270 if (!(ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &data_len
))) return FALSE
;
6271 len_bytes
= GET_LEN_BYTES(pbEncoded
[1]);
6273 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
+ 1 + len_bytes
, cbEncoded
- 1 - len_bytes
,
6274 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
6276 *pcbDecoded
= 1 + len_bytes
+ data_len
;
6280 static BOOL WINAPI
CRYPT_AsnDecodeOCSPBasicSignedResponse(DWORD dwCertEncodingType
,
6281 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6282 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6285 struct AsnDecodeSequenceItem items
[] = {
6286 { 0, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, ToBeSigned
),
6287 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
6288 offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, ToBeSigned
.pbData
), 0 },
6289 { ASN_SEQUENCEOF
, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.SignatureAlgorithm
),
6290 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
6291 offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.SignatureAlgorithm
.pszObjId
), 0 },
6292 { ASN_BITSTRING
, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.Signature
),
6293 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
6294 offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.Signature
.pbData
) },
6295 { 0, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.cCertEncoded
),
6296 CRYPT_AsnDecodeOCSPSignatureInfoCertEncoded
, FINALMEMBERSIZE(OCSP_SIGNATURE_INFO
, cCertEncoded
),
6297 TRUE
, TRUE
, offsetof(OCSP_BASIC_SIGNED_RESPONSE_INFO
, SignatureInfo
.rgCertEncoded
) },
6302 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6303 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
6304 pcbStructInfo
, NULL
, NULL
);
6308 SetLastError(STATUS_ACCESS_VIOLATION
);
6315 static BOOL
CRYPT_AsnDecodeOCSPHashAlgorithm(const BYTE
*pbEncoded
,
6316 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6324 SetLastError(CRYPT_E_ASN1_EOD
);
6327 if (pbEncoded
[0] != ASN_SEQUENCEOF
)
6329 SetLastError(CRYPT_E_ASN1_BADTAG
);
6333 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
6335 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6339 ret
= CRYPT_AsnDecodeAlgorithmId(pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
, dwFlags
,
6340 pvStructInfo
, pcbStructInfo
, &bytesDecoded
);
6341 if (ret
) *pcbDecoded
= bytesDecoded
+ lenBytes
+ 1;
6347 static BOOL
CRYPT_AsnDecodeOCSPNextUpdate(const BYTE
*pbEncoded
,
6348 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6356 SetLastError(CRYPT_E_ASN1_EOD
);
6359 if (pbEncoded
[0] != (ASN_CONTEXT
| ASN_CONSTRUCTOR
))
6361 SetLastError(CRYPT_E_ASN1_BADTAG
);
6365 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
6367 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6371 ret
= CRYPT_AsnDecodeGeneralizedTime(pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
, dwFlags
,
6372 pvStructInfo
, pcbStructInfo
, &bytesDecoded
);
6373 if (ret
) *pcbDecoded
= bytesDecoded
+ lenBytes
+ 1;
6379 static BOOL
CRYPT_AsnDecodeCertStatus(const BYTE
*pbEncoded
,
6380 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6384 BYTE tag
= pbEncoded
[0] & ~3, status
= pbEncoded
[0] & 3;
6385 DWORD bytesNeeded
= FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, ThisUpdate
) -
6386 FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, dwCertStatus
);
6390 SetLastError(CRYPT_E_ASN1_EOD
);
6397 if (tag
!= ASN_CONTEXT
)
6399 WARN("Unexpected tag %02x\n", tag
);
6400 SetLastError(CRYPT_E_ASN1_BADTAG
);
6403 if (cbEncoded
< 2 || pbEncoded
[1])
6405 SetLastError(CRYPT_E_ASN1_CORRUPT
);
6409 *pcbStructInfo
= bytesNeeded
;
6410 else if (*pcbStructInfo
< bytesNeeded
)
6412 *pcbStructInfo
= bytesNeeded
;
6413 SetLastError(ERROR_MORE_DATA
);
6418 *(DWORD
*)pvStructInfo
= 0;
6419 *(OCSP_BASIC_REVOKED_INFO
**)((char *)pvStructInfo
6420 + FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, pRevokedInfo
)
6421 - FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, dwCertStatus
)) = NULL
;
6423 *pcbStructInfo
= bytesNeeded
;
6431 if (tag
!= (ASN_CONTEXT
| ASN_CONSTRUCTOR
))
6433 WARN("Unexpected tag %02x\n", tag
);
6434 SetLastError(CRYPT_E_ASN1_BADTAG
);
6437 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
6439 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6440 DWORD bytesDecoded
, size
;
6445 size
= sizeof(date
);
6446 ret
= CRYPT_AsnDecodeGeneralizedTime(pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
6447 dwFlags
, &date
, &size
, &bytesDecoded
);
6450 OCSP_BASIC_REVOKED_INFO
*info
;
6452 bytesNeeded
+= sizeof(*info
);
6454 *pcbStructInfo
= bytesNeeded
;
6455 else if (*pcbStructInfo
< bytesNeeded
)
6457 *pcbStructInfo
= bytesNeeded
;
6458 SetLastError(ERROR_MORE_DATA
);
6463 *(DWORD
*)pvStructInfo
= 1;
6464 info
= *(OCSP_BASIC_REVOKED_INFO
**)((char *)pvStructInfo
6465 + FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, pRevokedInfo
)
6466 - FIELD_OFFSET(OCSP_BASIC_RESPONSE_ENTRY
, dwCertStatus
));
6467 info
->RevocationDate
= date
;
6469 *pcbStructInfo
= bytesNeeded
;
6470 *pcbDecoded
= 1 + lenBytes
+ bytesDecoded
;
6477 FIXME("Unhandled status %u\n", status
);
6478 SetLastError(CRYPT_E_ASN1_BADTAG
);
6485 static BOOL
CRYPT_AsnDecodeOCSPBasicResponseEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
6486 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
6488 struct AsnDecodeSequenceItem items
[] = {
6489 { ASN_SEQUENCEOF
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.HashAlgorithm
.pszObjId
),
6490 CRYPT_AsnDecodeOCSPHashAlgorithm
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
6491 offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.HashAlgorithm
.pszObjId
), 0 },
6492 { ASN_OCTETSTRING
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.IssuerNameHash
),
6493 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
6494 offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.IssuerNameHash
.pbData
), 0 },
6495 { ASN_OCTETSTRING
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.IssuerKeyHash
),
6496 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
6497 offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.IssuerKeyHash
.pbData
), 0 },
6498 { ASN_INTEGER
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.SerialNumber
),
6499 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
6500 offsetof(OCSP_BASIC_RESPONSE_ENTRY
, CertId
.SerialNumber
.pbData
), 0 },
6501 { 0, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, dwCertStatus
),
6502 CRYPT_AsnDecodeCertStatus
, sizeof(DWORD
), FALSE
, TRUE
,
6503 offsetof(OCSP_BASIC_RESPONSE_ENTRY
, pRevokedInfo
), 0 },
6504 { ASN_GENERALTIME
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, ThisUpdate
),
6505 CRYPT_AsnDecodeGeneralizedTime
, sizeof(FILETIME
), FALSE
, FALSE
,
6507 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, NextUpdate
),
6508 CRYPT_AsnDecodeOCSPNextUpdate
, sizeof(FILETIME
), TRUE
, FALSE
,
6510 { ASN_CONTEXT
| ASN_CONSTRUCTOR
/* FIXME */, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, cExtension
),
6511 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(OCSP_BASIC_RESPONSE_ENTRY
, cExtension
),
6512 TRUE
, TRUE
, offsetof(OCSP_BASIC_RESPONSE_ENTRY
, rgExtension
), 0 },
6515 return CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6516 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
,
6517 pcbStructInfo
, pcbDecoded
, NULL
);
6520 static BOOL
CRYPT_AsnDecodeOCSPBasicResponseEntriesArray(const BYTE
*pbEncoded
,
6521 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6524 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
6525 offsetof(OCSP_BASIC_RESPONSE_INFO
, cResponseEntry
), offsetof(OCSP_BASIC_RESPONSE_INFO
, rgResponseEntry
),
6526 MEMBERSIZE(OCSP_BASIC_RESPONSE_INFO
, cResponseEntry
, cExtension
),
6527 CRYPT_AsnDecodeOCSPBasicResponseEntry
, sizeof(OCSP_BASIC_RESPONSE_ENTRY
),
6530 return CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
6531 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
6534 static BOOL
CRYPT_AsnDecodeResponderIDByName(const BYTE
*pbEncoded
,
6535 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6538 OCSP_BASIC_RESPONSE_INFO
*info
= pvStructInfo
;
6539 DWORD dataLen
, decodedLen
, lenBytes
, bytesNeeded
= sizeof(*info
);
6540 BYTE tag
= pbEncoded
[0] & ~3;
6541 CERT_NAME_BLOB
*blob
;
6543 if (tag
!= (ASN_CONTEXT
| ASN_CONSTRUCTOR
))
6545 WARN("Unexpected tag %02x\n", tag
);
6546 SetLastError(CRYPT_E_ASN1_BADTAG
);
6550 if (!CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
))
6552 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6553 cbEncoded
-= 1 + lenBytes
;
6555 if (dataLen
> cbEncoded
)
6557 SetLastError(CRYPT_E_ASN1_EOD
);
6560 pbEncoded
+= 1 + lenBytes
;
6561 decodedLen
= 1 + lenBytes
+ dataLen
;
6563 if (pbEncoded
[0] != ASN_SEQUENCE
)
6565 WARN("Unexpected tag %02x %02x\n", pbEncoded
[0], pbEncoded
[1]);
6566 SetLastError(CRYPT_E_ASN1_BADTAG
);
6570 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)) bytesNeeded
+= dataLen
;
6571 if (pvStructInfo
&& *pcbStructInfo
>= bytesNeeded
)
6573 info
->dwResponderIdChoice
= 1;
6575 blob
= &info
->ByNameResponderId
;
6576 blob
->cbData
= dataLen
;
6577 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
6578 blob
->pbData
= (BYTE
*)pbEncoded
;
6579 else if (blob
->cbData
)
6581 blob
->pbData
= (BYTE
*)(info
+ 1);
6582 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
6587 *pcbDecoded
= decodedLen
;
6591 *pcbStructInfo
= bytesNeeded
;
6595 if (*pcbStructInfo
< bytesNeeded
)
6597 SetLastError(ERROR_MORE_DATA
);
6598 *pcbStructInfo
= bytesNeeded
;
6602 *pcbStructInfo
= bytesNeeded
;
6606 static BOOL
CRYPT_AsnDecodeResponderIDByKey(const BYTE
*pbEncoded
,
6607 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6610 OCSP_BASIC_RESPONSE_INFO
*info
= pvStructInfo
;
6611 DWORD dataLen
, decodedLen
, lenBytes
, bytesNeeded
= sizeof(*info
), len
;
6612 BYTE tag
= pbEncoded
[0] & ~3;
6613 CRYPT_HASH_BLOB
*blob
;
6615 if (tag
!= (ASN_CONTEXT
| ASN_CONSTRUCTOR
))
6617 WARN("Unexpected tag %02x\n", tag
);
6618 SetLastError(CRYPT_E_ASN1_BADTAG
);
6622 if (!CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
))
6624 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6625 cbEncoded
-= 1 + lenBytes
;
6626 decodedLen
= 1 + lenBytes
;
6628 if (dataLen
> cbEncoded
)
6630 SetLastError(CRYPT_E_ASN1_EOD
);
6633 pbEncoded
+= 1 + lenBytes
;
6634 if (pbEncoded
[0] != ASN_OCTETSTRING
)
6636 WARN("Unexpected tag %02x\n", pbEncoded
[0]);
6637 SetLastError(CRYPT_E_ASN1_BADTAG
);
6641 if (!CRYPT_GetLen(pbEncoded
, cbEncoded
, &len
))
6643 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
6644 decodedLen
+= 1 + lenBytes
+ len
;
6645 cbEncoded
-= 1 + lenBytes
;
6647 if (len
> cbEncoded
)
6649 SetLastError(CRYPT_E_ASN1_EOD
);
6652 pbEncoded
+= 1 + lenBytes
;
6654 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)) bytesNeeded
+= len
;
6655 if (pvStructInfo
&& *pcbStructInfo
>= bytesNeeded
)
6657 info
->dwResponderIdChoice
= 2;
6658 blob
= &info
->ByKeyResponderId
;
6660 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
6661 blob
->pbData
= (BYTE
*)pbEncoded
;
6662 else if (blob
->cbData
)
6664 blob
->pbData
= (BYTE
*)(info
+ 1);
6665 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
6670 *pcbDecoded
= decodedLen
;
6674 *pcbStructInfo
= bytesNeeded
;
6678 if (*pcbStructInfo
< bytesNeeded
)
6680 SetLastError(ERROR_MORE_DATA
);
6681 *pcbStructInfo
= bytesNeeded
;
6685 *pcbStructInfo
= bytesNeeded
;
6689 static BOOL
CRYPT_AsnDecodeResponderID(const BYTE
*pbEncoded
,
6690 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
6693 BYTE choice
= pbEncoded
[0] & 3;
6695 TRACE("choice %02x\n", choice
);
6699 return CRYPT_AsnDecodeResponderIDByName(pbEncoded
, cbEncoded
, dwFlags
,
6700 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
6702 return CRYPT_AsnDecodeResponderIDByKey(pbEncoded
, cbEncoded
, dwFlags
,
6703 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
6705 WARN("Unexpected choice %02x\n", choice
);
6706 SetLastError(CRYPT_E_ASN1_CORRUPT
);
6711 static BOOL WINAPI
CRYPT_AsnDecodeOCSPBasicResponse(DWORD dwCertEncodingType
,
6712 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6713 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6715 struct AsnDecodeSequenceItem items
[] = {
6717 CRYPT_AsnDecodeResponderID
, offsetof(OCSP_BASIC_RESPONSE_INFO
, ProducedAt
), FALSE
, TRUE
,
6718 offsetof(OCSP_BASIC_RESPONSE_INFO
, ByNameResponderId
.pbData
), 0 },
6719 { ASN_GENERALTIME
, offsetof(OCSP_BASIC_RESPONSE_INFO
, ProducedAt
),
6720 CRYPT_AsnDecodeGeneralizedTime
, sizeof(FILETIME
), FALSE
, FALSE
,
6722 { ASN_SEQUENCEOF
, offsetof(OCSP_BASIC_RESPONSE_INFO
, cResponseEntry
),
6723 CRYPT_AsnDecodeOCSPBasicResponseEntriesArray
, MEMBERSIZE(OCSP_BASIC_RESPONSE_INFO
, cResponseEntry
, cExtension
),
6724 TRUE
, TRUE
, offsetof(OCSP_BASIC_RESPONSE_INFO
, rgResponseEntry
) },
6725 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(OCSP_BASIC_RESPONSE_INFO
, cExtension
),
6726 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(OCSP_BASIC_RESPONSE_INFO
, cExtension
),
6727 TRUE
, TRUE
, offsetof(OCSP_BASIC_RESPONSE_INFO
, rgExtension
), 0 },
6733 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6734 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
6735 pcbStructInfo
, NULL
, NULL
);
6739 SetLastError(STATUS_ACCESS_VIOLATION
);
6746 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
6747 LPCSTR lpszStructType
)
6749 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6751 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
6752 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
6754 SetLastError(ERROR_FILE_NOT_FOUND
);
6757 if (IS_INTOID(lpszStructType
))
6759 switch (LOWORD(lpszStructType
))
6761 case LOWORD(X509_CERT
):
6762 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
6764 case LOWORD(X509_CERT_TO_BE_SIGNED
):
6765 decodeFunc
= CRYPT_AsnDecodeCert
;
6767 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
6768 decodeFunc
= CRYPT_AsnDecodeCRL
;
6770 case LOWORD(X509_EXTENSIONS
):
6771 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6773 case LOWORD(X509_NAME_VALUE
):
6774 decodeFunc
= CRYPT_AsnDecodeNameValue
;
6776 case LOWORD(X509_NAME
):
6777 decodeFunc
= CRYPT_AsnDecodeName
;
6779 case LOWORD(X509_PUBLIC_KEY_INFO
):
6780 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
6782 case LOWORD(X509_AUTHORITY_KEY_ID
):
6783 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6785 case LOWORD(X509_ALTERNATE_NAME
):
6786 decodeFunc
= CRYPT_AsnDecodeAltName
;
6788 case LOWORD(X509_BASIC_CONSTRAINTS
):
6789 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6791 case LOWORD(X509_BASIC_CONSTRAINTS2
):
6792 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6794 case LOWORD(X509_CERT_POLICIES
):
6795 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6797 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
6798 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
6800 case LOWORD(PKCS_RSA_PRIVATE_KEY
):
6801 decodeFunc
= CRYPT_AsnDecodeRsaPrivKey
;
6803 case LOWORD(X509_UNICODE_NAME
):
6804 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
6806 case LOWORD(PKCS_ATTRIBUTE
):
6807 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
6809 case LOWORD(X509_UNICODE_NAME_VALUE
):
6810 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
6812 case LOWORD(X509_OCTET_STRING
):
6813 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6815 case LOWORD(X509_BITS
):
6816 case LOWORD(X509_KEY_USAGE
):
6817 decodeFunc
= CRYPT_AsnDecodeBits
;
6819 case LOWORD(X509_INTEGER
):
6820 decodeFunc
= CRYPT_AsnDecodeInt
;
6822 case LOWORD(X509_MULTI_BYTE_INTEGER
):
6823 decodeFunc
= CRYPT_AsnDecodeInteger
;
6825 case LOWORD(X509_MULTI_BYTE_UINT
):
6826 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
6828 case LOWORD(X509_ENUMERATED
):
6829 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6831 case LOWORD(X509_CHOICE_OF_TIME
):
6832 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
6834 case LOWORD(X509_AUTHORITY_KEY_ID2
):
6835 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6837 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
6838 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6840 case LOWORD(PKCS_CONTENT_INFO
):
6841 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
6843 case LOWORD(X509_SEQUENCE_OF_ANY
):
6844 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
6846 case LOWORD(PKCS_UTC_TIME
):
6847 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6849 case LOWORD(X509_CRL_DIST_POINTS
):
6850 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6852 case LOWORD(X509_ENHANCED_KEY_USAGE
):
6853 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6855 case LOWORD(PKCS_CTL
):
6856 decodeFunc
= CRYPT_AsnDecodeCTL
;
6858 case LOWORD(PKCS_SMIME_CAPABILITIES
):
6859 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6861 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
6862 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6864 case LOWORD(PKCS_ATTRIBUTES
):
6865 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
6867 case LOWORD(X509_ISSUING_DIST_POINT
):
6868 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6870 case LOWORD(X509_NAME_CONSTRAINTS
):
6871 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6873 case LOWORD(X509_POLICY_MAPPINGS
):
6874 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6876 case LOWORD(X509_POLICY_CONSTRAINTS
):
6877 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6879 case LOWORD(PKCS7_SIGNER_INFO
):
6880 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
6882 case LOWORD(CMS_SIGNER_INFO
):
6883 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
6885 case LOWORD(X509_OBJECT_IDENTIFIER
):
6886 decodeFunc
= CRYPT_AsnDecodeObjectIdentifier
;
6888 case LOWORD(X509_ECC_SIGNATURE
):
6889 decodeFunc
= CRYPT_AsnDecodeEccSignature
;
6891 case LOWORD(CNG_RSA_PUBLIC_KEY_BLOB
):
6892 decodeFunc
= CRYPT_AsnDecodeRsaPubKey_Bcrypt
;
6894 case LOWORD(OCSP_RESPONSE
):
6895 decodeFunc
= CRYPT_AsnDecodeOCSPResponse
;
6897 case LOWORD(OCSP_BASIC_SIGNED_RESPONSE
):
6898 decodeFunc
= CRYPT_AsnDecodeOCSPBasicSignedResponse
;
6900 case LOWORD(OCSP_BASIC_RESPONSE
):
6901 decodeFunc
= CRYPT_AsnDecodeOCSPBasicResponse
;
6907 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
6908 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6909 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
6910 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6911 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
6912 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6913 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
6914 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6915 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
6916 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6917 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
6918 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6919 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
6920 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6921 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
6922 decodeFunc
= CRYPT_AsnDecodeBits
;
6923 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
6924 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6925 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
6926 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6927 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
6928 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6929 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
6930 decodeFunc
= CRYPT_AsnDecodeAltName
;
6931 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
6932 decodeFunc
= CRYPT_AsnDecodeAltName
;
6933 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
6934 decodeFunc
= CRYPT_AsnDecodeAltName
;
6935 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
6936 decodeFunc
= CRYPT_AsnDecodeAltName
;
6937 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
6938 decodeFunc
= CRYPT_AsnDecodeAltName
;
6939 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
6940 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6941 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
6942 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6943 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
6944 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6945 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
6946 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6947 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
6948 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6949 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
6950 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6951 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
6952 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6953 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
6954 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6955 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
6956 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6957 else if (!strcmp(lpszStructType
, szOID_CTL
))
6958 decodeFunc
= CRYPT_AsnDecodeCTL
;
6959 else if (!strcmp(lpszStructType
, szOID_ECC_PUBLIC_KEY
))
6960 decodeFunc
= CRYPT_AsnDecodeObjectIdentifier
;
6964 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
6965 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6967 static HCRYPTOIDFUNCSET set
= NULL
;
6968 CryptDecodeObjectFunc decodeFunc
= NULL
;
6971 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
6972 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6973 (void **)&decodeFunc
, hFunc
);
6977 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
6978 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6980 static HCRYPTOIDFUNCSET set
= NULL
;
6981 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6984 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
6985 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6986 (void **)&decodeFunc
, hFunc
);
6990 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6991 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
6992 DWORD
*pcbStructInfo
)
6994 return CryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
6995 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
);
6998 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6999 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
7000 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
7003 CryptDecodeObjectExFunc decodeFunc
;
7004 HCRYPTOIDFUNCADDR hFunc
= NULL
;
7006 TRACE_(crypt
)("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p)\n",
7007 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
7008 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
7010 if (!pvStructInfo
&& !pcbStructInfo
)
7012 SetLastError(ERROR_INVALID_PARAMETER
);
7015 if (cbEncoded
> MAX_ENCODED_LEN
)
7017 FIXME_(crypt
)("Returning CRYPT_E_ASN1_LARGE, cbEncoded %lu.\n", cbEncoded
);
7018 SetLastError(CRYPT_E_ASN1_LARGE
);
7022 SetLastError(NOERROR
);
7023 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
7027 SetLastError(ERROR_INVALID_PARAMETER
);
7030 *(BYTE
**)pvStructInfo
= NULL
;
7032 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
7035 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
7036 debugstr_a(lpszStructType
));
7037 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
7041 if (IS_INTOID(lpszStructType
))
7042 FIXME("Unimplemented decoder for lpszStructType OID %d\n", LOWORD(lpszStructType
));
7044 FIXME("Unsupported decoder for lpszStructType %s\n", lpszStructType
);
7048 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
7049 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
7052 CryptDecodeObjectFunc pCryptDecodeObject
=
7053 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
7055 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
7056 * directly, as that could cause an infinite loop.
7058 if (pCryptDecodeObject
)
7060 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
7062 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
7063 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
7064 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
7065 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
7067 ret
= pCryptDecodeObject(dwCertEncodingType
,
7068 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
7069 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
7071 CRYPT_FreeSpace(pDecodePara
, *(BYTE
**)pvStructInfo
);
7075 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
7076 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
7080 CryptFreeOIDFunctionAddress(hFunc
, 0);
7081 TRACE_(crypt
)("returning %d\n", ret
);
7085 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
7089 TRACE_(crypt
)("(%p)\n", pPFX
);
7091 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
7092 * version integer of length 1 (3 encoded byes) and at least one other
7093 * datum (two encoded bytes), plus at least two bytes for the outer
7094 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
7096 if (pPFX
->cbData
< 7)
7098 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
7102 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
7104 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
7106 /* Need at least three bytes for the integer version */
7107 if (pPFX
->cbData
< 1 + lenLen
+ 3)
7109 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
7110 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
7111 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */