2 * Copyright 2005-2009 Juan Lang
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 * This file implements ASN.1 DER decoding of a limited set of types.
19 * It isn't a full ASN.1 implementation. Microsoft implements BER
20 * encoding of many of the basic types in msasn1.dll, but that interface isn't
21 * implemented, so I implement them here.
24 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski
25 * (available online, look for a PDF copy as the HTML versions tend to have
26 * translation errors.)
28 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html
30 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject"
34 #include "wine/port.h"
41 #define NONAMELESSUNION
48 #include "wine/debug.h"
49 #include "wine/exception.h"
50 #include "crypt32_private.h"
52 /* This is a bit arbitrary, but to set some limit: */
53 #define MAX_ENCODED_LEN 0x02000000
55 #define ASN_FLAGS_MASK 0xe0
56 #define ASN_TYPE_MASK 0x1f
58 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
59 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
61 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
62 DWORD
, DWORD
, void *, DWORD
*);
63 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
64 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
66 /* Internal decoders don't do memory allocation or exception handling, and
67 * they report how many bytes they decoded.
69 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
70 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
72 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
73 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
75 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
76 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
78 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time.
80 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
81 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
82 /* Assumes algo->Parameters.pbData is set ahead of time. */
83 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
84 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
85 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
86 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
87 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
88 static BOOL
CRYPT_AsnDecodeOctets(const BYTE
*pbEncoded
,
89 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
91 /* Doesn't check the tag, assumes the caller does so */
92 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
93 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
94 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
95 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
96 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
97 * member has been initialized, doesn't do exception handling, and doesn't do
98 * memory allocation. Also doesn't check tag, assumes the caller has checked
101 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
102 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
104 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
105 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
106 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
108 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
109 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
112 /* Gets the number of length bytes from the given (leading) length byte */
113 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
115 /* Helper function to get the encoded length of the data starting at pbEncoded,
116 * where pbEncoded[0] is the tag. If the data are too short to contain a
117 * length or if the length is too large for cbEncoded, sets an appropriate
118 * error code and returns FALSE. If the encoded length is unknown due to
119 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
121 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
128 SetLastError(CRYPT_E_ASN1_CORRUPT
);
131 else if (pbEncoded
[1] <= 0x7f)
133 if (pbEncoded
[1] + 1 > cbEncoded
)
135 SetLastError(CRYPT_E_ASN1_EOD
);
144 else if (pbEncoded
[1] == 0x80)
146 *len
= CMSG_INDEFINITE_LENGTH
;
151 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
153 if (lenLen
> sizeof(DWORD
) + 1)
155 SetLastError(CRYPT_E_ASN1_LARGE
);
158 else if (lenLen
+ 2 > cbEncoded
)
160 SetLastError(CRYPT_E_ASN1_CORRUPT
);
173 if (out
+ lenLen
+ 1 > cbEncoded
)
175 SetLastError(CRYPT_E_ASN1_EOD
);
188 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
189 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
193 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
194 *len
== CMSG_INDEFINITE_LENGTH
)
196 SetLastError(CRYPT_E_ASN1_CORRUPT
);
202 /* Helper function to check *pcbStructInfo, set it to the required size, and
203 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
204 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
205 * pointer to the newly allocated memory.
207 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
208 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
213 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
215 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
216 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
218 *(BYTE
**)pvStructInfo
= LocalAlloc(LPTR
, bytesNeeded
);
219 if (!*(BYTE
**)pvStructInfo
)
222 *pcbStructInfo
= bytesNeeded
;
224 else if (*pcbStructInfo
< bytesNeeded
)
226 *pcbStructInfo
= bytesNeeded
;
227 SetLastError(ERROR_MORE_DATA
);
231 *pcbStructInfo
= bytesNeeded
;
235 static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA
*pDecodePara
, LPVOID pv
)
237 if (pDecodePara
&& pDecodePara
->pfnFree
)
238 pDecodePara
->pfnFree(pv
);
243 /* Helper function to check *pcbStructInfo and set it to the required size.
244 * Assumes pvStructInfo is not NULL.
246 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
250 if (*pcbStructInfo
< bytesNeeded
)
252 *pcbStructInfo
= bytesNeeded
;
253 SetLastError(ERROR_MORE_DATA
);
258 *pcbStructInfo
= bytesNeeded
;
265 * The expected tag of the item. If tag is 0, decodeFunc is called
266 * regardless of the tag value seen.
268 * A sequence is decoded into a struct. The offset member is the
269 * offset of this item within that struct.
271 * The decoder function to use. If this is NULL, then the member isn't
272 * decoded, but minSize space is reserved for it.
274 * The minimum amount of space occupied after decoding. You must set this.
276 * If true, and the tag doesn't match the expected tag for this item,
277 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
278 * filled with 0 for this member.
279 * hasPointer, pointerOffset:
280 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
281 * the offset within the struct of the data pointer (or to the
282 * first data pointer, if more than one exist).
284 * Used by CRYPT_AsnDecodeSequence, not for your use.
286 struct AsnDecodeSequenceItem
290 InternalDecodeFunc decodeFunc
;
298 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member))
299 #define MEMBERSIZE(s, member, nextmember) \
300 (offsetof(s, nextmember) - offsetof(s, member))
302 /* Decodes the items in a sequence, where the items are described in items,
303 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
304 * pvStructInfo. nextData is a pointer to the memory location at which the
305 * first decoded item with a dynamic pointer should point.
306 * Upon decoding, *cbDecoded is the total number of bytes decoded.
307 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
309 static BOOL
CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items
[],
310 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
311 void *pvStructInfo
, BYTE
*nextData
, DWORD
*cbDecoded
)
314 DWORD i
, decoded
= 0;
315 const BYTE
*ptr
= pbEncoded
;
317 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
318 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
320 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
322 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
326 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
327 cbEncoded
- (ptr
- pbEncoded
), &itemLen
)))
329 BYTE itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
331 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
333 DWORD itemEncodedLen
;
335 if (itemLen
== CMSG_INDEFINITE_LENGTH
)
336 itemEncodedLen
= cbEncoded
- (ptr
- pbEncoded
);
338 itemEncodedLen
= 1 + itemLenBytes
+ itemLen
;
339 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
341 TRACE("Setting next pointer to %p\n",
343 *(BYTE
**)((BYTE
*)pvStructInfo
+
344 items
[i
].pointerOffset
) = nextData
;
346 if (items
[i
].decodeFunc
)
351 TRACE("decoding item %d\n", i
);
353 TRACE("sizing item %d\n", i
);
354 ret
= items
[i
].decodeFunc(ptr
, itemEncodedLen
,
355 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
356 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
357 : NULL
, &items
[i
].size
, &itemDecoded
);
360 if (items
[i
].size
< items
[i
].minSize
)
361 items
[i
].size
= items
[i
].minSize
;
362 else if (items
[i
].size
> items
[i
].minSize
)
364 /* Account for alignment padding */
365 items
[i
].size
= ALIGN_DWORD_PTR(items
[i
].size
);
367 TRACE("item %d size: %d\n", i
, items
[i
].size
);
368 if (nextData
&& items
[i
].hasPointer
&&
369 items
[i
].size
> items
[i
].minSize
)
370 nextData
+= items
[i
].size
- items
[i
].minSize
;
371 if (itemDecoded
> itemEncodedLen
)
373 WARN("decoded length %d exceeds encoded %d\n",
374 itemDecoded
, itemEncodedLen
);
375 SetLastError(CRYPT_E_ASN1_CORRUPT
);
381 decoded
+= itemDecoded
;
382 TRACE("item %d: decoded %d bytes\n", i
,
386 else if (items
[i
].optional
&&
387 GetLastError() == CRYPT_E_ASN1_BADTAG
)
389 TRACE("skipping optional item %d\n", i
);
390 items
[i
].size
= items
[i
].minSize
;
391 SetLastError(NOERROR
);
395 TRACE("item %d failed: %08x\n", i
,
398 else if (itemLen
== CMSG_INDEFINITE_LENGTH
)
400 ERR("can't use indefinite length encoding without a decoder\n");
401 SetLastError(CRYPT_E_ASN1_CORRUPT
);
406 TRACE("item %d: decoded %d bytes\n", i
, itemEncodedLen
);
407 ptr
+= itemEncodedLen
;
408 decoded
+= itemEncodedLen
;
409 items
[i
].size
= items
[i
].minSize
;
412 else if (items
[i
].optional
)
414 TRACE("skipping optional item %d\n", i
);
415 items
[i
].size
= items
[i
].minSize
;
419 TRACE("item %d: tag %02x doesn't match expected %02x\n",
420 i
, ptr
[0], items
[i
].tag
);
421 SetLastError(CRYPT_E_ASN1_BADTAG
);
426 else if (items
[i
].optional
)
428 TRACE("missing optional item %d, skipping\n", i
);
429 items
[i
].size
= items
[i
].minSize
;
433 TRACE("not enough bytes for item %d, failing\n", i
);
434 SetLastError(CRYPT_E_ASN1_CORRUPT
);
439 *cbDecoded
= decoded
;
440 TRACE("returning %d\n", ret
);
444 /* This decodes an arbitrary sequence into a contiguous block of memory
445 * (basically, a struct.) Each element being decoded is described by a struct
446 * AsnDecodeSequenceItem, see above.
447 * startingPointer is an optional pointer to the first place where dynamic
448 * data will be stored. If you know the starting offset, you may pass it
449 * here. Otherwise, pass NULL, and one will be inferred from the items.
451 static BOOL
CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items
[],
452 DWORD cItem
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
453 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
454 DWORD
*pcbDecoded
, void *startingPointer
)
458 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
459 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
464 SetLastError(CRYPT_E_ASN1_EOD
);
467 if (pbEncoded
[0] == ASN_SEQUENCE
)
471 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
473 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
474 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
475 BOOL indefinite
= FALSE
;
477 cbEncoded
-= 1 + lenBytes
;
478 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
484 else if (cbEncoded
< dataLen
)
486 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
488 SetLastError(CRYPT_E_ASN1_CORRUPT
);
493 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
494 ptr
, dataLen
, dwFlags
, NULL
, NULL
, &cbDecoded
);
495 if (ret
&& dataLen
== CMSG_INDEFINITE_LENGTH
)
497 if (cbDecoded
> cbEncoded
- 2)
499 /* Not enough space for 0 TLV */
500 SetLastError(CRYPT_E_ASN1_CORRUPT
);
503 else if (*(ptr
+ cbDecoded
) != 0 ||
504 *(ptr
+ cbDecoded
+ 1) != 0)
506 TRACE("expected 0 TLV\n");
507 SetLastError(CRYPT_E_ASN1_CORRUPT
);
514 if (ret
&& !indefinite
&& cbDecoded
!= dataLen
)
516 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
518 SetLastError(CRYPT_E_ASN1_CORRUPT
);
523 DWORD i
, bytesNeeded
= 0, structSize
= 0;
525 for (i
= 0; i
< cItem
; i
++)
527 if (items
[i
].size
> items
[i
].minSize
)
528 bytesNeeded
+= items
[i
].size
- items
[i
].minSize
;
529 structSize
= max( structSize
, items
[i
].offset
+ items
[i
].minSize
);
531 bytesNeeded
+= structSize
;
533 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
535 *pcbStructInfo
= bytesNeeded
;
536 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
537 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
541 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
542 pvStructInfo
= *(BYTE
**)pvStructInfo
;
544 nextData
= startingPointer
;
546 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
547 memset(pvStructInfo
, 0, structSize
);
548 ret
= CRYPT_AsnDecodeSequenceItems(items
, cItem
,
549 ptr
, dataLen
, dwFlags
, pvStructInfo
, nextData
,
551 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
552 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
559 SetLastError(CRYPT_E_ASN1_BADTAG
);
562 TRACE("returning %d (%08x)\n", ret
, GetLastError());
567 * The expected tag of the entire encoded array (usually a variant
568 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
569 * regardless of the tag seen.
571 * The offset within the outer structure at which the count exists.
572 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0,
573 * while CRYPT_ATTRIBUTE has countOffset ==
574 * offsetof(CRYPT_ATTRIBUTE, cValue).
576 * The offset within the outer structure at which the array pointer exists.
577 * For example, CRYPT_ATTRIBUTES has arrayOffset ==
578 * offsetof(CRYPT_ATTRIBUTES, rgAttr).
580 * The minimum size of the decoded array. On WIN32, this is always 8:
581 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to
584 * used to decode each item in the array
586 * is the minimum size of each decoded item
588 * indicates whether each item has a dynamic pointer
590 * indicates the offset within itemSize at which the pointer exists
592 struct AsnArrayDescriptor
598 InternalDecodeFunc decodeFunc
;
604 struct AsnArrayItemSize
610 /* Decodes an array of like types into a structure described by a struct
611 * AsnArrayDescriptor.
613 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
614 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
615 const CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
620 TRACE("%p, %p, %d, %p, %d\n", arrayDesc
, pbEncoded
,
621 cbEncoded
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
625 SetLastError(CRYPT_E_ASN1_EOD
);
628 else if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
632 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
634 DWORD bytesNeeded
= arrayDesc
->minArraySize
, cItems
= 0, decoded
;
635 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
636 /* There can be arbitrarily many items, but there is often only one.
638 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
640 decoded
= 1 + lenBytes
;
644 BOOL doneDecoding
= FALSE
;
646 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
648 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
655 SetLastError(CRYPT_E_ASN1_CORRUPT
);
662 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
666 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
668 /* Each item decoded may not tolerate extraneous bytes,
669 * so get the length of the next element if known.
671 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
672 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
674 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
675 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
677 itemEncoded
= 1 + GET_LEN_BYTES(ptr
[1]) +
681 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
682 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
686 /* Ignore an item that failed to decode but the decoder doesn't want to fail the whole process */
694 if (itemSizes
!= &itemSize
)
695 itemSizes
= CryptMemRealloc(itemSizes
,
696 cItems
* sizeof(struct AsnArrayItemSize
));
701 cItems
* sizeof(struct AsnArrayItemSize
));
703 *itemSizes
= itemSize
;
707 decoded
+= itemDecoded
;
708 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
709 itemSizes
[cItems
- 1].size
= size
;
722 *pcbDecoded
= decoded
;
724 *pcbStructInfo
= bytesNeeded
;
725 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
726 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
733 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
734 pvStructInfo
= *(void **)pvStructInfo
;
735 pcItems
= pvStructInfo
;
737 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
739 rgItems
= (BYTE
*)pvStructInfo
+
740 arrayDesc
->minArraySize
;
741 *(void **)((BYTE
*)pcItems
-
742 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
) =
746 rgItems
= *(void **)((BYTE
*)pcItems
-
747 arrayDesc
->countOffset
+ arrayDesc
->arrayOffset
);
748 nextData
= (BYTE
*)rgItems
+ cItems
* arrayDesc
->itemSize
;
749 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
750 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
755 if (arrayDesc
->hasPointer
)
756 *(BYTE
**)((BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
757 + arrayDesc
->pointerOffset
) = nextData
;
758 ret
= arrayDesc
->decodeFunc(ptr
,
759 itemSizes
[i
].encodedLen
,
760 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
761 (BYTE
*)rgItems
+ i
* arrayDesc
->itemSize
,
762 &itemSizes
[i
].size
, &itemDecoded
);
765 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
769 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
770 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
773 if (itemSizes
!= &itemSize
)
774 CryptMemFree(itemSizes
);
779 SetLastError(CRYPT_E_ASN1_BADTAG
);
785 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
786 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
787 * to CRYPT_E_ASN1_CORRUPT.
788 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
791 static BOOL
CRYPT_AsnDecodeDerBlob(const BYTE
*pbEncoded
, DWORD cbEncoded
,
792 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
797 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
799 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
800 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
802 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
803 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
806 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
808 *pcbStructInfo
= bytesNeeded
;
809 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
811 CRYPT_DER_BLOB
*blob
;
813 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
814 pvStructInfo
= *(BYTE
**)pvStructInfo
;
816 blob
->cbData
= 1 + lenBytes
+ dataLen
;
819 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
820 blob
->pbData
= (BYTE
*)pbEncoded
;
823 assert(blob
->pbData
);
824 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
829 SetLastError(CRYPT_E_ASN1_CORRUPT
);
837 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
838 static BOOL
CRYPT_AsnDecodeBitsSwapBytes(const BYTE
*pbEncoded
,
839 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
844 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
845 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
847 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
850 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
851 dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pvStructInfo
, pcbStructInfo
,
853 if (ret
&& pvStructInfo
)
855 CRYPT_BIT_BLOB
*blob
= pvStructInfo
;
862 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
864 temp
= blob
->pbData
[i
];
865 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
866 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
870 TRACE("returning %d (%08x)\n", ret
, GetLastError());
874 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
875 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
876 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
880 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
881 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
885 struct AsnDecodeSequenceItem items
[] = {
886 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
887 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
888 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
889 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
890 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
891 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
892 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
893 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
894 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
895 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
898 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
899 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
900 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
901 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
902 pcbStructInfo
, NULL
, NULL
);
906 SetLastError(STATUS_ACCESS_VIOLATION
);
911 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
915 static BOOL
CRYPT_AsnDecodeCertVersion(const BYTE
*pbEncoded
, DWORD cbEncoded
,
916 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
921 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
923 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
925 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
+ 1 + lenBytes
, dataLen
,
926 dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
928 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
933 static BOOL
CRYPT_AsnDecodeValidity(const BYTE
*pbEncoded
, DWORD cbEncoded
,
934 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
938 struct AsnDecodeSequenceItem items
[] = {
939 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
940 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
941 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
942 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
945 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
946 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
951 static BOOL
CRYPT_AsnDecodeCertExtensionsInternal(const BYTE
*pbEncoded
,
952 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
956 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
957 offsetof(CERT_INFO
, cExtension
), offsetof(CERT_INFO
, rgExtension
),
958 FINALMEMBERSIZE(CERT_INFO
, cExtension
),
959 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
960 offsetof(CERT_EXTENSION
, pszObjId
) };
962 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
963 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
965 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
966 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
970 static BOOL
CRYPT_AsnDecodeCertExtensions(const BYTE
*pbEncoded
,
971 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
977 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
979 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
981 ret
= CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
982 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
983 if (ret
&& pcbDecoded
)
984 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
989 static BOOL
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
990 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
991 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
994 struct AsnDecodeSequenceItem items
[] = {
995 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
996 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
997 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
998 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
999 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
1000 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
1001 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1002 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1003 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1004 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1006 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
1007 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
1009 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
1010 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
1012 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
1013 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
1014 FALSE
, TRUE
, offsetof(CERT_INFO
,
1015 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
1016 { ASN_CONTEXT
| 1, offsetof(CERT_INFO
, IssuerUniqueId
),
1017 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1018 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
1019 { ASN_CONTEXT
| 2, offsetof(CERT_INFO
, SubjectUniqueId
),
1020 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1021 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
1022 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
1023 CRYPT_AsnDecodeCertExtensions
, FINALMEMBERSIZE(CERT_INFO
, cExtension
),
1024 TRUE
, TRUE
, offsetof(CERT_INFO
, rgExtension
), 0 },
1027 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1028 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1030 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1031 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
1033 if (ret
&& pvStructInfo
)
1037 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1038 info
= *(CERT_INFO
**)pvStructInfo
;
1040 info
= pvStructInfo
;
1041 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
1042 !info
->Subject
.cbData
)
1044 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1045 /* Don't need to deallocate, because it should have failed on the
1046 * first pass (and no memory was allocated.)
1052 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1056 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
1057 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1058 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1062 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1063 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1069 /* Unless told not to, first try to decode it as a signed cert. */
1070 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1072 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
1074 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1075 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1076 &signedCert
, &size
);
1080 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1081 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
1082 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1083 pvStructInfo
, pcbStructInfo
);
1084 LocalFree(signedCert
);
1087 /* Failing that, try it as an unsigned cert */
1091 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
1092 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
1093 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1098 SetLastError(STATUS_ACCESS_VIOLATION
);
1102 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1106 static BOOL
CRYPT_AsnDecodeCRLEntryExtensions(const BYTE
*pbEncoded
,
1107 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1111 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1112 offsetof(CRL_ENTRY
, cExtension
), offsetof(CRL_ENTRY
, rgExtension
),
1113 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
),
1114 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1115 offsetof(CERT_EXTENSION
, pszObjId
) };
1117 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1118 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1120 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1121 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1125 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1126 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1129 struct AsnDecodeSequenceItem items
[] = {
1130 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1131 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1132 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1133 { 0, offsetof(CRL_ENTRY
, RevocationDate
),
1134 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1135 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1136 CRYPT_AsnDecodeCRLEntryExtensions
,
1137 FINALMEMBERSIZE(CRL_ENTRY
, cExtension
), TRUE
, TRUE
,
1138 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1140 PCRL_ENTRY entry
= pvStructInfo
;
1142 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1145 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1146 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1147 entry
? entry
->SerialNumber
.pbData
: NULL
);
1148 if (ret
&& entry
&& !entry
->SerialNumber
.cbData
)
1150 WARN("empty CRL entry serial number\n");
1151 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1157 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO
1158 * whose rgCRLEntry member has been set prior to calling.
1160 static BOOL
CRYPT_AsnDecodeCRLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1161 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1164 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1165 offsetof(CRL_INFO
, cCRLEntry
), offsetof(CRL_INFO
, rgCRLEntry
),
1166 MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1167 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1168 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1170 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1171 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1173 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1174 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1175 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1179 static BOOL
CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE
*pbEncoded
,
1180 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1184 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1185 offsetof(CRL_INFO
, cExtension
), offsetof(CRL_INFO
, rgExtension
),
1186 FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1187 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1188 offsetof(CERT_EXTENSION
, pszObjId
) };
1190 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
1191 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
1193 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1194 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1198 static BOOL
CRYPT_AsnDecodeCRLExtensions(const BYTE
*pbEncoded
,
1199 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1205 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1207 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1209 ret
= CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
1210 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
1211 if (ret
&& pcbDecoded
)
1212 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1217 static BOOL
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1218 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1219 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1221 struct AsnDecodeSequenceItem items
[] = {
1222 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1223 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1224 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1225 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1226 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1227 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1228 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1230 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1231 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1232 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTimeInternal
,
1233 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1234 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1235 CRYPT_AsnDecodeCRLEntries
, MEMBERSIZE(CRL_INFO
, cCRLEntry
, cExtension
),
1236 TRUE
, TRUE
, offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1237 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1238 CRYPT_AsnDecodeCRLExtensions
, FINALMEMBERSIZE(CRL_INFO
, cExtension
),
1239 TRUE
, TRUE
, offsetof(CRL_INFO
, rgExtension
), 0 },
1243 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1244 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1246 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
), pbEncoded
, cbEncoded
, dwFlags
,
1247 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1249 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1253 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1254 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1255 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1259 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1260 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1266 /* Unless told not to, first try to decode it as a signed crl. */
1267 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1269 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1271 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1272 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1277 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1278 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1279 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1280 pvStructInfo
, pcbStructInfo
);
1281 LocalFree(signedCrl
);
1284 /* Failing that, try it as an unsigned crl */
1288 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1289 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1290 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1295 SetLastError(STATUS_ACCESS_VIOLATION
);
1299 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1303 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1304 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1309 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1310 pvStructInfo
, *pcbStructInfo
);
1312 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1314 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1315 DWORD bytesNeeded
= sizeof(LPSTR
);
1322 snprintf(str
, sizeof(str
), "%d.%d",
1323 pbEncoded
[1 + lenBytes
] / 40,
1324 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1326 bytesNeeded
+= strlen(str
) + 1;
1327 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1328 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1332 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1339 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1342 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1349 snprintf(str
, sizeof(str
), ".%d", val
);
1350 bytesNeeded
+= strlen(str
);
1355 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1357 *pcbStructInfo
= bytesNeeded
;
1358 else if (*pcbStructInfo
< bytesNeeded
)
1360 *pcbStructInfo
= bytesNeeded
;
1361 SetLastError(ERROR_MORE_DATA
);
1369 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1372 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1373 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1375 pszObjId
+= strlen(pszObjId
);
1376 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1377 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1381 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1390 sprintf(pszObjId
, ".%d", val
);
1391 pszObjId
+= strlen(pszObjId
);
1395 *(LPSTR
*)pvStructInfo
= NULL
;
1396 *pcbStructInfo
= bytesNeeded
;
1402 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1403 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1407 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1408 pvStructInfo
, *pcbStructInfo
);
1410 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1411 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1412 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1415 SetLastError(CRYPT_E_ASN1_BADTAG
);
1421 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1422 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1424 struct AsnDecodeSequenceItem items
[] = {
1425 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1426 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1427 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1428 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1429 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1430 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1431 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1432 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1435 PCERT_EXTENSION ext
= pvStructInfo
;
1437 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1441 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1442 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1443 pbEncoded
, cbEncoded
, dwFlags
, NULL
, ext
, pcbStructInfo
,
1444 pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1446 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1447 debugstr_a(ext
->pszObjId
));
1448 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1452 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1453 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1454 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1458 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1459 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
1463 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1464 offsetof(CERT_EXTENSIONS
, cExtension
),
1465 offsetof(CERT_EXTENSIONS
, rgExtension
),
1466 sizeof(CERT_EXTENSIONS
),
1467 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1468 offsetof(CERT_EXTENSION
, pszObjId
) };
1469 CERT_EXTENSIONS
*exts
= pvStructInfo
;
1471 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1472 exts
->rgExtension
= (CERT_EXTENSION
*)(exts
+ 1);
1473 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1474 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1478 SetLastError(STATUS_ACCESS_VIOLATION
);
1485 /* Warning: this assumes the address of value->Value.pbData is already set, in
1486 * order to avoid overwriting memory. (In some cases, it may change it, if it
1487 * doesn't copy anything to memory.) Be sure to set it correctly!
1489 static BOOL
CRYPT_AsnDecodeNameValueInternal(const BYTE
*pbEncoded
,
1490 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1495 CERT_NAME_VALUE
*value
= pvStructInfo
;
1497 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1499 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1500 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1502 switch (pbEncoded
[0])
1504 case ASN_OCTETSTRING
:
1505 valueType
= CERT_RDN_OCTET_STRING
;
1506 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1507 bytesNeeded
+= dataLen
;
1509 case ASN_NUMERICSTRING
:
1510 valueType
= CERT_RDN_NUMERIC_STRING
;
1511 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1512 bytesNeeded
+= dataLen
;
1514 case ASN_PRINTABLESTRING
:
1515 valueType
= CERT_RDN_PRINTABLE_STRING
;
1516 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1517 bytesNeeded
+= dataLen
;
1520 valueType
= CERT_RDN_IA5_STRING
;
1521 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1522 bytesNeeded
+= dataLen
;
1525 valueType
= CERT_RDN_T61_STRING
;
1526 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1527 bytesNeeded
+= dataLen
;
1529 case ASN_VIDEOTEXSTRING
:
1530 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1531 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1532 bytesNeeded
+= dataLen
;
1534 case ASN_GRAPHICSTRING
:
1535 valueType
= CERT_RDN_GRAPHIC_STRING
;
1536 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1537 bytesNeeded
+= dataLen
;
1539 case ASN_VISIBLESTRING
:
1540 valueType
= CERT_RDN_VISIBLE_STRING
;
1541 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1542 bytesNeeded
+= dataLen
;
1544 case ASN_GENERALSTRING
:
1545 valueType
= CERT_RDN_GENERAL_STRING
;
1546 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1547 bytesNeeded
+= dataLen
;
1549 case ASN_UNIVERSALSTRING
:
1550 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1551 SetLastError(CRYPT_E_ASN1_BADTAG
);
1554 valueType
= CERT_RDN_BMP_STRING
;
1555 bytesNeeded
+= dataLen
;
1557 case ASN_UTF8STRING
:
1558 valueType
= CERT_RDN_UTF8_STRING
;
1559 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1560 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * sizeof(WCHAR
);
1563 SetLastError(CRYPT_E_ASN1_BADTAG
);
1568 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1570 *pcbStructInfo
= bytesNeeded
;
1571 else if (*pcbStructInfo
< bytesNeeded
)
1573 *pcbStructInfo
= bytesNeeded
;
1574 SetLastError(ERROR_MORE_DATA
);
1579 *pcbStructInfo
= bytesNeeded
;
1580 value
->dwValueType
= valueType
;
1585 assert(value
->Value
.pbData
);
1586 switch (pbEncoded
[0])
1588 case ASN_OCTETSTRING
:
1589 case ASN_NUMERICSTRING
:
1590 case ASN_PRINTABLESTRING
:
1593 case ASN_VIDEOTEXSTRING
:
1594 case ASN_GRAPHICSTRING
:
1595 case ASN_VISIBLESTRING
:
1596 case ASN_GENERALSTRING
:
1597 value
->Value
.cbData
= dataLen
;
1598 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1599 memcpy(value
->Value
.pbData
,
1600 pbEncoded
+ 1 + lenBytes
, dataLen
);
1602 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1607 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1609 value
->Value
.cbData
= dataLen
;
1610 for (i
= 0; i
< dataLen
/ 2; i
++)
1611 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1612 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1615 case ASN_UTF8STRING
:
1617 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1619 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1620 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1621 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1628 value
->Value
.cbData
= 0;
1629 value
->Value
.pbData
= NULL
;
1636 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1637 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1638 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1644 ret
= CRYPT_AsnDecodeNameValueInternal(pbEncoded
, cbEncoded
,
1645 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1646 if (ret
&& pvStructInfo
)
1648 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1649 pcbStructInfo
, *pcbStructInfo
);
1652 CERT_NAME_VALUE
*value
;
1654 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1655 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1656 value
= pvStructInfo
;
1657 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1658 ret
= CRYPT_AsnDecodeNameValueInternal( pbEncoded
, cbEncoded
,
1659 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1660 pcbStructInfo
, NULL
);
1661 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1662 CRYPT_FreeSpace(pDecodePara
, value
);
1668 SetLastError(STATUS_ACCESS_VIOLATION
);
1675 static BOOL
CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE
*pbEncoded
,
1676 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1681 CERT_NAME_VALUE
*value
= pvStructInfo
;
1683 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1685 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1686 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1688 switch (pbEncoded
[0])
1690 case ASN_NUMERICSTRING
:
1691 valueType
= CERT_RDN_NUMERIC_STRING
;
1693 bytesNeeded
+= (dataLen
+ 1) * 2;
1695 case ASN_PRINTABLESTRING
:
1696 valueType
= CERT_RDN_PRINTABLE_STRING
;
1698 bytesNeeded
+= (dataLen
+ 1) * 2;
1701 valueType
= CERT_RDN_IA5_STRING
;
1703 bytesNeeded
+= (dataLen
+ 1) * 2;
1706 valueType
= CERT_RDN_T61_STRING
;
1708 bytesNeeded
+= (dataLen
+ 1) * 2;
1710 case ASN_VIDEOTEXSTRING
:
1711 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1713 bytesNeeded
+= (dataLen
+ 1) * 2;
1715 case ASN_GRAPHICSTRING
:
1716 valueType
= CERT_RDN_GRAPHIC_STRING
;
1718 bytesNeeded
+= (dataLen
+ 1) * 2;
1720 case ASN_VISIBLESTRING
:
1721 valueType
= CERT_RDN_VISIBLE_STRING
;
1723 bytesNeeded
+= (dataLen
+ 1) * 2;
1725 case ASN_GENERALSTRING
:
1726 valueType
= CERT_RDN_GENERAL_STRING
;
1728 bytesNeeded
+= (dataLen
+ 1) * 2;
1730 case ASN_UNIVERSALSTRING
:
1731 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1733 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
1736 valueType
= CERT_RDN_BMP_STRING
;
1738 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
1740 case ASN_UTF8STRING
:
1741 valueType
= CERT_RDN_UTF8_STRING
;
1743 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
1744 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
1747 SetLastError(CRYPT_E_ASN1_BADTAG
);
1752 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1754 *pcbStructInfo
= bytesNeeded
;
1755 else if (*pcbStructInfo
< bytesNeeded
)
1757 *pcbStructInfo
= bytesNeeded
;
1758 SetLastError(ERROR_MORE_DATA
);
1763 *pcbStructInfo
= bytesNeeded
;
1764 value
->dwValueType
= valueType
;
1768 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1770 assert(value
->Value
.pbData
);
1771 switch (pbEncoded
[0])
1773 case ASN_NUMERICSTRING
:
1774 case ASN_PRINTABLESTRING
:
1777 case ASN_VIDEOTEXSTRING
:
1778 case ASN_GRAPHICSTRING
:
1779 case ASN_VISIBLESTRING
:
1780 case ASN_GENERALSTRING
:
1781 value
->Value
.cbData
= dataLen
* 2;
1782 for (i
= 0; i
< dataLen
; i
++)
1783 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1786 case ASN_UNIVERSALSTRING
:
1787 value
->Value
.cbData
= dataLen
/ 2;
1788 for (i
= 0; i
< dataLen
/ 4; i
++)
1789 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1790 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1794 value
->Value
.cbData
= dataLen
;
1795 for (i
= 0; i
< dataLen
/ 2; i
++)
1796 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1797 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1800 case ASN_UTF8STRING
:
1801 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1802 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1803 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * sizeof(WCHAR
);
1804 *(WCHAR
*)(value
->Value
.pbData
+ value
->Value
.cbData
) = 0;
1805 value
->Value
.cbData
+= sizeof(WCHAR
);
1811 value
->Value
.cbData
= 0;
1812 value
->Value
.pbData
= NULL
;
1819 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1820 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1821 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1827 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
, cbEncoded
,
1828 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
1829 if (ret
&& pvStructInfo
)
1831 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1832 pcbStructInfo
, *pcbStructInfo
);
1835 CERT_NAME_VALUE
*value
;
1837 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1838 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1839 value
= pvStructInfo
;
1840 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1841 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded
,
1842 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
1843 pcbStructInfo
, NULL
);
1844 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1845 CRYPT_FreeSpace(pDecodePara
, value
);
1851 SetLastError(STATUS_ACCESS_VIOLATION
);
1858 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1859 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1862 struct AsnDecodeSequenceItem items
[] = {
1863 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1864 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1865 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1866 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1867 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1868 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1870 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1872 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1873 pvStructInfo
, *pcbStructInfo
);
1876 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1877 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1878 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1879 attr
? attr
->pszObjId
: NULL
);
1882 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1883 debugstr_a(attr
->pszObjId
));
1884 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1886 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1890 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1891 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1894 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1895 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1897 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1898 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1900 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1901 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1905 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1906 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1907 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1913 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1914 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
1915 sizeof(CERT_NAME_INFO
),
1916 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1917 offsetof(CERT_RDN
, rgRDNAttr
) };
1918 DWORD bytesNeeded
= 0;
1920 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1921 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
1926 *pcbStructInfo
= bytesNeeded
;
1927 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1928 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1930 CERT_NAME_INFO
*info
;
1932 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1933 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1934 info
= pvStructInfo
;
1935 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
1936 sizeof(CERT_NAME_INFO
));
1937 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
1938 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1939 &bytesNeeded
, NULL
);
1940 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
1941 CRYPT_FreeSpace(pDecodePara
, info
);
1947 SetLastError(STATUS_ACCESS_VIOLATION
);
1954 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1955 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1959 struct AsnDecodeSequenceItem items
[] = {
1960 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1961 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1962 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1963 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1964 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1965 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1967 CERT_RDN_ATTR
*attr
= pvStructInfo
;
1969 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1970 pvStructInfo
, *pcbStructInfo
);
1973 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1974 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
1975 pbEncoded
, cbEncoded
, dwFlags
, NULL
, attr
, pcbStructInfo
, pcbDecoded
,
1976 attr
? attr
->pszObjId
: NULL
);
1979 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1980 debugstr_a(attr
->pszObjId
));
1981 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1983 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1987 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1988 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1991 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1992 offsetof(CERT_RDN
, cRDNAttr
), offsetof(CERT_RDN
, rgRDNAttr
),
1994 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1995 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1997 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1998 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2002 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
2003 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2004 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2010 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2011 offsetof(CERT_NAME_INFO
, cRDN
), offsetof(CERT_NAME_INFO
, rgRDN
),
2012 sizeof(CERT_NAME_INFO
),
2013 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
2014 offsetof(CERT_RDN
, rgRDNAttr
) };
2015 DWORD bytesNeeded
= 0;
2017 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2018 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
,
2023 *pcbStructInfo
= bytesNeeded
;
2024 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2025 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2027 CERT_NAME_INFO
*info
;
2029 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2030 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2031 info
= pvStructInfo
;
2032 info
->rgRDN
= (CERT_RDN
*)((BYTE
*)pvStructInfo
+
2033 sizeof(CERT_NAME_INFO
));
2034 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2035 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2036 &bytesNeeded
, NULL
);
2037 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2038 CRYPT_FreeSpace(pDecodePara
, info
);
2044 SetLastError(STATUS_ACCESS_VIOLATION
);
2051 static BOOL
CRYPT_FindEncodedLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2054 BOOL ret
= TRUE
, done
= FALSE
;
2055 DWORD indefiniteNestingLevels
= 0, decoded
= 0;
2057 TRACE("(%p, %d)\n", pbEncoded
, cbEncoded
);
2064 else if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
,
2067 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2069 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
2071 indefiniteNestingLevels
++;
2072 pbEncoded
+= 1 + lenBytes
;
2073 cbEncoded
-= 1 + lenBytes
;
2074 decoded
+= 1 + lenBytes
;
2075 TRACE("indefiniteNestingLevels = %d\n",
2076 indefiniteNestingLevels
);
2080 if (pbEncoded
[0] == 0 && pbEncoded
[1] == 0 &&
2081 indefiniteNestingLevels
)
2083 indefiniteNestingLevels
--;
2084 TRACE("indefiniteNestingLevels = %d\n",
2085 indefiniteNestingLevels
);
2087 pbEncoded
+= 1 + lenBytes
+ dataLen
;
2088 cbEncoded
-= 1 + lenBytes
+ dataLen
;
2089 decoded
+= 1 + lenBytes
+ dataLen
;
2090 if (!indefiniteNestingLevels
)
2094 } while (ret
&& !done
);
2095 /* If we haven't found all 0 TLVs, we haven't found the end */
2096 if (ret
&& indefiniteNestingLevels
)
2098 SetLastError(CRYPT_E_ASN1_EOD
);
2102 *pcbDecoded
= decoded
;
2103 TRACE("returning %d (%d)\n", ret
, ret
? *pcbDecoded
: 0);
2107 static BOOL
CRYPT_AsnDecodeCopyBytes(const BYTE
*pbEncoded
,
2108 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2112 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
), encodedLen
= 0;
2114 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2115 pvStructInfo
, *pcbStructInfo
);
2117 if ((ret
= CRYPT_FindEncodedLen(pbEncoded
, cbEncoded
, &encodedLen
)))
2119 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2120 bytesNeeded
+= encodedLen
;
2122 *pcbStructInfo
= bytesNeeded
;
2123 else if (*pcbStructInfo
< bytesNeeded
)
2125 SetLastError(ERROR_MORE_DATA
);
2126 *pcbStructInfo
= bytesNeeded
;
2131 PCRYPT_OBJID_BLOB blob
= pvStructInfo
;
2133 *pcbStructInfo
= bytesNeeded
;
2134 blob
->cbData
= encodedLen
;
2137 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2138 blob
->pbData
= (LPBYTE
)pbEncoded
;
2141 assert(blob
->pbData
);
2142 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2146 blob
->pbData
= NULL
;
2149 *pcbDecoded
= encodedLen
;
2154 static BOOL
CRYPT_AsnDecodeCTLUsage(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2155 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2158 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2159 offsetof(CTL_USAGE
, cUsageIdentifier
),
2160 offsetof(CTL_USAGE
, rgpszUsageIdentifier
),
2162 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2164 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2165 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2169 static BOOL
CRYPT_AsnDecodeCTLEntryAttributes(const BYTE
*pbEncoded
,
2170 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2173 struct AsnArrayDescriptor arrayDesc
= { 0,
2174 offsetof(CTL_ENTRY
, cAttribute
), offsetof(CTL_ENTRY
, rgAttribute
),
2175 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
),
2176 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2177 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2180 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2181 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2185 static BOOL
CRYPT_AsnDecodeCTLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2186 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2188 struct AsnDecodeSequenceItem items
[] = {
2189 { ASN_OCTETSTRING
, offsetof(CTL_ENTRY
, SubjectIdentifier
),
2190 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
2191 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
), 0 },
2192 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CTL_ENTRY
, cAttribute
),
2193 CRYPT_AsnDecodeCTLEntryAttributes
,
2194 FINALMEMBERSIZE(CTL_ENTRY
, cAttribute
), FALSE
, TRUE
,
2195 offsetof(CTL_ENTRY
, rgAttribute
), 0 },
2198 CTL_ENTRY
*entry
= pvStructInfo
;
2200 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
2203 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2204 pbEncoded
, cbEncoded
, dwFlags
, NULL
, entry
, pcbStructInfo
,
2205 pcbDecoded
, entry
? entry
->SubjectIdentifier
.pbData
: NULL
);
2209 static BOOL
CRYPT_AsnDecodeCTLEntries(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2210 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2213 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2214 offsetof(CTL_INFO
, cCTLEntry
), offsetof(CTL_INFO
, rgCTLEntry
),
2215 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2216 CRYPT_AsnDecodeCTLEntry
, sizeof(CTL_ENTRY
), TRUE
,
2217 offsetof(CTL_ENTRY
, SubjectIdentifier
.pbData
) };
2219 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2220 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2222 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2223 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2227 static BOOL
CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE
*pbEncoded
,
2228 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2232 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2233 offsetof(CTL_INFO
, cExtension
), offsetof(CTL_INFO
, rgExtension
),
2234 FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2235 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
2236 offsetof(CERT_EXTENSION
, pszObjId
) };
2238 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2239 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2241 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2242 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2246 static BOOL
CRYPT_AsnDecodeCTLExtensions(const BYTE
*pbEncoded
,
2247 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2253 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2255 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2257 ret
= CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded
+ 1 + lenBytes
,
2258 dataLen
, dwFlags
, pvStructInfo
, pcbStructInfo
, NULL
);
2259 if (ret
&& pcbDecoded
)
2260 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2265 static BOOL WINAPI
CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType
,
2266 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2267 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2271 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2272 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2276 struct AsnDecodeSequenceItem items
[] = {
2277 { ASN_INTEGER
, offsetof(CTL_INFO
, dwVersion
),
2278 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
2279 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectUsage
),
2280 CRYPT_AsnDecodeCTLUsage
, sizeof(CTL_USAGE
), FALSE
, TRUE
,
2281 offsetof(CTL_INFO
, SubjectUsage
.rgpszUsageIdentifier
), 0 },
2282 { ASN_OCTETSTRING
, offsetof(CTL_INFO
, ListIdentifier
),
2283 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), TRUE
,
2284 TRUE
, offsetof(CTL_INFO
, ListIdentifier
.pbData
), 0 },
2285 { ASN_INTEGER
, offsetof(CTL_INFO
, SequenceNumber
),
2286 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2287 TRUE
, TRUE
, offsetof(CTL_INFO
, SequenceNumber
.pbData
), 0 },
2288 { 0, offsetof(CTL_INFO
, ThisUpdate
),
2289 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), FALSE
, FALSE
,
2291 { 0, offsetof(CTL_INFO
, NextUpdate
),
2292 CRYPT_AsnDecodeChoiceOfTimeInternal
, sizeof(FILETIME
), TRUE
, FALSE
,
2294 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, SubjectAlgorithm
),
2295 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2296 FALSE
, TRUE
, offsetof(CTL_INFO
, SubjectAlgorithm
.pszObjId
), 0 },
2297 { ASN_SEQUENCEOF
, offsetof(CTL_INFO
, cCTLEntry
),
2298 CRYPT_AsnDecodeCTLEntries
,
2299 MEMBERSIZE(CTL_INFO
, cCTLEntry
, cExtension
),
2300 TRUE
, TRUE
, offsetof(CTL_INFO
, rgCTLEntry
), 0 },
2301 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CTL_INFO
, cExtension
),
2302 CRYPT_AsnDecodeCTLExtensions
, FINALMEMBERSIZE(CTL_INFO
, cExtension
),
2303 TRUE
, TRUE
, offsetof(CTL_INFO
, rgExtension
), 0 },
2306 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2307 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2308 pcbStructInfo
, NULL
, NULL
);
2312 SetLastError(STATUS_ACCESS_VIOLATION
);
2318 static BOOL
CRYPT_AsnDecodeSMIMECapability(const BYTE
*pbEncoded
,
2319 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2323 struct AsnDecodeSequenceItem items
[] = {
2324 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
),
2325 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2326 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
), 0 },
2327 { 0, offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
),
2328 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2329 offsetof(CRYPT_SMIME_CAPABILITY
, Parameters
.pbData
), 0 },
2331 PCRYPT_SMIME_CAPABILITY capability
= pvStructInfo
;
2333 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2334 pvStructInfo
, *pcbStructInfo
);
2336 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2337 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2338 pcbDecoded
, capability
? capability
->pszObjId
: NULL
);
2339 TRACE("returning %d\n", ret
);
2343 static BOOL WINAPI
CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType
,
2344 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2345 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2349 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2350 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2354 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2355 offsetof(CRYPT_SMIME_CAPABILITIES
, cCapability
),
2356 offsetof(CRYPT_SMIME_CAPABILITIES
, rgCapability
),
2357 sizeof(CRYPT_SMIME_CAPABILITIES
),
2358 CRYPT_AsnDecodeSMIMECapability
, sizeof(CRYPT_SMIME_CAPABILITY
), TRUE
,
2359 offsetof(CRYPT_SMIME_CAPABILITY
, pszObjId
) };
2360 CRYPT_SMIME_CAPABILITIES
*capabilities
= pvStructInfo
;
2362 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2363 capabilities
->rgCapability
= (CRYPT_SMIME_CAPABILITY
*)(capabilities
+ 1);
2364 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2365 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2369 SetLastError(STATUS_ACCESS_VIOLATION
);
2372 TRACE("returning %d\n", ret
);
2376 static BOOL
CRYPT_AsnDecodeIA5String(const BYTE
*pbEncoded
,
2377 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2382 LPSTR
*pStr
= pvStructInfo
;
2384 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2386 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2387 DWORD bytesNeeded
= sizeof(LPSTR
) + sizeof(char);
2389 if (pbEncoded
[0] != ASN_IA5STRING
)
2391 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2396 bytesNeeded
+= dataLen
;
2398 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2400 *pcbStructInfo
= bytesNeeded
;
2401 else if (*pcbStructInfo
< bytesNeeded
)
2403 *pcbStructInfo
= bytesNeeded
;
2404 SetLastError(ERROR_MORE_DATA
);
2409 *pcbStructInfo
= bytesNeeded
;
2415 memcpy(str
, pbEncoded
+ 1 + lenBytes
, dataLen
);
2426 static BOOL
CRYPT_AsnDecodeNoticeNumbers(const BYTE
*pbEncoded
,
2427 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2430 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2431 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2432 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, rgNoticeNumbers
),
2433 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2434 CRYPT_AsnDecodeIntInternal
, sizeof(int), FALSE
, 0 };
2437 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2438 pvStructInfo
, pvStructInfo
? *pcbDecoded
: 0);
2440 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2441 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2442 TRACE("returning %d\n", ret
);
2446 static BOOL
CRYPT_AsnDecodeNoticeReference(const BYTE
*pbEncoded
,
2447 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2451 struct AsnDecodeSequenceItem items
[] = {
2452 { ASN_IA5STRING
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2453 pszOrganization
), CRYPT_AsnDecodeIA5String
, sizeof(LPSTR
), FALSE
, TRUE
,
2454 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, pszOrganization
), 0 },
2455 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2456 cNoticeNumbers
), CRYPT_AsnDecodeNoticeNumbers
,
2457 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
, cNoticeNumbers
),
2458 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
,
2459 rgNoticeNumbers
), 0 },
2461 DWORD bytesNeeded
= 0;
2463 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2464 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
2466 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2467 pbEncoded
, cbEncoded
, dwFlags
, NULL
, NULL
, &bytesNeeded
, pcbDecoded
,
2471 /* The caller is expecting a pointer to a
2472 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas
2473 * CRYPT_AsnDecodeSequence is decoding a
2474 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes
2475 * needed, and decode again if the requisite space is available.
2477 bytesNeeded
+= sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
);
2479 *pcbStructInfo
= bytesNeeded
;
2480 else if (*pcbStructInfo
< bytesNeeded
)
2482 *pcbStructInfo
= bytesNeeded
;
2483 SetLastError(ERROR_MORE_DATA
);
2488 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef
;
2490 *pcbStructInfo
= bytesNeeded
;
2491 /* The pointer (pvStructInfo) passed in points to the first dynamic
2492 * pointer, so use it as the pointer to the
2493 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the
2494 * appropriate offset for the first dynamic pointer within the
2495 * notice reference by pointing to the first memory location past
2496 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE.
2499 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
*)pvStructInfo
;
2500 noticeRef
->pszOrganization
= (LPSTR
)((LPBYTE
)noticeRef
+
2501 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE
));
2502 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
), pbEncoded
, cbEncoded
, dwFlags
,
2503 NULL
, noticeRef
, &bytesNeeded
, pcbDecoded
, noticeRef
->pszOrganization
);
2506 TRACE("returning %d\n", ret
);
2510 static BOOL
CRYPT_AsnDecodeUnicodeString(const BYTE
*pbEncoded
,
2511 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2517 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2519 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2520 DWORD bytesNeeded
= sizeof(LPWSTR
);
2522 switch (pbEncoded
[0])
2524 case ASN_NUMERICSTRING
:
2526 bytesNeeded
+= (dataLen
+ 1) * 2;
2528 case ASN_PRINTABLESTRING
:
2530 bytesNeeded
+= (dataLen
+ 1) * 2;
2534 bytesNeeded
+= (dataLen
+ 1) * 2;
2538 bytesNeeded
+= (dataLen
+ 1) * 2;
2540 case ASN_VIDEOTEXSTRING
:
2542 bytesNeeded
+= (dataLen
+ 1) * 2;
2544 case ASN_GRAPHICSTRING
:
2546 bytesNeeded
+= (dataLen
+ 1) * 2;
2548 case ASN_VISIBLESTRING
:
2550 bytesNeeded
+= (dataLen
+ 1) * 2;
2552 case ASN_GENERALSTRING
:
2554 bytesNeeded
+= (dataLen
+ 1) * 2;
2556 case ASN_UNIVERSALSTRING
:
2558 bytesNeeded
+= dataLen
/ 2 + sizeof(WCHAR
);
2562 bytesNeeded
+= dataLen
+ sizeof(WCHAR
);
2564 case ASN_UTF8STRING
:
2566 bytesNeeded
+= (MultiByteToWideChar(CP_UTF8
, 0,
2567 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) + 1) * 2;
2570 SetLastError(CRYPT_E_ASN1_BADTAG
);
2575 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2577 *pcbStructInfo
= bytesNeeded
;
2578 else if (*pcbStructInfo
< bytesNeeded
)
2580 *pcbStructInfo
= bytesNeeded
;
2581 SetLastError(ERROR_MORE_DATA
);
2586 LPWSTR
*pStr
= pvStructInfo
;
2588 *pcbStructInfo
= bytesNeeded
;
2595 switch (pbEncoded
[0])
2597 case ASN_NUMERICSTRING
:
2598 case ASN_PRINTABLESTRING
:
2601 case ASN_VIDEOTEXSTRING
:
2602 case ASN_GRAPHICSTRING
:
2603 case ASN_VISIBLESTRING
:
2604 case ASN_GENERALSTRING
:
2605 for (i
= 0; i
< dataLen
; i
++)
2606 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
2609 case ASN_UNIVERSALSTRING
:
2610 for (i
= 0; i
< dataLen
/ 4; i
++)
2611 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
2612 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
2616 for (i
= 0; i
< dataLen
/ 2; i
++)
2617 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2618 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2621 case ASN_UTF8STRING
:
2623 int len
= MultiByteToWideChar(CP_UTF8
, 0,
2624 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
2625 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
2638 static BOOL
CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2639 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
2640 DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2643 struct AsnDecodeSequenceItem items
[] = {
2644 { ASN_SEQUENCE
, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
,
2645 pNoticeReference
), CRYPT_AsnDecodeNoticeReference
,
2646 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
), TRUE
, TRUE
,
2647 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pNoticeReference
), 0 },
2648 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
),
2649 CRYPT_AsnDecodeUnicodeString
, sizeof(LPWSTR
), TRUE
, TRUE
,
2650 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE
, pszDisplayText
), 0 },
2652 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
= pvStructInfo
;
2654 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2655 pvStructInfo
, *pcbStructInfo
);
2657 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2658 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2659 pcbDecoded
, notice
? notice
->pNoticeReference
: NULL
);
2660 TRACE("returning %d\n", ret
);
2664 static BOOL WINAPI
CRYPT_AsnDecodePolicyQualifierUserNotice(
2665 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2666 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2667 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2671 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2672 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2676 DWORD bytesNeeded
= 0;
2678 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded
,
2679 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
,
2684 *pcbStructInfo
= bytesNeeded
;
2685 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2686 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2688 PCERT_POLICY_QUALIFIER_USER_NOTICE notice
;
2690 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2691 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2692 notice
= pvStructInfo
;
2693 notice
->pNoticeReference
=
2694 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE
)
2695 ((BYTE
*)pvStructInfo
+
2696 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE
));
2697 ret
= CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
2698 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
2699 pvStructInfo
, &bytesNeeded
, NULL
);
2700 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2701 CRYPT_FreeSpace(pDecodePara
, notice
);
2707 SetLastError(STATUS_ACCESS_VIOLATION
);
2710 TRACE("returning %d\n", ret
);
2714 static BOOL
CRYPT_AsnDecodePKCSAttributeValue(const BYTE
*pbEncoded
,
2715 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2719 struct AsnArrayDescriptor arrayDesc
= { 0,
2720 offsetof(CRYPT_ATTRIBUTE
, cValue
), offsetof(CRYPT_ATTRIBUTE
, rgValue
),
2721 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
),
2722 CRYPT_AsnDecodeCopyBytes
,
2723 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
2725 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2726 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
2728 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2729 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2733 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
2734 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2738 struct AsnDecodeSequenceItem items
[] = {
2739 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
2740 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2741 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
2742 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
2743 CRYPT_AsnDecodePKCSAttributeValue
,
2744 FINALMEMBERSIZE(CRYPT_ATTRIBUTE
, cValue
), FALSE
,
2745 TRUE
, offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
2747 PCRYPT_ATTRIBUTE attr
= pvStructInfo
;
2749 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2750 pvStructInfo
, *pcbStructInfo
);
2752 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2753 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2754 pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
2755 TRACE("returning %d\n", ret
);
2759 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
2760 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2761 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2765 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2766 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2770 DWORD bytesNeeded
= 0;
2772 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2773 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
2777 *pcbStructInfo
= bytesNeeded
;
2778 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2779 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2781 PCRYPT_ATTRIBUTE attr
;
2783 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2784 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2785 attr
= pvStructInfo
;
2786 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
2787 sizeof(CRYPT_ATTRIBUTE
));
2788 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
2789 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
2791 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2792 CRYPT_FreeSpace(pDecodePara
, attr
);
2798 SetLastError(STATUS_ACCESS_VIOLATION
);
2801 TRACE("returning %d\n", ret
);
2805 static BOOL
CRYPT_AsnDecodePKCSAttributesInternal(const BYTE
*pbEncoded
,
2806 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2809 struct AsnArrayDescriptor arrayDesc
= { 0,
2810 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2811 sizeof(CRYPT_ATTRIBUTES
),
2812 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2813 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2816 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2817 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
2821 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2822 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2823 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2827 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2828 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2832 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
2833 offsetof(CRYPT_ATTRIBUTES
, cAttr
), offsetof(CRYPT_ATTRIBUTES
, rgAttr
),
2834 sizeof(CRYPT_ATTRIBUTES
),
2835 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
),
2836 TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2837 CRYPT_ATTRIBUTES
*attrs
= pvStructInfo
;
2839 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2840 attrs
->rgAttr
= (CRYPT_ATTRIBUTE
*)(attrs
+ 1);
2841 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
2842 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2846 SetLastError(STATUS_ACCESS_VIOLATION
);
2849 TRACE("returning %d\n", ret
);
2853 static BOOL
CRYPT_AsnDecodeAlgorithmId(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2854 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2856 CRYPT_ALGORITHM_IDENTIFIER
*algo
= pvStructInfo
;
2858 struct AsnDecodeSequenceItem items
[] = {
2859 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2860 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
2861 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2862 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2863 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2864 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2867 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
2868 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
2870 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2871 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2872 pcbDecoded
, algo
? algo
->pszObjId
: NULL
);
2873 if (ret
&& pvStructInfo
)
2875 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2876 debugstr_a(algo
->pszObjId
));
2881 static BOOL
CRYPT_AsnDecodePubKeyInfoInternal(const BYTE
*pbEncoded
,
2882 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
2886 struct AsnDecodeSequenceItem items
[] = {
2887 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2888 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2889 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2890 Algorithm
.pszObjId
) },
2891 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2892 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2893 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2895 PCERT_PUBLIC_KEY_INFO info
= pvStructInfo
;
2897 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
2898 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
2899 pcbDecoded
, info
? info
->Algorithm
.Parameters
.pbData
: NULL
);
2903 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2904 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2905 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2911 DWORD bytesNeeded
= 0;
2913 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2914 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
2917 *pcbStructInfo
= bytesNeeded
;
2918 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2919 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2921 PCERT_PUBLIC_KEY_INFO info
;
2923 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2924 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2925 info
= pvStructInfo
;
2926 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2927 sizeof(CERT_PUBLIC_KEY_INFO
);
2928 ret
= CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded
, cbEncoded
,
2929 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
2930 &bytesNeeded
, NULL
);
2931 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
2932 CRYPT_FreeSpace(pDecodePara
, info
);
2938 SetLastError(STATUS_ACCESS_VIOLATION
);
2945 static BOOL
CRYPT_AsnDecodeBool(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2946 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2952 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2955 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2957 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2960 if (pbEncoded
[1] > 1)
2962 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2969 *pcbStructInfo
= sizeof(BOOL
);
2972 else if (*pcbStructInfo
< sizeof(BOOL
))
2974 *pcbStructInfo
= sizeof(BOOL
);
2975 SetLastError(ERROR_MORE_DATA
);
2980 *pcbStructInfo
= sizeof(BOOL
);
2981 *(BOOL
*)pvStructInfo
= pbEncoded
[2] != 0;
2984 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2988 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2989 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2991 PCERT_ALT_NAME_ENTRY entry
= pvStructInfo
;
2992 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2995 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2996 pvStructInfo
, *pcbStructInfo
);
3000 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3003 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3004 if (1 + lenBytes
> cbEncoded
)
3006 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3009 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3011 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3013 case 1: /* rfc822Name */
3014 case 2: /* dNSName */
3015 case 6: /* uniformResourceIdentifier */
3016 if (memchr(pbEncoded
+ 1 + lenBytes
, 0, dataLen
))
3018 SetLastError(CRYPT_E_ASN1_RULE
);
3022 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
3024 case 4: /* directoryName */
3025 case 7: /* iPAddress */
3026 bytesNeeded
+= dataLen
;
3028 case 8: /* registeredID */
3029 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
3033 /* FIXME: ugly, shouldn't need to know internals of OID decode
3034 * function to use it.
3036 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
3039 case 0: /* otherName */
3040 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3041 SetLastError(CRYPT_E_ASN1_BADTAG
);
3044 case 3: /* x400Address, unimplemented */
3045 case 5: /* ediPartyName, unimplemented */
3046 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3047 SetLastError(CRYPT_E_ASN1_BADTAG
);
3051 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
3052 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3058 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
3060 *pcbStructInfo
= bytesNeeded
;
3061 else if (*pcbStructInfo
< bytesNeeded
)
3063 *pcbStructInfo
= bytesNeeded
;
3064 SetLastError(ERROR_MORE_DATA
);
3069 *pcbStructInfo
= bytesNeeded
;
3070 /* MS used values one greater than the asn1 ones.. sigh */
3071 entry
->dwAltNameChoice
= (pbEncoded
[0] & ASN_TYPE_MASK
) + 1;
3072 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
3074 case 1: /* rfc822Name */
3075 case 2: /* dNSName */
3076 case 6: /* uniformResourceIdentifier */
3080 for (i
= 0; i
< dataLen
; i
++)
3081 entry
->u
.pwszURL
[i
] =
3082 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
3083 entry
->u
.pwszURL
[i
] = 0;
3084 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
3085 debugstr_w(entry
->u
.pwszURL
));
3088 case 4: /* directoryName */
3089 /* The data are memory-equivalent with the IPAddress case,
3092 case 7: /* iPAddress */
3093 /* The next data pointer is in the pwszURL spot, that is,
3094 * the first 4 bytes. Need to move it to the next spot.
3096 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
3097 entry
->u
.IPAddress
.cbData
= dataLen
;
3098 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
3101 case 8: /* registeredID */
3102 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
3103 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
3112 static BOOL
CRYPT_AsnDecodeAltNameInternal(const BYTE
*pbEncoded
,
3113 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3117 struct AsnArrayDescriptor arrayDesc
= { 0,
3118 offsetof(CERT_ALT_NAME_INFO
, cAltEntry
),
3119 offsetof(CERT_ALT_NAME_INFO
, rgAltEntry
),
3120 sizeof(CERT_ALT_NAME_INFO
),
3121 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3122 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3124 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3125 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3127 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3128 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3132 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
3133 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3134 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3140 struct AsnDecodeSequenceItem items
[] = {
3141 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
3142 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3143 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
3144 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3145 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
3146 CRYPT_AsnDecodeOctets
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
3147 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
3148 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
3149 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3150 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3151 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
3154 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3155 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3156 pcbStructInfo
, NULL
, NULL
);
3160 SetLastError(STATUS_ACCESS_VIOLATION
);
3167 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
3168 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3169 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3175 struct AsnDecodeSequenceItem items
[] = {
3176 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
3177 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
),
3178 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
3179 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
3180 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
3181 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
3182 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3183 AuthorityCertIssuer
.rgAltEntry
), 0 },
3184 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3185 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
3186 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
3187 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
3188 AuthorityCertSerialNumber
.pbData
), 0 },
3191 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3192 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3193 pcbStructInfo
, NULL
, NULL
);
3197 SetLastError(STATUS_ACCESS_VIOLATION
);
3204 static BOOL
CRYPT_AsnDecodeAccessDescription(const BYTE
*pbEncoded
,
3205 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3208 struct AsnDecodeSequenceItem items
[] = {
3209 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
),
3210 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3211 offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
), 0 },
3212 { 0, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
),
3213 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), FALSE
,
3214 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, AccessLocation
.u
.pwszURL
), 0 },
3216 CERT_ACCESS_DESCRIPTION
*descr
= pvStructInfo
;
3218 return CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3219 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3220 pcbDecoded
, descr
? descr
->pszAccessMethod
: NULL
);
3223 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType
,
3224 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3225 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3229 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3230 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3234 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3235 offsetof(CERT_AUTHORITY_INFO_ACCESS
, cAccDescr
),
3236 offsetof(CERT_AUTHORITY_INFO_ACCESS
, rgAccDescr
),
3237 sizeof(CERT_AUTHORITY_INFO_ACCESS
),
3238 CRYPT_AsnDecodeAccessDescription
, sizeof(CERT_ACCESS_DESCRIPTION
),
3239 TRUE
, offsetof(CERT_ACCESS_DESCRIPTION
, pszAccessMethod
) };
3240 CERT_AUTHORITY_INFO_ACCESS
*info
= pvStructInfo
;
3242 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3243 info
->rgAccDescr
= (CERT_ACCESS_DESCRIPTION
*)(info
+ 1);
3244 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3245 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3249 SetLastError(STATUS_ACCESS_VIOLATION
);
3256 static BOOL
CRYPT_AsnDecodePKCSContent(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3257 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3262 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3263 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3265 /* The caller has already checked the tag, no need to check it again.
3266 * Check the outer length is valid:
3268 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
3270 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3273 pbEncoded
+= 1 + lenBytes
;
3274 cbEncoded
-= 1 + lenBytes
;
3275 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3276 cbEncoded
-= 2; /* space for 0 TLV */
3277 /* Check the inner length is valid: */
3278 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &innerLen
)))
3282 ret
= CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
,
3283 pvStructInfo
, pcbStructInfo
, &decodedLen
);
3284 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
3286 if (*(pbEncoded
+ decodedLen
) != 0 ||
3287 *(pbEncoded
+ decodedLen
+ 1) != 0)
3289 TRACE("expected 0 TLV, got {%02x,%02x}\n",
3290 *(pbEncoded
+ decodedLen
),
3291 *(pbEncoded
+ decodedLen
+ 1));
3292 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3298 if (ret
&& pcbDecoded
)
3300 *pcbDecoded
= 1 + lenBytes
+ decodedLen
;
3301 TRACE("decoded %d bytes\n", *pcbDecoded
);
3308 static BOOL
CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE
*pbEncoded
,
3309 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3312 CRYPT_CONTENT_INFO
*info
= pvStructInfo
;
3313 struct AsnDecodeSequenceItem items
[] = {
3314 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
3315 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
3316 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
3317 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
3318 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
3319 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
3320 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
3324 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3325 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3327 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3328 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3329 pcbDecoded
, info
? info
->pszObjId
: NULL
);
3333 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
3334 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3335 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3339 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3340 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3344 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
, cbEncoded
,
3345 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
3346 if (ret
&& pvStructInfo
)
3348 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3349 pcbStructInfo
, *pcbStructInfo
);
3352 CRYPT_CONTENT_INFO
*info
;
3354 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3355 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3356 info
= pvStructInfo
;
3357 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
3358 sizeof(CRYPT_CONTENT_INFO
));
3359 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded
,
3360 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3361 pcbStructInfo
, NULL
);
3362 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3363 CRYPT_FreeSpace(pDecodePara
, info
);
3369 SetLastError(STATUS_ACCESS_VIOLATION
);
3375 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3376 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3377 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
3380 struct AsnDecodeSequenceItem items
[] = {
3381 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
3382 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3383 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
3384 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3385 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
3387 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
3388 CRYPT_AsnDecodePKCSContentInfoInternal
,
3389 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
3390 ContentInfo
.pszObjId
), 0 },
3391 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
3392 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
3393 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
3396 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3397 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, digestedData
, pcbDigestedData
,
3402 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
3403 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3404 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3408 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3409 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3413 DWORD bytesNeeded
= 0;
3415 if ((ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3416 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
3419 *pcbStructInfo
= bytesNeeded
;
3420 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3421 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3423 CERT_ALT_NAME_INFO
*name
;
3425 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3426 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3427 name
= pvStructInfo
;
3428 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
3429 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
3430 ret
= CRYPT_AsnDecodeAltNameInternal(pbEncoded
, cbEncoded
,
3431 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3432 &bytesNeeded
, NULL
);
3433 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3434 CRYPT_FreeSpace(pDecodePara
, name
);
3440 SetLastError(STATUS_ACCESS_VIOLATION
);
3447 struct PATH_LEN_CONSTRAINT
3449 BOOL fPathLenConstraint
;
3450 DWORD dwPathLenConstraint
;
3453 static BOOL
CRYPT_AsnDecodePathLenConstraint(const BYTE
*pbEncoded
,
3454 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3458 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
), size
;
3460 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3461 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3465 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
, NULL
,
3467 *pcbStructInfo
= bytesNeeded
;
3469 else if (*pcbStructInfo
< bytesNeeded
)
3471 SetLastError(ERROR_MORE_DATA
);
3472 *pcbStructInfo
= bytesNeeded
;
3477 struct PATH_LEN_CONSTRAINT
*constraint
= pvStructInfo
;
3479 *pcbStructInfo
= bytesNeeded
;
3480 size
= sizeof(constraint
->dwPathLenConstraint
);
3481 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3482 &constraint
->dwPathLenConstraint
, &size
, pcbDecoded
);
3484 constraint
->fPathLenConstraint
= TRUE
;
3485 TRACE("got an int, dwPathLenConstraint is %d\n",
3486 constraint
->dwPathLenConstraint
);
3488 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3492 static BOOL
CRYPT_AsnDecodeSubtreeConstraints(const BYTE
*pbEncoded
,
3493 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3497 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3498 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3499 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
),
3500 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3501 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
3502 offsetof(CERT_NAME_BLOB
, pbData
) };
3504 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
3505 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
3507 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3508 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3509 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3513 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
3514 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3515 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3521 struct AsnDecodeSequenceItem items
[] = {
3522 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
3523 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
3524 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
3525 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3526 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3527 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3528 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
3529 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
3530 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO
, cSubtreesConstraint
),
3532 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
3535 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3536 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3537 pcbStructInfo
, NULL
, NULL
);
3541 SetLastError(STATUS_ACCESS_VIOLATION
);
3548 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
3549 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3550 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3556 struct AsnDecodeSequenceItem items
[] = {
3557 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
3558 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
3559 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
3560 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
3561 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
3564 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3565 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3566 pcbStructInfo
, NULL
, NULL
);
3570 SetLastError(STATUS_ACCESS_VIOLATION
);
3577 static BOOL
CRYPT_AsnDecodePolicyQualifier(const BYTE
*pbEncoded
,
3578 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3581 struct AsnDecodeSequenceItem items
[] = {
3582 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_QUALIFIER_INFO
,
3583 pszPolicyQualifierId
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3584 FALSE
, TRUE
, offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
),
3586 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
),
3587 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
3588 offsetof(CERT_POLICY_QUALIFIER_INFO
, Qualifier
.pbData
), 0 },
3591 CERT_POLICY_QUALIFIER_INFO
*qualifier
= pvStructInfo
;
3593 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3594 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3596 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3597 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3598 pcbDecoded
, qualifier
? qualifier
->pszPolicyQualifierId
: NULL
);
3602 static BOOL
CRYPT_AsnDecodePolicyQualifiers(const BYTE
*pbEncoded
,
3603 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3607 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3608 offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3609 offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
),
3610 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
),
3611 CRYPT_AsnDecodePolicyQualifier
, sizeof(CERT_POLICY_QUALIFIER_INFO
), TRUE
,
3612 offsetof(CERT_POLICY_QUALIFIER_INFO
, pszPolicyQualifierId
) };
3614 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3615 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3617 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3618 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
3619 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
3623 static BOOL
CRYPT_AsnDecodeCertPolicy(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3624 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3626 struct AsnDecodeSequenceItem items
[] = {
3627 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
),
3628 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
3629 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
), 0 },
3630 { ASN_SEQUENCEOF
, offsetof(CERT_POLICY_INFO
, cPolicyQualifier
),
3631 CRYPT_AsnDecodePolicyQualifiers
,
3632 FINALMEMBERSIZE(CERT_POLICY_INFO
, cPolicyQualifier
), TRUE
,
3633 TRUE
, offsetof(CERT_POLICY_INFO
, rgPolicyQualifier
), 0 },
3635 CERT_POLICY_INFO
*info
= pvStructInfo
;
3638 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3639 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3641 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3642 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3643 pcbDecoded
, info
? info
->pszPolicyIdentifier
: NULL
);
3647 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType
,
3648 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3649 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3653 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3654 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3658 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3659 offsetof(CERT_POLICIES_INFO
, cPolicyInfo
),
3660 offsetof(CERT_POLICIES_INFO
, rgPolicyInfo
),
3661 sizeof(CERT_POLICIES_INFO
),
3662 CRYPT_AsnDecodeCertPolicy
, sizeof(CERT_POLICY_INFO
), TRUE
,
3663 offsetof(CERT_POLICY_INFO
, pszPolicyIdentifier
) };
3664 CERT_POLICIES_INFO
*info
= pvStructInfo
;
3666 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3667 info
->rgPolicyInfo
= (CERT_POLICY_INFO
*)(info
+ 1);
3669 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3670 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3674 SetLastError(STATUS_ACCESS_VIOLATION
);
3680 static BOOL
CRYPT_AsnDecodeCertPolicyMapping(const BYTE
*pbEncoded
,
3681 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3684 struct AsnDecodeSequenceItem items
[] = {
3685 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3686 pszIssuerDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3687 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
), 0 },
3688 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_POLICY_MAPPING
,
3689 pszSubjectDomainPolicy
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
3690 FALSE
, TRUE
, offsetof(CERT_POLICY_MAPPING
, pszSubjectDomainPolicy
), 0 },
3692 CERT_POLICY_MAPPING
*mapping
= pvStructInfo
;
3695 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3696 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3698 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3699 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
3700 pcbDecoded
, mapping
? mapping
->pszIssuerDomainPolicy
: NULL
);
3704 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType
,
3705 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3706 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3710 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3711 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3715 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3716 offsetof(CERT_POLICY_MAPPINGS_INFO
, cPolicyMapping
),
3717 offsetof(CERT_POLICY_MAPPINGS_INFO
, rgPolicyMapping
),
3718 sizeof(CERT_POLICY_MAPPING
),
3719 CRYPT_AsnDecodeCertPolicyMapping
, sizeof(CERT_POLICY_MAPPING
), TRUE
,
3720 offsetof(CERT_POLICY_MAPPING
, pszIssuerDomainPolicy
) };
3721 CERT_POLICY_MAPPINGS_INFO
*info
= pvStructInfo
;
3723 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
3724 info
->rgPolicyMapping
= (CERT_POLICY_MAPPING
*)(info
+ 1);
3725 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
3726 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3730 SetLastError(STATUS_ACCESS_VIOLATION
);
3736 static BOOL
CRYPT_AsnDecodeRequireExplicit(const BYTE
*pbEncoded
,
3737 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3741 DWORD skip
, size
= sizeof(skip
);
3745 SetLastError(CRYPT_E_ASN1_EOD
);
3748 if (pbEncoded
[0] != (ASN_CONTEXT
| 0))
3750 SetLastError(CRYPT_E_ASN1_BADTAG
);
3753 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3754 &skip
, &size
, pcbDecoded
)))
3756 DWORD bytesNeeded
= MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3757 fRequireExplicitPolicy
, fInhibitPolicyMapping
);
3760 *pcbStructInfo
= bytesNeeded
;
3761 else if (*pcbStructInfo
< bytesNeeded
)
3763 *pcbStructInfo
= bytesNeeded
;
3764 SetLastError(ERROR_MORE_DATA
);
3769 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3770 CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
);
3772 *pcbStructInfo
= bytesNeeded
;
3773 /* The BOOL is implicit: if the integer is present, then it's
3776 info
->fRequireExplicitPolicy
= TRUE
;
3777 info
->dwRequireExplicitPolicySkipCerts
= skip
;
3783 static BOOL
CRYPT_AsnDecodeInhibitMapping(const BYTE
*pbEncoded
,
3784 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3788 DWORD skip
, size
= sizeof(skip
);
3792 SetLastError(CRYPT_E_ASN1_EOD
);
3795 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
3797 SetLastError(CRYPT_E_ASN1_BADTAG
);
3800 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
3801 &skip
, &size
, pcbDecoded
)))
3803 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
,
3804 fInhibitPolicyMapping
);
3807 *pcbStructInfo
= bytesNeeded
;
3808 else if (*pcbStructInfo
< bytesNeeded
)
3810 *pcbStructInfo
= bytesNeeded
;
3811 SetLastError(ERROR_MORE_DATA
);
3816 CERT_POLICY_CONSTRAINTS_INFO
*info
= CONTAINING_RECORD(pvStructInfo
,
3817 CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
);
3819 *pcbStructInfo
= bytesNeeded
;
3820 /* The BOOL is implicit: if the integer is present, then it's
3823 info
->fInhibitPolicyMapping
= TRUE
;
3824 info
->dwInhibitPolicyMappingSkipCerts
= skip
;
3830 static BOOL WINAPI
CRYPT_AsnDecodeCertPolicyConstraints(
3831 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3832 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3833 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3837 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3838 pDecodePara
, pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0);
3842 struct AsnDecodeSequenceItem items
[] = {
3844 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
),
3845 CRYPT_AsnDecodeRequireExplicit
,
3846 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fRequireExplicitPolicy
,
3847 fInhibitPolicyMapping
), TRUE
, FALSE
, 0, 0 },
3849 offsetof(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3850 CRYPT_AsnDecodeInhibitMapping
,
3851 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO
, fInhibitPolicyMapping
),
3852 TRUE
, FALSE
, 0, 0 },
3855 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3856 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3857 pcbStructInfo
, NULL
, NULL
);
3861 SetLastError(STATUS_ACCESS_VIOLATION
);
3867 #define RSA1_MAGIC 0x31415352
3869 struct DECODED_RSA_PUB_KEY
3872 CRYPT_INTEGER_BLOB modulus
;
3875 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
3876 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3877 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3883 struct AsnDecodeSequenceItem items
[] = {
3884 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
3885 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3886 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
3888 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
3889 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3891 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
3894 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
3895 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
3899 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
3900 decodedKey
->modulus
.cbData
;
3904 *pcbStructInfo
= bytesNeeded
;
3907 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3908 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3911 RSAPUBKEY
*rsaPubKey
;
3913 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3914 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3916 hdr
->bType
= PUBLICKEYBLOB
;
3917 hdr
->bVersion
= CUR_BLOB_VERSION
;
3919 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
3920 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
3921 sizeof(BLOBHEADER
));
3922 rsaPubKey
->magic
= RSA1_MAGIC
;
3923 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
3924 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
3925 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
3926 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
3927 decodedKey
->modulus
.cbData
);
3929 LocalFree(decodedKey
);
3934 SetLastError(STATUS_ACCESS_VIOLATION
);
3941 #define RSA2_MAGIC 0x32415352
3943 struct DECODED_RSA_PRIV_KEY
3947 CRYPT_INTEGER_BLOB modulus
;
3948 CRYPT_INTEGER_BLOB privexp
;
3949 CRYPT_INTEGER_BLOB prime1
;
3950 CRYPT_INTEGER_BLOB prime2
;
3951 CRYPT_INTEGER_BLOB exponent1
;
3952 CRYPT_INTEGER_BLOB exponent2
;
3953 CRYPT_INTEGER_BLOB coefficient
;
3956 static BOOL WINAPI
CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType
,
3957 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3958 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3965 struct AsnDecodeSequenceItem items
[] = {
3966 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, version
),
3967 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3968 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
),
3969 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3970 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, modulus
.pbData
),
3972 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, pubexp
),
3973 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3974 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
),
3975 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3976 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, privexp
.pbData
),
3978 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
),
3979 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3980 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime1
.pbData
),
3982 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
),
3983 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3984 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, prime2
.pbData
),
3986 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
),
3987 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3988 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent1
.pbData
),
3990 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
),
3991 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3992 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, exponent2
.pbData
),
3994 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
),
3995 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
3996 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PRIV_KEY
, coefficient
.pbData
),
3999 struct DECODED_RSA_PRIV_KEY
*decodedKey
= NULL
;
4002 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
4003 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
,
4007 halflen
= decodedKey
->prime1
.cbData
;
4008 if (halflen
< decodedKey
->prime2
.cbData
)
4009 halflen
= decodedKey
->prime2
.cbData
;
4010 if (halflen
< decodedKey
->exponent1
.cbData
)
4011 halflen
= decodedKey
->exponent1
.cbData
;
4012 if (halflen
< decodedKey
->exponent2
.cbData
)
4013 halflen
= decodedKey
->exponent2
.cbData
;
4014 if (halflen
< decodedKey
->coefficient
.cbData
)
4015 halflen
= decodedKey
->coefficient
.cbData
;
4016 if (halflen
* 2 < decodedKey
->modulus
.cbData
)
4017 halflen
= decodedKey
->modulus
.cbData
/ 2 + decodedKey
->modulus
.cbData
% 2;
4018 if (halflen
* 2 < decodedKey
->privexp
.cbData
)
4019 halflen
= decodedKey
->privexp
.cbData
/ 2 + decodedKey
->privexp
.cbData
% 2;
4023 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
4028 *pcbStructInfo
= bytesNeeded
;
4031 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4032 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4035 RSAPUBKEY
*rsaPubKey
;
4038 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4039 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4042 hdr
->bType
= PRIVATEKEYBLOB
;
4043 hdr
->bVersion
= CUR_BLOB_VERSION
;
4045 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
4047 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
4048 sizeof(BLOBHEADER
));
4049 rsaPubKey
->magic
= RSA2_MAGIC
;
4050 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
4051 rsaPubKey
->bitlen
= halflen
* 16;
4053 vardata
= (BYTE
*)(rsaPubKey
+ 1);
4054 memset(vardata
, 0, halflen
* 9);
4056 decodedKey
->modulus
.pbData
, decodedKey
->modulus
.cbData
);
4057 memcpy(vardata
+ halflen
* 2,
4058 decodedKey
->prime1
.pbData
, decodedKey
->prime1
.cbData
);
4059 memcpy(vardata
+ halflen
* 3,
4060 decodedKey
->prime2
.pbData
, decodedKey
->prime2
.cbData
);
4061 memcpy(vardata
+ halflen
* 4,
4062 decodedKey
->exponent1
.pbData
, decodedKey
->exponent1
.cbData
);
4063 memcpy(vardata
+ halflen
* 5,
4064 decodedKey
->exponent2
.pbData
, decodedKey
->exponent2
.cbData
);
4065 memcpy(vardata
+ halflen
* 6,
4066 decodedKey
->coefficient
.pbData
, decodedKey
->coefficient
.cbData
);
4067 memcpy(vardata
+ halflen
* 7,
4068 decodedKey
->privexp
.pbData
, decodedKey
->privexp
.cbData
);
4072 LocalFree(decodedKey
);
4077 SetLastError(STATUS_ACCESS_VIOLATION
);
4084 static BOOL
CRYPT_AsnDecodeOctets(const BYTE
*pbEncoded
,
4085 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4089 DWORD bytesNeeded
, dataLen
;
4091 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
4092 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4094 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4096 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4098 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4099 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
4101 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
4103 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4105 *pcbStructInfo
= bytesNeeded
;
4106 else if (*pcbStructInfo
< bytesNeeded
)
4108 SetLastError(ERROR_MORE_DATA
);
4109 *pcbStructInfo
= bytesNeeded
;
4114 CRYPT_DATA_BLOB
*blob
;
4116 *pcbStructInfo
= bytesNeeded
;
4117 blob
= pvStructInfo
;
4118 blob
->cbData
= dataLen
;
4119 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4120 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
4123 assert(blob
->pbData
);
4125 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
4133 static BOOL
CRYPT_AsnDecodeOctetStringInternal(const BYTE
*encoded
, DWORD encoded_size
,
4134 DWORD flags
, void *buf
, DWORD
*buf_size
, DWORD
*ret_decoded
)
4136 DWORD decoded
= 0, indefinite_len_depth
= 0, len_size
, len
, bytes_needed
;
4137 CRYPT_DATA_BLOB
*blob
;
4140 while (encoded
[0] == (ASN_CONSTRUCTOR
| ASN_OCTETSTRING
))
4142 if (!CRYPT_GetLengthIndefinite(encoded
, encoded_size
, &len
))
4145 len_size
= GET_LEN_BYTES(encoded
[1]);
4146 encoded
+= 1 + len_size
;
4147 encoded_size
-= 1 + len_size
;
4148 decoded
+= 1 + len_size
;
4150 if (len
== CMSG_INDEFINITE_LENGTH
)
4152 indefinite_len_depth
++;
4153 if (encoded_size
< 2)
4155 SetLastError(CRYPT_E_ASN1_EOD
);
4163 if (encoded
[0] != ASN_OCTETSTRING
)
4165 WARN("Unexpected tag %02x\n", encoded
[0]);
4166 SetLastError(CRYPT_E_ASN1_BADTAG
);
4170 if (!CRYPT_GetLen(encoded
, encoded_size
, &len
))
4172 len_size
= GET_LEN_BYTES(encoded
[1]);
4173 decoded
+= 1 + len_size
+ len
;
4174 encoded_size
-= 1 + len_size
;
4176 if (len
> encoded_size
)
4178 SetLastError(CRYPT_E_ASN1_EOD
);
4182 *ret_decoded
= decoded
;
4184 encoded
+= 1 + len_size
;
4188 while (indefinite_len_depth
--)
4190 if (encoded
[0] || encoded
[1])
4192 TRACE("expected 0 TLV, got %02x %02x\n", encoded
[0], encoded
[1]);
4193 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4198 bytes_needed
= sizeof(*blob
);
4199 if (!(flags
& CRYPT_DECODE_NOCOPY_FLAG
)) bytes_needed
+= len
;
4202 *buf_size
= bytes_needed
;
4205 if (*buf_size
< bytes_needed
)
4207 SetLastError(ERROR_MORE_DATA
);
4208 *buf_size
= bytes_needed
;
4212 *buf_size
= bytes_needed
;
4215 if (flags
& CRYPT_DECODE_NOCOPY_FLAG
)
4216 blob
->pbData
= (BYTE
*)string
;
4217 else if (blob
->cbData
)
4218 memcpy(blob
->pbData
, string
, blob
->cbData
);
4221 *ret_decoded
= decoded
;
4225 static BOOL WINAPI
CRYPT_AsnDecodeOctetString(DWORD dwCertEncodingType
,
4226 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4227 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4231 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4232 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4236 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4242 DWORD bytesNeeded
= 0;
4244 if ((ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4245 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4248 *pcbStructInfo
= bytesNeeded
;
4249 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4250 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4252 CRYPT_DATA_BLOB
*blob
;
4254 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4255 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4256 blob
= pvStructInfo
;
4257 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
4258 ret
= CRYPT_AsnDecodeOctetStringInternal(pbEncoded
, cbEncoded
,
4259 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4260 &bytesNeeded
, NULL
);
4261 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4262 CRYPT_FreeSpace(pDecodePara
, blob
);
4268 SetLastError(STATUS_ACCESS_VIOLATION
);
4275 static BOOL
CRYPT_AsnDecodeBitsInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4276 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4279 DWORD bytesNeeded
, dataLen
;
4280 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4282 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4283 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
4285 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4287 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4288 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
4290 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
4292 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4294 *pcbStructInfo
= bytesNeeded
;
4295 else if (*pcbStructInfo
< bytesNeeded
)
4297 *pcbStructInfo
= bytesNeeded
;
4298 SetLastError(ERROR_MORE_DATA
);
4303 CRYPT_BIT_BLOB
*blob
;
4305 *pcbStructInfo
= bytesNeeded
;
4306 blob
= pvStructInfo
;
4307 blob
->cbData
= dataLen
- 1;
4308 blob
->cUnusedBits
= *(pbEncoded
+ 1 + lenBytes
);
4309 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
4311 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 + lenBytes
;
4315 assert(blob
->pbData
);
4318 BYTE mask
= 0xff << blob
->cUnusedBits
;
4320 memcpy(blob
->pbData
, pbEncoded
+ 2 + lenBytes
,
4322 blob
->pbData
[blob
->cbData
- 1] &= mask
;
4330 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
4331 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4332 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4336 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
4337 pDecodePara
, pvStructInfo
, pcbStructInfo
);
4341 DWORD bytesNeeded
= 0;
4345 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4348 else if (pbEncoded
[0] != ASN_BITSTRING
)
4350 SetLastError(CRYPT_E_ASN1_BADTAG
);
4353 else if ((ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4354 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4357 *pcbStructInfo
= bytesNeeded
;
4358 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4359 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4361 CRYPT_BIT_BLOB
*blob
;
4363 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4364 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4365 blob
= pvStructInfo
;
4366 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
4367 ret
= CRYPT_AsnDecodeBitsInternal(pbEncoded
, cbEncoded
,
4368 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4369 &bytesNeeded
, NULL
);
4370 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4371 CRYPT_FreeSpace(pDecodePara
, blob
);
4377 SetLastError(STATUS_ACCESS_VIOLATION
);
4381 TRACE("returning %d (%08x)\n", ret
, GetLastError());
4385 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
4386 static BOOL
CRYPT_AsnDecodeIntInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4387 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
4392 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4394 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4397 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4398 if (dataLen
> sizeof(int))
4400 SetLastError(CRYPT_E_ASN1_LARGE
);
4403 else if (!pvStructInfo
)
4404 *pcbStructInfo
= sizeof(int);
4405 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
4409 if (dataLen
&& pbEncoded
[1 + lenBytes
] & 0x80)
4411 /* initialize to a negative value to sign-extend */
4416 for (i
= 0; i
< dataLen
; i
++)
4419 val
|= pbEncoded
[1 + lenBytes
+ i
];
4421 memcpy(pvStructInfo
, &val
, sizeof(int));
4427 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
4428 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4429 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4435 DWORD bytesNeeded
= 0;
4439 SetLastError(CRYPT_E_ASN1_EOD
);
4442 else if (pbEncoded
[0] != ASN_INTEGER
)
4444 SetLastError(CRYPT_E_ASN1_BADTAG
);
4448 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4449 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4453 *pcbStructInfo
= bytesNeeded
;
4454 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4455 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4457 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4458 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4459 ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
,
4460 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4461 &bytesNeeded
, NULL
);
4462 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4463 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4469 SetLastError(STATUS_ACCESS_VIOLATION
);
4476 static BOOL
CRYPT_AsnDecodeIntegerInternal(const BYTE
*pbEncoded
,
4477 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4481 DWORD bytesNeeded
, dataLen
;
4483 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4485 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4487 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4489 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4491 *pcbStructInfo
= bytesNeeded
;
4492 else if (*pcbStructInfo
< bytesNeeded
)
4494 *pcbStructInfo
= bytesNeeded
;
4495 SetLastError(ERROR_MORE_DATA
);
4500 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4502 *pcbStructInfo
= bytesNeeded
;
4503 blob
->cbData
= dataLen
;
4504 assert(blob
->pbData
);
4509 for (i
= 0; i
< blob
->cbData
; i
++)
4511 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4520 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
4521 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4522 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4528 DWORD bytesNeeded
= 0;
4530 if (pbEncoded
[0] != ASN_INTEGER
)
4532 SetLastError(CRYPT_E_ASN1_BADTAG
);
4536 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4537 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4541 *pcbStructInfo
= bytesNeeded
;
4542 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4543 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4545 CRYPT_INTEGER_BLOB
*blob
;
4547 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4548 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4549 blob
= pvStructInfo
;
4550 blob
->pbData
= (BYTE
*)pvStructInfo
+
4551 sizeof(CRYPT_INTEGER_BLOB
);
4552 ret
= CRYPT_AsnDecodeIntegerInternal(pbEncoded
, cbEncoded
,
4553 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4554 &bytesNeeded
, NULL
);
4555 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4556 CRYPT_FreeSpace(pDecodePara
, blob
);
4562 SetLastError(STATUS_ACCESS_VIOLATION
);
4569 static BOOL
CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE
*pbEncoded
,
4570 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4575 if (pbEncoded
[0] == ASN_INTEGER
)
4577 DWORD bytesNeeded
, dataLen
;
4579 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
4581 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
4584 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
4585 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
4587 *pcbStructInfo
= bytesNeeded
;
4588 else if (*pcbStructInfo
< bytesNeeded
)
4590 *pcbStructInfo
= bytesNeeded
;
4591 SetLastError(ERROR_MORE_DATA
);
4596 CRYPT_INTEGER_BLOB
*blob
= pvStructInfo
;
4598 *pcbStructInfo
= bytesNeeded
;
4599 blob
->cbData
= dataLen
;
4600 assert(blob
->pbData
);
4601 /* remove leading zero byte if it exists */
4602 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
4611 for (i
= 0; i
< blob
->cbData
; i
++)
4613 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
4622 SetLastError(CRYPT_E_ASN1_BADTAG
);
4628 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
4629 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4630 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4636 DWORD bytesNeeded
= 0;
4638 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
, cbEncoded
,
4639 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
)))
4642 *pcbStructInfo
= bytesNeeded
;
4643 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4644 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4646 CRYPT_INTEGER_BLOB
*blob
;
4648 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4649 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4650 blob
= pvStructInfo
;
4651 blob
->pbData
= (BYTE
*)pvStructInfo
+
4652 sizeof(CRYPT_INTEGER_BLOB
);
4653 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded
,
4654 cbEncoded
, dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, pvStructInfo
,
4655 &bytesNeeded
, NULL
);
4656 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4657 CRYPT_FreeSpace(pDecodePara
, blob
);
4663 SetLastError(STATUS_ACCESS_VIOLATION
);
4670 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
4671 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4672 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4678 *pcbStructInfo
= sizeof(int);
4683 if (pbEncoded
[0] == ASN_ENUMERATED
)
4685 unsigned int val
= 0, i
;
4689 SetLastError(CRYPT_E_ASN1_EOD
);
4692 else if (pbEncoded
[1] == 0)
4694 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4699 /* A little strange looking, but we have to accept a sign byte:
4700 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
4701 * assuming a small length is okay here, it has to be in short
4704 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
4706 SetLastError(CRYPT_E_ASN1_LARGE
);
4709 for (i
= 0; i
< pbEncoded
[1]; i
++)
4712 val
|= pbEncoded
[2 + i
];
4714 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4715 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
4717 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4718 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4719 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
4725 SetLastError(CRYPT_E_ASN1_BADTAG
);
4731 SetLastError(STATUS_ACCESS_VIOLATION
);
4738 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
4741 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
4746 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
4748 if (!isdigit(*(pbEncoded))) \
4750 SetLastError(CRYPT_E_ASN1_CORRUPT); \
4756 (word) += *(pbEncoded)++ - '0'; \
4761 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
4762 SYSTEMTIME
*sysTime
)
4766 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
4768 WORD hours
, minutes
= 0;
4769 BYTE sign
= *pbEncoded
++;
4772 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
4773 if (ret
&& hours
>= 24)
4775 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4780 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
4781 if (ret
&& minutes
>= 60)
4783 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4791 sysTime
->wHour
+= hours
;
4792 sysTime
->wMinute
+= minutes
;
4796 if (hours
> sysTime
->wHour
)
4799 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
4802 sysTime
->wHour
-= hours
;
4803 if (minutes
> sysTime
->wMinute
)
4806 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
4809 sysTime
->wMinute
-= minutes
;
4816 #define MIN_ENCODED_TIME_LENGTH 10
4818 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
4819 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4824 if (pbEncoded
[0] == ASN_UTCTIME
)
4827 SetLastError(CRYPT_E_ASN1_EOD
);
4828 else if (pbEncoded
[1] > 0x7f)
4830 /* long-form date strings really can't be valid */
4831 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4835 SYSTEMTIME sysTime
= { 0 };
4836 BYTE len
= pbEncoded
[1];
4838 if (len
< MIN_ENCODED_TIME_LENGTH
)
4839 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4844 *pcbDecoded
= 2 + len
;
4846 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
4847 if (sysTime
.wYear
>= 50)
4848 sysTime
.wYear
+= 1900;
4850 sysTime
.wYear
+= 2000;
4851 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4852 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4853 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4854 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
4857 if (len
>= 2 && isdigit(*pbEncoded
) &&
4858 isdigit(*(pbEncoded
+ 1)))
4859 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4861 else if (isdigit(*pbEncoded
))
4862 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
4865 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4871 *pcbStructInfo
= sizeof(FILETIME
);
4872 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4874 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4880 SetLastError(CRYPT_E_ASN1_BADTAG
);
4884 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
4885 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4886 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4892 DWORD bytesNeeded
= 0;
4894 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4895 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
4899 *pcbStructInfo
= bytesNeeded
;
4900 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
4901 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
4903 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4904 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4905 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
4906 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4907 &bytesNeeded
, NULL
);
4908 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
4909 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
4915 SetLastError(STATUS_ACCESS_VIOLATION
);
4921 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
4922 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4927 if (pbEncoded
[0] == ASN_GENERALTIME
)
4930 SetLastError(CRYPT_E_ASN1_EOD
);
4931 else if (pbEncoded
[1] > 0x7f)
4933 /* long-form date strings really can't be valid */
4934 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4938 BYTE len
= pbEncoded
[1];
4940 if (len
< MIN_ENCODED_TIME_LENGTH
)
4941 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4944 SYSTEMTIME sysTime
= { 0 };
4948 *pcbDecoded
= 2 + len
;
4950 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
4951 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
4952 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
4953 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
4956 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4959 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
4961 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
4968 /* workaround macro weirdness */
4969 digits
= min(len
, 3);
4970 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
4971 sysTime
.wMilliseconds
);
4974 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
4980 *pcbStructInfo
= sizeof(FILETIME
);
4981 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
4983 ret
= SystemTimeToFileTime(&sysTime
, pvStructInfo
);
4989 SetLastError(CRYPT_E_ASN1_BADTAG
);
4993 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
4994 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4998 InternalDecodeFunc decode
= NULL
;
5000 if (pbEncoded
[0] == ASN_UTCTIME
)
5001 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
5002 else if (pbEncoded
[0] == ASN_GENERALTIME
)
5003 decode
= CRYPT_AsnDecodeGeneralizedTime
;
5005 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
5006 pcbStructInfo
, pcbDecoded
);
5009 SetLastError(CRYPT_E_ASN1_BADTAG
);
5015 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
5016 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5017 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5023 DWORD bytesNeeded
= 0;
5025 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5026 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
5030 *pcbStructInfo
= bytesNeeded
;
5031 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5032 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5034 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5035 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5036 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
5037 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5038 &bytesNeeded
, NULL
);
5039 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5040 CRYPT_FreeSpace(pDecodePara
, pvStructInfo
);
5046 SetLastError(STATUS_ACCESS_VIOLATION
);
5053 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
5054 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5055 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5061 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
5063 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
5065 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5070 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5071 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
5073 ptr
= pbEncoded
+ 1 + lenBytes
;
5074 remainingLen
= dataLen
;
5075 while (ret
&& remainingLen
)
5079 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5082 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5084 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5085 ptr
+= 1 + nextLenBytes
+ nextLen
;
5086 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
5087 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
5088 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
5094 CRYPT_SEQUENCE_OF_ANY
*seq
;
5099 *pcbStructInfo
= bytesNeeded
;
5100 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
5101 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
5103 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5104 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5106 seq
->cValue
= cValue
;
5107 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
5109 nextPtr
= (BYTE
*)seq
->rgValue
+
5110 cValue
* sizeof(CRYPT_DER_BLOB
);
5111 ptr
= pbEncoded
+ 1 + lenBytes
;
5112 remainingLen
= dataLen
;
5114 while (ret
&& remainingLen
)
5118 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
5121 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
5123 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
5125 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
5126 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
5129 seq
->rgValue
[i
].pbData
= nextPtr
;
5130 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
5132 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
5134 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
5135 ptr
+= 1 + nextLenBytes
+ nextLen
;
5139 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5140 CRYPT_FreeSpace(pDecodePara
, seq
);
5147 SetLastError(CRYPT_E_ASN1_BADTAG
);
5153 SetLastError(STATUS_ACCESS_VIOLATION
);
5160 static BOOL
CRYPT_AsnDecodeDistPointName(const BYTE
*pbEncoded
,
5161 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5166 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
5168 DWORD bytesNeeded
= 0, dataLen
;
5170 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
5172 struct AsnArrayDescriptor arrayDesc
= {
5173 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5174 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.cAltEntry
),
5175 offsetof(CRL_DIST_POINT_NAME
, u
.FullName
.rgAltEntry
),
5176 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
),
5177 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
5178 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
5179 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
5184 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5185 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5186 dwFlags
, NULL
, NULL
, &nameLen
, NULL
);
5187 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
-
5188 FINALMEMBERSIZE(CRL_DIST_POINT_NAME
, u
);
5191 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
5193 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
5195 *pcbStructInfo
= bytesNeeded
;
5196 else if (*pcbStructInfo
< bytesNeeded
)
5198 *pcbStructInfo
= bytesNeeded
;
5199 SetLastError(ERROR_MORE_DATA
);
5204 CRL_DIST_POINT_NAME
*name
= pvStructInfo
;
5206 *pcbStructInfo
= bytesNeeded
;
5209 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
5210 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
5211 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
5212 dwFlags
, NULL
, &name
->u
.FullName
.cAltEntry
, &nameLen
,
5216 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
5222 SetLastError(CRYPT_E_ASN1_BADTAG
);
5228 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5229 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5231 struct AsnDecodeSequenceItem items
[] = {
5232 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
5233 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5234 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
5235 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5236 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
5237 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
5238 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
5239 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
5240 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
5241 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
5243 CRL_DIST_POINT
*point
= pvStructInfo
;
5246 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5247 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5248 pcbDecoded
, point
? point
->DistPointName
.u
.FullName
.rgAltEntry
: NULL
);
5252 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
5253 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5254 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5258 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5259 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5263 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5264 offsetof(CRL_DIST_POINTS_INFO
, cDistPoint
),
5265 offsetof(CRL_DIST_POINTS_INFO
, rgDistPoint
),
5266 sizeof(CRL_DIST_POINTS_INFO
),
5267 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
5268 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
5269 CRL_DIST_POINTS_INFO
*info
= pvStructInfo
;
5271 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5272 info
->rgDistPoint
= (CRL_DIST_POINT
*)(info
+ 1);
5273 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5274 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5278 SetLastError(STATUS_ACCESS_VIOLATION
);
5285 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
5286 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5287 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5291 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5292 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5296 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
5297 offsetof(CERT_ENHKEY_USAGE
, cUsageIdentifier
),
5298 offsetof(CERT_ENHKEY_USAGE
, rgpszUsageIdentifier
),
5299 sizeof(CERT_ENHKEY_USAGE
),
5300 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
5301 CERT_ENHKEY_USAGE
*usage
= pvStructInfo
;
5303 if (pvStructInfo
&& !(dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5304 usage
->rgpszUsageIdentifier
= (LPSTR
*)(usage
+ 1);
5305 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5306 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
5310 SetLastError(STATUS_ACCESS_VIOLATION
);
5317 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
5318 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5319 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5323 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5324 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5328 struct AsnDecodeSequenceItem items
[] = {
5329 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
5330 DistPointName
), CRYPT_AsnDecodeDistPointName
,
5331 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
5332 offsetof(CRL_ISSUING_DIST_POINT
,
5333 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
5334 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
5335 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5337 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
5338 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
5340 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
5341 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
5342 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
5343 OnlySomeReasonFlags
.pbData
), 0 },
5344 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
5345 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
5348 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5349 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5350 pcbStructInfo
, NULL
, NULL
);
5354 SetLastError(STATUS_ACCESS_VIOLATION
);
5361 static BOOL
CRYPT_AsnDecodeMaximum(const BYTE
*pbEncoded
,
5362 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5366 DWORD max
, size
= sizeof(max
);
5368 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5369 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5373 SetLastError(CRYPT_E_ASN1_EOD
);
5376 if (pbEncoded
[0] != (ASN_CONTEXT
| 1))
5378 SetLastError(CRYPT_E_ASN1_BADTAG
);
5381 if ((ret
= CRYPT_AsnDecodeIntInternal(pbEncoded
, cbEncoded
, dwFlags
,
5382 &max
, &size
, pcbDecoded
)))
5384 DWORD bytesNeeded
= FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
);
5387 *pcbStructInfo
= bytesNeeded
;
5388 else if (*pcbStructInfo
< bytesNeeded
)
5390 *pcbStructInfo
= bytesNeeded
;
5391 SetLastError(ERROR_MORE_DATA
);
5396 CERT_GENERAL_SUBTREE
*subtree
= CONTAINING_RECORD(pvStructInfo
,
5397 CERT_GENERAL_SUBTREE
, fMaximum
);
5399 *pcbStructInfo
= bytesNeeded
;
5400 /* The BOOL is implicit: if the integer is present, then it's
5403 subtree
->fMaximum
= TRUE
;
5404 subtree
->dwMaximum
= max
;
5407 TRACE("returning %d\n", ret
);
5411 static BOOL
CRYPT_AsnDecodeSubtree(const BYTE
*pbEncoded
,
5412 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5416 struct AsnDecodeSequenceItem items
[] = {
5417 { 0, offsetof(CERT_GENERAL_SUBTREE
, Base
),
5418 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
, TRUE
,
5419 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
), 0 },
5420 { ASN_CONTEXT
| 0, offsetof(CERT_GENERAL_SUBTREE
, dwMinimum
),
5421 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
5422 { ASN_CONTEXT
| 1, offsetof(CERT_GENERAL_SUBTREE
, fMaximum
),
5423 CRYPT_AsnDecodeMaximum
, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE
, fMaximum
),
5424 TRUE
, FALSE
, 0, 0 },
5426 CERT_GENERAL_SUBTREE
*subtree
= pvStructInfo
;
5428 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5429 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5431 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5432 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5433 pcbDecoded
, subtree
? subtree
->Base
.u
.pwszURL
: NULL
);
5436 TRACE("%d\n", *pcbDecoded
);
5437 if (*pcbDecoded
< cbEncoded
)
5438 TRACE("%02x %02x\n", *(pbEncoded
+ *pcbDecoded
),
5439 *(pbEncoded
+ *pcbDecoded
+ 1));
5441 TRACE("returning %d\n", ret
);
5445 static BOOL
CRYPT_AsnDecodePermittedSubtree(const BYTE
*pbEncoded
,
5446 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5450 struct AsnArrayDescriptor arrayDesc
= { 0,
5451 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5452 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
),
5453 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5455 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5456 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5458 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5459 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5461 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5462 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5466 static BOOL
CRYPT_AsnDecodeExcludedSubtree(const BYTE
*pbEncoded
,
5467 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5471 struct AsnArrayDescriptor arrayDesc
= { 0,
5472 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5473 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
),
5474 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5475 CRYPT_AsnDecodeSubtree
, sizeof(CERT_GENERAL_SUBTREE
), TRUE
,
5476 offsetof(CERT_GENERAL_SUBTREE
, Base
.u
.pwszURL
) };
5478 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5479 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5481 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5482 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5486 static BOOL WINAPI
CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType
,
5487 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5488 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5492 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5493 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5497 struct AsnDecodeSequenceItem items
[] = {
5498 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
5499 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
),
5500 CRYPT_AsnDecodePermittedSubtree
,
5501 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cPermittedSubtree
,
5502 cExcludedSubtree
), TRUE
, TRUE
,
5503 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgPermittedSubtree
), 0 },
5504 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
5505 offsetof(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5506 CRYPT_AsnDecodeExcludedSubtree
,
5507 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO
, cExcludedSubtree
),
5509 offsetof(CERT_NAME_CONSTRAINTS_INFO
, rgExcludedSubtree
), 0 },
5512 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5513 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
5514 pcbStructInfo
, NULL
, NULL
);
5518 SetLastError(STATUS_ACCESS_VIOLATION
);
5524 static BOOL
CRYPT_AsnDecodeIssuerSerialNumber(const BYTE
*pbEncoded
,
5525 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5529 struct AsnDecodeSequenceItem items
[] = {
5530 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
5531 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
5533 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
5534 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
5535 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
5537 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
= pvStructInfo
;
5539 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5540 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5542 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5543 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5544 pcbDecoded
, issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
5545 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
5547 SetLastError(CRYPT_E_ASN1_CORRUPT
);
5550 TRACE("returning %d\n", ret
);
5554 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
5555 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5558 CMSG_SIGNER_INFO
*info
= pvStructInfo
;
5559 struct AsnDecodeSequenceItem items
[] = {
5560 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
5561 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5562 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
5563 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
5564 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
5565 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
5566 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5567 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5568 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5569 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
5570 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5571 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5572 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
5573 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5574 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
5575 HashEncryptionAlgorithm
.pszObjId
), 0 },
5576 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
5577 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5578 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5579 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5580 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
5581 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5582 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5586 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5587 pvStructInfo
, *pcbStructInfo
);
5589 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5590 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5591 pcbDecoded
, info
? info
->Issuer
.pbData
: NULL
);
5595 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
5596 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5597 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5601 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5602 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5606 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
5607 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5608 if (ret
&& pvStructInfo
)
5610 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5611 pcbStructInfo
, *pcbStructInfo
);
5614 CMSG_SIGNER_INFO
*info
;
5616 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5617 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5618 info
= pvStructInfo
;
5619 info
->Issuer
.pbData
= ((BYTE
*)info
+
5620 sizeof(CMSG_SIGNER_INFO
));
5621 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
5622 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5623 pcbStructInfo
, NULL
);
5624 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5625 CRYPT_FreeSpace(pDecodePara
, info
);
5631 SetLastError(STATUS_ACCESS_VIOLATION
);
5634 TRACE("returning %d\n", ret
);
5638 static BOOL
verify_and_copy_certificate(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5639 void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5641 PCCERT_CONTEXT cert
;
5643 cert
= CertCreateCertificateContext(X509_ASN_ENCODING
, pbEncoded
, cbEncoded
);
5646 WARN("CertCreateCertificateContext error %#x\n", GetLastError());
5652 CertFreeCertificateContext(cert
);
5654 return CRYPT_AsnDecodeCopyBytes(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5657 static BOOL
CRYPT_AsnDecodeCMSCertEncoded(const BYTE
*pbEncoded
,
5658 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5662 struct AsnArrayDescriptor arrayDesc
= { 0,
5663 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
5664 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
),
5665 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
),
5666 verify_and_copy_certificate
,
5667 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5669 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5670 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5672 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5673 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5677 static BOOL
CRYPT_AsnDecodeCMSCrlEncoded(const BYTE
*pbEncoded
,
5678 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5682 struct AsnArrayDescriptor arrayDesc
= { 0,
5683 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
),
5684 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
),
5685 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
),
5686 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DER_BLOB
),
5687 TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
5689 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5690 pvStructInfo
, pvStructInfo
? *pcbStructInfo
: 0, pcbDecoded
);
5692 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5693 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5697 static BOOL
CRYPT_AsnDecodeCMSSignerId(const BYTE
*pbEncoded
,
5698 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5701 CERT_ID
*id
= pvStructInfo
;
5704 if (*pbEncoded
== ASN_SEQUENCEOF
)
5706 ret
= CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded
, cbEncoded
, dwFlags
,
5707 id
? &id
->u
.IssuerSerialNumber
: NULL
, pcbStructInfo
, pcbDecoded
);
5711 id
->dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5712 if (*pcbStructInfo
> sizeof(CERT_ISSUER_SERIAL_NUMBER
))
5713 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5714 sizeof(CERT_ISSUER_SERIAL_NUMBER
);
5716 *pcbStructInfo
= sizeof(CERT_ID
);
5719 else if (*pbEncoded
== (ASN_CONTEXT
| 0))
5721 ret
= CRYPT_AsnDecodeOctets(pbEncoded
, cbEncoded
, dwFlags
,
5722 id
? &id
->u
.KeyId
: NULL
, pcbStructInfo
, pcbDecoded
);
5726 id
->dwIdChoice
= CERT_ID_KEY_IDENTIFIER
;
5727 if (*pcbStructInfo
> sizeof(CRYPT_DATA_BLOB
))
5728 *pcbStructInfo
= sizeof(CERT_ID
) + *pcbStructInfo
-
5729 sizeof(CRYPT_DATA_BLOB
);
5731 *pcbStructInfo
= sizeof(CERT_ID
);
5735 SetLastError(CRYPT_E_ASN1_BADTAG
);
5739 static BOOL
CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE
*pbEncoded
,
5740 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5743 CMSG_CMS_SIGNER_INFO
*info
= pvStructInfo
;
5744 struct AsnDecodeSequenceItem items
[] = {
5745 { ASN_INTEGER
, offsetof(CMSG_CMS_SIGNER_INFO
, dwVersion
),
5746 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5747 { 0, offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
),
5748 CRYPT_AsnDecodeCMSSignerId
, sizeof(CERT_ID
), FALSE
, TRUE
,
5749 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
), 0 },
5750 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
),
5751 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5752 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
5753 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5754 offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
),
5755 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5756 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
5757 { ASN_SEQUENCEOF
, offsetof(CMSG_CMS_SIGNER_INFO
, HashEncryptionAlgorithm
),
5758 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
5759 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
,
5760 HashEncryptionAlgorithm
.pszObjId
), 0 },
5761 { ASN_OCTETSTRING
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
),
5762 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
5763 FALSE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
5764 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5765 offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
),
5766 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
5767 TRUE
, TRUE
, offsetof(CMSG_CMS_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
5771 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5772 pvStructInfo
, *pcbStructInfo
);
5774 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5775 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5776 pcbDecoded
, info
? info
->SignerId
.u
.KeyId
.pbData
: NULL
);
5780 static BOOL WINAPI
CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType
,
5781 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
5782 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
5786 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
5787 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
5791 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
, cbEncoded
,
5792 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
5793 if (ret
&& pvStructInfo
)
5795 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
5796 pcbStructInfo
, *pcbStructInfo
);
5799 CMSG_CMS_SIGNER_INFO
*info
;
5801 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
5802 pvStructInfo
= *(BYTE
**)pvStructInfo
;
5803 info
= pvStructInfo
;
5804 info
->SignerId
.u
.KeyId
.pbData
= ((BYTE
*)info
+
5805 sizeof(CMSG_CMS_SIGNER_INFO
));
5806 ret
= CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded
,
5807 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
5808 pcbStructInfo
, NULL
);
5809 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
5810 CRYPT_FreeSpace(pDecodePara
, info
);
5816 SetLastError(STATUS_ACCESS_VIOLATION
);
5819 TRACE("returning %d\n", ret
);
5823 static BOOL
CRYPT_DecodeSignerArray(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5824 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5827 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5828 offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5829 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
),
5830 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
),
5831 CRYPT_AsnDecodeCMSSignerInfoInternal
, sizeof(CMSG_CMS_SIGNER_INFO
), TRUE
,
5832 offsetof(CMSG_CMS_SIGNER_INFO
, SignerId
.u
.KeyId
.pbData
) };
5834 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5835 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5837 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5838 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5842 BOOL
CRYPT_AsnDecodeCMSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5843 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5844 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
5847 struct AsnDecodeSequenceItem items
[] = {
5848 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
5849 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5850 /* Placeholder for the hash algorithms - redundant with those in the
5851 * signers, so just ignore them.
5853 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
5854 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
5855 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
5856 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
5857 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
5858 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
), CRYPT_AsnDecodeCMSCertEncoded
,
5859 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCertEncoded
, cCrlEncoded
), TRUE
, TRUE
,
5860 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
5861 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
5862 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_AsnDecodeCMSCrlEncoded
,
5863 MEMBERSIZE(CRYPT_SIGNED_INFO
, cCrlEncoded
, content
), TRUE
, TRUE
,
5864 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
5865 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
5866 CRYPT_DecodeSignerArray
,
5867 FINALMEMBERSIZE(CRYPT_SIGNED_INFO
, cSignerInfo
), TRUE
, TRUE
,
5868 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
5871 TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5872 pDecodePara
, signedInfo
, pcbSignedInfo
);
5874 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5875 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, signedInfo
, pcbSignedInfo
,
5877 TRACE("returning %d\n", ret
);
5881 static BOOL
CRYPT_AsnDecodeRecipientInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5882 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
5885 CMSG_KEY_TRANS_RECIPIENT_INFO
*info
= pvStructInfo
;
5886 struct AsnDecodeSequenceItem items
[] = {
5887 { ASN_INTEGER
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, dwVersion
),
5888 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5889 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5890 RecipientId
.u
.IssuerSerialNumber
), CRYPT_AsnDecodeIssuerSerialNumber
,
5891 sizeof(CERT_ISSUER_SERIAL_NUMBER
), FALSE
, TRUE
,
5892 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5893 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
), 0 },
5894 { ASN_SEQUENCEOF
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5895 KeyEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5896 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5897 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5898 KeyEncryptionAlgorithm
.pszObjId
), 0 },
5899 { ASN_OCTETSTRING
, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
),
5900 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DATA_BLOB
), FALSE
, TRUE
,
5901 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
, EncryptedKey
.pbData
), 0 },
5904 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5905 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5907 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5908 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5909 pcbDecoded
, info
? info
->RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
:
5912 info
->RecipientId
.dwIdChoice
= CERT_ID_ISSUER_SERIAL_NUMBER
;
5913 TRACE("returning %d\n", ret
);
5917 static BOOL
CRYPT_DecodeRecipientInfoArray(const BYTE
*pbEncoded
,
5918 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5922 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
5923 offsetof(CRYPT_ENVELOPED_DATA
, cRecipientInfo
),
5924 offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
),
5925 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5926 CRYPT_AsnDecodeRecipientInfo
, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO
), TRUE
,
5927 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO
,
5928 RecipientId
.u
.IssuerSerialNumber
.Issuer
.pbData
) };
5930 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5931 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5933 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
,
5934 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
);
5935 TRACE("returning %d\n", ret
);
5939 static BOOL
CRYPT_AsnDecodeEncryptedContentInfo(const BYTE
*pbEncoded
,
5940 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
5944 CRYPT_ENCRYPTED_CONTENT_INFO
*info
= pvStructInfo
;
5945 struct AsnDecodeSequenceItem items
[] = {
5946 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5947 contentType
), CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
),
5948 FALSE
, TRUE
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5950 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5951 contentEncryptionAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
5952 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
5953 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5954 contentEncryptionAlgorithm
.pszObjId
), 0 },
5955 { ASN_CONTEXT
| 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
,
5956 encryptedContent
), CRYPT_AsnDecodeOctets
,
5957 sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
5958 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO
, encryptedContent
.pbData
) },
5961 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5962 pvStructInfo
, *pcbStructInfo
, pcbDecoded
);
5964 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5965 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
,
5966 pcbDecoded
, info
? info
->contentType
: NULL
);
5967 TRACE("returning %d\n", ret
);
5971 BOOL
CRYPT_AsnDecodePKCSEnvelopedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
5972 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
5973 CRYPT_ENVELOPED_DATA
*envelopedData
, DWORD
*pcbEnvelopedData
)
5976 struct AsnDecodeSequenceItem items
[] = {
5977 { ASN_INTEGER
, offsetof(CRYPT_ENVELOPED_DATA
, version
),
5978 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
5979 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ENVELOPED_DATA
,
5980 cRecipientInfo
), CRYPT_DecodeRecipientInfoArray
,
5981 MEMBERSIZE(CRYPT_ENVELOPED_DATA
, cRecipientInfo
, encryptedContentInfo
),
5982 FALSE
, TRUE
, offsetof(CRYPT_ENVELOPED_DATA
, rgRecipientInfo
), 0 },
5983 { ASN_SEQUENCEOF
, offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
),
5984 CRYPT_AsnDecodeEncryptedContentInfo
,
5985 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO
), FALSE
, TRUE
,
5986 offsetof(CRYPT_ENVELOPED_DATA
, encryptedContentInfo
.contentType
), 0 },
5989 TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded
, cbEncoded
, dwFlags
,
5990 pDecodePara
, envelopedData
, pcbEnvelopedData
);
5992 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
5993 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, envelopedData
,
5994 pcbEnvelopedData
, NULL
, NULL
);
5995 TRACE("returning %d\n", ret
);
5999 static BOOL WINAPI
CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType
,
6000 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6001 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6003 DWORD bytesNeeded
= 0;
6008 ret
= CRYPT_AsnDecodeOidInternal(pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
6009 NULL
, &bytesNeeded
, NULL
);
6013 *pcbStructInfo
= bytesNeeded
;
6014 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
6018 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6019 pvStructInfo
= *(BYTE
**)pvStructInfo
;
6021 info
= pvStructInfo
;
6022 *info
= (void *)((BYTE
*)info
+ sizeof(*info
));
6023 ret
= CRYPT_AsnDecodeOidInternal(pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
6024 pvStructInfo
, &bytesNeeded
, NULL
);
6025 if (!ret
&& (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
))
6026 CRYPT_FreeSpace(pDecodePara
, info
);
6032 SetLastError(STATUS_ACCESS_VIOLATION
);
6039 static BOOL WINAPI
CRYPT_AsnDecodeEccSignature(DWORD dwCertEncodingType
,
6040 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6041 CRYPT_DECODE_PARA
*pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6044 struct AsnDecodeSequenceItem items
[] = {
6045 { ASN_INTEGER
, offsetof(CERT_ECC_SIGNATURE
, r
),
6046 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_UINT_BLOB
), FALSE
,
6047 TRUE
, offsetof(CERT_ECC_SIGNATURE
, r
.pbData
), 0 },
6048 { ASN_INTEGER
, offsetof(CERT_ECC_SIGNATURE
, s
),
6049 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_UINT_BLOB
), FALSE
,
6050 TRUE
, offsetof(CERT_ECC_SIGNATURE
, s
.pbData
), 0 },
6055 ret
= CRYPT_AsnDecodeSequence(items
, ARRAY_SIZE(items
),
6056 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
6057 pcbStructInfo
, NULL
, NULL
);
6061 SetLastError(STATUS_ACCESS_VIOLATION
);
6068 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
6069 LPCSTR lpszStructType
)
6071 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6073 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
6074 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
6076 SetLastError(ERROR_FILE_NOT_FOUND
);
6079 if (IS_INTOID(lpszStructType
))
6081 switch (LOWORD(lpszStructType
))
6083 case LOWORD(X509_CERT
):
6084 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
6086 case LOWORD(X509_CERT_TO_BE_SIGNED
):
6087 decodeFunc
= CRYPT_AsnDecodeCert
;
6089 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED
):
6090 decodeFunc
= CRYPT_AsnDecodeCRL
;
6092 case LOWORD(X509_EXTENSIONS
):
6093 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6095 case LOWORD(X509_NAME_VALUE
):
6096 decodeFunc
= CRYPT_AsnDecodeNameValue
;
6098 case LOWORD(X509_NAME
):
6099 decodeFunc
= CRYPT_AsnDecodeName
;
6101 case LOWORD(X509_PUBLIC_KEY_INFO
):
6102 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
6104 case LOWORD(X509_AUTHORITY_KEY_ID
):
6105 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6107 case LOWORD(X509_ALTERNATE_NAME
):
6108 decodeFunc
= CRYPT_AsnDecodeAltName
;
6110 case LOWORD(X509_BASIC_CONSTRAINTS
):
6111 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6113 case LOWORD(X509_BASIC_CONSTRAINTS2
):
6114 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6116 case LOWORD(X509_CERT_POLICIES
):
6117 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6119 case LOWORD(RSA_CSP_PUBLICKEYBLOB
):
6120 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
6122 case LOWORD(PKCS_RSA_PRIVATE_KEY
):
6123 decodeFunc
= CRYPT_AsnDecodeRsaPrivKey
;
6125 case LOWORD(X509_UNICODE_NAME
):
6126 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
6128 case LOWORD(PKCS_ATTRIBUTE
):
6129 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
6131 case LOWORD(X509_UNICODE_NAME_VALUE
):
6132 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
6134 case LOWORD(X509_OCTET_STRING
):
6135 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6137 case LOWORD(X509_BITS
):
6138 case LOWORD(X509_KEY_USAGE
):
6139 decodeFunc
= CRYPT_AsnDecodeBits
;
6141 case LOWORD(X509_INTEGER
):
6142 decodeFunc
= CRYPT_AsnDecodeInt
;
6144 case LOWORD(X509_MULTI_BYTE_INTEGER
):
6145 decodeFunc
= CRYPT_AsnDecodeInteger
;
6147 case LOWORD(X509_MULTI_BYTE_UINT
):
6148 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
6150 case LOWORD(X509_ENUMERATED
):
6151 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6153 case LOWORD(X509_CHOICE_OF_TIME
):
6154 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
6156 case LOWORD(X509_AUTHORITY_KEY_ID2
):
6157 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6159 case LOWORD(X509_AUTHORITY_INFO_ACCESS
):
6160 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6162 case LOWORD(PKCS_CONTENT_INFO
):
6163 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
6165 case LOWORD(X509_SEQUENCE_OF_ANY
):
6166 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
6168 case LOWORD(PKCS_UTC_TIME
):
6169 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6171 case LOWORD(X509_CRL_DIST_POINTS
):
6172 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6174 case LOWORD(X509_ENHANCED_KEY_USAGE
):
6175 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6177 case LOWORD(PKCS_CTL
):
6178 decodeFunc
= CRYPT_AsnDecodeCTL
;
6180 case LOWORD(PKCS_SMIME_CAPABILITIES
):
6181 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6183 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE
):
6184 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6186 case LOWORD(PKCS_ATTRIBUTES
):
6187 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
6189 case LOWORD(X509_ISSUING_DIST_POINT
):
6190 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6192 case LOWORD(X509_NAME_CONSTRAINTS
):
6193 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6195 case LOWORD(X509_POLICY_MAPPINGS
):
6196 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6198 case LOWORD(X509_POLICY_CONSTRAINTS
):
6199 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6201 case LOWORD(PKCS7_SIGNER_INFO
):
6202 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
6204 case LOWORD(CMS_SIGNER_INFO
):
6205 decodeFunc
= CRYPT_AsnDecodeCMSSignerInfo
;
6207 case LOWORD(X509_OBJECT_IDENTIFIER
):
6208 decodeFunc
= CRYPT_AsnDecodeObjectIdentifier
;
6210 case LOWORD(X509_ECC_SIGNATURE
):
6211 decodeFunc
= CRYPT_AsnDecodeEccSignature
;
6215 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
6216 decodeFunc
= CRYPT_AsnDecodeExtensions
;
6217 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
6218 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
6219 else if (!strcmp(lpszStructType
, szOID_RSA_SMIMECapabilities
))
6220 decodeFunc
= CRYPT_AsnDecodeSMIMECapabilities
;
6221 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
6222 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
6223 else if (!strcmp(lpszStructType
, szOID_LEGACY_POLICY_MAPPINGS
))
6224 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6225 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
6226 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
6227 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
6228 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
6229 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
6230 decodeFunc
= CRYPT_AsnDecodeBits
;
6231 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
6232 decodeFunc
= CRYPT_AsnDecodeOctetString
;
6233 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
6234 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
6235 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
6236 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
6237 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
6238 decodeFunc
= CRYPT_AsnDecodeAltName
;
6239 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
6240 decodeFunc
= CRYPT_AsnDecodeAltName
;
6241 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
6242 decodeFunc
= CRYPT_AsnDecodeAltName
;
6243 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
6244 decodeFunc
= CRYPT_AsnDecodeAltName
;
6245 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
6246 decodeFunc
= CRYPT_AsnDecodeAltName
;
6247 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
6248 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
6249 else if (!strcmp(lpszStructType
, szOID_CERT_POLICIES
))
6250 decodeFunc
= CRYPT_AsnDecodeCertPolicies
;
6251 else if (!strcmp(lpszStructType
, szOID_POLICY_MAPPINGS
))
6252 decodeFunc
= CRYPT_AsnDecodeCertPolicyMappings
;
6253 else if (!strcmp(lpszStructType
, szOID_POLICY_CONSTRAINTS
))
6254 decodeFunc
= CRYPT_AsnDecodeCertPolicyConstraints
;
6255 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
6256 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
6257 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
6258 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
6259 else if (!strcmp(lpszStructType
, szOID_NAME_CONSTRAINTS
))
6260 decodeFunc
= CRYPT_AsnDecodeNameConstraints
;
6261 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_INFO_ACCESS
))
6262 decodeFunc
= CRYPT_AsnDecodeAuthorityInfoAccess
;
6263 else if (!strcmp(lpszStructType
, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE
))
6264 decodeFunc
= CRYPT_AsnDecodePolicyQualifierUserNotice
;
6265 else if (!strcmp(lpszStructType
, szOID_CTL
))
6266 decodeFunc
= CRYPT_AsnDecodeCTL
;
6267 else if (!strcmp(lpszStructType
, szOID_ECC_PUBLIC_KEY
))
6268 decodeFunc
= CRYPT_AsnDecodeObjectIdentifier
;
6272 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
6273 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6275 static HCRYPTOIDFUNCSET set
= NULL
;
6276 CryptDecodeObjectFunc decodeFunc
= NULL
;
6279 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
6280 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6281 (void **)&decodeFunc
, hFunc
);
6285 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
6286 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
6288 static HCRYPTOIDFUNCSET set
= NULL
;
6289 CryptDecodeObjectExFunc decodeFunc
= NULL
;
6292 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
6293 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
6294 (void **)&decodeFunc
, hFunc
);
6298 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6299 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
6300 DWORD
*pcbStructInfo
)
6302 return CryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
6303 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
);
6306 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
6307 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
6308 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
6311 CryptDecodeObjectExFunc decodeFunc
;
6312 HCRYPTOIDFUNCADDR hFunc
= NULL
;
6314 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
6315 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
6316 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6318 if (!pvStructInfo
&& !pcbStructInfo
)
6320 SetLastError(ERROR_INVALID_PARAMETER
);
6323 if (cbEncoded
> MAX_ENCODED_LEN
)
6325 SetLastError(CRYPT_E_ASN1_LARGE
);
6329 SetLastError(NOERROR
);
6330 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6334 SetLastError(ERROR_INVALID_PARAMETER
);
6337 *(BYTE
**)pvStructInfo
= NULL
;
6339 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
6342 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
6343 debugstr_a(lpszStructType
));
6344 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
6348 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
6349 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
6352 CryptDecodeObjectFunc pCryptDecodeObject
=
6353 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
6355 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
6356 * directly, as that could cause an infinite loop.
6358 if (pCryptDecodeObject
)
6360 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
6362 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6363 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
6364 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
6365 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
6367 ret
= pCryptDecodeObject(dwCertEncodingType
,
6368 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
6369 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
6371 CRYPT_FreeSpace(pDecodePara
, *(BYTE
**)pvStructInfo
);
6375 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
6376 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
6380 CryptFreeOIDFunctionAddress(hFunc
, 0);
6381 TRACE_(crypt
)("returning %d\n", ret
);
6385 BOOL WINAPI
PFXIsPFXBlob(CRYPT_DATA_BLOB
*pPFX
)
6389 TRACE_(crypt
)("(%p)\n", pPFX
);
6391 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a
6392 * version integer of length 1 (3 encoded byes) and at least one other
6393 * datum (two encoded bytes), plus at least two bytes for the outer
6394 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length.
6396 if (pPFX
->cbData
< 7)
6398 else if (pPFX
->pbData
[0] == ASN_SEQUENCE
)
6402 if ((ret
= CRYPT_GetLengthIndefinite(pPFX
->pbData
, pPFX
->cbData
, &len
)))
6404 BYTE lenLen
= GET_LEN_BYTES(pPFX
->pbData
[1]);
6406 /* Need at least three bytes for the integer version */
6407 if (pPFX
->cbData
< 1 + lenLen
+ 3)
6409 else if (pPFX
->pbData
[1 + lenLen
] != ASN_INTEGER
|| /* Tag */
6410 pPFX
->pbData
[1 + lenLen
+ 1] != 1 || /* Definite length */
6411 pPFX
->pbData
[1 + lenLen
+ 2] != 3) /* PFX version */