2 * Copyright 2005-2007 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"
38 #define NONAMELESSUNION
45 #include "wine/debug.h"
46 #include "wine/exception.h"
47 #include "crypt32_private.h"
49 /* This is a bit arbitrary, but to set some limit: */
50 #define MAX_ENCODED_LEN 0x02000000
52 #define ASN_FLAGS_MASK 0xe0
53 #define ASN_TYPE_MASK 0x1f
55 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
56 WINE_DECLARE_DEBUG_CHANNEL(crypt
);
64 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
65 DWORD
, DWORD
, void *, DWORD
*);
66 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
67 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
69 /* Internal decoders don't do memory allocation or exception handling, and
70 * they report how many bytes they decoded.
72 typedef BOOL (*InternalDecodeFunc
)(const BYTE
*pbEncoded
, DWORD cbEncoded
,
73 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
);
75 /* Prototypes for built-in decoders. They follow the Ex style prototypes.
76 * The dwCertEncodingType and lpszStructType are ignored by the built-in
77 * functions, but the parameters are retained to simplify CryptDecodeObjectEx,
78 * since it must call functions in external DLLs that follow these signatures.
80 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
81 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
82 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
83 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
84 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
85 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
86 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
87 * time, doesn't do memory allocation, and doesn't do exception handling.
88 * (This isn't intended to be the externally-called one.)
90 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
91 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
92 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
93 /* Assumes algo->Parameters.pbData is set ahead of time. Internal func. */
94 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
95 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
96 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
97 /* Internal function */
98 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
99 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
100 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
101 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
102 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
103 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
104 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
105 /* Like CRYPT_AsnDecodeBits, but assumes the CRYPT_INTEGER_BLOB's pbData
106 * member has been initialized, doesn't do exception handling, and doesn't do
109 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
110 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
111 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
112 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
113 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
114 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
115 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
116 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
117 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
118 static BOOL WINAPI
CRYPT_AsnDecodeIntInternal(DWORD dwCertEncodingType
,
119 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
120 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
121 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
122 * member has been initialized, doesn't do exception handling, and doesn't do
123 * memory allocation. Also doesn't check tag, assumes the caller has checked
126 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
127 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
128 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
129 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
130 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
131 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
132 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
133 void *pvStructInfo
, DWORD
*pcbStructInfo
);
135 /* Gets the number of length bytes from the given (leading) length byte */
136 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f))
138 /* Helper function to get the encoded length of the data starting at pbEncoded,
139 * where pbEncoded[0] is the tag. If the data are too short to contain a
140 * length or if the length is too large for cbEncoded, sets an appropriate
141 * error code and returns FALSE. If the encoded length is unknown due to
142 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH.
144 static BOOL
CRYPT_GetLengthIndefinite(const BYTE
*pbEncoded
, DWORD cbEncoded
,
151 SetLastError(CRYPT_E_ASN1_CORRUPT
);
154 else if (pbEncoded
[1] <= 0x7f)
156 if (pbEncoded
[1] + 1 > cbEncoded
)
158 SetLastError(CRYPT_E_ASN1_EOD
);
167 else if (pbEncoded
[1] == 0x80)
169 *len
= CMSG_INDEFINITE_LENGTH
;
174 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
176 if (lenLen
> sizeof(DWORD
) + 1)
178 SetLastError(CRYPT_E_ASN1_LARGE
);
181 else if (lenLen
+ 2 > cbEncoded
)
183 SetLastError(CRYPT_E_ASN1_CORRUPT
);
196 if (out
+ lenLen
+ 1 > cbEncoded
)
198 SetLastError(CRYPT_E_ASN1_EOD
);
211 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */
212 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
216 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, len
)) &&
217 *len
== CMSG_INDEFINITE_LENGTH
)
219 SetLastError(CRYPT_E_ASN1_CORRUPT
);
225 /* Helper function to check *pcbStructInfo, set it to the required size, and
226 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
227 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
228 * pointer to the newly allocated memory.
230 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
231 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
236 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
238 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
239 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
241 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
242 if (!*(BYTE
**)pvStructInfo
)
245 *pcbStructInfo
= bytesNeeded
;
247 else if (*pcbStructInfo
< bytesNeeded
)
249 *pcbStructInfo
= bytesNeeded
;
250 SetLastError(ERROR_MORE_DATA
);
256 /* Helper function to check *pcbStructInfo and set it to the required size.
257 * Assumes pvStructInfo is not NULL.
259 static BOOL
CRYPT_DecodeCheckSpace(DWORD
*pcbStructInfo
, DWORD bytesNeeded
)
263 if (*pcbStructInfo
< bytesNeeded
)
265 *pcbStructInfo
= bytesNeeded
;
266 SetLastError(ERROR_MORE_DATA
);
271 *pcbStructInfo
= bytesNeeded
;
278 * The expected tag of the item. If tag is 0, decodeFunc is called
279 * regardless of the tag value seen.
281 * A sequence is decoded into a struct. The offset member is the
282 * offset of this item within that struct.
284 * The decoder function to use. If this is NULL, then the member isn't
285 * decoded, but minSize space is reserved for it.
287 * The minimum amount of space occupied after decoding. You must set this.
289 * If true, and the tag doesn't match the expected tag for this item,
290 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
291 * filled with 0 for this member.
292 * hasPointer, pointerOffset:
293 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
294 * the offset within the struct of the data pointer (or to the
295 * first data pointer, if more than one exist).
297 * Used by CRYPT_AsnDecodeSequence, not for your use.
299 struct AsnDecodeSequenceItem
303 CryptDecodeObjectExFunc decodeFunc
;
311 /* Decodes the items in a sequence, where the items are described in items,
312 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
313 * pvStructInfo. nextData is a pointer to the memory location at which the
314 * first decoded item with a dynamic pointer should point.
315 * Upon decoding, *cbDecoded is the total number of bytes decoded.
316 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
318 static BOOL
CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType
,
319 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
320 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, BYTE
*nextData
,
324 DWORD i
, decoded
= 0;
325 const BYTE
*ptr
= pbEncoded
;
327 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
328 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
330 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
332 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
336 if ((ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
339 BYTE nextItemLenBytes
= GET_LEN_BYTES(ptr
[1]);
341 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
343 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
345 TRACE("Setting next pointer to %p\n",
347 *(BYTE
**)((BYTE
*)pvStructInfo
+
348 items
[i
].pointerOffset
) = nextData
;
350 if (items
[i
].decodeFunc
)
353 TRACE("decoding item %d\n", i
);
355 TRACE("sizing item %d\n", i
);
356 ret
= items
[i
].decodeFunc(dwCertEncodingType
,
357 NULL
, ptr
, 1 + nextItemLenBytes
+ nextItemLen
,
358 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
359 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
360 : NULL
, &items
[i
].size
);
363 /* Account for alignment padding */
364 if (items
[i
].size
% sizeof(DWORD_PTR
))
365 items
[i
].size
+= sizeof(DWORD_PTR
) -
366 items
[i
].size
% sizeof(DWORD_PTR
);
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 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
372 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
373 TRACE("item %d: decoded %d bytes\n", i
,
374 1 + nextItemLenBytes
+ nextItemLen
);
376 else if (items
[i
].optional
&&
377 GetLastError() == CRYPT_E_ASN1_BADTAG
)
379 TRACE("skipping optional item %d\n", i
);
380 items
[i
].size
= items
[i
].minSize
;
381 SetLastError(NOERROR
);
385 TRACE("item %d failed: %08x\n", i
,
390 TRACE("item %d: decoded %d bytes\n", i
,
391 1 + nextItemLenBytes
+ nextItemLen
);
392 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
393 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
394 items
[i
].size
= items
[i
].minSize
;
397 else if (items
[i
].optional
)
399 TRACE("skipping optional item %d\n", i
);
400 items
[i
].size
= items
[i
].minSize
;
404 TRACE("item %d: tag %02x doesn't match expected %02x\n",
405 i
, ptr
[0], items
[i
].tag
);
406 SetLastError(CRYPT_E_ASN1_BADTAG
);
411 else if (items
[i
].optional
)
413 TRACE("missing optional item %d, skipping\n", i
);
414 items
[i
].size
= items
[i
].minSize
;
418 TRACE("not enough bytes for item %d, failing\n", i
);
419 SetLastError(CRYPT_E_ASN1_CORRUPT
);
424 *cbDecoded
= decoded
;
425 TRACE("returning %d\n", ret
);
429 /* This decodes an arbitrary sequence into a contiguous block of memory
430 * (basically, a struct.) Each element being decoded is described by a struct
431 * AsnDecodeSequenceItem, see above.
432 * startingPointer is an optional pointer to the first place where dynamic
433 * data will be stored. If you know the starting offset, you may pass it
434 * here. Otherwise, pass NULL, and one will be inferred from the items.
436 static BOOL
CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType
,
437 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
438 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
439 void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
,
440 void *startingPointer
)
444 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
445 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
448 if (pbEncoded
[0] == ASN_SEQUENCE
)
452 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
454 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
455 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
457 cbEncoded
-= 1 + lenBytes
;
458 if (cbEncoded
< dataLen
)
460 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
462 SetLastError(CRYPT_E_ASN1_CORRUPT
);
466 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
, ptr
,
467 cbEncoded
, dwFlags
, NULL
, NULL
, &cbDecoded
);
468 if (ret
&& cbDecoded
!= dataLen
)
470 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
472 SetLastError(CRYPT_E_ASN1_CORRUPT
);
477 DWORD i
, bytesNeeded
= 0, structSize
= 0;
479 for (i
= 0; i
< cItem
; i
++)
481 bytesNeeded
+= items
[i
].size
;
482 structSize
+= items
[i
].minSize
;
484 if (ret
&& pcbDecoded
)
485 *pcbDecoded
= 1 + lenBytes
+ cbDecoded
;
487 *pcbStructInfo
= bytesNeeded
;
488 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
489 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
493 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
494 pvStructInfo
= *(BYTE
**)pvStructInfo
;
496 nextData
= (BYTE
*)startingPointer
;
498 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
499 memset(pvStructInfo
, 0, structSize
);
500 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
,
501 ptr
, cbEncoded
, dwFlags
, pvStructInfo
, nextData
,
509 SetLastError(CRYPT_E_ASN1_BADTAG
);
512 TRACE("returning %d (%08x)\n", ret
, GetLastError());
517 * The expected tag of the entire encoded array (usually a variant
518 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
519 * regardless of the tag seen.
521 * used to decode each item in the array
523 * is the minimum size of each decoded item
525 * indicates whether each item has a dynamic pointer
527 * indicates the offset within itemSize at which the pointer exists
529 struct AsnArrayDescriptor
532 InternalDecodeFunc decodeFunc
;
538 struct AsnArrayItemSize
544 /* Decodes an array of like types into a struct GenericArray.
545 * The layout and decoding of the array are described by a struct
546 * AsnArrayDescriptor.
548 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
549 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
550 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
551 DWORD
*pcbDecoded
, void *startingPointer
)
555 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
556 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
559 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
563 if ((ret
= CRYPT_GetLengthIndefinite(pbEncoded
, cbEncoded
, &dataLen
)))
565 DWORD bytesNeeded
, cItems
= 0, decoded
;
566 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
567 /* There can be arbitrarily many items, but there is often only one.
569 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
571 decoded
= 1 + lenBytes
;
572 bytesNeeded
= sizeof(struct GenericArray
);
576 BOOL doneDecoding
= FALSE
;
578 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&& !doneDecoding
; )
582 itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
583 if (dataLen
== CMSG_INDEFINITE_LENGTH
)
588 if (itemLenBytes
!= 1 || ptr
[1] != 0)
590 SetLastError(CRYPT_E_ASN1_CORRUPT
);
597 else if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
)
601 DWORD itemEncoded
, itemDataLen
, itemDecoded
, size
= 0;
603 /* Each item decoded may not tolerate extraneous bytes,
604 * so get the length of the next element if known.
606 if ((ret
= CRYPT_GetLengthIndefinite(ptr
,
607 cbEncoded
- (ptr
- pbEncoded
), &itemDataLen
)))
609 if (itemDataLen
== CMSG_INDEFINITE_LENGTH
)
610 itemEncoded
= cbEncoded
- (ptr
- pbEncoded
);
612 itemEncoded
= 1 + itemLenBytes
+ itemDataLen
;
615 ret
= arrayDesc
->decodeFunc(ptr
, itemEncoded
,
616 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &size
,
621 if (itemSizes
!= &itemSize
)
622 itemSizes
= CryptMemRealloc(itemSizes
,
623 cItems
* sizeof(struct AsnArrayItemSize
));
628 cItems
* sizeof(struct AsnArrayItemSize
));
630 memcpy(itemSizes
, &itemSize
,
635 decoded
+= itemDecoded
;
636 itemSizes
[cItems
- 1].encodedLen
= itemEncoded
;
637 itemSizes
[cItems
- 1].size
= size
;
650 *pcbDecoded
= decoded
;
652 *pcbStructInfo
= bytesNeeded
;
653 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
654 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
659 struct GenericArray
*array
;
661 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
662 pvStructInfo
= *(BYTE
**)pvStructInfo
;
663 array
= (struct GenericArray
*)pvStructInfo
;
664 array
->cItems
= cItems
;
666 array
->rgItems
= startingPointer
;
668 array
->rgItems
= (BYTE
*)array
+
669 sizeof(struct GenericArray
);
670 nextData
= (BYTE
*)array
->rgItems
+
671 array
->cItems
* arrayDesc
->itemSize
;
672 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
673 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
676 if (arrayDesc
->hasPointer
)
677 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
678 + arrayDesc
->pointerOffset
) = nextData
;
679 ret
= arrayDesc
->decodeFunc(ptr
,
680 itemSizes
[i
].encodedLen
,
681 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
682 array
->rgItems
+ i
* arrayDesc
->itemSize
,
683 &itemSizes
[i
].size
, NULL
);
688 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
689 ret
= CRYPT_GetLen(ptr
,
690 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
692 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
697 if (itemSizes
!= &itemSize
)
698 CryptMemFree(itemSizes
);
703 SetLastError(CRYPT_E_ASN1_BADTAG
);
709 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
710 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
711 * to CRYPT_E_ASN1_CORRUPT.
712 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
715 static BOOL WINAPI
CRYPT_AsnDecodeDerBlob(DWORD dwCertEncodingType
,
716 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
717 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
722 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
724 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
725 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
727 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
728 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
731 *pcbStructInfo
= bytesNeeded
;
732 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, bytesNeeded
)))
734 CRYPT_DER_BLOB
*blob
;
736 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
737 pvStructInfo
= *(BYTE
**)pvStructInfo
;
738 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
739 blob
->cbData
= 1 + lenBytes
+ dataLen
;
742 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
743 blob
->pbData
= (BYTE
*)pbEncoded
;
746 assert(blob
->pbData
);
747 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
752 SetLastError(CRYPT_E_ASN1_CORRUPT
);
760 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
761 static BOOL WINAPI
CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType
,
762 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
763 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
767 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
768 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
770 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
773 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
, lpszStructType
,
774 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pDecodePara
,
775 pvStructInfo
, pcbStructInfo
);
776 if (ret
&& pvStructInfo
)
778 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
785 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
787 temp
= blob
->pbData
[i
];
788 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
789 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
793 TRACE("returning %d (%08x)\n", ret
, GetLastError());
797 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
798 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
799 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
803 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
804 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
808 struct AsnDecodeSequenceItem items
[] = {
809 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
810 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
811 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
812 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
813 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
814 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
815 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
816 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
817 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
818 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
821 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
822 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
823 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
824 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
825 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
829 SetLastError(STATUS_ACCESS_VIOLATION
);
834 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
838 /* Internal function */
839 static BOOL WINAPI
CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType
,
840 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
841 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
846 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
848 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
850 ret
= CRYPT_AsnDecodeIntInternal(dwCertEncodingType
, NULL
,
851 pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
, pDecodePara
, pvStructInfo
,
857 static BOOL WINAPI
CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType
,
858 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
859 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
863 struct AsnDecodeSequenceItem items
[] = {
864 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
865 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
866 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
867 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
870 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
871 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
872 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
876 /* Internal function */
877 static BOOL WINAPI
CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType
,
878 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
879 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
884 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
886 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
888 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
889 X509_EXTENSIONS
, pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
,
890 pDecodePara
, pvStructInfo
, pcbStructInfo
);
895 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
896 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
897 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
900 struct AsnDecodeSequenceItem items
[] = {
901 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
902 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
903 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
904 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
905 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
906 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
907 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
908 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
909 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
910 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
912 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
913 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
915 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
916 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
918 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
919 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
920 FALSE
, TRUE
, offsetof(CERT_INFO
,
921 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
922 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
923 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
924 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
925 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
926 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
927 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
928 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
929 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
930 offsetof(CERT_INFO
, rgExtension
), 0 },
933 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
934 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
936 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
937 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
938 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
939 if (ret
&& pvStructInfo
)
943 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
944 info
= *(CERT_INFO
**)pvStructInfo
;
946 info
= (CERT_INFO
*)pvStructInfo
;
947 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
948 !info
->Subject
.cbData
)
950 SetLastError(CRYPT_E_ASN1_CORRUPT
);
951 /* Don't need to deallocate, because it should have failed on the
952 * first pass (and no memory was allocated.)
958 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
962 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
963 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
964 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
968 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
969 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
975 /* Unless told not to, first try to decode it as a signed cert. */
976 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
978 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
980 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
981 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
982 (BYTE
*)&signedCert
, &size
);
986 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
987 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
988 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
989 pvStructInfo
, pcbStructInfo
);
990 LocalFree(signedCert
);
993 /* Failing that, try it as an unsigned cert */
997 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
998 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
999 pDecodePara
, pvStructInfo
, pcbStructInfo
);
1004 SetLastError(STATUS_ACCESS_VIOLATION
);
1008 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1012 static BOOL
CRYPT_AsnDecodeCRLEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1013 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1016 struct AsnDecodeSequenceItem items
[] = {
1017 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
1018 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
1019 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
1020 { 0, offsetof(CRL_ENTRY
, RevocationDate
), CRYPT_AsnDecodeChoiceOfTime
,
1021 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1022 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
1023 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1024 offsetof(CRL_ENTRY
, rgExtension
), 0 },
1026 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
1028 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
1031 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1032 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1033 NULL
, entry
, pcbStructInfo
, pcbDecoded
,
1034 entry
? entry
->SerialNumber
.pbData
: NULL
);
1038 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1039 * been set prior to calling.
1041 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType
,
1042 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1043 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1046 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1047 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1048 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1049 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
1051 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1052 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1054 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1055 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
,
1056 entries
? entries
->rgItems
: NULL
);
1057 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1061 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1062 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1063 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1065 struct AsnDecodeSequenceItem items
[] = {
1066 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1067 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1068 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1069 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1070 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1071 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1072 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1074 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
1075 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1076 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
1077 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1078 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1079 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1080 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1081 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1082 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1083 offsetof(CRL_INFO
, rgExtension
), 0 },
1087 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1088 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1090 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1091 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1092 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1094 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1098 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1099 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1100 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1104 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1105 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1111 /* Unless told not to, first try to decode it as a signed crl. */
1112 if (!(dwFlags
& CRYPT_DECODE_TO_BE_SIGNED_FLAG
))
1114 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1116 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
,
1117 X509_CERT
, pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1118 (BYTE
*)&signedCrl
, &size
);
1122 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1123 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1124 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1125 pvStructInfo
, pcbStructInfo
);
1126 LocalFree(signedCrl
);
1129 /* Failing that, try it as an unsigned crl */
1133 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1134 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1135 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1140 SetLastError(STATUS_ACCESS_VIOLATION
);
1144 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1148 static BOOL
CRYPT_AsnDecodeOidIgnoreTag(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1149 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1154 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1155 pvStructInfo
, *pcbStructInfo
);
1157 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1159 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1160 DWORD bytesNeeded
= sizeof(LPSTR
);
1164 /* The largest possible string for the first two components
1165 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1170 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1171 pbEncoded
[1 + lenBytes
] / 40,
1172 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1174 bytesNeeded
+= strlen(firstTwo
) + 1;
1175 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1176 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1178 /* large enough for ".4000000" */
1182 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1189 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1192 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1199 snprintf(str
, sizeof(str
), ".%d", val
);
1200 bytesNeeded
+= strlen(str
);
1205 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
1207 *pcbStructInfo
= bytesNeeded
;
1208 else if (*pcbStructInfo
< bytesNeeded
)
1210 *pcbStructInfo
= bytesNeeded
;
1211 SetLastError(ERROR_MORE_DATA
);
1219 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1222 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1223 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1225 pszObjId
+= strlen(pszObjId
);
1226 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1227 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1231 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1240 sprintf(pszObjId
, ".%d", val
);
1241 pszObjId
+= strlen(pszObjId
);
1245 *(LPSTR
*)pvStructInfo
= NULL
;
1246 *pcbStructInfo
= bytesNeeded
;
1252 static BOOL WINAPI
CRYPT_AsnDecodeOidIgnoreTagWrap(DWORD dwCertEncodingType
,
1253 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1254 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1256 return CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1257 pvStructInfo
, pcbStructInfo
, NULL
);
1260 static BOOL
CRYPT_AsnDecodeOidInternal(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1261 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1265 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1266 pvStructInfo
, *pcbStructInfo
);
1268 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1269 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, dwFlags
,
1270 pvStructInfo
, pcbStructInfo
, pcbDecoded
);
1273 SetLastError(CRYPT_E_ASN1_BADTAG
);
1279 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1282 static BOOL
CRYPT_AsnDecodeExtension(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1283 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1285 struct AsnDecodeSequenceItem items
[] = {
1286 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1287 CRYPT_AsnDecodeOidIgnoreTagWrap
, sizeof(LPSTR
), FALSE
, TRUE
,
1288 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1289 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1290 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1291 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1292 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1293 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1296 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1298 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1302 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1303 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1304 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1305 ext
, pcbStructInfo
, pcbDecoded
, ext
? ext
->pszObjId
: NULL
);
1307 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1308 debugstr_a(ext
->pszObjId
));
1309 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1313 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
1314 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1315 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1318 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1319 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1320 offsetof(CERT_EXTENSION
, pszObjId
) };
1321 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1323 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1324 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1326 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1327 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
,
1328 exts
? exts
->rgExtension
: NULL
);
1332 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1333 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1334 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1340 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1341 lpszStructType
, pbEncoded
, cbEncoded
,
1342 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1343 if (ret
&& pvStructInfo
)
1345 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1346 pcbStructInfo
, *pcbStructInfo
);
1349 CERT_EXTENSIONS
*exts
;
1351 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1352 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1353 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1354 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1355 sizeof(CERT_EXTENSIONS
));
1356 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1357 lpszStructType
, pbEncoded
, cbEncoded
,
1358 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1365 SetLastError(STATUS_ACCESS_VIOLATION
);
1372 /* Warning: this assumes the address of value->Value.pbData is already set, in
1373 * order to avoid overwriting memory. (In some cases, it may change it, if it
1374 * doesn't copy anything to memory.) Be sure to set it correctly!
1376 static BOOL WINAPI
CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType
,
1377 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1378 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1382 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1384 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1386 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1387 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1389 switch (pbEncoded
[0])
1391 case ASN_OCTETSTRING
:
1392 valueType
= CERT_RDN_OCTET_STRING
;
1393 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1394 bytesNeeded
+= dataLen
;
1396 case ASN_NUMERICSTRING
:
1397 valueType
= CERT_RDN_NUMERIC_STRING
;
1398 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1399 bytesNeeded
+= dataLen
;
1401 case ASN_PRINTABLESTRING
:
1402 valueType
= CERT_RDN_PRINTABLE_STRING
;
1403 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1404 bytesNeeded
+= dataLen
;
1407 valueType
= CERT_RDN_IA5_STRING
;
1408 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1409 bytesNeeded
+= dataLen
;
1412 valueType
= CERT_RDN_T61_STRING
;
1413 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1414 bytesNeeded
+= dataLen
;
1416 case ASN_VIDEOTEXSTRING
:
1417 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1418 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1419 bytesNeeded
+= dataLen
;
1421 case ASN_GRAPHICSTRING
:
1422 valueType
= CERT_RDN_GRAPHIC_STRING
;
1423 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1424 bytesNeeded
+= dataLen
;
1426 case ASN_VISIBLESTRING
:
1427 valueType
= CERT_RDN_VISIBLE_STRING
;
1428 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1429 bytesNeeded
+= dataLen
;
1431 case ASN_GENERALSTRING
:
1432 valueType
= CERT_RDN_GENERAL_STRING
;
1433 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1434 bytesNeeded
+= dataLen
;
1436 case ASN_UNIVERSALSTRING
:
1437 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1438 SetLastError(CRYPT_E_ASN1_BADTAG
);
1441 valueType
= CERT_RDN_BMP_STRING
;
1442 bytesNeeded
+= dataLen
;
1444 case ASN_UTF8STRING
:
1445 valueType
= CERT_RDN_UTF8_STRING
;
1446 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1447 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1450 SetLastError(CRYPT_E_ASN1_BADTAG
);
1455 *pcbStructInfo
= bytesNeeded
;
1456 else if (*pcbStructInfo
< bytesNeeded
)
1458 *pcbStructInfo
= bytesNeeded
;
1459 SetLastError(ERROR_MORE_DATA
);
1464 *pcbStructInfo
= bytesNeeded
;
1465 value
->dwValueType
= valueType
;
1470 assert(value
->Value
.pbData
);
1471 switch (pbEncoded
[0])
1473 case ASN_OCTETSTRING
:
1474 case ASN_NUMERICSTRING
:
1475 case ASN_PRINTABLESTRING
:
1478 case ASN_VIDEOTEXSTRING
:
1479 case ASN_GRAPHICSTRING
:
1480 case ASN_VISIBLESTRING
:
1481 case ASN_GENERALSTRING
:
1482 value
->Value
.cbData
= dataLen
;
1485 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1486 memcpy(value
->Value
.pbData
,
1487 pbEncoded
+ 1 + lenBytes
, dataLen
);
1489 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1495 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1497 value
->Value
.cbData
= dataLen
;
1498 for (i
= 0; i
< dataLen
/ 2; i
++)
1499 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1500 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1503 case ASN_UTF8STRING
:
1505 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1507 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1508 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1509 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1516 value
->Value
.cbData
= 0;
1517 value
->Value
.pbData
= NULL
;
1524 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1525 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1526 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1532 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1533 lpszStructType
, pbEncoded
, cbEncoded
,
1534 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1535 if (ret
&& pvStructInfo
)
1537 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1538 pcbStructInfo
, *pcbStructInfo
);
1541 CERT_NAME_VALUE
*value
;
1543 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1544 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1545 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1546 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1547 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1548 lpszStructType
, pbEncoded
, cbEncoded
,
1549 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1556 SetLastError(STATUS_ACCESS_VIOLATION
);
1563 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValueInternal(
1564 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1565 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1566 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1570 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1572 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1574 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1575 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1577 switch (pbEncoded
[0])
1579 case ASN_NUMERICSTRING
:
1580 valueType
= CERT_RDN_NUMERIC_STRING
;
1581 bytesNeeded
+= dataLen
* 2;
1583 case ASN_PRINTABLESTRING
:
1584 valueType
= CERT_RDN_PRINTABLE_STRING
;
1585 bytesNeeded
+= dataLen
* 2;
1588 valueType
= CERT_RDN_IA5_STRING
;
1589 bytesNeeded
+= dataLen
* 2;
1592 valueType
= CERT_RDN_T61_STRING
;
1593 bytesNeeded
+= dataLen
* 2;
1595 case ASN_VIDEOTEXSTRING
:
1596 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1597 bytesNeeded
+= dataLen
* 2;
1599 case ASN_GRAPHICSTRING
:
1600 valueType
= CERT_RDN_GRAPHIC_STRING
;
1601 bytesNeeded
+= dataLen
* 2;
1603 case ASN_VISIBLESTRING
:
1604 valueType
= CERT_RDN_VISIBLE_STRING
;
1605 bytesNeeded
+= dataLen
* 2;
1607 case ASN_GENERALSTRING
:
1608 valueType
= CERT_RDN_GENERAL_STRING
;
1609 bytesNeeded
+= dataLen
* 2;
1611 case ASN_UNIVERSALSTRING
:
1612 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1613 bytesNeeded
+= dataLen
/ 2;
1616 valueType
= CERT_RDN_BMP_STRING
;
1617 bytesNeeded
+= dataLen
;
1619 case ASN_UTF8STRING
:
1620 valueType
= CERT_RDN_UTF8_STRING
;
1621 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1622 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1625 SetLastError(CRYPT_E_ASN1_BADTAG
);
1630 *pcbStructInfo
= bytesNeeded
;
1631 else if (*pcbStructInfo
< bytesNeeded
)
1633 *pcbStructInfo
= bytesNeeded
;
1634 SetLastError(ERROR_MORE_DATA
);
1639 *pcbStructInfo
= bytesNeeded
;
1640 value
->dwValueType
= valueType
;
1644 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1646 assert(value
->Value
.pbData
);
1647 switch (pbEncoded
[0])
1649 case ASN_NUMERICSTRING
:
1650 case ASN_PRINTABLESTRING
:
1653 case ASN_VIDEOTEXSTRING
:
1654 case ASN_GRAPHICSTRING
:
1655 case ASN_VISIBLESTRING
:
1656 case ASN_GENERALSTRING
:
1657 value
->Value
.cbData
= dataLen
* 2;
1658 for (i
= 0; i
< dataLen
; i
++)
1659 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1661 case ASN_UNIVERSALSTRING
:
1662 value
->Value
.cbData
= dataLen
/ 2;
1663 for (i
= 0; i
< dataLen
/ 4; i
++)
1664 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1665 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1668 value
->Value
.cbData
= dataLen
;
1669 for (i
= 0; i
< dataLen
/ 2; i
++)
1670 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1671 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1673 case ASN_UTF8STRING
:
1674 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1675 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1676 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1682 value
->Value
.cbData
= 0;
1683 value
->Value
.pbData
= NULL
;
1690 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1691 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1692 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1698 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(dwCertEncodingType
,
1699 lpszStructType
, pbEncoded
, cbEncoded
,
1700 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1701 if (ret
&& pvStructInfo
)
1703 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1704 pcbStructInfo
, *pcbStructInfo
);
1707 CERT_NAME_VALUE
*value
;
1709 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1710 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1711 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1712 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1713 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(
1714 dwCertEncodingType
, lpszStructType
, pbEncoded
, cbEncoded
,
1715 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1722 SetLastError(STATUS_ACCESS_VIOLATION
);
1729 static BOOL
CRYPT_AsnDecodeRdnAttr(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1730 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1733 struct AsnDecodeSequenceItem items
[] = {
1734 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1735 CRYPT_AsnDecodeOidIgnoreTagWrap
, sizeof(LPSTR
), FALSE
, TRUE
,
1736 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1737 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1738 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1739 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1741 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1743 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1744 pvStructInfo
, *pcbStructInfo
);
1747 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1748 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1749 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1750 attr
, pcbStructInfo
, pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
1753 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1754 debugstr_a(attr
->pszObjId
));
1755 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1757 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1761 static BOOL
CRYPT_AsnDecodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1762 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1765 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1766 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1767 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1768 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1770 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1771 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1772 rdn
? rdn
->rgRDNAttr
: NULL
);
1776 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1777 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1778 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1784 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1785 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1786 offsetof(CERT_RDN
, rgRDNAttr
) };
1788 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1789 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1793 SetLastError(STATUS_ACCESS_VIOLATION
);
1800 static BOOL
CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE
*pbEncoded
,
1801 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1805 struct AsnDecodeSequenceItem items
[] = {
1806 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1807 CRYPT_AsnDecodeOidIgnoreTagWrap
, sizeof(LPSTR
), FALSE
, TRUE
,
1808 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1809 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1810 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1811 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1813 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1815 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1816 pvStructInfo
, *pcbStructInfo
);
1819 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1820 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1821 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1822 attr
, pcbStructInfo
, pcbDecoded
, attr
? attr
->pszObjId
: NULL
);
1825 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1826 debugstr_a(attr
->pszObjId
));
1827 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1829 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1833 static BOOL
CRYPT_AsnDecodeUnicodeRdn(const BYTE
*pbEncoded
, DWORD cbEncoded
,
1834 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
1837 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1838 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1839 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1840 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1842 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1843 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1844 rdn
? rdn
->rgRDNAttr
: NULL
);
1848 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1849 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1850 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1856 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1857 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1858 offsetof(CERT_RDN
, rgRDNAttr
) };
1860 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1861 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
1865 SetLastError(STATUS_ACCESS_VIOLATION
);
1872 static BOOL
CRYPT_AsnDecodeCopyBytesInternal(const BYTE
*pbEncoded
,
1873 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1877 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
1879 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1880 pvStructInfo
, *pcbStructInfo
);
1882 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1883 bytesNeeded
+= cbEncoded
;
1885 *pcbDecoded
= cbEncoded
;
1887 *pcbStructInfo
= bytesNeeded
;
1888 else if (*pcbStructInfo
< bytesNeeded
)
1890 SetLastError(ERROR_MORE_DATA
);
1891 *pcbStructInfo
= bytesNeeded
;
1896 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1898 *pcbStructInfo
= bytesNeeded
;
1899 blob
->cbData
= cbEncoded
;
1900 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1901 blob
->pbData
= (LPBYTE
)pbEncoded
;
1904 assert(blob
->pbData
);
1905 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1911 static BOOL WINAPI
CRYPT_DecodeDERArray(DWORD dwCertEncodingType
,
1912 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1913 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1916 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytesInternal
,
1917 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
1918 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
1920 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1921 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1923 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1924 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
,
1925 array
? array
->rgItems
: NULL
);
1929 static BOOL
CRYPT_AsnDecodePKCSAttributeInternal(const BYTE
*pbEncoded
,
1930 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1934 struct AsnDecodeSequenceItem items
[] = {
1935 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
1936 CRYPT_AsnDecodeOidIgnoreTagWrap
, sizeof(LPSTR
), FALSE
, TRUE
,
1937 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
1938 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
1939 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
1940 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
1942 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
1944 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1945 pvStructInfo
, *pcbStructInfo
);
1947 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1948 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1949 NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
1950 attr
? attr
->pszObjId
: NULL
);
1951 TRACE("returning %d\n", ret
);
1955 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
1956 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1957 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1961 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1962 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1968 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
1969 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
1973 *pcbStructInfo
= bytesNeeded
;
1974 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1975 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1977 PCRYPT_ATTRIBUTE attr
;
1979 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1980 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1981 attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
1982 attr
->pszObjId
= (LPSTR
)((BYTE
*)pvStructInfo
+
1983 sizeof(CRYPT_ATTRIBUTE
));
1984 ret
= CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded
, cbEncoded
,
1985 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
, &bytesNeeded
,
1992 SetLastError(STATUS_ACCESS_VIOLATION
);
1995 TRACE("returning %d\n", ret
);
1999 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributesInternal(
2000 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2001 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2002 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2004 struct AsnArrayDescriptor arrayDesc
= { 0,
2005 CRYPT_AsnDecodePKCSAttributeInternal
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
2006 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
2007 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2010 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2011 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, attrs
? attrs
->rgAttr
:
2016 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
2017 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2018 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2022 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2023 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2030 SetLastError(CRYPT_E_ASN1_EOD
);
2031 else if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
2032 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2033 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(
2034 dwCertEncodingType
, lpszStructType
, pbEncoded
, cbEncoded
,
2035 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2038 *pcbStructInfo
= bytesNeeded
;
2039 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2040 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2042 PCRYPT_ATTRIBUTES attrs
;
2044 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2045 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2046 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
2047 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
2048 sizeof(CRYPT_ATTRIBUTES
));
2049 ret
= CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType
,
2050 lpszStructType
, pbEncoded
, cbEncoded
,
2051 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2058 SetLastError(STATUS_ACCESS_VIOLATION
);
2061 TRACE("returning %d\n", ret
);
2065 static BOOL WINAPI
CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType
,
2066 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2067 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2070 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
2072 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2073 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2075 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2076 bytesNeeded
+= cbEncoded
;
2078 *pcbStructInfo
= bytesNeeded
;
2079 else if (*pcbStructInfo
< bytesNeeded
)
2081 SetLastError(ERROR_MORE_DATA
);
2082 *pcbStructInfo
= bytesNeeded
;
2087 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
2089 *pcbStructInfo
= bytesNeeded
;
2090 blob
->cbData
= cbEncoded
;
2091 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2092 blob
->pbData
= (LPBYTE
)pbEncoded
;
2095 assert(blob
->pbData
);
2096 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
2102 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
2103 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2104 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2106 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
2107 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
2109 struct AsnDecodeSequenceItem items
[] = {
2110 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
2111 CRYPT_AsnDecodeOidIgnoreTagWrap
, sizeof(LPSTR
), FALSE
, TRUE
,
2112 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
2113 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
2114 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
2115 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
2118 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2119 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2121 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2122 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2123 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
,
2124 algo
? algo
->pszObjId
: NULL
);
2125 if (ret
&& pvStructInfo
)
2127 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
2128 debugstr_a(algo
->pszObjId
));
2133 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
2134 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2135 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2138 struct AsnDecodeSequenceItem items
[] = {
2139 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
2140 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2141 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2142 Algorithm
.pszObjId
) },
2143 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2144 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2145 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2147 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2149 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2150 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2151 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, info
?
2152 info
->Algorithm
.Parameters
.pbData
: NULL
);
2156 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2157 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2158 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2166 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
2167 lpszStructType
, pbEncoded
, cbEncoded
,
2168 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2171 *pcbStructInfo
= bytesNeeded
;
2172 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2173 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2175 PCERT_PUBLIC_KEY_INFO info
;
2177 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2178 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2179 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2180 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2181 sizeof(CERT_PUBLIC_KEY_INFO
);
2182 ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
2183 lpszStructType
, pbEncoded
, cbEncoded
,
2184 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2191 SetLastError(STATUS_ACCESS_VIOLATION
);
2198 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
2199 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2200 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2206 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2209 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2211 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2214 if (pbEncoded
[1] > 1)
2216 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2221 *pcbStructInfo
= sizeof(BOOL
);
2224 else if (*pcbStructInfo
< sizeof(BOOL
))
2226 *pcbStructInfo
= sizeof(BOOL
);
2227 SetLastError(ERROR_MORE_DATA
);
2232 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2235 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2239 static BOOL
CRYPT_AsnDecodeAltNameEntry(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2240 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
2242 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2243 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2246 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2247 pvStructInfo
, *pcbStructInfo
);
2251 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2254 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2255 if (1 + lenBytes
> cbEncoded
)
2257 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2260 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2262 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2264 case 1: /* rfc822Name */
2265 case 2: /* dNSName */
2266 case 6: /* uniformResourceIdentifier */
2267 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2269 case 4: /* directoryName */
2270 case 7: /* iPAddress */
2271 bytesNeeded
+= dataLen
;
2273 case 8: /* registeredID */
2274 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0, NULL
,
2278 /* FIXME: ugly, shouldn't need to know internals of OID decode
2279 * function to use it.
2281 bytesNeeded
+= dataLen
- sizeof(LPSTR
);
2284 case 0: /* otherName */
2285 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2286 SetLastError(CRYPT_E_ASN1_BADTAG
);
2289 case 3: /* x400Address, unimplemented */
2290 case 5: /* ediPartyName, unimplemented */
2291 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2292 SetLastError(CRYPT_E_ASN1_BADTAG
);
2296 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2297 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2303 *pcbDecoded
= 1 + lenBytes
+ dataLen
;
2305 *pcbStructInfo
= bytesNeeded
;
2306 else if (*pcbStructInfo
< bytesNeeded
)
2308 *pcbStructInfo
= bytesNeeded
;
2309 SetLastError(ERROR_MORE_DATA
);
2314 *pcbStructInfo
= bytesNeeded
;
2315 /* MS used values one greater than the asn1 ones.. sigh */
2316 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
2317 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2319 case 1: /* rfc822Name */
2320 case 2: /* dNSName */
2321 case 6: /* uniformResourceIdentifier */
2325 for (i
= 0; i
< dataLen
; i
++)
2326 entry
->u
.pwszURL
[i
] =
2327 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2328 entry
->u
.pwszURL
[i
] = 0;
2329 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2330 debugstr_w(entry
->u
.pwszURL
));
2333 case 4: /* directoryName */
2334 entry
->dwAltNameChoice
= CERT_ALT_NAME_DIRECTORY_NAME
;
2335 /* The data are memory-equivalent with the IPAddress case,
2338 case 7: /* iPAddress */
2339 /* The next data pointer is in the pwszURL spot, that is,
2340 * the first 4 bytes. Need to move it to the next spot.
2342 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2343 entry
->u
.IPAddress
.cbData
= dataLen
;
2344 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2347 case 8: /* registeredID */
2348 ret
= CRYPT_AsnDecodeOidIgnoreTag(pbEncoded
, cbEncoded
, 0,
2349 &entry
->u
.pszRegisteredID
, &dataLen
, NULL
);
2358 static BOOL WINAPI
CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType
,
2359 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2360 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2363 struct AsnArrayDescriptor arrayDesc
= { 0,
2364 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2365 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2366 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2368 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2369 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2372 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2373 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2374 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
,
2375 info
? info
->rgAltEntry
: NULL
);
2379 /* Like CRYPT_AsnDecodeIntegerInternal, but swaps the bytes */
2380 static BOOL WINAPI
CRYPT_AsnDecodeIntegerSwapBytes(DWORD dwCertEncodingType
,
2381 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2382 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2386 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2387 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2389 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
2392 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
, lpszStructType
,
2393 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pDecodePara
,
2394 pvStructInfo
, pcbStructInfo
);
2395 if (ret
&& pvStructInfo
)
2397 CRYPT_DATA_BLOB
*blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2404 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
2406 temp
= blob
->pbData
[i
];
2407 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
2408 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
2412 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2416 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2417 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2418 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2424 struct AsnDecodeSequenceItem items
[] = {
2425 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2426 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2427 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2428 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2429 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2430 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2431 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2432 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2433 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2434 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2435 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2438 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2439 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2440 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
2444 SetLastError(STATUS_ACCESS_VIOLATION
);
2451 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2452 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2453 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2459 struct AsnDecodeSequenceItem items
[] = {
2460 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
2461 CRYPT_AsnDecodeIntegerSwapBytes
, sizeof(CRYPT_DATA_BLOB
),
2462 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
2463 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2464 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
2465 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
2466 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2467 AuthorityCertIssuer
.rgAltEntry
), 0 },
2468 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2469 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2470 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2471 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2472 AuthorityCertSerialNumber
.pbData
), 0 },
2475 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2476 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2477 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
2481 SetLastError(STATUS_ACCESS_VIOLATION
);
2488 static BOOL WINAPI
CRYPT_AsnDecodePKCSContent(DWORD dwCertEncodingType
,
2489 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2490 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2495 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2496 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2498 /* The caller has already checked the tag, no need to check it again.
2499 * Check the outer length is valid by calling CRYPT_GetLen:
2501 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2503 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2506 pbEncoded
+= 1 + lenBytes
;
2507 /* Check the inner length is valid by calling CRYPT_GetLen again: */
2508 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &innerLen
)))
2510 ret
= CRYPT_AsnDecodeCopyBytes(dwCertEncodingType
, NULL
,
2511 pbEncoded
, dataLen
, dwFlags
, pDecodePara
, pvStructInfo
,
2518 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfoInternal(
2519 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2520 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2521 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2523 CRYPT_CONTENT_INFO
*info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2524 struct AsnDecodeSequenceItem items
[] = {
2525 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
2526 CRYPT_AsnDecodeOidIgnoreTagWrap
, sizeof(LPSTR
), FALSE
, TRUE
,
2527 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
2528 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
2529 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
2530 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
2531 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
2535 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2536 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2538 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2539 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2540 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
,
2541 info
? info
->pszObjId
: NULL
);
2545 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
2546 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2547 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2551 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2552 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2556 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(dwCertEncodingType
,
2557 lpszStructType
, pbEncoded
, cbEncoded
,
2558 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
2559 if (ret
&& pvStructInfo
)
2561 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
2562 pcbStructInfo
, *pcbStructInfo
);
2565 CRYPT_CONTENT_INFO
*info
;
2567 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2568 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2569 info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2570 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
2571 sizeof(CRYPT_CONTENT_INFO
));
2572 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(dwCertEncodingType
,
2573 lpszStructType
, pbEncoded
, cbEncoded
,
2574 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2581 SetLastError(STATUS_ACCESS_VIOLATION
);
2587 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2588 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2589 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
2592 struct AsnDecodeSequenceItem items
[] = {
2593 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
),
2594 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2595 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
2596 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2597 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
2599 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
2600 CRYPT_AsnDecodePKCSContentInfoInternal
,
2601 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
2602 ContentInfo
.pszObjId
), 0 },
2603 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
2604 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
2605 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
2608 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
2609 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2610 pDecodePara
, digestedData
, pcbDigestedData
, NULL
, NULL
);
2614 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2615 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2616 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2620 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2621 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2627 if ((ret
= CRYPT_AsnDecodeAltNameInternal(dwCertEncodingType
,
2628 lpszStructType
, pbEncoded
, cbEncoded
,
2629 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2632 *pcbStructInfo
= bytesNeeded
;
2633 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2634 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2636 CERT_ALT_NAME_INFO
*name
;
2638 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2639 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2640 name
= (CERT_ALT_NAME_INFO
*)pvStructInfo
;
2641 name
->rgAltEntry
= (PCERT_ALT_NAME_ENTRY
)
2642 ((BYTE
*)pvStructInfo
+ sizeof(CERT_ALT_NAME_INFO
));
2643 ret
= CRYPT_AsnDecodeAltNameInternal(dwCertEncodingType
,
2644 lpszStructType
, pbEncoded
, cbEncoded
,
2645 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2652 SetLastError(STATUS_ACCESS_VIOLATION
);
2659 struct PATH_LEN_CONSTRAINT
2661 BOOL fPathLenConstraint
;
2662 DWORD dwPathLenConstraint
;
2665 static BOOL WINAPI
CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType
,
2666 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2667 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2671 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2672 pvStructInfo
, *pcbStructInfo
);
2676 if (pbEncoded
[0] == ASN_INTEGER
)
2678 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
);
2681 *pcbStructInfo
= bytesNeeded
;
2682 else if (*pcbStructInfo
< bytesNeeded
)
2684 SetLastError(ERROR_MORE_DATA
);
2685 *pcbStructInfo
= bytesNeeded
;
2690 struct PATH_LEN_CONSTRAINT
*constraint
=
2691 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
2692 DWORD size
= sizeof(constraint
->dwPathLenConstraint
);
2694 ret
= CRYPT_AsnDecodeIntInternal(dwCertEncodingType
, NULL
,
2695 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
,
2696 &constraint
->dwPathLenConstraint
, &size
);
2698 constraint
->fPathLenConstraint
= TRUE
;
2699 TRACE("got an int, dwPathLenConstraint is %d\n",
2700 constraint
->dwPathLenConstraint
);
2705 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2709 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2713 static BOOL WINAPI
CRYPT_AsnDecodeSubtreeConstraints(DWORD dwCertEncodingType
,
2714 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2715 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2718 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2719 CRYPT_AsnDecodeCopyBytesInternal
, sizeof(CERT_NAME_BLOB
), TRUE
,
2720 offsetof(CERT_NAME_BLOB
, pbData
) };
2721 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2723 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2724 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2726 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2727 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
,
2728 entries
? entries
->rgItems
: NULL
);
2729 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
2733 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
2734 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2735 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2741 struct AsnDecodeSequenceItem items
[] = {
2742 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
2743 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2744 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
2745 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2746 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2747 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2748 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2749 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
2750 sizeof(struct GenericArray
), TRUE
, TRUE
,
2751 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
2754 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2755 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2756 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
2760 SetLastError(STATUS_ACCESS_VIOLATION
);
2767 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
2768 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2769 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2775 struct AsnDecodeSequenceItem items
[] = {
2776 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
2777 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
2778 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
2779 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2780 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2783 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2784 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2785 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
2789 SetLastError(STATUS_ACCESS_VIOLATION
);
2796 #define RSA1_MAGIC 0x31415352
2798 struct DECODED_RSA_PUB_KEY
2801 CRYPT_INTEGER_BLOB modulus
;
2804 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
2805 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2806 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2812 struct AsnDecodeSequenceItem items
[] = {
2813 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
2814 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2815 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
2817 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
2818 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2820 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
2823 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2824 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
2825 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
, &size
, NULL
, NULL
);
2828 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2829 decodedKey
->modulus
.cbData
;
2833 *pcbStructInfo
= bytesNeeded
;
2836 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2837 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2840 RSAPUBKEY
*rsaPubKey
;
2842 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2843 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2844 hdr
= (BLOBHEADER
*)pvStructInfo
;
2845 hdr
->bType
= PUBLICKEYBLOB
;
2846 hdr
->bVersion
= CUR_BLOB_VERSION
;
2848 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2849 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
2850 sizeof(BLOBHEADER
));
2851 rsaPubKey
->magic
= RSA1_MAGIC
;
2852 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
2853 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
2854 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
2855 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
2856 decodedKey
->modulus
.cbData
);
2858 LocalFree(decodedKey
);
2863 SetLastError(STATUS_ACCESS_VIOLATION
);
2870 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
2871 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2872 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2875 DWORD bytesNeeded
, dataLen
;
2877 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2878 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2880 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2882 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2883 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
2885 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
2887 *pcbStructInfo
= bytesNeeded
;
2888 else if (*pcbStructInfo
< bytesNeeded
)
2890 SetLastError(ERROR_MORE_DATA
);
2891 *pcbStructInfo
= bytesNeeded
;
2896 CRYPT_DATA_BLOB
*blob
;
2897 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2899 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2900 blob
->cbData
= dataLen
;
2901 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2902 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
2905 assert(blob
->pbData
);
2907 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
2915 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
2916 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2917 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2921 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2922 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2930 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2933 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
2935 SetLastError(CRYPT_E_ASN1_BADTAG
);
2938 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2939 lpszStructType
, pbEncoded
, cbEncoded
,
2940 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2943 *pcbStructInfo
= bytesNeeded
;
2944 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2945 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2947 CRYPT_DATA_BLOB
*blob
;
2949 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2950 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2951 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2952 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
2953 ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2954 lpszStructType
, pbEncoded
, cbEncoded
,
2955 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2962 SetLastError(STATUS_ACCESS_VIOLATION
);
2969 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
2970 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2971 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2975 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2976 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2978 if (pbEncoded
[0] == ASN_BITSTRING
)
2980 DWORD bytesNeeded
, dataLen
;
2982 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2984 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2985 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
2987 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
2989 *pcbStructInfo
= bytesNeeded
;
2990 else if (*pcbStructInfo
< bytesNeeded
)
2992 *pcbStructInfo
= bytesNeeded
;
2993 SetLastError(ERROR_MORE_DATA
);
2998 CRYPT_BIT_BLOB
*blob
;
3000 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3001 blob
->cbData
= dataLen
- 1;
3002 blob
->cUnusedBits
= *(pbEncoded
+ 1 +
3003 GET_LEN_BYTES(pbEncoded
[1]));
3004 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3006 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 +
3007 GET_LEN_BYTES(pbEncoded
[1]);
3011 assert(blob
->pbData
);
3014 BYTE mask
= 0xff << blob
->cUnusedBits
;
3016 memcpy(blob
->pbData
, pbEncoded
+ 2 +
3017 GET_LEN_BYTES(pbEncoded
[1]), blob
->cbData
);
3018 blob
->pbData
[blob
->cbData
- 1] &= mask
;
3026 SetLastError(CRYPT_E_ASN1_BADTAG
);
3029 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3033 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
3034 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3035 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3039 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
3040 pDecodePara
, pvStructInfo
, pcbStructInfo
);
3046 if ((ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
3047 lpszStructType
, pbEncoded
, cbEncoded
,
3048 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
3051 *pcbStructInfo
= bytesNeeded
;
3052 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3053 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3055 CRYPT_BIT_BLOB
*blob
;
3057 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3058 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3059 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
3060 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
3061 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
3062 lpszStructType
, pbEncoded
, cbEncoded
,
3063 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3070 SetLastError(STATUS_ACCESS_VIOLATION
);
3074 TRACE("returning %d (%08x)\n", ret
, GetLastError());
3078 static BOOL WINAPI
CRYPT_AsnDecodeIntInternal(DWORD dwCertEncodingType
,
3079 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
,
3080 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
,
3081 DWORD
*pcbStructInfo
)
3084 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
3085 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
3086 DWORD size
= sizeof(buf
);
3088 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
3089 if (pbEncoded
[0] != ASN_INTEGER
)
3091 SetLastError(CRYPT_E_ASN1_BADTAG
);
3095 ret
= CRYPT_AsnDecodeIntegerInternal(X509_ASN_ENCODING
, NULL
,
3096 pbEncoded
, cbEncoded
, 0, NULL
, &buf
, &size
);
3100 *pcbStructInfo
= sizeof(int);
3101 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
, sizeof(int))))
3105 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
3107 /* initialize to a negative value to sign-extend */
3112 for (i
= 0; i
< blob
->cbData
; i
++)
3115 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
3117 memcpy(pvStructInfo
, &val
, sizeof(int));
3120 else if (GetLastError() == ERROR_MORE_DATA
)
3121 SetLastError(CRYPT_E_ASN1_LARGE
);
3125 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
3126 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3127 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3135 ret
= CRYPT_AsnDecodeIntInternal(dwCertEncodingType
, lpszStructType
,
3136 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
,
3141 *pcbStructInfo
= bytesNeeded
;
3142 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3143 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3145 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3146 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3147 ret
= CRYPT_AsnDecodeIntInternal(dwCertEncodingType
,
3148 lpszStructType
, pbEncoded
, cbEncoded
,
3149 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3156 SetLastError(STATUS_ACCESS_VIOLATION
);
3163 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
3164 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3165 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3168 DWORD bytesNeeded
, dataLen
;
3170 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3172 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3174 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3176 *pcbStructInfo
= bytesNeeded
;
3177 else if (*pcbStructInfo
< bytesNeeded
)
3179 *pcbStructInfo
= bytesNeeded
;
3180 SetLastError(ERROR_MORE_DATA
);
3185 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3187 blob
->cbData
= dataLen
;
3188 assert(blob
->pbData
);
3193 for (i
= 0; i
< blob
->cbData
; i
++)
3195 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3204 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
3205 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3206 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3214 if (pbEncoded
[0] != ASN_INTEGER
)
3216 SetLastError(CRYPT_E_ASN1_BADTAG
);
3220 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
3221 lpszStructType
, pbEncoded
, cbEncoded
,
3222 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
);
3226 *pcbStructInfo
= bytesNeeded
;
3227 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3228 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3230 CRYPT_INTEGER_BLOB
*blob
;
3232 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3233 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3234 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3235 blob
->pbData
= (BYTE
*)pvStructInfo
+
3236 sizeof(CRYPT_INTEGER_BLOB
);
3237 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
3238 lpszStructType
, pbEncoded
, cbEncoded
,
3239 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3246 SetLastError(STATUS_ACCESS_VIOLATION
);
3253 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
3254 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3255 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3256 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3260 if (pbEncoded
[0] == ASN_INTEGER
)
3262 DWORD bytesNeeded
, dataLen
;
3264 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3266 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3268 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3270 *pcbStructInfo
= bytesNeeded
;
3271 else if (*pcbStructInfo
< bytesNeeded
)
3273 *pcbStructInfo
= bytesNeeded
;
3274 SetLastError(ERROR_MORE_DATA
);
3279 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3281 blob
->cbData
= dataLen
;
3282 assert(blob
->pbData
);
3283 /* remove leading zero byte if it exists */
3284 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
3293 for (i
= 0; i
< blob
->cbData
; i
++)
3295 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3304 SetLastError(CRYPT_E_ASN1_BADTAG
);
3310 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
3311 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3312 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3320 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
3321 lpszStructType
, pbEncoded
, cbEncoded
,
3322 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
3325 *pcbStructInfo
= bytesNeeded
;
3326 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3327 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3329 CRYPT_INTEGER_BLOB
*blob
;
3331 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3332 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3333 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3334 blob
->pbData
= (BYTE
*)pvStructInfo
+
3335 sizeof(CRYPT_INTEGER_BLOB
);
3336 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
3337 lpszStructType
, pbEncoded
, cbEncoded
,
3338 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3345 SetLastError(STATUS_ACCESS_VIOLATION
);
3352 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
3353 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3354 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3360 *pcbStructInfo
= sizeof(int);
3365 if (pbEncoded
[0] == ASN_ENUMERATED
)
3367 unsigned int val
= 0, i
;
3371 SetLastError(CRYPT_E_ASN1_EOD
);
3374 else if (pbEncoded
[1] == 0)
3376 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3381 /* A little strange looking, but we have to accept a sign byte:
3382 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3383 * assuming a small length is okay here, it has to be in short
3386 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
3388 SetLastError(CRYPT_E_ASN1_LARGE
);
3391 for (i
= 0; i
< pbEncoded
[1]; i
++)
3394 val
|= pbEncoded
[2 + i
];
3396 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3397 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
3399 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3400 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3401 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
3407 SetLastError(CRYPT_E_ASN1_BADTAG
);
3413 SetLastError(STATUS_ACCESS_VIOLATION
);
3420 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3423 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3428 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3430 if (!isdigit(*(pbEncoded))) \
3432 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3438 (word) += *(pbEncoded)++ - '0'; \
3443 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
3444 SYSTEMTIME
*sysTime
)
3451 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
3453 WORD hours
, minutes
= 0;
3454 BYTE sign
= *pbEncoded
++;
3457 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
3458 if (ret
&& hours
>= 24)
3460 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3465 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
3466 if (ret
&& minutes
>= 60)
3468 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3476 sysTime
->wHour
+= hours
;
3477 sysTime
->wMinute
+= minutes
;
3481 if (hours
> sysTime
->wHour
)
3484 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
3487 sysTime
->wHour
-= hours
;
3488 if (minutes
> sysTime
->wMinute
)
3491 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
3494 sysTime
->wMinute
-= minutes
;
3501 SetLastError(STATUS_ACCESS_VIOLATION
);
3508 #define MIN_ENCODED_TIME_LENGTH 10
3510 static BOOL
CRYPT_AsnDecodeUtcTimeInternal(const BYTE
*pbEncoded
,
3511 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3516 if (pbEncoded
[0] == ASN_UTCTIME
)
3519 SetLastError(CRYPT_E_ASN1_EOD
);
3520 else if (pbEncoded
[1] > 0x7f)
3522 /* long-form date strings really can't be valid */
3523 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3527 SYSTEMTIME sysTime
= { 0 };
3528 BYTE len
= pbEncoded
[1];
3530 if (len
< MIN_ENCODED_TIME_LENGTH
)
3531 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3536 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
3537 if (sysTime
.wYear
>= 50)
3538 sysTime
.wYear
+= 1900;
3540 sysTime
.wYear
+= 2000;
3541 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3542 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3543 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3544 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3547 if (len
>= 2 && isdigit(*pbEncoded
) &&
3548 isdigit(*(pbEncoded
+ 1)))
3549 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3551 else if (isdigit(*pbEncoded
))
3552 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3555 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3561 *pcbStructInfo
= sizeof(FILETIME
);
3562 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3564 ret
= SystemTimeToFileTime(&sysTime
,
3565 (FILETIME
*)pvStructInfo
);
3571 SetLastError(CRYPT_E_ASN1_BADTAG
);
3575 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
3576 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3577 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3585 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3586 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3590 *pcbStructInfo
= bytesNeeded
;
3591 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3592 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3594 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3595 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3596 ret
= CRYPT_AsnDecodeUtcTimeInternal(pbEncoded
, cbEncoded
,
3597 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3598 &bytesNeeded
, NULL
);
3604 SetLastError(STATUS_ACCESS_VIOLATION
);
3610 static BOOL
CRYPT_AsnDecodeGeneralizedTime(const BYTE
*pbEncoded
,
3611 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3616 if (pbEncoded
[0] == ASN_GENERALTIME
)
3619 SetLastError(CRYPT_E_ASN1_EOD
);
3620 else if (pbEncoded
[1] > 0x7f)
3622 /* long-form date strings really can't be valid */
3623 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3627 BYTE len
= pbEncoded
[1];
3629 if (len
< MIN_ENCODED_TIME_LENGTH
)
3630 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3633 SYSTEMTIME sysTime
= { 0 };
3637 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3638 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3639 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3640 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3643 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3646 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3648 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3655 /* workaround macro weirdness */
3656 digits
= min(len
, 3);
3657 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3658 sysTime
.wMilliseconds
);
3661 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3667 *pcbStructInfo
= sizeof(FILETIME
);
3668 else if ((ret
= CRYPT_DecodeCheckSpace(pcbStructInfo
,
3670 ret
= SystemTimeToFileTime(&sysTime
,
3671 (FILETIME
*)pvStructInfo
);
3677 SetLastError(CRYPT_E_ASN1_BADTAG
);
3681 static BOOL
CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE
*pbEncoded
,
3682 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
3686 InternalDecodeFunc decode
= NULL
;
3688 if (pbEncoded
[0] == ASN_UTCTIME
)
3689 decode
= CRYPT_AsnDecodeUtcTimeInternal
;
3690 else if (pbEncoded
[0] == ASN_GENERALTIME
)
3691 decode
= CRYPT_AsnDecodeGeneralizedTime
;
3693 ret
= decode(pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
3694 pcbStructInfo
, pcbDecoded
);
3697 SetLastError(CRYPT_E_ASN1_BADTAG
);
3703 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
3704 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3705 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3713 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
3714 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, &bytesNeeded
, NULL
);
3718 *pcbStructInfo
= bytesNeeded
;
3719 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3720 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3722 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3723 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3724 ret
= CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded
, cbEncoded
,
3725 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
3726 &bytesNeeded
, NULL
);
3732 SetLastError(STATUS_ACCESS_VIOLATION
);
3739 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
3740 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3741 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3747 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
3749 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
3751 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3756 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3757 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
3759 ptr
= pbEncoded
+ 1 + lenBytes
;
3760 remainingLen
= dataLen
;
3761 while (ret
&& remainingLen
)
3765 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3768 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3770 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3771 ptr
+= 1 + nextLenBytes
+ nextLen
;
3772 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
3773 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
3774 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
3780 CRYPT_SEQUENCE_OF_ANY
*seq
;
3784 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3785 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3787 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3788 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3789 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
3790 seq
->cValue
= cValue
;
3791 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
3793 nextPtr
= (BYTE
*)seq
->rgValue
+
3794 cValue
* sizeof(CRYPT_DER_BLOB
);
3795 ptr
= pbEncoded
+ 1 + lenBytes
;
3796 remainingLen
= dataLen
;
3798 while (ret
&& remainingLen
)
3802 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3805 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3807 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
3809 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3810 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
3813 seq
->rgValue
[i
].pbData
= nextPtr
;
3814 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
3816 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
3818 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3819 ptr
+= 1 + nextLenBytes
+ nextLen
;
3829 SetLastError(CRYPT_E_ASN1_BADTAG
);
3835 SetLastError(STATUS_ACCESS_VIOLATION
);
3842 static BOOL WINAPI
CRYPT_AsnDecodeDistPointName(DWORD dwCertEncodingType
,
3843 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3844 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3848 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
3850 DWORD bytesNeeded
, dataLen
;
3852 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3854 struct AsnArrayDescriptor arrayDesc
= {
3855 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
3856 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3857 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3858 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3864 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3865 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3866 0, NULL
, NULL
, &nameLen
, NULL
, NULL
);
3867 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
;
3870 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
3872 *pcbStructInfo
= bytesNeeded
;
3873 else if (*pcbStructInfo
< bytesNeeded
)
3875 *pcbStructInfo
= bytesNeeded
;
3876 SetLastError(ERROR_MORE_DATA
);
3881 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
3885 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3886 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3887 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3888 0, NULL
, &name
->u
.FullName
, pcbStructInfo
, NULL
,
3889 name
->u
.FullName
.rgAltEntry
);
3892 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3898 SetLastError(CRYPT_E_ASN1_BADTAG
);
3904 static BOOL
CRYPT_AsnDecodeDistPoint(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3905 DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
, DWORD
*pcbDecoded
)
3907 struct AsnDecodeSequenceItem items
[] = {
3908 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
3909 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3910 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
3911 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3912 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
3913 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
3914 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
3915 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
3916 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
3917 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
3921 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
3922 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3923 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
, NULL
);
3927 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
3928 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3929 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3933 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3934 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3938 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3939 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
3940 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
3942 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3943 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
3947 SetLastError(STATUS_ACCESS_VIOLATION
);
3954 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
3955 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3956 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3960 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3961 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3965 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3966 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
3968 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3969 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
3973 SetLastError(STATUS_ACCESS_VIOLATION
);
3980 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
3981 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3982 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3986 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3987 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3991 struct AsnDecodeSequenceItem items
[] = {
3992 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
3993 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3994 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
3995 offsetof(CRL_ISSUING_DIST_POINT
,
3996 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3997 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
3998 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4000 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
4001 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
4003 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
4004 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
4005 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
4006 OnlySomeReasonFlags
.pbData
), 0 },
4007 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
4008 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
4011 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
4012 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
4013 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
, NULL
);
4017 SetLastError(STATUS_ACCESS_VIOLATION
);
4024 static BOOL WINAPI
CRYPT_AsnDecodeIssuerSerialNumber(DWORD dwCertEncodingType
,
4025 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4026 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4029 struct AsnDecodeSequenceItem items
[] = {
4030 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
4031 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
4033 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
4034 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
4035 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
4037 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
4038 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
4040 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4041 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4043 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
4044 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
4045 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
,
4046 issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
4047 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
4049 SetLastError(CRYPT_E_ASN1_CORRUPT
);
4052 TRACE("returning %d\n", ret
);
4056 static BOOL
CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE
*pbEncoded
,
4057 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
4060 CMSG_SIGNER_INFO
*info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4061 struct AsnDecodeSequenceItem items
[] = {
4062 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
4063 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4064 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
4065 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
4066 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
4067 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
4068 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4069 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
4070 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4071 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
4072 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4073 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
4074 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
4075 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
4076 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
4077 HashEncryptionAlgorithm
.pszObjId
), 0 },
4078 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
4079 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
4080 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
4081 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4082 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
4083 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
4084 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
4088 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4089 pvStructInfo
, *pcbStructInfo
);
4091 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
4092 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
4093 dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
, pcbDecoded
,
4094 info
? info
->Issuer
.pbData
: NULL
);
4098 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
4099 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4100 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4104 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4105 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4109 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
, cbEncoded
,
4110 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pcbStructInfo
, NULL
);
4111 if (ret
&& pvStructInfo
)
4113 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
4114 pcbStructInfo
, *pcbStructInfo
);
4117 CMSG_SIGNER_INFO
*info
;
4119 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4120 pvStructInfo
= *(BYTE
**)pvStructInfo
;
4121 info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
4122 info
->Issuer
.pbData
= ((BYTE
*)info
+
4123 sizeof(CMSG_SIGNER_INFO
));
4124 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded
,
4125 cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, pvStructInfo
,
4126 pcbStructInfo
, NULL
);
4132 SetLastError(STATUS_ACCESS_VIOLATION
);
4135 TRACE("returning %d\n", ret
);
4139 static BOOL WINAPI
CRYPT_DecodeSignerArray(DWORD dwCertEncodingType
,
4140 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4141 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4144 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
4145 CRYPT_AsnDecodePKCSSignerInfoInternal
, sizeof(CMSG_SIGNER_INFO
), TRUE
,
4146 offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
) };
4147 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
4149 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4150 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
4152 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
4153 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
,
4154 array
? array
->rgItems
: NULL
);
4158 BOOL
CRYPT_AsnDecodePKCSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
4159 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
4160 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
4163 struct AsnDecodeSequenceItem items
[] = {
4164 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
),
4165 CRYPT_AsnDecodeIntInternal
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
4166 /* Placeholder for the hash algorithms - redundant with those in the
4167 * signers, so just ignore them.
4169 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
4170 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
4171 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
4172 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
4173 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
4174 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
4175 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4176 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
4177 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
4178 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_DecodeDERArray
,
4179 sizeof(struct GenericArray
), TRUE
, TRUE
,
4180 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
4181 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
4182 CRYPT_DecodeSignerArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
4183 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
4186 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
4187 pDecodePara
, signedInfo
, *pcbSignedInfo
);
4189 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
4190 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
4191 pDecodePara
, signedInfo
, pcbSignedInfo
, NULL
, NULL
);
4192 TRACE("returning %d\n", ret
);
4196 static CryptDecodeObjectExFunc
CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType
,
4197 LPCSTR lpszStructType
)
4199 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4201 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
4202 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
4204 SetLastError(ERROR_FILE_NOT_FOUND
);
4207 if (!HIWORD(lpszStructType
))
4209 switch (LOWORD(lpszStructType
))
4211 case (WORD
)X509_CERT
:
4212 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
4214 case (WORD
)X509_CERT_TO_BE_SIGNED
:
4215 decodeFunc
= CRYPT_AsnDecodeCert
;
4217 case (WORD
)X509_CERT_CRL_TO_BE_SIGNED
:
4218 decodeFunc
= CRYPT_AsnDecodeCRL
;
4220 case (WORD
)X509_EXTENSIONS
:
4221 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4223 case (WORD
)X509_NAME_VALUE
:
4224 decodeFunc
= CRYPT_AsnDecodeNameValue
;
4226 case (WORD
)X509_NAME
:
4227 decodeFunc
= CRYPT_AsnDecodeName
;
4229 case (WORD
)X509_PUBLIC_KEY_INFO
:
4230 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
4232 case (WORD
)X509_AUTHORITY_KEY_ID
:
4233 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4235 case (WORD
)X509_ALTERNATE_NAME
:
4236 decodeFunc
= CRYPT_AsnDecodeAltName
;
4238 case (WORD
)X509_BASIC_CONSTRAINTS
:
4239 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4241 case (WORD
)X509_BASIC_CONSTRAINTS2
:
4242 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4244 case (WORD
)RSA_CSP_PUBLICKEYBLOB
:
4245 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
4247 case (WORD
)X509_UNICODE_NAME
:
4248 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
4250 case (WORD
)PKCS_ATTRIBUTE
:
4251 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
4253 case (WORD
)X509_UNICODE_NAME_VALUE
:
4254 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
4256 case (WORD
)X509_OCTET_STRING
:
4257 decodeFunc
= CRYPT_AsnDecodeOctets
;
4259 case (WORD
)X509_BITS
:
4260 case (WORD
)X509_KEY_USAGE
:
4261 decodeFunc
= CRYPT_AsnDecodeBits
;
4263 case (WORD
)X509_INTEGER
:
4264 decodeFunc
= CRYPT_AsnDecodeInt
;
4266 case (WORD
)X509_MULTI_BYTE_INTEGER
:
4267 decodeFunc
= CRYPT_AsnDecodeInteger
;
4269 case (WORD
)X509_MULTI_BYTE_UINT
:
4270 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
4272 case (WORD
)X509_ENUMERATED
:
4273 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4275 case (WORD
)X509_CHOICE_OF_TIME
:
4276 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
4278 case (WORD
)X509_AUTHORITY_KEY_ID2
:
4279 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4281 case (WORD
)PKCS_CONTENT_INFO
:
4282 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
4284 case (WORD
)X509_SEQUENCE_OF_ANY
:
4285 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
4287 case (WORD
)PKCS_UTC_TIME
:
4288 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4290 case (WORD
)X509_CRL_DIST_POINTS
:
4291 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4293 case (WORD
)X509_ENHANCED_KEY_USAGE
:
4294 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4296 case (WORD
)PKCS_ATTRIBUTES
:
4297 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
4299 case (WORD
)X509_ISSUING_DIST_POINT
:
4300 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4302 case (WORD
)PKCS7_SIGNER_INFO
:
4303 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
4307 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
4308 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4309 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
4310 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4311 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
4312 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4313 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
4314 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4315 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
4316 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4317 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
4318 decodeFunc
= CRYPT_AsnDecodeBits
;
4319 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
4320 decodeFunc
= CRYPT_AsnDecodeOctets
;
4321 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
4322 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4323 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
4324 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4325 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
4326 decodeFunc
= CRYPT_AsnDecodeAltName
;
4327 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
4328 decodeFunc
= CRYPT_AsnDecodeAltName
;
4329 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
4330 decodeFunc
= CRYPT_AsnDecodeAltName
;
4331 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
4332 decodeFunc
= CRYPT_AsnDecodeAltName
;
4333 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
4334 decodeFunc
= CRYPT_AsnDecodeAltName
;
4335 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
4336 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4337 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
4338 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4339 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
4340 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4344 static CryptDecodeObjectFunc
CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType
,
4345 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4347 static HCRYPTOIDFUNCSET set
= NULL
;
4348 CryptDecodeObjectFunc decodeFunc
= NULL
;
4351 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
4352 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4353 (void **)&decodeFunc
, hFunc
);
4357 static CryptDecodeObjectExFunc
CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType
,
4358 LPCSTR lpszStructType
, HCRYPTOIDFUNCADDR
*hFunc
)
4360 static HCRYPTOIDFUNCSET set
= NULL
;
4361 CryptDecodeObjectExFunc decodeFunc
= NULL
;
4364 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
4365 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4366 (void **)&decodeFunc
, hFunc
);
4370 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4371 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
4372 DWORD
*pcbStructInfo
)
4375 CryptDecodeObjectFunc pCryptDecodeObject
= NULL
;
4376 CryptDecodeObjectExFunc pCryptDecodeObjectEx
= NULL
;
4377 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4379 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType
,
4380 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
4381 pvStructInfo
, pcbStructInfo
);
4383 if (!pvStructInfo
&& !pcbStructInfo
)
4385 SetLastError(ERROR_INVALID_PARAMETER
);
4390 SetLastError(CRYPT_E_ASN1_EOD
);
4393 if (cbEncoded
> MAX_ENCODED_LEN
)
4395 SetLastError(CRYPT_E_ASN1_LARGE
);
4399 if (!(pCryptDecodeObjectEx
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
,
4402 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4403 debugstr_a(lpszStructType
));
4404 pCryptDecodeObject
= CRYPT_LoadDecoderFunc(dwCertEncodingType
,
4405 lpszStructType
, &hFunc
);
4406 if (!pCryptDecodeObject
)
4407 pCryptDecodeObjectEx
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
,
4408 lpszStructType
, &hFunc
);
4410 if (pCryptDecodeObject
)
4411 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4412 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
4413 else if (pCryptDecodeObjectEx
)
4414 ret
= pCryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
,
4415 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
4416 pvStructInfo
, pcbStructInfo
);
4418 CryptFreeOIDFunctionAddress(hFunc
, 0);
4419 TRACE_(crypt
)("returning %d\n", ret
);
4423 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
4424 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
4425 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
4428 CryptDecodeObjectExFunc decodeFunc
;
4429 HCRYPTOIDFUNCADDR hFunc
= NULL
;
4431 TRACE_(crypt
)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
4432 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
4433 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
4435 if (!pvStructInfo
&& !pcbStructInfo
)
4437 SetLastError(ERROR_INVALID_PARAMETER
);
4442 SetLastError(CRYPT_E_ASN1_EOD
);
4445 if (cbEncoded
> MAX_ENCODED_LEN
)
4447 SetLastError(CRYPT_E_ASN1_LARGE
);
4451 SetLastError(NOERROR
);
4452 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
4453 *(BYTE
**)pvStructInfo
= NULL
;
4454 decodeFunc
= CRYPT_GetBuiltinDecoder(dwCertEncodingType
, lpszStructType
);
4457 TRACE_(crypt
)("OID %s not found or unimplemented, looking for DLL\n",
4458 debugstr_a(lpszStructType
));
4459 decodeFunc
= CRYPT_LoadDecoderExFunc(dwCertEncodingType
, lpszStructType
,
4463 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
4464 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
4467 CryptDecodeObjectFunc pCryptDecodeObject
=
4468 CRYPT_LoadDecoderFunc(dwCertEncodingType
, lpszStructType
, &hFunc
);
4470 /* Try CryptDecodeObject function. Don't call CryptDecodeObject
4471 * directly, as that could cause an infinite loop.
4473 if (pCryptDecodeObject
)
4475 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
4477 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4478 pbEncoded
, cbEncoded
, dwFlags
, NULL
, pcbStructInfo
);
4479 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
4480 pvStructInfo
, pcbStructInfo
, *pcbStructInfo
)))
4481 ret
= pCryptDecodeObject(dwCertEncodingType
,
4482 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
,
4483 *(BYTE
**)pvStructInfo
, pcbStructInfo
);
4486 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
4487 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
4491 CryptFreeOIDFunctionAddress(hFunc
, 0);
4492 TRACE_(crypt
)("returning %d\n", ret
);