2 * Copyright 2005-2009 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
61 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
62 DWORD
, DWORD
, void *, DWORD
*);
63 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
64 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
66 /* Internal decoders don't do memory allocation or exception handling, and
67 * they report how many bytes they decoded.
69 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
70 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
72 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
73 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
75 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
76 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
78 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
80 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
81 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
82 /* Assumes algo->Parameters.pbData is set ahead of time. */
83 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
84 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
85 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
86 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
87 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
88 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
89 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
91 /* Doesn't check the tag, assumes the caller does so */
92 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
93 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
94 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
95 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
96 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
97 * member has been initialized, doesn't do exception handling, and doesn't do
98 * memory allocation. Also doesn't check tag, assumes the caller has checked
101 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
102 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
104 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
105 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
106 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
108 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
109 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
112 /* Gets the number of length bytes from the given (leading) length byte */
113 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
115 /* Helper function to get the encoded length of the data starting at pbEncoded,
116 * where pbEncoded[0] is the tag. If the data are too short to contain a
117 * length or if the length is too large for cbEncoded, sets an appropriate
118 * error code and returns FALSE. If the encoded length is unknown due to
119 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
121 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
128 SetLastError(CRYPT_E_ASN1_CORRUPT
);
131 else if (pbEncoded
[1] <= 0x7f)
133 if (pbEncoded
[1] + 1 > cbEncoded
)
135 SetLastError(CRYPT_E_ASN1_EOD
);
144 else if (pbEncoded
[1] == 0x80)
146 *len
= CMSG_INDEFINITE_LENGTH
;
151 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
153 if (lenLen
> sizeof(DWORD
) + 1)
155 SetLastError(CRYPT_E_ASN1_LARGE
);
158 else if (lenLen
+ 2 > cbEncoded
)
160 SetLastError(CRYPT_E_ASN1_CORRUPT
);
173 if (out
+ lenLen
+ 1 > cbEncoded
)
175 SetLastError(CRYPT_E_ASN1_EOD
);
188 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
189 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
193 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
194 *len
== CMSG_INDEFINITE_LENGTH
)
196 SetLastError(CRYPT_E_ASN1_CORRUPT
);
202 /* Helper function to check *pcbStructInfo, set it to the required size, and
203 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
204 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
205 * pointer to the newly allocated memory.
207 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
208 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
213 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
215 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
216 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
218 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
219 if (!*(BYTE
**)pvStructInfo
)
222 *pcbStructInfo
= bytesNeeded
;
224 else if (*pcbStructInfo
< bytesNeeded
)
226 *pcbStructInfo
= bytesNeeded
;
227 SetLastError(ERROR_MORE_DATA
);
231 *pcbStructInfo
= bytesNeeded
;
235 static void CRYPT_FreeSpace(PCRYPT_DECODE_PARA pDecodePara
, LPVOID pv
)
237 if (pDecodePara
&& pDecodePara
->pfnFree
)
238 pDecodePara
->pfnFree(pv
);
243 /* Helper function to check *pcbStructInfo and set it to the required size.
244 * Assumes pvStructInfo is not NULL.
246 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
250 if (*pcbStructInfo
< bytesNeeded
)
252 *pcbStructInfo
= bytesNeeded
;
253 SetLastError(ERROR_MORE_DATA
);
258 *pcbStructInfo
= bytesNeeded
;
265 * The expected tag of the item. If tag is 0, decodeFunc is called
266 * regardless of the tag value seen.
268 * A sequence is decoded into a struct. The offset member is the
269 * offset of this item within that struct.
271 * The decoder function to use. If this is NULL, then the member isn't
272 * decoded, but minSize space is reserved for it.
274 * The minimum amount of space occupied after decoding. You must set this.
276 * If true, and the tag doesn't match the expected tag for this item,
277 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
278 * filled with 0 for this member.
279 * hasPointer, pointerOffset:
280 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
281 * the offset within the struct of the data pointer (or to the
282 * first data pointer, if more than one exist).
284 * Used by CRYPT_AsnDecodeSequence, not for your use.
286 struct AsnDecodeSequenceItem
290 InternalDecodeFunc decodeFunc
;
298 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
299 #define MEMBERSIZE(s, member, nextmember) \
300 (offsetof(s, nextmember) - offsetof(s, member))
302 /* Decodes the items in a sequence, where the items are described in items,
303 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
304 * pvStructInfo. nextData is a pointer to the memory location at which the
305 * first decoded item with a dynamic pointer should point.
306 * Upon decoding, *cbDecoded is the total number of bytes decoded.
307 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
309 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
310 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
311 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
314 DWORD i
, decoded
= 0;
315 const BYTE
*ptr
= pbEncoded
;
317 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
318 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
320 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
322 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
326 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
327 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
329 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
331 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
333 DWORD itemEncodedLen
;
335 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
336 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
338 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
339 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
341 TRACE("Setting next pointer to %p\n",
343 *(BYTE
**)((BYTE
*)pvStructInfo
+
344 items
[i
].pointerOffset
) = nextData
;
346 if (items
[i
].decodeFunc
)
351 TRACE("decoding item %d\n", i
);
353 TRACE("sizing item %d\n", i
);
354 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
355 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
356 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
357 : NULL
, &items
[i
].size
, &itemDecoded
);
360 if (items
[i
].size
< items
[i
].minSize
)
361 items
[i
].size
= items
[i
].minSize
;
362 else if (items
[i
].size
> items
[i
].minSize
)
364 /* Account for alignment padding */
365 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
367 TRACE("item %d size: %d\n", i
, items
[i
].size
);
368 if (nextData
&& items
[i
].hasPointer
&&
369 items
[i
].size
> items
[i
].minSize
)
370 nextData
+= items
[i
].size
- items
[i
].minSize
;
371 if (itemDecoded
> itemEncodedLen
)
373 WARN("decoded length %d exceeds encoded %d\n",
374 itemDecoded
, itemEncodedLen
);
375 SetLastError(CRYPT_E_ASN1_CORRUPT
);
381 decoded
+= itemDecoded
;
382 TRACE("item %d: decoded %d bytes\n", i
,
386 else if (items
[i
].optional
&&
387 GetLastError() == CRYPT_E_ASN1_BADTAG
)
389 TRACE("skipping optional item %d\n", i
);
390 items
[i
].size
= items
[i
].minSize
;
391 SetLastError(NOERROR
);
395 TRACE("item %d failed: %08x\n", i
,
398 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
400 ERR("can't use indefinite length encoding without a decoder\n");
401 SetLastError(CRYPT_E_ASN1_CORRUPT
);
406 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
407 ptr
+= itemEncodedLen
;
408 decoded
+= itemEncodedLen
;
409 items
[i
].size
= items
[i
].minSize
;
412 else if (items
[i
].optional
)
414 TRACE("skipping optional item %d\n", i
);
415 items
[i
].size
= items
[i
].minSize
;
419 TRACE("item %d: tag %02x doesn't match expected %02x\n",
420 i
, ptr
[0], items
[i
].tag
);
421 SetLastError(CRYPT_E_ASN1_BADTAG
);
426 else if (items
[i
].optional
)
428 TRACE("missing optional item %d, skipping\n", i
);
429 items
[i
].size
= items
[i
].minSize
;
433 TRACE("not enough bytes for item %d, failing\n", i
);
434 SetLastError(CRYPT_E_ASN1_CORRUPT
);
439 *cbDecoded
= decoded
;
440 TRACE("returning %d\n", ret
);
444 /* This decodes an arbitrary sequence into a contiguous block of memory
445 * (basically, a struct.) Each element being decoded is described by a struct
446 * AsnDecodeSequenceItem, see above.
447 * startingPointer is an optional pointer to the first place where dynamic
448 * data will be stored. If you know the starting offset, you may pass it
449 * here. Otherwise, pass NULL, and one will be inferred from the items.
451 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
452 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
453 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
454 DWORD
*pcbDecoded
, void *startingPointer
)
458 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
459 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
464 SetLastError(CRYPT_E_ASN1_EOD
);
467 if (pbEncoded
[0] == ASN_SEQUENCE
)
471 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
473 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
474 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
475 BOOL indefinite
= FALSE
;
477 cbEncoded
-= 1 + lenBytes
;
478 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
483 else if (cbEncoded
< dataLen
)
485 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
487 SetLastError(CRYPT_E_ASN1_CORRUPT
);
492 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
493 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
494 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
496 if (cbDecoded
> cbEncoded
- 2)
498 /* Not enough space for 0 TLV */
499 SetLastError(CRYPT_E_ASN1_CORRUPT
);
502 else if (*(ptr
+ cbDecoded
) != 0 ||
503 *(ptr
+ cbDecoded
+ 1) != 0)
505 TRACE("expected 0 TLV\n");
506 SetLastError(CRYPT_E_ASN1_CORRUPT
);
513 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
515 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
517 SetLastError(CRYPT_E_ASN1_CORRUPT
);
522 DWORD i
, bytesNeeded
= 0, structSize
= 0;
524 for (i
= 0; i
< cItem
; i
++)
526 bytesNeeded
+= items
[i
].size
;
527 structSize
= max( structSize
, items
[i
].offset
+ items
[i
].minSize
);
530 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
532 *pcbStructInfo
= bytesNeeded
;
533 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
534 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
538 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
539 pvStructInfo
= *(BYTE
**)pvStructInfo
;
541 nextData
= startingPointer
;
543 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
544 memset(pvStructInfo
, 0, structSize
);
545 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
546 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
548 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
549 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
556 SetLastError(CRYPT_E_ASN1_BADTAG
);
559 TRACE("returning %d (%08x)\n", ret
, GetLastError());
564 * The expected tag of the entire encoded array (usually a variant
565 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
566 * regardless of the tag seen.
568 * The offset within the outer structure at which the count exists.
569 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
570 * while CRYPT_ATTRIBUTE has countOffset ==
571 * offsetof(CRYPT_ATTRIBUTE, cValue).
573 * The offset within the outer structure at which the array pointer exists.
574 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
575 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
577 * The minimum size of the decoded array. On WIN32, this is always 8:
578 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
581 * used to decode each item in the array
583 * is the minimum size of each decoded item
585 * indicates whether each item has a dynamic pointer
587 * indicates the offset within itemSize at which the pointer exists
589 struct AsnArrayDescriptor
595 InternalDecodeFunc decodeFunc
;
601 struct AsnArrayItemSize
607 /* Decodes an array of like types into a structure described by a struct
608 * AsnArrayDescriptor.
610 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
611 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
612 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
617 TRACE("%p, %p, %d, %p, %d\n", arrayDesc
, pbEncoded
,
618 cbEncoded
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
622 SetLastError(CRYPT_E_ASN1_EOD
);
625 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
629 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
631 DWORD bytesNeeded
= arrayDesc
->minArraySize
, cItems
= 0, decoded
;
632 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
633 /* There can be arbitrarily many items, but there is often only one.
635 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
637 decoded
= 1 + lenBytes
;
641 BOOL doneDecoding
= FALSE
;
643 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
645 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
652 SetLastError(CRYPT_E_ASN1_CORRUPT
);
659 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
663 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
665 /* Each item decoded may not tolerate extraneous bytes,
666 * so get the length of the next element if known.
668 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
669 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
671 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
672 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
674 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
678 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
679 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
684 if (itemSizes
!= &itemSize
)
685 itemSizes
= CryptMemRealloc(itemSizes
,
686 cItems
* sizeof(struct AsnArrayItemSize
));
691 cItems
* sizeof(struct AsnArrayItemSize
));
693 memcpy(itemSizes
, &itemSize
,
698 decoded
+= itemDecoded
;
699 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
700 itemSizes
[cItems
- 1].size
= size
;
713 *pcbDecoded
= decoded
;
715 *pcbStructInfo
= bytesNeeded
;
716 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
717 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
724 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
725 pvStructInfo
= *(void **)pvStructInfo
;
726 pcItems
= pvStructInfo
;
728 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
730 rgItems
= (BYTE
*)pvStructInfo
+
731 arrayDesc
->minArraySize
;
732 *(void **)((BYTE
*)pcItems
-
733 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
) =
737 rgItems
= *(void **)((BYTE
*)pcItems
-
738 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
);
739 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
740 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
741 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
746 if (arrayDesc
->hasPointer
)
747 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
748 + arrayDesc
->pointerOffset
) = nextData
;
749 ret
= arrayDesc
->decodeFunc(ptr
,
750 itemSizes
[i
].encodedLen
,
751 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
752 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
753 &itemSizes
[i
].size
, &itemDecoded
);
756 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
762 if (itemSizes
!= &itemSize
)
763 CryptMemFree(itemSizes
);
768 SetLastError(CRYPT_E_ASN1_BADTAG
);
774 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
775 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
776 * to CRYPT_E_ASN1_CORRUPT.
777 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
780 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
781 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
786 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
788 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
789 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
791 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
792 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
795 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
797 *pcbStructInfo
= bytesNeeded
;
798 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
800 CRYPT_DER_BLOB
*blob
;
802 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
803 pvStructInfo
= *(BYTE
**)pvStructInfo
;
805 blob
->cbData
= 1 + lenBytes
+ dataLen
;
808 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
809 blob
->pbData
= (BYTE
*)pbEncoded
;
812 assert(blob
->pbData
);
813 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
818 SetLastError(CRYPT_E_ASN1_CORRUPT
);
826 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
827 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
828 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
833 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
834 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
836 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
839 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
840 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
842 if (ret
&& pvStructInfo
)
844 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
851 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
853 temp
= blob
->pbData
[i
];
854 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
855 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
859 TRACE("returning %d (%08x)\n", ret
, GetLastError());
863 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
864 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
865 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
869 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
870 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
874 struct AsnDecodeSequenceItem items
[] = {
875 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
876 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
877 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
878 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
879 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
880 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
881 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
882 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
883 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
884 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
887 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
888 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
889 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
890 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
891 pcbStructInfo
, NULL
, NULL
);
895 SetLastError(STATUS_ACCESS_VIOLATION
);
900 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
904 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
905 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
910 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
912 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
914 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
915 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
917 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
922 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
923 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
927 struct AsnDecodeSequenceItem items
[] = {
928 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
929 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
930 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
931 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
934 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
935 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
940 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
941 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
945 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
946 offsetof(CERT_INFO
, cExtension
), offsetof(CERT_INFO
, rgExtension
),
947 FINALMEMBERSIZE(CERT_INFO
, cExtension
),
948 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
949 offsetof(CERT_EXTENSION
, pszObjId
) };
951 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
952 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
954 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
955 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
959 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
960 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
966 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
968 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
970 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
971 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
972 if (ret
&& pcbDecoded
)
973 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
978 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
979 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
980 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
983 struct AsnDecodeSequenceItem items
[] = {
984 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
985 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
986 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
987 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
988 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
989 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
990 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
991 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
992 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
993 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
995 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
996 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
998 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
999 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1001 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
1002 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
1003 FALSE
, TRUE
, offsetof(CERT_INFO
,
1004 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
1005 { ASN_CONTEXT
| 1, offsetof(CERT_INFO
, IssuerUniqueId
),
1006 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1007 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
1008 { ASN_CONTEXT
| 2, offsetof(CERT_INFO
, SubjectUniqueId
),
1009 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1010 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
1011 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
1012 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
1013 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1016 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1017 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1019 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1020 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1022 if (ret
&& pvStructInfo
)
1026 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1027 info
= *(CERT_INFO
**)pvStructInfo
;
1029 info
= pvStructInfo
;
1030 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1031 !info
->Subject
.cbData
)
1033 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1034 /* Don't need to deallocate, because it should have failed on the
1035 * first pass (and no memory was allocated.)
1041 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1045 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1046 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1047 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1051 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1052 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1058 /* Unless told not to, first try to decode it as a signed cert. */
1059 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1061 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1063 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1064 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1065 &signedCert
, &size
);
1069 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1070 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1071 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1072 pvStructInfo
, pcbStructInfo
);
1073 LocalFree(signedCert
);
1076 /* Failing that, try it as an unsigned cert */
1080 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1081 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1082 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1087 SetLastError(STATUS_ACCESS_VIOLATION
);
1091 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1095 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1096 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1100 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1101 offsetof(CRL_ENTRY
, cExtension
), offsetof(CRL_ENTRY
, rgExtension
),
1102 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
),
1103 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1104 offsetof(CERT_EXTENSION
, pszObjId
) };
1106 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1107 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1109 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1110 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1114 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1115 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1118 struct AsnDecodeSequenceItem items
[] = {
1119 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1120 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1121 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1122 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1123 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1124 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1125 CRYPT_AsnDecodeCRLEntryExtensions
,
1126 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1127 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1129 PCRL_ENTRY entry
= pvStructInfo
;
1131 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1134 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1135 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1136 entry
? entry
->SerialNumber
.pbData
: NULL
);
1137 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1139 WARN("empty CRL entry serial number\n");
1140 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1146 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1147 * whose rgCRLEntry member has been set prior to calling.
1149 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1150 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1153 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1154 offsetof(CRL_INFO
, cCRLEntry
), offsetof(CRL_INFO
, rgCRLEntry
),
1155 MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1156 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1157 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1159 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1160 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1162 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1163 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1164 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1168 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1169 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1173 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1174 offsetof(CRL_INFO
, cExtension
), offsetof(CRL_INFO
, rgExtension
),
1175 FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1176 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1177 offsetof(CERT_EXTENSION
, pszObjId
) };
1179 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1180 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1182 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1183 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1187 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1188 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1194 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1196 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1198 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1199 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1200 if (ret
&& pcbDecoded
)
1201 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1206 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1207 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1208 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1210 struct AsnDecodeSequenceItem items
[] = {
1211 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1212 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1213 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1214 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1215 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1216 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1217 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1219 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1220 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1221 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1222 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1223 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1224 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1225 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1226 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1227 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1228 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1232 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1233 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1235 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1236 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1239 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1243 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1244 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1245 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1249 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1250 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1256 /* Unless told not to, first try to decode it as a signed crl. */
1257 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1259 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1261 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1262 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1267 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1268 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1269 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1270 pvStructInfo
, pcbStructInfo
);
1271 LocalFree(signedCrl
);
1274 /* Failing that, try it as an unsigned crl */
1278 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1279 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1280 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1285 SetLastError(STATUS_ACCESS_VIOLATION
);
1289 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1293 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1294 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1299 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1300 pvStructInfo
, *pcbStructInfo
);
1302 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1304 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1305 DWORD bytesNeeded
= sizeof(LPSTR
);
1309 /* The largest possible string for the first two components
1310 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1315 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1316 pbEncoded
[1 + lenBytes
] / 40,
1317 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1319 bytesNeeded
+= strlen(firstTwo
) + 1;
1320 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1321 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1323 /* large enough for ".4000000" */
1327 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1334 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1337 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1344 snprintf(str
, sizeof(str
), ".%d", val
);
1345 bytesNeeded
+= strlen(str
);
1350 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1352 *pcbStructInfo
= bytesNeeded
;
1353 else if (*pcbStructInfo
< bytesNeeded
)
1355 *pcbStructInfo
= bytesNeeded
;
1356 SetLastError(ERROR_MORE_DATA
);
1364 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1367 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1368 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1370 pszObjId
+= strlen(pszObjId
);
1371 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1372 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1376 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1385 sprintf(pszObjId
, ".%d", val
);
1386 pszObjId
+= strlen(pszObjId
);
1390 *(LPSTR
*)pvStructInfo
= NULL
;
1391 *pcbStructInfo
= bytesNeeded
;
1397 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1398 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1402 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1403 pvStructInfo
, *pcbStructInfo
);
1405 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1406 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1407 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1410 SetLastError(CRYPT_E_ASN1_BADTAG
);
1416 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1417 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1419 struct AsnDecodeSequenceItem items
[] = {
1420 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1421 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1422 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1423 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1424 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1425 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1426 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1427 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1430 PCERT_EXTENSION ext
= pvStructInfo
;
1432 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1436 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1437 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1438 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1439 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1441 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1442 debugstr_a(ext
->pszObjId
));
1443 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1447 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1448 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1449 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1453 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1454 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1458 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1459 offsetof(CERT_EXTENSIONS
, cExtension
),
1460 offsetof(CERT_EXTENSIONS
, rgExtension
),
1461 sizeof(CERT_EXTENSIONS
),
1462 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1463 offsetof(CERT_EXTENSION
, pszObjId
) };
1465 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1466 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1470 SetLastError(STATUS_ACCESS_VIOLATION
);
1477 /* Warning: this assumes the address of value->Value.pbData is already set, in
1478 * order to avoid overwriting memory. (In some cases, it may change it, if it
1479 * doesn't copy anything to memory.) Be sure to set it correctly!
1481 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1482 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1487 CERT_NAME_VALUE
*value
= pvStructInfo
;
1489 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1491 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1492 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1494 switch (pbEncoded
[0])
1496 case ASN_OCTETSTRING
:
1497 valueType
= CERT_RDN_OCTET_STRING
;
1498 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1499 bytesNeeded
+= dataLen
;
1501 case ASN_NUMERICSTRING
:
1502 valueType
= CERT_RDN_NUMERIC_STRING
;
1503 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1504 bytesNeeded
+= dataLen
;
1506 case ASN_PRINTABLESTRING
:
1507 valueType
= CERT_RDN_PRINTABLE_STRING
;
1508 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1509 bytesNeeded
+= dataLen
;
1512 valueType
= CERT_RDN_IA5_STRING
;
1513 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1514 bytesNeeded
+= dataLen
;
1517 valueType
= CERT_RDN_T61_STRING
;
1518 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1519 bytesNeeded
+= dataLen
;
1521 case ASN_VIDEOTEXSTRING
:
1522 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1523 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1524 bytesNeeded
+= dataLen
;
1526 case ASN_GRAPHICSTRING
:
1527 valueType
= CERT_RDN_GRAPHIC_STRING
;
1528 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1529 bytesNeeded
+= dataLen
;
1531 case ASN_VISIBLESTRING
:
1532 valueType
= CERT_RDN_VISIBLE_STRING
;
1533 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1534 bytesNeeded
+= dataLen
;
1536 case ASN_GENERALSTRING
:
1537 valueType
= CERT_RDN_GENERAL_STRING
;
1538 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1539 bytesNeeded
+= dataLen
;
1541 case ASN_UNIVERSALSTRING
:
1542 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1543 SetLastError(CRYPT_E_ASN1_BADTAG
);
1546 valueType
= CERT_RDN_BMP_STRING
;
1547 bytesNeeded
+= dataLen
;
1549 case ASN_UTF8STRING
:
1550 valueType
= CERT_RDN_UTF8_STRING
;
1551 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1552 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1555 SetLastError(CRYPT_E_ASN1_BADTAG
);
1560 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1562 *pcbStructInfo
= bytesNeeded
;
1563 else if (*pcbStructInfo
< bytesNeeded
)
1565 *pcbStructInfo
= bytesNeeded
;
1566 SetLastError(ERROR_MORE_DATA
);
1571 *pcbStructInfo
= bytesNeeded
;
1572 value
->dwValueType
= valueType
;
1577 assert(value
->Value
.pbData
);
1578 switch (pbEncoded
[0])
1580 case ASN_OCTETSTRING
:
1581 case ASN_NUMERICSTRING
:
1582 case ASN_PRINTABLESTRING
:
1585 case ASN_VIDEOTEXSTRING
:
1586 case ASN_GRAPHICSTRING
:
1587 case ASN_VISIBLESTRING
:
1588 case ASN_GENERALSTRING
:
1589 value
->Value
.cbData
= dataLen
;
1592 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1593 memcpy(value
->Value
.pbData
,
1594 pbEncoded
+ 1 + lenBytes
, dataLen
);
1596 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1602 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1604 value
->Value
.cbData
= dataLen
;
1605 for (i
= 0; i
< dataLen
/ 2; i
++)
1606 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1607 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1610 case ASN_UTF8STRING
:
1612 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1614 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1615 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1616 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1623 value
->Value
.cbData
= 0;
1624 value
->Value
.pbData
= NULL
;
1631 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1632 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1633 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1639 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1640 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1641 if (ret
&& pvStructInfo
)
1643 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1644 pcbStructInfo
, *pcbStructInfo
);
1647 CERT_NAME_VALUE
*value
;
1649 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1650 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1651 value
= pvStructInfo
;
1652 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1653 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1654 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1655 pcbStructInfo
, NULL
);
1661 SetLastError(STATUS_ACCESS_VIOLATION
);
1668 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1669 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1674 CERT_NAME_VALUE
*value
= pvStructInfo
;
1676 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1678 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1679 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1681 switch (pbEncoded
[0])
1683 case ASN_NUMERICSTRING
:
1684 valueType
= CERT_RDN_NUMERIC_STRING
;
1686 bytesNeeded
+= (dataLen
+ 1) * 2;
1688 case ASN_PRINTABLESTRING
:
1689 valueType
= CERT_RDN_PRINTABLE_STRING
;
1691 bytesNeeded
+= (dataLen
+ 1) * 2;
1694 valueType
= CERT_RDN_IA5_STRING
;
1696 bytesNeeded
+= (dataLen
+ 1) * 2;
1699 valueType
= CERT_RDN_T61_STRING
;
1701 bytesNeeded
+= (dataLen
+ 1) * 2;
1703 case ASN_VIDEOTEXSTRING
:
1704 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1706 bytesNeeded
+= (dataLen
+ 1) * 2;
1708 case ASN_GRAPHICSTRING
:
1709 valueType
= CERT_RDN_GRAPHIC_STRING
;
1711 bytesNeeded
+= (dataLen
+ 1) * 2;
1713 case ASN_VISIBLESTRING
:
1714 valueType
= CERT_RDN_VISIBLE_STRING
;
1716 bytesNeeded
+= (dataLen
+ 1) * 2;
1718 case ASN_GENERALSTRING
:
1719 valueType
= CERT_RDN_GENERAL_STRING
;
1721 bytesNeeded
+= (dataLen
+ 1) * 2;
1723 case ASN_UNIVERSALSTRING
:
1724 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1726 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1729 valueType
= CERT_RDN_BMP_STRING
;
1731 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1733 case ASN_UTF8STRING
:
1734 valueType
= CERT_RDN_UTF8_STRING
;
1736 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1737 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1740 SetLastError(CRYPT_E_ASN1_BADTAG
);
1745 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1747 *pcbStructInfo
= bytesNeeded
;
1748 else if (*pcbStructInfo
< bytesNeeded
)
1750 *pcbStructInfo
= bytesNeeded
;
1751 SetLastError(ERROR_MORE_DATA
);
1756 *pcbStructInfo
= bytesNeeded
;
1757 value
->dwValueType
= valueType
;
1761 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1763 assert(value
->Value
.pbData
);
1764 switch (pbEncoded
[0])
1766 case ASN_NUMERICSTRING
:
1767 case ASN_PRINTABLESTRING
:
1770 case ASN_VIDEOTEXSTRING
:
1771 case ASN_GRAPHICSTRING
:
1772 case ASN_VISIBLESTRING
:
1773 case ASN_GENERALSTRING
:
1774 value
->Value
.cbData
= dataLen
* 2;
1775 for (i
= 0; i
< dataLen
; i
++)
1776 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1779 case ASN_UNIVERSALSTRING
:
1780 value
->Value
.cbData
= dataLen
/ 2;
1781 for (i
= 0; i
< dataLen
/ 4; i
++)
1782 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1783 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1787 value
->Value
.cbData
= dataLen
;
1788 for (i
= 0; i
< dataLen
/ 2; i
++)
1789 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1790 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1793 case ASN_UTF8STRING
:
1794 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1795 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1796 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1797 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1798 value
->Value
.cbData
+= sizeof(WCHAR
);
1804 value
->Value
.cbData
= 0;
1805 value
->Value
.pbData
= NULL
;
1812 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1813 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1814 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1820 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1821 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1822 if (ret
&& pvStructInfo
)
1824 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1825 pcbStructInfo
, *pcbStructInfo
);
1828 CERT_NAME_VALUE
*value
;
1830 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1831 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1832 value
= pvStructInfo
;
1833 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1834 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1835 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1836 pcbStructInfo
, NULL
);
1842 SetLastError(STATUS_ACCESS_VIOLATION
);
1849 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1850 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1853 struct AsnDecodeSequenceItem items
[] = {
1854 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1855 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1856 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1857 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1858 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1859 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1861 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1863 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1864 pvStructInfo
, *pcbStructInfo
);
1867 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1868 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1869 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1870 attr
? attr
->pszObjId
: NULL
);
1873 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1874 debugstr_a(attr
->pszObjId
));
1875 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1877 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1881 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1882 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1885 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1886 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1888 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1889 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1891 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1892 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1896 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1897 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1898 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1904 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1905 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1906 sizeof(CERT_NAME_INFO
),
1907 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1908 offsetof(CERT_RDN
, rgRDNAttr
) };
1911 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1912 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1917 *pcbStructInfo
= bytesNeeded
;
1918 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1919 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1921 CERT_NAME_INFO
*info
;
1923 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1924 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1925 info
= pvStructInfo
;
1926 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1927 sizeof(CERT_NAME_INFO
));
1928 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1929 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1930 &bytesNeeded
, NULL
);
1936 SetLastError(STATUS_ACCESS_VIOLATION
);
1943 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1944 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1948 struct AsnDecodeSequenceItem items
[] = {
1949 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1950 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1951 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1952 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1953 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1954 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1956 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1958 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1959 pvStructInfo
, *pcbStructInfo
);
1962 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1963 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
1964 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1965 attr
? attr
->pszObjId
: NULL
);
1968 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1969 debugstr_a(attr
->pszObjId
));
1970 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1972 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1976 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1977 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1980 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1981 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1983 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1984 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1986 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1987 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1991 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1992 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1993 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1999 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2000 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2001 sizeof(CERT_NAME_INFO
),
2002 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2003 offsetof(CERT_RDN
, rgRDNAttr
) };
2006 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2007 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2012 *pcbStructInfo
= bytesNeeded
;
2013 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2014 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2016 CERT_NAME_INFO
*info
;
2018 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2019 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2020 info
= pvStructInfo
;
2021 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2022 sizeof(CERT_NAME_INFO
));
2023 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2024 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2025 &bytesNeeded
, NULL
);
2031 SetLastError(STATUS_ACCESS_VIOLATION
);
2038 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2041 BOOL ret
= TRUE
, done
= FALSE
;
2042 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2044 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2051 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2054 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2056 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2058 indefiniteNestingLevels
++;
2059 pbEncoded
+= 1 + lenBytes
;
2060 cbEncoded
-= 1 + lenBytes
;
2061 decoded
+= 1 + lenBytes
;
2062 TRACE("indefiniteNestingLevels = %d\n",
2063 indefiniteNestingLevels
);
2067 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2068 indefiniteNestingLevels
)
2070 indefiniteNestingLevels
--;
2071 TRACE("indefiniteNestingLevels = %d\n",
2072 indefiniteNestingLevels
);
2074 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2075 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2076 decoded
+= 1 + lenBytes
+ dataLen
;
2077 if (!indefiniteNestingLevels
)
2081 } while (ret
&& !done
);
2082 /* If we haven't found all 0 TLVs, we haven't found the end */
2083 if (ret
&& indefiniteNestingLevels
)
2085 SetLastError(CRYPT_E_ASN1_EOD
);
2089 *pcbDecoded
= decoded
;
2090 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2094 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2095 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2099 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2101 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2102 pvStructInfo
, *pcbStructInfo
);
2104 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2106 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2107 bytesNeeded
+= encodedLen
;
2109 *pcbStructInfo
= bytesNeeded
;
2110 else if (*pcbStructInfo
< bytesNeeded
)
2112 SetLastError(ERROR_MORE_DATA
);
2113 *pcbStructInfo
= bytesNeeded
;
2118 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2120 *pcbStructInfo
= bytesNeeded
;
2121 blob
->cbData
= encodedLen
;
2124 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2125 blob
->pbData
= (LPBYTE
)pbEncoded
;
2128 assert(blob
->pbData
);
2129 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2133 blob
->pbData
= NULL
;
2136 *pcbDecoded
= encodedLen
;
2141 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2142 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2145 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2146 offsetof(CTL_USAGE
, cUsageIdentifier
),
2147 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2149 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2151 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2152 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2156 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2157 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2160 struct AsnArrayDescriptor arrayDesc
= { 0,
2161 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2162 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2163 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2164 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2167 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2168 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2172 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2173 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2175 struct AsnDecodeSequenceItem items
[] = {
2176 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2177 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2178 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2179 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2180 CRYPT_AsnDecodeCTLEntryAttributes
,
2181 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2182 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2185 CTL_ENTRY
*entry
= pvStructInfo
;
2187 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2190 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2191 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2192 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2196 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2197 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2200 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2201 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2202 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2203 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2204 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2206 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2207 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2209 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2210 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2214 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2215 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2219 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2220 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2221 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2222 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2223 offsetof(CERT_EXTENSION
, pszObjId
) };
2225 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2226 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2228 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2229 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2233 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2234 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2240 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2242 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2244 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2245 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2246 if (ret
&& pcbDecoded
)
2247 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2252 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2253 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2254 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2258 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2259 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2263 struct AsnDecodeSequenceItem items
[] = {
2264 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2265 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2266 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2267 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2268 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2269 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2270 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2271 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2272 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2273 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2274 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2275 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2276 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2278 { 0, offsetof(CTL_INFO
, NextUpdate
),
2279 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2281 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2282 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2283 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2284 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2285 CRYPT_AsnDecodeCTLEntries
,
2286 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2287 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2288 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2289 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2290 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2293 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2294 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2295 pcbStructInfo
, NULL
, NULL
);
2299 SetLastError(STATUS_ACCESS_VIOLATION
);
2305 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2306 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2310 struct AsnDecodeSequenceItem items
[] = {
2311 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2312 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2313 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2314 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2315 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2316 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2318 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2320 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2321 pvStructInfo
, *pcbStructInfo
);
2323 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2324 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2325 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2326 TRACE("returning %d\n", ret
);
2330 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2331 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2332 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2336 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2337 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2341 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2342 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2343 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2344 sizeof(CRYPT_SMIME_CAPABILITIES
),
2345 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2346 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2348 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2349 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2353 SetLastError(STATUS_ACCESS_VIOLATION
);
2356 TRACE("returning %d\n", ret
);
2360 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2361 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2366 LPSTR
*pStr
= pvStructInfo
;
2368 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2370 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2371 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2373 if (pbEncoded
[0] != ASN_IA5STRING
)
2375 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2380 bytesNeeded
+= dataLen
;
2382 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2384 *pcbStructInfo
= bytesNeeded
;
2385 else if (*pcbStructInfo
< bytesNeeded
)
2387 *pcbStructInfo
= bytesNeeded
;
2388 SetLastError(ERROR_MORE_DATA
);
2393 *pcbStructInfo
= bytesNeeded
;
2399 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2410 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2411 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2414 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2415 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2416 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2417 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2418 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2421 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2422 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2424 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2425 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2426 TRACE("returning %d\n", ret
);
2430 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2431 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2435 struct AsnDecodeSequenceItem items
[] = {
2436 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2437 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2438 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2439 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2440 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2441 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2442 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2443 rgNoticeNumbers
), 0 },
2447 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2448 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2450 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2451 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2455 /* The caller is expecting a pointer to a
2456 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2457 * CRYPT_AsnDecodeSequence is decoding a
2458 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2459 * needed, and decode again if the requisite space is available.
2461 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2463 *pcbStructInfo
= bytesNeeded
;
2464 else if (*pcbStructInfo
< bytesNeeded
)
2466 *pcbStructInfo
= bytesNeeded
;
2467 SetLastError(ERROR_MORE_DATA
);
2472 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2474 *pcbStructInfo
= bytesNeeded
;
2475 /* The pointer (pvStructInfo) passed in points to the first dynamic
2476 * pointer, so use it as the pointer to the
2477 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2478 * appropriate offset for the first dynamic pointer within the
2479 * notice reference by pointing to the first memory location past
2480 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2483 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2484 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2485 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2486 ret
= CRYPT_AsnDecodeSequence(items
,
2487 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2488 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
,
2489 noticeRef
->pszOrganization
);
2492 TRACE("returning %d\n", ret
);
2496 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2497 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2503 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2505 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2506 DWORD bytesNeeded
= sizeof(LPWSTR
);
2508 switch (pbEncoded
[0])
2510 case ASN_NUMERICSTRING
:
2512 bytesNeeded
+= (dataLen
+ 1) * 2;
2514 case ASN_PRINTABLESTRING
:
2516 bytesNeeded
+= (dataLen
+ 1) * 2;
2520 bytesNeeded
+= (dataLen
+ 1) * 2;
2524 bytesNeeded
+= (dataLen
+ 1) * 2;
2526 case ASN_VIDEOTEXSTRING
:
2528 bytesNeeded
+= (dataLen
+ 1) * 2;
2530 case ASN_GRAPHICSTRING
:
2532 bytesNeeded
+= (dataLen
+ 1) * 2;
2534 case ASN_VISIBLESTRING
:
2536 bytesNeeded
+= (dataLen
+ 1) * 2;
2538 case ASN_GENERALSTRING
:
2540 bytesNeeded
+= (dataLen
+ 1) * 2;
2542 case ASN_UNIVERSALSTRING
:
2544 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2548 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2550 case ASN_UTF8STRING
:
2552 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2553 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2556 SetLastError(CRYPT_E_ASN1_BADTAG
);
2561 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2563 *pcbStructInfo
= bytesNeeded
;
2564 else if (*pcbStructInfo
< bytesNeeded
)
2566 *pcbStructInfo
= bytesNeeded
;
2567 SetLastError(ERROR_MORE_DATA
);
2572 LPWSTR
*pStr
= pvStructInfo
;
2574 *pcbStructInfo
= bytesNeeded
;
2578 LPWSTR str
= *(LPWSTR
*)pStr
;
2581 switch (pbEncoded
[0])
2583 case ASN_NUMERICSTRING
:
2584 case ASN_PRINTABLESTRING
:
2587 case ASN_VIDEOTEXSTRING
:
2588 case ASN_GRAPHICSTRING
:
2589 case ASN_VISIBLESTRING
:
2590 case ASN_GENERALSTRING
:
2591 for (i
= 0; i
< dataLen
; i
++)
2592 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2595 case ASN_UNIVERSALSTRING
:
2596 for (i
= 0; i
< dataLen
/ 4; i
++)
2597 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2598 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2602 for (i
= 0; i
< dataLen
/ 2; i
++)
2603 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2604 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2607 case ASN_UTF8STRING
:
2609 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2610 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2611 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2624 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2625 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2626 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2629 struct AsnDecodeSequenceItem items
[] = {
2630 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2631 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2632 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2633 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2634 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2635 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2636 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2638 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2640 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2641 pvStructInfo
, *pcbStructInfo
);
2643 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2644 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2645 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2646 TRACE("returning %d\n", ret
);
2650 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2651 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2652 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2653 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2657 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2658 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2664 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2665 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2670 *pcbStructInfo
= bytesNeeded
;
2671 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2672 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2674 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2676 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2677 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2678 notice
= pvStructInfo
;
2679 notice
->pNoticeReference
=
2680 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2681 ((BYTE
*)pvStructInfo
+
2682 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2683 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2684 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2685 pvStructInfo
, &bytesNeeded
, NULL
);
2691 SetLastError(STATUS_ACCESS_VIOLATION
);
2694 TRACE("returning %d\n", ret
);
2698 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2699 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2703 struct AsnArrayDescriptor arrayDesc
= { 0,
2704 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2705 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2706 CRYPT_AsnDecodeCopyBytes
,
2707 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2709 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2710 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2712 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2713 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2717 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2718 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2722 struct AsnDecodeSequenceItem items
[] = {
2723 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2724 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2725 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2726 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2727 CRYPT_AsnDecodePKCSAttributeValue
,
2728 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2729 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2731 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2733 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2734 pvStructInfo
, *pcbStructInfo
);
2736 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2737 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2738 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2739 TRACE("returning %d\n", ret
);
2743 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2744 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2745 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2749 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2750 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2756 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2757 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2761 *pcbStructInfo
= bytesNeeded
;
2762 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2763 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2765 PCRYPT_ATTRIBUTE attr
;
2767 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2768 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2769 attr
= pvStructInfo
;
2770 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2771 sizeof(CRYPT_ATTRIBUTE
));
2772 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2773 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2780 SetLastError(STATUS_ACCESS_VIOLATION
);
2783 TRACE("returning %d\n", ret
);
2787 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2788 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2791 struct AsnArrayDescriptor arrayDesc
= { 0,
2792 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2793 sizeof(CRYPT_ATTRIBUTES
),
2794 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2795 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2798 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2799 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2803 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2804 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2805 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2809 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2810 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2814 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2815 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2816 sizeof(CRYPT_ATTRIBUTES
),
2817 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2818 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2820 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2821 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2825 SetLastError(STATUS_ACCESS_VIOLATION
);
2828 TRACE("returning %d\n", ret
);
2832 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2833 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2835 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2837 struct AsnDecodeSequenceItem items
[] = {
2838 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2839 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2840 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2841 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2842 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2843 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2846 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2847 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2849 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2850 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2851 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2852 if (ret
&& pvStructInfo
)
2854 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2855 debugstr_a(algo
->pszObjId
));
2860 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2861 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2865 struct AsnDecodeSequenceItem items
[] = {
2866 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2867 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2868 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2869 Algorithm
.pszObjId
) },
2870 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2871 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2872 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2874 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2876 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
2877 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2878 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2882 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2883 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2884 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2892 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2893 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2896 *pcbStructInfo
= bytesNeeded
;
2897 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2898 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2900 PCERT_PUBLIC_KEY_INFO info
;
2902 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2903 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2904 info
= pvStructInfo
;
2905 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2906 sizeof(CERT_PUBLIC_KEY_INFO
);
2907 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2908 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2909 &bytesNeeded
, NULL
);
2915 SetLastError(STATUS_ACCESS_VIOLATION
);
2922 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2923 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2929 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2932 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2934 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2937 if (pbEncoded
[1] > 1)
2939 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2946 *pcbStructInfo
= sizeof(BOOL
);
2949 else if (*pcbStructInfo
< sizeof(BOOL
))
2951 *pcbStructInfo
= sizeof(BOOL
);
2952 SetLastError(ERROR_MORE_DATA
);
2957 *pcbStructInfo
= sizeof(BOOL
);
2958 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2961 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2965 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2966 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2968 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2969 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2972 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2973 pvStructInfo
, *pcbStructInfo
);
2977 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2980 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2981 if (1 + lenBytes
> cbEncoded
)
2983 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2986 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2988 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2990 case 1: /* rfc822Name */
2991 case 2: /* dNSName */
2992 case 6: /* uniformResourceIdentifier */
2993 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
2995 SetLastError(CRYPT_E_ASN1_RULE
);
2999 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3001 case 4: /* directoryName */
3002 case 7: /* iPAddress */
3003 bytesNeeded
+= dataLen
;
3005 case 8: /* registeredID */
3006 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3010 /* FIXME: ugly, shouldn't need to know internals of OID decode
3011 * function to use it.
3013 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3016 case 0: /* otherName */
3017 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3018 SetLastError(CRYPT_E_ASN1_BADTAG
);
3021 case 3: /* x400Address, unimplemented */
3022 case 5: /* ediPartyName, unimplemented */
3023 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3024 SetLastError(CRYPT_E_ASN1_BADTAG
);
3028 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3029 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3035 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3037 *pcbStructInfo
= bytesNeeded
;
3038 else if (*pcbStructInfo
< bytesNeeded
)
3040 *pcbStructInfo
= bytesNeeded
;
3041 SetLastError(ERROR_MORE_DATA
);
3046 *pcbStructInfo
= bytesNeeded
;
3047 /* MS used values one greater than the asn1 ones.. sigh */
3048 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3049 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3051 case 1: /* rfc822Name */
3052 case 2: /* dNSName */
3053 case 6: /* uniformResourceIdentifier */
3057 for (i
= 0; i
< dataLen
; i
++)
3058 entry
->u
.pwszURL
[i
] =
3059 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3060 entry
->u
.pwszURL
[i
] = 0;
3061 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3062 debugstr_w(entry
->u
.pwszURL
));
3065 case 4: /* directoryName */
3066 /* The data are memory-equivalent with the IPAddress case,
3069 case 7: /* iPAddress */
3070 /* The next data pointer is in the pwszURL spot, that is,
3071 * the first 4 bytes. Need to move it to the next spot.
3073 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3074 entry
->u
.IPAddress
.cbData
= dataLen
;
3075 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3078 case 8: /* registeredID */
3079 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3080 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3089 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3090 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3094 struct AsnArrayDescriptor arrayDesc
= { 0,
3095 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3096 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3097 sizeof(CERT_ALT_NAME_INFO
),
3098 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3099 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3101 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3102 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3104 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3105 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3109 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3110 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3111 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3117 struct AsnDecodeSequenceItem items
[] = {
3118 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3119 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3120 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3121 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3122 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3123 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3124 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3125 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3126 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3127 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3128 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3131 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3132 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3133 pcbStructInfo
, NULL
, NULL
);
3137 SetLastError(STATUS_ACCESS_VIOLATION
);
3144 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3145 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3146 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3152 struct AsnDecodeSequenceItem items
[] = {
3153 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3154 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DATA_BLOB
),
3155 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3156 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3157 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3158 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3159 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3160 AuthorityCertIssuer
.rgAltEntry
), 0 },
3161 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3162 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3163 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3164 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3165 AuthorityCertSerialNumber
.pbData
), 0 },
3168 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3169 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3170 pcbStructInfo
, NULL
, NULL
);
3174 SetLastError(STATUS_ACCESS_VIOLATION
);
3181 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3182 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3185 struct AsnDecodeSequenceItem items
[] = {
3186 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3187 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3188 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3189 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3190 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3191 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3193 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3195 return CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3196 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3197 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3200 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3201 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3202 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3206 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3207 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3211 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3212 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3213 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3214 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3215 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3216 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3218 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3219 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3223 SetLastError(STATUS_ACCESS_VIOLATION
);
3230 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3231 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3236 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3237 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3239 /* The caller has already checked the tag, no need to check it again.
3240 * Check the outer length is valid:
3242 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3244 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3247 pbEncoded
+= 1 + lenBytes
;
3248 cbEncoded
-= 1 + lenBytes
;
3249 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3250 cbEncoded
-= 2; /* space for 0 TLV */
3251 /* Check the inner length is valid: */
3252 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3256 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3257 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3258 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3260 if (*(pbEncoded
+ decodedLen
) != 0 ||
3261 *(pbEncoded
+ decodedLen
+ 1) != 0)
3263 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3264 *(pbEncoded
+ decodedLen
),
3265 *(pbEncoded
+ decodedLen
+ 1));
3266 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3272 if (ret
&& pcbDecoded
)
3274 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3275 TRACE("decoded %d bytes\n", *pcbDecoded
);
3282 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3283 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3286 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3287 struct AsnDecodeSequenceItem items
[] = {
3288 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3289 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3290 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3291 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3292 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3293 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3294 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3298 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3299 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3301 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3302 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3303 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3307 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3308 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3309 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3313 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3314 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3318 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3319 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3320 if (ret
&& pvStructInfo
)
3322 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3323 pcbStructInfo
, *pcbStructInfo
);
3326 CRYPT_CONTENT_INFO
*info
;
3328 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3329 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3330 info
= pvStructInfo
;
3331 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3332 sizeof(CRYPT_CONTENT_INFO
));
3333 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3334 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3335 pcbStructInfo
, NULL
);
3341 SetLastError(STATUS_ACCESS_VIOLATION
);
3347 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3348 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3349 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3352 struct AsnDecodeSequenceItem items
[] = {
3353 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3354 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3355 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3356 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3357 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3359 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3360 CRYPT_AsnDecodePKCSContentInfoInternal
,
3361 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3362 ContentInfo
.pszObjId
), 0 },
3363 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3364 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3365 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3368 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3369 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3374 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3375 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3376 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3380 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3381 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3387 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3388 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3391 *pcbStructInfo
= bytesNeeded
;
3392 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3393 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3395 CERT_ALT_NAME_INFO
*name
;
3397 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3398 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3399 name
= pvStructInfo
;
3400 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3401 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3402 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3403 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3404 &bytesNeeded
, NULL
);
3410 SetLastError(STATUS_ACCESS_VIOLATION
);
3417 struct PATH_LEN_CONSTRAINT
3419 BOOL fPathLenConstraint
;
3420 DWORD dwPathLenConstraint
;
3423 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3424 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3428 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3430 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3431 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3435 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3437 *pcbStructInfo
= bytesNeeded
;
3439 else if (*pcbStructInfo
< bytesNeeded
)
3441 SetLastError(ERROR_MORE_DATA
);
3442 *pcbStructInfo
= bytesNeeded
;
3447 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3449 *pcbStructInfo
= bytesNeeded
;
3450 size
= sizeof(constraint
->dwPathLenConstraint
);
3451 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3452 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3454 constraint
->fPathLenConstraint
= TRUE
;
3455 TRACE("got an int, dwPathLenConstraint is %d\n",
3456 constraint
->dwPathLenConstraint
);
3458 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3462 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3463 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3467 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3468 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3469 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3470 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3471 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3472 offsetof(CERT_NAME_BLOB
, pbData
) };
3474 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3475 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3477 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3478 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3479 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3483 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3484 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3485 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3491 struct AsnDecodeSequenceItem items
[] = {
3492 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3493 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3494 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3495 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3496 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3497 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3498 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3499 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3500 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3502 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3505 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3506 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3507 pcbStructInfo
, NULL
, NULL
);
3511 SetLastError(STATUS_ACCESS_VIOLATION
);
3518 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3519 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3520 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3526 struct AsnDecodeSequenceItem items
[] = {
3527 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3528 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3529 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3530 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3531 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3534 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3535 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3536 pcbStructInfo
, NULL
, NULL
);
3540 SetLastError(STATUS_ACCESS_VIOLATION
);
3547 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3548 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3551 struct AsnDecodeSequenceItem items
[] = {
3552 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3553 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3554 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3556 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3557 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3558 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3561 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3563 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3564 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3566 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3567 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3568 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3572 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3573 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3577 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3578 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3579 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3580 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3581 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3582 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3584 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3585 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3587 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3588 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3589 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3593 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3594 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3596 struct AsnDecodeSequenceItem items
[] = {
3597 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3598 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3599 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3600 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3601 CRYPT_AsnDecodePolicyQualifiers
,
3602 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3603 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3605 CERT_POLICY_INFO
*info
= pvStructInfo
;
3608 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3609 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3611 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3612 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3613 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3617 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3618 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3619 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3623 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3624 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3628 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3629 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3630 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3631 sizeof(CERT_POLICIES_INFO
),
3632 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3633 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3635 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3636 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3640 SetLastError(STATUS_ACCESS_VIOLATION
);
3646 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3647 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3650 struct AsnDecodeSequenceItem items
[] = {
3651 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3652 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3653 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3654 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3655 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3656 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3658 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3661 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3662 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3664 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3665 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3666 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3670 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3671 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3672 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3676 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3677 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3681 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3682 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3683 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3684 sizeof(CERT_POLICY_MAPPING
),
3685 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3686 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3688 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3689 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3693 SetLastError(STATUS_ACCESS_VIOLATION
);
3699 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3700 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3704 DWORD skip
, size
= sizeof(skip
);
3708 SetLastError(CRYPT_E_ASN1_EOD
);
3711 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3713 SetLastError(CRYPT_E_ASN1_BADTAG
);
3716 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3717 &skip
, &size
, pcbDecoded
)))
3719 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3720 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3723 *pcbStructInfo
= bytesNeeded
;
3724 else if (*pcbStructInfo
< bytesNeeded
)
3726 *pcbStructInfo
= bytesNeeded
;
3727 SetLastError(ERROR_MORE_DATA
);
3732 CERT_POLICY_CONSTRAINTS_INFO
*info
=
3733 (CERT_POLICY_CONSTRAINTS_INFO
*)((BYTE
*)pvStructInfo
-
3734 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
));
3736 *pcbStructInfo
= bytesNeeded
;
3737 /* The BOOL is implicit: if the integer is present, then it's
3740 info
->fRequireExplicitPolicy
= TRUE
;
3741 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3747 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3748 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3752 DWORD skip
, size
= sizeof(skip
);
3756 SetLastError(CRYPT_E_ASN1_EOD
);
3759 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3761 SetLastError(CRYPT_E_ASN1_BADTAG
);
3764 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3765 &skip
, &size
, pcbDecoded
)))
3767 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3768 fInhibitPolicyMapping
);
3771 *pcbStructInfo
= bytesNeeded
;
3772 else if (*pcbStructInfo
< bytesNeeded
)
3774 *pcbStructInfo
= bytesNeeded
;
3775 SetLastError(ERROR_MORE_DATA
);
3780 CERT_POLICY_CONSTRAINTS_INFO
*info
=
3781 (CERT_POLICY_CONSTRAINTS_INFO
*)((BYTE
*)pvStructInfo
-
3782 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
));
3784 *pcbStructInfo
= bytesNeeded
;
3785 /* The BOOL is implicit: if the integer is present, then it's
3788 info
->fInhibitPolicyMapping
= TRUE
;
3789 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3795 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3796 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3797 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3798 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3802 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3803 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3807 struct AsnDecodeSequenceItem items
[] = {
3809 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3810 CRYPT_AsnDecodeRequireExplicit
,
3811 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3812 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3814 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3815 CRYPT_AsnDecodeInhibitMapping
,
3816 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3817 TRUE
, FALSE
, 0, 0 },
3820 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3821 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3822 pcbStructInfo
, NULL
, NULL
);
3826 SetLastError(STATUS_ACCESS_VIOLATION
);
3832 #define RSA1_MAGIC 0x31415352
3834 struct DECODED_RSA_PUB_KEY
3837 CRYPT_INTEGER_BLOB modulus
;
3840 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3841 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3842 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3848 struct AsnDecodeSequenceItem items
[] = {
3849 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3850 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3851 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3853 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3854 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3856 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3859 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
3860 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3864 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3865 decodedKey
->modulus
.cbData
;
3869 *pcbStructInfo
= bytesNeeded
;
3872 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3873 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3876 RSAPUBKEY
*rsaPubKey
;
3878 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3879 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3881 hdr
->bType
= PUBLICKEYBLOB
;
3882 hdr
->bVersion
= CUR_BLOB_VERSION
;
3884 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3885 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3886 sizeof(BLOBHEADER
));
3887 rsaPubKey
->magic
= RSA1_MAGIC
;
3888 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3889 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3890 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3891 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3892 decodedKey
->modulus
.cbData
);
3894 LocalFree(decodedKey
);
3899 SetLastError(STATUS_ACCESS_VIOLATION
);
3906 static BOOL
CRYPT_AsnDecodeOctetsInternal(const BYTE
*pbEncoded
,
3907 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3911 DWORD bytesNeeded
, dataLen
;
3913 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3914 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3916 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3918 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3920 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3921 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
3923 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
3925 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3927 *pcbStructInfo
= bytesNeeded
;
3928 else if (*pcbStructInfo
< bytesNeeded
)
3930 SetLastError(ERROR_MORE_DATA
);
3931 *pcbStructInfo
= bytesNeeded
;
3936 CRYPT_DATA_BLOB
*blob
;
3938 *pcbStructInfo
= bytesNeeded
;
3939 blob
= pvStructInfo
;
3940 blob
->cbData
= dataLen
;
3941 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3942 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
3945 assert(blob
->pbData
);
3947 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
3955 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
3956 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3957 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3961 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3962 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3970 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3973 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
3975 SetLastError(CRYPT_E_ASN1_BADTAG
);
3978 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3979 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3982 *pcbStructInfo
= bytesNeeded
;
3983 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3984 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3986 CRYPT_DATA_BLOB
*blob
;
3988 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3989 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3990 blob
= pvStructInfo
;
3991 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
3992 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
,
3993 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3994 &bytesNeeded
, NULL
);
4000 SetLastError(STATUS_ACCESS_VIOLATION
);
4007 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4008 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4011 DWORD bytesNeeded
, dataLen
;
4012 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4014 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4015 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4017 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4019 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4020 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4022 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4024 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4026 *pcbStructInfo
= bytesNeeded
;
4027 else if (*pcbStructInfo
< bytesNeeded
)
4029 *pcbStructInfo
= bytesNeeded
;
4030 SetLastError(ERROR_MORE_DATA
);
4035 CRYPT_BIT_BLOB
*blob
;
4037 *pcbStructInfo
= bytesNeeded
;
4038 blob
= pvStructInfo
;
4039 blob
->cbData
= dataLen
- 1;
4040 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4041 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4043 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4047 assert(blob
->pbData
);
4050 BYTE mask
= 0xff << blob
->cUnusedBits
;
4052 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4054 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4062 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4063 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4064 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4068 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4069 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4077 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4080 else if (pbEncoded
[0] != ASN_BITSTRING
)
4082 SetLastError(CRYPT_E_ASN1_BADTAG
);
4085 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4086 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4089 *pcbStructInfo
= bytesNeeded
;
4090 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4091 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4093 CRYPT_BIT_BLOB
*blob
;
4095 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4096 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4097 blob
= pvStructInfo
;
4098 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4099 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4100 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4101 &bytesNeeded
, NULL
);
4107 SetLastError(STATUS_ACCESS_VIOLATION
);
4111 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4115 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4116 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4117 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4122 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4124 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4127 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4128 if (dataLen
> sizeof(int))
4130 SetLastError(CRYPT_E_ASN1_LARGE
);
4133 else if (!pvStructInfo
)
4134 *pcbStructInfo
= sizeof(int);
4135 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4139 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4141 /* initialize to a negative value to sign-extend */
4146 for (i
= 0; i
< dataLen
; i
++)
4149 val
|= pbEncoded
[1 + lenBytes
+ i
];
4151 memcpy(pvStructInfo
, &val
, sizeof(int));
4157 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4158 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4159 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4169 SetLastError(CRYPT_E_ASN1_EOD
);
4172 else if (pbEncoded
[0] != ASN_INTEGER
)
4174 SetLastError(CRYPT_E_ASN1_BADTAG
);
4178 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4179 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4183 *pcbStructInfo
= bytesNeeded
;
4184 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4185 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4187 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4188 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4189 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4190 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4191 &bytesNeeded
, NULL
);
4197 SetLastError(STATUS_ACCESS_VIOLATION
);
4204 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4205 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4209 DWORD bytesNeeded
, dataLen
;
4211 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4213 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4215 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4217 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4219 *pcbStructInfo
= bytesNeeded
;
4220 else if (*pcbStructInfo
< bytesNeeded
)
4222 *pcbStructInfo
= bytesNeeded
;
4223 SetLastError(ERROR_MORE_DATA
);
4228 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4230 *pcbStructInfo
= bytesNeeded
;
4231 blob
->cbData
= dataLen
;
4232 assert(blob
->pbData
);
4237 for (i
= 0; i
< blob
->cbData
; i
++)
4239 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4248 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4249 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4250 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4258 if (pbEncoded
[0] != ASN_INTEGER
)
4260 SetLastError(CRYPT_E_ASN1_BADTAG
);
4264 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4265 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4269 *pcbStructInfo
= bytesNeeded
;
4270 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4271 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4273 CRYPT_INTEGER_BLOB
*blob
;
4275 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4276 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4277 blob
= pvStructInfo
;
4278 blob
->pbData
= (BYTE
*)pvStructInfo
+
4279 sizeof(CRYPT_INTEGER_BLOB
);
4280 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4281 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4282 &bytesNeeded
, NULL
);
4288 SetLastError(STATUS_ACCESS_VIOLATION
);
4295 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4296 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4301 if (pbEncoded
[0] == ASN_INTEGER
)
4303 DWORD bytesNeeded
, dataLen
;
4305 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4307 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4310 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4311 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4313 *pcbStructInfo
= bytesNeeded
;
4314 else if (*pcbStructInfo
< bytesNeeded
)
4316 *pcbStructInfo
= bytesNeeded
;
4317 SetLastError(ERROR_MORE_DATA
);
4322 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4324 *pcbStructInfo
= bytesNeeded
;
4325 blob
->cbData
= dataLen
;
4326 assert(blob
->pbData
);
4327 /* remove leading zero byte if it exists */
4328 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4337 for (i
= 0; i
< blob
->cbData
; i
++)
4339 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4348 SetLastError(CRYPT_E_ASN1_BADTAG
);
4354 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4355 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4356 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4364 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4365 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4368 *pcbStructInfo
= bytesNeeded
;
4369 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4370 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4372 CRYPT_INTEGER_BLOB
*blob
;
4374 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4375 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4376 blob
= pvStructInfo
;
4377 blob
->pbData
= (BYTE
*)pvStructInfo
+
4378 sizeof(CRYPT_INTEGER_BLOB
);
4379 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4380 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4381 &bytesNeeded
, NULL
);
4387 SetLastError(STATUS_ACCESS_VIOLATION
);
4394 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4395 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4396 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4402 *pcbStructInfo
= sizeof(int);
4407 if (pbEncoded
[0] == ASN_ENUMERATED
)
4409 unsigned int val
= 0, i
;
4413 SetLastError(CRYPT_E_ASN1_EOD
);
4416 else if (pbEncoded
[1] == 0)
4418 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4423 /* A little strange looking, but we have to accept a sign byte:
4424 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4425 * assuming a small length is okay here, it has to be in short
4428 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4430 SetLastError(CRYPT_E_ASN1_LARGE
);
4433 for (i
= 0; i
< pbEncoded
[1]; i
++)
4436 val
|= pbEncoded
[2 + i
];
4438 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4439 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4441 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4442 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4443 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4449 SetLastError(CRYPT_E_ASN1_BADTAG
);
4455 SetLastError(STATUS_ACCESS_VIOLATION
);
4462 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4465 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4470 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4472 if (!isdigit(*(pbEncoded))) \
4474 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4480 (word) += *(pbEncoded)++ - '0'; \
4485 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4486 SYSTEMTIME
*sysTime
)
4490 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4492 WORD hours
, minutes
= 0;
4493 BYTE sign
= *pbEncoded
++;
4496 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4497 if (ret
&& hours
>= 24)
4499 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4504 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4505 if (ret
&& minutes
>= 60)
4507 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4515 sysTime
->wHour
+= hours
;
4516 sysTime
->wMinute
+= minutes
;
4520 if (hours
> sysTime
->wHour
)
4523 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4526 sysTime
->wHour
-= hours
;
4527 if (minutes
> sysTime
->wMinute
)
4530 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4533 sysTime
->wMinute
-= minutes
;
4540 #define MIN_ENCODED_TIME_LENGTH 10
4542 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4543 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4548 if (pbEncoded
[0] == ASN_UTCTIME
)
4551 SetLastError(CRYPT_E_ASN1_EOD
);
4552 else if (pbEncoded
[1] > 0x7f)
4554 /* long-form date strings really can't be valid */
4555 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4559 SYSTEMTIME sysTime
= { 0 };
4560 BYTE len
= pbEncoded
[1];
4562 if (len
< MIN_ENCODED_TIME_LENGTH
)
4563 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4568 *pcbDecoded
= 2 + len
;
4570 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4571 if (sysTime
.wYear
>= 50)
4572 sysTime
.wYear
+= 1900;
4574 sysTime
.wYear
+= 2000;
4575 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4576 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4577 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4578 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4581 if (len
>= 2 && isdigit(*pbEncoded
) &&
4582 isdigit(*(pbEncoded
+ 1)))
4583 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4585 else if (isdigit(*pbEncoded
))
4586 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4589 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4595 *pcbStructInfo
= sizeof(FILETIME
);
4596 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4598 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4604 SetLastError(CRYPT_E_ASN1_BADTAG
);
4608 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4609 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4610 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4618 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4619 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4623 *pcbStructInfo
= bytesNeeded
;
4624 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4625 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4627 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4628 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4629 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4630 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4631 &bytesNeeded
, NULL
);
4637 SetLastError(STATUS_ACCESS_VIOLATION
);
4643 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4644 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4649 if (pbEncoded
[0] == ASN_GENERALTIME
)
4652 SetLastError(CRYPT_E_ASN1_EOD
);
4653 else if (pbEncoded
[1] > 0x7f)
4655 /* long-form date strings really can't be valid */
4656 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4660 BYTE len
= pbEncoded
[1];
4662 if (len
< MIN_ENCODED_TIME_LENGTH
)
4663 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4666 SYSTEMTIME sysTime
= { 0 };
4670 *pcbDecoded
= 2 + len
;
4672 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4673 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4674 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4675 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4678 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4681 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4683 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4690 /* workaround macro weirdness */
4691 digits
= min(len
, 3);
4692 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4693 sysTime
.wMilliseconds
);
4696 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4702 *pcbStructInfo
= sizeof(FILETIME
);
4703 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4705 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4711 SetLastError(CRYPT_E_ASN1_BADTAG
);
4715 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4716 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4720 InternalDecodeFunc decode
= NULL
;
4722 if (pbEncoded
[0] == ASN_UTCTIME
)
4723 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
4724 else if (pbEncoded
[0] == ASN_GENERALTIME
)
4725 decode
= CRYPT_AsnDecodeGeneralizedTime
;
4727 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
4728 pcbStructInfo
, pcbDecoded
);
4731 SetLastError(CRYPT_E_ASN1_BADTAG
);
4737 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
4738 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4739 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4747 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4748 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4752 *pcbStructInfo
= bytesNeeded
;
4753 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4754 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4756 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4757 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4758 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
4759 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4760 &bytesNeeded
, NULL
);
4766 SetLastError(STATUS_ACCESS_VIOLATION
);
4773 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
4774 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4775 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4781 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
4783 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
4785 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4790 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4791 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
4793 ptr
= pbEncoded
+ 1 + lenBytes
;
4794 remainingLen
= dataLen
;
4795 while (ret
&& remainingLen
)
4799 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4802 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4804 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4805 ptr
+= 1 + nextLenBytes
+ nextLen
;
4806 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
4807 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
4808 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
4814 CRYPT_SEQUENCE_OF_ANY
*seq
;
4819 *pcbStructInfo
= bytesNeeded
;
4820 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4821 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4823 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4824 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4826 seq
->cValue
= cValue
;
4827 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
4829 nextPtr
= (BYTE
*)seq
->rgValue
+
4830 cValue
* sizeof(CRYPT_DER_BLOB
);
4831 ptr
= pbEncoded
+ 1 + lenBytes
;
4832 remainingLen
= dataLen
;
4834 while (ret
&& remainingLen
)
4838 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
4841 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
4843 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
4845 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4846 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
4849 seq
->rgValue
[i
].pbData
= nextPtr
;
4850 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
4852 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
4854 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
4855 ptr
+= 1 + nextLenBytes
+ nextLen
;
4865 SetLastError(CRYPT_E_ASN1_BADTAG
);
4871 SetLastError(STATUS_ACCESS_VIOLATION
);
4878 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
4879 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4884 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
4886 DWORD bytesNeeded
, dataLen
;
4888 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4890 struct AsnArrayDescriptor arrayDesc
= {
4891 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
4892 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
4893 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
4894 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
4895 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
4896 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
4897 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4902 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4903 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4904 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
4905 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
4906 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
4909 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
4911 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4913 *pcbStructInfo
= bytesNeeded
;
4914 else if (*pcbStructInfo
< bytesNeeded
)
4916 *pcbStructInfo
= bytesNeeded
;
4917 SetLastError(ERROR_MORE_DATA
);
4922 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
4924 *pcbStructInfo
= bytesNeeded
;
4927 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
4928 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
4929 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
4930 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
4934 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
4940 SetLastError(CRYPT_E_ASN1_BADTAG
);
4946 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4947 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4949 struct AsnDecodeSequenceItem items
[] = {
4950 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
4951 DistPointName
), CRYPT_AsnDecodeDistPointName
,
4952 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
4953 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
4954 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
4955 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
4956 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
4957 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
4958 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
4959 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
4961 CRL_DIST_POINT
*point
= pvStructInfo
;
4964 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
4965 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
4966 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
4970 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
4971 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4972 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4976 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4977 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4981 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
4982 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
4983 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
4984 sizeof(CRL_DIST_POINTS_INFO
),
4985 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
4986 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
4988 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
4989 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
4993 SetLastError(STATUS_ACCESS_VIOLATION
);
5000 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5001 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5002 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5006 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5007 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5011 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5012 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5013 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5014 sizeof(CERT_ENHKEY_USAGE
),
5015 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5017 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5018 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5022 SetLastError(STATUS_ACCESS_VIOLATION
);
5029 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5030 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5031 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5035 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5036 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5040 struct AsnDecodeSequenceItem items
[] = {
5041 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5042 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5043 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5044 offsetof(CRL_ISSUING_DIST_POINT
,
5045 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5046 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5047 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5049 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5050 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5052 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5053 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5054 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5055 OnlySomeReasonFlags
.pbData
), 0 },
5056 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5057 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5060 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5061 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5062 pcbStructInfo
, NULL
, NULL
);
5066 SetLastError(STATUS_ACCESS_VIOLATION
);
5073 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5074 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5078 DWORD max
, size
= sizeof(max
);
5080 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5081 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5085 SetLastError(CRYPT_E_ASN1_EOD
);
5088 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5090 SetLastError(CRYPT_E_ASN1_BADTAG
);
5093 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5094 &max
, &size
, pcbDecoded
)))
5096 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5099 *pcbStructInfo
= bytesNeeded
;
5100 else if (*pcbStructInfo
< bytesNeeded
)
5102 *pcbStructInfo
= bytesNeeded
;
5103 SetLastError(ERROR_MORE_DATA
);
5108 CERT_GENERAL_SUBTREE
*subtree
= (CERT_GENERAL_SUBTREE
*)
5109 ((BYTE
*)pvStructInfo
- offsetof(CERT_GENERAL_SUBTREE
, fMaximum
));
5111 *pcbStructInfo
= bytesNeeded
;
5112 /* The BOOL is implicit: if the integer is present, then it's
5115 subtree
->fMaximum
= TRUE
;
5116 subtree
->dwMaximum
= max
;
5119 TRACE("returning %d\n", ret
);
5123 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5124 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5128 struct AsnDecodeSequenceItem items
[] = {
5129 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5130 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5131 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5132 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5133 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5134 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5135 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5136 TRUE
, FALSE
, 0, 0 },
5138 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5140 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5141 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5143 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5144 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5145 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5148 TRACE("%d\n", *pcbDecoded
);
5149 if (*pcbDecoded
< cbEncoded
)
5150 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5151 *(pbEncoded
+ *pcbDecoded
+ 1));
5153 TRACE("returning %d\n", ret
);
5157 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5158 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5162 struct AsnArrayDescriptor arrayDesc
= { 0,
5163 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5164 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5165 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5167 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5168 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5170 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5171 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5173 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5174 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5178 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5179 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5183 struct AsnArrayDescriptor arrayDesc
= { 0,
5184 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5185 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5186 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5187 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5188 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5190 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5191 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5193 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5194 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5198 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5199 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5200 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5204 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5205 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5209 struct AsnDecodeSequenceItem items
[] = {
5210 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5211 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5212 CRYPT_AsnDecodePermittedSubtree
,
5213 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5214 cExcludedSubtree
), TRUE
, TRUE
,
5215 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5216 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5217 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5218 CRYPT_AsnDecodeExcludedSubtree
,
5219 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5221 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5224 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5225 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5226 pcbStructInfo
, NULL
, NULL
);
5230 SetLastError(STATUS_ACCESS_VIOLATION
);
5236 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5237 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5241 struct AsnDecodeSequenceItem items
[] = {
5242 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5243 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5245 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5246 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5247 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5249 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5251 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5252 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5254 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5255 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5256 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5257 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5259 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5262 TRACE("returning %d\n", ret
);
5266 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5267 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5270 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5271 struct AsnDecodeSequenceItem items
[] = {
5272 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5273 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5274 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5275 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5276 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5277 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5278 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5279 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5280 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5281 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5282 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5283 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5284 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5285 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5286 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5287 HashEncryptionAlgorithm
.pszObjId
), 0 },
5288 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5289 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5290 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5291 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5292 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5293 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5294 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5298 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5299 pvStructInfo
, *pcbStructInfo
);
5301 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5302 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5303 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5307 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5308 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5309 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5313 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5314 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5318 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5319 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5320 if (ret
&& pvStructInfo
)
5322 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5323 pcbStructInfo
, *pcbStructInfo
);
5326 CMSG_SIGNER_INFO
*info
;
5328 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5329 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5330 info
= pvStructInfo
;
5331 info
->Issuer
.pbData
= ((BYTE
*)info
+
5332 sizeof(CMSG_SIGNER_INFO
));
5333 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5334 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5335 pcbStructInfo
, NULL
);
5341 SetLastError(STATUS_ACCESS_VIOLATION
);
5344 TRACE("returning %d\n", ret
);
5348 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5349 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5353 struct AsnArrayDescriptor arrayDesc
= { 0,
5354 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5355 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5356 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5357 CRYPT_AsnDecodeCopyBytes
,
5358 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5360 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5361 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5363 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5364 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5368 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5369 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5373 struct AsnArrayDescriptor arrayDesc
= { 0,
5374 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5375 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5376 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5377 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5378 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5380 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5381 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5383 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5384 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5388 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5389 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5392 CERT_ID
*id
= pvStructInfo
;
5395 if (*pbEncoded
== ASN_SEQUENCEOF
)
5397 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5398 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5402 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5403 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5404 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5405 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5407 *pcbStructInfo
= sizeof(CERT_ID
);
5410 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5412 ret
= CRYPT_AsnDecodeOctetsInternal(pbEncoded
, cbEncoded
, dwFlags
,
5413 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5417 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5418 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5419 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5420 sizeof(CRYPT_DATA_BLOB
);
5422 *pcbStructInfo
= sizeof(CERT_ID
);
5426 SetLastError(CRYPT_E_ASN1_BADTAG
);
5430 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5431 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5434 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5435 struct AsnDecodeSequenceItem items
[] = {
5436 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5437 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5438 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5439 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5440 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5441 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5442 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5443 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5444 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5445 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5446 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5447 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5448 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5449 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5450 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5451 HashEncryptionAlgorithm
.pszObjId
), 0 },
5452 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5453 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
5454 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5455 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5456 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5457 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5458 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5462 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5463 pvStructInfo
, *pcbStructInfo
);
5465 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5466 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5467 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5471 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5472 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5473 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5477 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5478 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5482 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5483 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5484 if (ret
&& pvStructInfo
)
5486 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5487 pcbStructInfo
, *pcbStructInfo
);
5490 CMSG_CMS_SIGNER_INFO
*info
;
5492 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5493 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5494 info
= pvStructInfo
;
5495 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5496 sizeof(CMSG_CMS_SIGNER_INFO
));
5497 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5498 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5499 pcbStructInfo
, NULL
);
5505 SetLastError(STATUS_ACCESS_VIOLATION
);
5508 TRACE("returning %d\n", ret
);
5512 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5513 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5516 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5517 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5518 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5519 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5520 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5521 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5523 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5524 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5526 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5527 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5531 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5532 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5533 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5536 struct AsnDecodeSequenceItem items
[] = {
5537 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5538 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5539 /* Placeholder for the hash algorithms - redundant with those in the
5540 * signers, so just ignore them.
5542 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5543 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5544 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5545 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5546 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5547 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5548 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5549 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5550 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5551 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5552 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5553 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5554 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5555 CRYPT_DecodeSignerArray
,
5556 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5557 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5560 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5561 pDecodePara
, signedInfo
, *pcbSignedInfo
);
5563 ret
= CRYPT_AsnDecodeSequence(items
, sizeof(items
) / sizeof(items
[0]),
5564 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5566 TRACE("returning %d\n", ret
);
5570 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
5571 LPCSTR lpszStructType
)
5573 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5575 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
5576 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
5578 SetLastError(ERROR_FILE_NOT_FOUND
);
5581 if (!HIWORD(lpszStructType
))
5583 switch (LOWORD(lpszStructType
))
5585 case LOWORD(X509_CERT
):
5586 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
5588 case LOWORD(X509_CERT_TO_BE_SIGNED
):
5589 decodeFunc
= CRYPT_AsnDecodeCert
;
5591 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
5592 decodeFunc
= CRYPT_AsnDecodeCRL
;
5594 case LOWORD(X509_EXTENSIONS
):
5595 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5597 case LOWORD(X509_NAME_VALUE
):
5598 decodeFunc
= CRYPT_AsnDecodeNameValue
;
5600 case LOWORD(X509_NAME
):
5601 decodeFunc
= CRYPT_AsnDecodeName
;
5603 case LOWORD(X509_PUBLIC_KEY_INFO
):
5604 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
5606 case LOWORD(X509_AUTHORITY_KEY_ID
):
5607 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5609 case LOWORD(X509_ALTERNATE_NAME
):
5610 decodeFunc
= CRYPT_AsnDecodeAltName
;
5612 case LOWORD(X509_BASIC_CONSTRAINTS
):
5613 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5615 case LOWORD(X509_BASIC_CONSTRAINTS2
):
5616 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5618 case LOWORD(X509_CERT_POLICIES
):
5619 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5621 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
5622 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
5624 case LOWORD(X509_UNICODE_NAME
):
5625 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
5627 case LOWORD(PKCS_ATTRIBUTE
):
5628 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
5630 case LOWORD(X509_UNICODE_NAME_VALUE
):
5631 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
5633 case LOWORD(X509_OCTET_STRING
):
5634 decodeFunc
= CRYPT_AsnDecodeOctets
;
5636 case LOWORD(X509_BITS
):
5637 case LOWORD(X509_KEY_USAGE
):
5638 decodeFunc
= CRYPT_AsnDecodeBits
;
5640 case LOWORD(X509_INTEGER
):
5641 decodeFunc
= CRYPT_AsnDecodeInt
;
5643 case LOWORD(X509_MULTI_BYTE_INTEGER
):
5644 decodeFunc
= CRYPT_AsnDecodeInteger
;
5646 case LOWORD(X509_MULTI_BYTE_UINT
):
5647 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
5649 case LOWORD(X509_ENUMERATED
):
5650 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5652 case LOWORD(X509_CHOICE_OF_TIME
):
5653 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
5655 case LOWORD(X509_AUTHORITY_KEY_ID2
):
5656 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5658 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
5659 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5661 case LOWORD(PKCS_CONTENT_INFO
):
5662 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
5664 case LOWORD(X509_SEQUENCE_OF_ANY
):
5665 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
5667 case LOWORD(PKCS_UTC_TIME
):
5668 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5670 case LOWORD(X509_CRL_DIST_POINTS
):
5671 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5673 case LOWORD(X509_ENHANCED_KEY_USAGE
):
5674 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5676 case LOWORD(PKCS_CTL
):
5677 decodeFunc
= CRYPT_AsnDecodeCTL
;
5679 case LOWORD(PKCS_SMIME_CAPABILITIES
):
5680 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5682 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
5683 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5685 case LOWORD(PKCS_ATTRIBUTES
):
5686 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
5688 case LOWORD(X509_ISSUING_DIST_POINT
):
5689 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5691 case LOWORD(X509_NAME_CONSTRAINTS
):
5692 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5694 case LOWORD(X509_POLICY_MAPPINGS
):
5695 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5697 case LOWORD(X509_POLICY_CONSTRAINTS
):
5698 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5700 case LOWORD(PKCS7_SIGNER_INFO
):
5701 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
5703 case LOWORD(CMS_SIGNER_INFO
):
5704 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
5708 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
5709 decodeFunc
= CRYPT_AsnDecodeExtensions
;
5710 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
5711 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
5712 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
5713 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
5714 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
5715 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
5716 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
5717 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5718 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
5719 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
5720 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
5721 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
5722 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
5723 decodeFunc
= CRYPT_AsnDecodeBits
;
5724 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
5725 decodeFunc
= CRYPT_AsnDecodeOctets
;
5726 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
5727 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
5728 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
5729 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
5730 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
5731 decodeFunc
= CRYPT_AsnDecodeAltName
;
5732 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
5733 decodeFunc
= CRYPT_AsnDecodeAltName
;
5734 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
5735 decodeFunc
= CRYPT_AsnDecodeAltName
;
5736 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
5737 decodeFunc
= CRYPT_AsnDecodeAltName
;
5738 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
5739 decodeFunc
= CRYPT_AsnDecodeAltName
;
5740 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
5741 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
5742 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
5743 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
5744 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
5745 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
5746 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
5747 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
5748 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
5749 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
5750 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
5751 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
5752 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
5753 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
5754 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
5755 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
5756 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
5757 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
5758 else if (!strcmp(lpszStructType
, szOID_CTL
))
5759 decodeFunc
= CRYPT_AsnDecodeCTL
;
5763 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
5764 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5766 static HCRYPTOIDFUNCSET set
= NULL
;
5767 CryptDecodeObjectFunc decodeFunc
= NULL
;
5770 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
5771 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5772 (void **)&decodeFunc
, hFunc
);
5776 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
5777 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
5779 static HCRYPTOIDFUNCSET set
= NULL
;
5780 CryptDecodeObjectExFunc decodeFunc
= NULL
;
5783 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
5784 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
5785 (void **)&decodeFunc
, hFunc
);
5789 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5790 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
5791 DWORD
*pcbStructInfo
)
5794 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
5795 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
5796 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5798 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
5799 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
5800 pvStructInfo
, pcbStructInfo
);
5802 if (!pvStructInfo
&& !pcbStructInfo
)
5804 SetLastError(ERROR_INVALID_PARAMETER
);
5807 if (cbEncoded
> MAX_ENCODED_LEN
)
5809 SetLastError(CRYPT_E_ASN1_LARGE
);
5813 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
5816 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5817 debugstr_a(lpszStructType
));
5818 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
5819 lpszStructType
, &hFunc
);
5820 if (!pCryptDecodeObject
)
5821 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
5822 lpszStructType
, &hFunc
);
5824 if (pCryptDecodeObject
)
5825 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5826 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5827 else if (pCryptDecodeObjectEx
)
5828 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
5829 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
5830 pvStructInfo
, pcbStructInfo
);
5832 CryptFreeOIDFunctionAddress(hFunc
, 0);
5833 TRACE_(crypt
)("returning %d\n", ret
);
5837 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
5838 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5839 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5842 CryptDecodeObjectExFunc decodeFunc
;
5843 HCRYPTOIDFUNCADDR hFunc
= NULL
;
5845 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
5846 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
5847 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5849 if (!pvStructInfo
&& !pcbStructInfo
)
5851 SetLastError(ERROR_INVALID_PARAMETER
);
5854 if (cbEncoded
> MAX_ENCODED_LEN
)
5856 SetLastError(CRYPT_E_ASN1_LARGE
);
5860 SetLastError(NOERROR
);
5861 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
5862 *(BYTE
**)pvStructInfo
= NULL
;
5863 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
5866 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
5867 debugstr_a(lpszStructType
));
5868 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
5872 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
5873 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
5876 CryptDecodeObjectFunc pCryptDecodeObject
=
5877 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
5879 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
5880 * directly, as that could cause an infinite loop.
5882 if (pCryptDecodeObject
)
5884 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5886 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5887 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
5888 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5889 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
5890 ret
= pCryptDecodeObject(dwCertEncodingType
,
5891 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
5892 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
5895 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
5896 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
5900 CryptFreeOIDFunctionAddress(hFunc
, 0);
5901 TRACE_(crypt
)("returning %d\n", ret
);
5905 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
5909 TRACE_(crypt
)("(%p)\n", pPFX
);
5911 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
5912 * version integer of length 1 (3 encoded byes) and at least one other
5913 * datum (two encoded bytes), plus at least two bytes for the outer
5914 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
5916 if (pPFX
->cbData
< 7)
5918 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
5922 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
5924 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
5926 /* Need at least three bytes for the integer version */
5927 if (pPFX
->cbData
< 1 + lenLen
+ 3)
5929 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
5930 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
5931 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */
5940 HCERTSTORE WINAPI
PFXImportCertStore(CRYPT_DATA_BLOB
*pPFX
, LPCWSTR szPassword
,
5943 FIXME_(crypt
)("(%p, %p, %08x): stub\n", pPFX
, szPassword
, dwFlags
);