2 * Copyright 2005 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 is
21 * undocumented, 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
31 * http://msdn.microsoft.com/library/en-us/seccrypto/security/constants_for_cryptencodeobject_and_cryptdecodeobject.asp
39 #define NONAMELESSUNION
47 #include "wine/debug.h"
48 #include "wine/exception.h"
49 #include "crypt32_private.h"
51 /* This is a bit arbitrary, but to set some limit: */
52 #define MAX_ENCODED_LEN 0x02000000
54 #define ASN_FLAGS_MASK 0xe0
55 #define ASN_TYPE_MASK 0x1f
57 WINE_DEFAULT_DEBUG_CHANNEL(crypt
);
65 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
66 DWORD
, DWORD
, void *, DWORD
*);
67 typedef BOOL (WINAPI
*CryptDecodeObjectExFunc
)(DWORD
, LPCSTR
, const BYTE
*,
68 DWORD
, DWORD
, PCRYPT_DECODE_PARA
, void *, DWORD
*);
70 /* Prototypes for built-in decoders. They follow the Ex style prototypes.
71 * The dwCertEncodingType and lpszStructType are ignored by the built-in
72 * functions, but the parameters are retained to simplify CryptDecodeObjectEx,
73 * since it must call functions in external DLLs that follow these signatures.
75 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
76 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
77 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
78 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
79 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
80 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
81 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
82 * time, doesn't do memory allocation, and doesn't do exception handling.
83 * (This isn't intended to be the externally-called one.)
85 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
86 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
87 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
88 /* Assumes algo->Parameters.pbData is set ahead of time. Internal func. */
89 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
90 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
91 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
92 /* Internal function */
93 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
94 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
95 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
96 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
97 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
98 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
99 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
100 /* Like CRYPT_AsnDecodeBits, but assumes the CRYPT_INTEGER_BLOB's pbData
101 * member has been initialized, doesn't do exception handling, and doesn't do
104 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
105 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
106 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
107 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
108 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
109 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
110 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
111 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
112 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
113 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
114 * member has been initialized, doesn't do exception handling, and doesn't do
117 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
118 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
119 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
120 /* Like CRYPT_AsnDecodeInteger, but unsigned. */
121 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
122 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
123 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
124 void *pvStructInfo
, DWORD
*pcbStructInfo
);
126 BOOL WINAPI
CryptDecodeObject(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
127 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
,
128 DWORD
*pcbStructInfo
)
130 static HCRYPTOIDFUNCSET set
= NULL
;
132 CryptDecodeObjectFunc pCryptDecodeObject
;
133 HCRYPTOIDFUNCADDR hFunc
;
135 TRACE("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p)\n", dwCertEncodingType
,
136 debugstr_a(lpszStructType
), pbEncoded
, cbEncoded
, dwFlags
,
137 pvStructInfo
, pcbStructInfo
);
139 if (!pvStructInfo
&& !pcbStructInfo
)
141 SetLastError(ERROR_INVALID_PARAMETER
);
145 /* Try registered DLL first.. */
147 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC
, 0);
148 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
149 (void **)&pCryptDecodeObject
, &hFunc
);
150 if (pCryptDecodeObject
)
152 ret
= pCryptDecodeObject(dwCertEncodingType
, lpszStructType
,
153 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
154 CryptFreeOIDFunctionAddress(hFunc
, 0);
158 /* If not, use CryptDecodeObjectEx */
159 ret
= CryptDecodeObjectEx(dwCertEncodingType
, lpszStructType
, pbEncoded
,
160 cbEncoded
, dwFlags
, NULL
, pvStructInfo
, pcbStructInfo
);
165 /* Gets the number of length bytes from the given (leading) length byte */
166 #define GET_LEN_BYTES(b) ((b) <= 0x7f ? 1 : 1 + ((b) & 0x7f))
168 /* Helper function to get the encoded length of the data starting at pbEncoded,
169 * where pbEncoded[0] is the tag. If the data are too short to contain a
170 * length or if the length is too large for cbEncoded, sets an appropriate
171 * error code and returns FALSE.
173 static BOOL WINAPI
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
,
180 SetLastError(CRYPT_E_ASN1_CORRUPT
);
183 else if (pbEncoded
[1] <= 0x7f)
185 if (pbEncoded
[1] + 1 > cbEncoded
)
187 SetLastError(CRYPT_E_ASN1_EOD
);
198 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
200 if (lenLen
> sizeof(DWORD
) + 1)
202 SetLastError(CRYPT_E_ASN1_LARGE
);
205 else if (lenLen
+ 2 > cbEncoded
)
207 SetLastError(CRYPT_E_ASN1_CORRUPT
);
220 if (out
+ lenLen
+ 1 > cbEncoded
)
222 SetLastError(CRYPT_E_ASN1_EOD
);
235 /* Helper function to check *pcbStructInfo, set it to the required size, and
236 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
237 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
238 * pointer to the newly allocated memory.
240 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
241 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
246 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
248 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
249 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
251 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
252 if (!*(BYTE
**)pvStructInfo
)
255 *pcbStructInfo
= bytesNeeded
;
257 else if (*pcbStructInfo
< bytesNeeded
)
259 *pcbStructInfo
= bytesNeeded
;
260 SetLastError(ERROR_MORE_DATA
);
267 * The expected tag of the item. If tag is 0, decodeFunc is called
268 * regardless of the tag value seen.
270 * A sequence is decoded into a struct. The offset member is the
271 * offset of this item within that struct.
273 * The decoder function to use. If this is NULL, then the member isn't
274 * decoded, but minSize space is reserved for it.
276 * The minimum amount of space occupied after decoding. You must set this.
278 * If true, and the tag doesn't match the expected tag for this item,
279 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
280 * filled with 0 for this member.
281 * hasPointer, pointerOffset, minSize:
282 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
283 * the offset within the (outer) struct of the data pointer (or to the
284 * first data pointer, if more than one exist).
286 * Used by CRYPT_AsnDecodeSequence, not for your use.
288 struct AsnDecodeSequenceItem
292 CryptDecodeObjectExFunc decodeFunc
;
300 static BOOL
CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType
,
301 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
302 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, BYTE
*nextData
)
308 ptr
= pbEncoded
+ 1 + GET_LEN_BYTES(pbEncoded
[1]);
309 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
311 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
315 if ((ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
318 BYTE nextItemLenBytes
= GET_LEN_BYTES(ptr
[1]);
320 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
322 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
324 TRACE("Setting next pointer to %p\n",
326 *(BYTE
**)((BYTE
*)pvStructInfo
+
327 items
[i
].pointerOffset
) = nextData
;
329 if (items
[i
].decodeFunc
)
332 TRACE("decoding item %ld\n", i
);
334 TRACE("sizing item %ld\n", i
);
335 ret
= items
[i
].decodeFunc(dwCertEncodingType
,
336 NULL
, ptr
, 1 + nextItemLenBytes
+ nextItemLen
,
337 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
338 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
339 : NULL
, &items
[i
].size
);
342 if (nextData
&& items
[i
].hasPointer
&&
343 items
[i
].size
> items
[i
].minSize
)
345 nextData
+= items
[i
].size
- items
[i
].minSize
;
346 /* align nextData to DWORD boundaries */
347 if (items
[i
].size
% sizeof(DWORD
))
348 nextData
+= sizeof(DWORD
) - items
[i
].size
%
351 /* Account for alignment padding */
352 if (items
[i
].size
% sizeof(DWORD
))
353 items
[i
].size
+= sizeof(DWORD
) -
354 items
[i
].size
% sizeof(DWORD
);
355 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
357 else if (items
[i
].optional
&&
358 GetLastError() == CRYPT_E_ASN1_BADTAG
)
360 TRACE("skipping optional item %ld\n", i
);
361 items
[i
].size
= items
[i
].minSize
;
362 SetLastError(NOERROR
);
366 TRACE("item %ld failed: %08lx\n", i
,
370 items
[i
].size
= items
[i
].minSize
;
372 else if (items
[i
].optional
)
374 TRACE("skipping optional item %ld\n", i
);
375 items
[i
].size
= items
[i
].minSize
;
379 TRACE("tag %02x doesn't match expected %02x\n",
380 ptr
[0], items
[i
].tag
);
381 SetLastError(CRYPT_E_ASN1_BADTAG
);
386 else if (items
[i
].optional
)
388 TRACE("missing optional item %ld, skipping\n", i
);
389 items
[i
].size
= items
[i
].minSize
;
393 TRACE("not enough bytes for item %ld, failing\n", i
);
394 SetLastError(CRYPT_E_ASN1_CORRUPT
);
398 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
400 TRACE("%ld remaining bytes, failing\n", cbEncoded
-
402 SetLastError(CRYPT_E_ASN1_CORRUPT
);
408 /* This decodes an arbitrary sequence into a contiguous block of memory
409 * (basically, a struct.) Each element being decoded is described by a struct
410 * AsnDecodeSequenceItem, see above.
411 * startingPointer is an optional pointer to the first place where dynamic
412 * data will be stored. If you know the starting offset, you may pass it
413 * here. Otherwise, pass NULL, and one will be inferred from the items.
414 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
415 * If any undecoded data are left over, fails with CRYPT_E_ASN1_CORRUPT.
417 static BOOL
CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType
,
418 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
419 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
420 void *pvStructInfo
, DWORD
*pcbStructInfo
, void *startingPointer
)
424 TRACE("%p, %ld, %p, %ld, %08lx, %p, %p, %ld, %p\n", items
, cItem
, pbEncoded
,
425 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
428 if (pbEncoded
[0] == ASN_SEQUENCE
)
432 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
436 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
, pbEncoded
,
437 cbEncoded
, dwFlags
, NULL
, NULL
);
440 DWORD bytesNeeded
= 0, structSize
= 0;
442 for (i
= 0; i
< cItem
; i
++)
444 bytesNeeded
+= items
[i
].size
;
445 structSize
+= items
[i
].minSize
;
448 *pcbStructInfo
= bytesNeeded
;
449 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
450 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
454 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
455 pvStructInfo
= *(BYTE
**)pvStructInfo
;
457 nextData
= (BYTE
*)startingPointer
;
459 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
460 memset(pvStructInfo
, 0, structSize
);
461 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
,
462 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, nextData
);
469 SetLastError(CRYPT_E_ASN1_BADTAG
);
472 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
477 * The expected tag of the entire encoded array (usually a variant
478 * of ASN_SETOF or ASN_SEQUENCEOF.)
480 * used to decode each item in the array
482 * is the minimum size of each decoded item
484 * indicates whether each item has a dynamic pointer
486 * indicates the offset within itemSize at which the pointer exists
488 struct AsnArrayDescriptor
491 CryptDecodeObjectExFunc decodeFunc
;
497 struct AsnArrayItemSize
503 /* Decodes an array of like types into a struct GenericArray.
504 * The layout and decoding of the array are described by a struct
505 * AsnArrayDescriptor.
507 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
508 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
509 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
510 void *startingPointer
)
514 TRACE("%p, %p, %ld, %08lx, %p, %p, %ld, %p\n", arrayDesc
, pbEncoded
,
515 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
518 if (pbEncoded
[0] == arrayDesc
->tag
)
522 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
524 DWORD bytesNeeded
, cItems
= 0;
525 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
526 /* There can be arbitrarily many items, but there is often only one.
528 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
530 bytesNeeded
= sizeof(struct GenericArray
);
535 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
536 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
538 DWORD itemLenBytes
, itemDataLen
, size
;
540 itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
541 /* Each item decoded may not tolerate extraneous bytes, so
542 * get the length of the next element and pass it directly.
544 ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
547 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
548 1 + itemLenBytes
+ itemDataLen
,
549 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
,
556 if (itemSizes
!= &itemSize
)
557 itemSizes
= CryptMemRealloc(itemSizes
,
558 cItems
* sizeof(struct AsnArrayItemSize
));
563 cItems
* sizeof(struct AsnArrayItemSize
));
564 memcpy(itemSizes
, &itemSize
, sizeof(itemSize
));
568 itemSizes
[cItems
- 1].encodedLen
= 1 + itemLenBytes
570 itemSizes
[cItems
- 1].size
= size
;
572 ret
= CRYPT_GetLen(ptr
,
573 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
575 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
585 *pcbStructInfo
= bytesNeeded
;
586 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
587 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
592 struct GenericArray
*array
;
594 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
595 pvStructInfo
= *(BYTE
**)pvStructInfo
;
596 array
= (struct GenericArray
*)pvStructInfo
;
597 array
->cItems
= cItems
;
599 array
->rgItems
= startingPointer
;
601 array
->rgItems
= (BYTE
*)array
+
602 sizeof(struct GenericArray
);
603 nextData
= (BYTE
*)array
->rgItems
+
604 array
->cItems
* arrayDesc
->itemSize
;
605 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
606 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
609 if (arrayDesc
->hasPointer
)
610 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
611 + arrayDesc
->pointerOffset
) = nextData
;
612 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
613 itemSizes
[i
].encodedLen
,
614 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
615 array
->rgItems
+ i
* arrayDesc
->itemSize
,
621 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
622 ret
= CRYPT_GetLen(ptr
,
623 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
625 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
630 if (itemSizes
!= &itemSize
)
631 CryptMemFree(itemSizes
);
636 SetLastError(CRYPT_E_ASN1_BADTAG
);
642 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
643 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
644 * to CRYPT_E_ASN1_CORRUPT.
645 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
648 static BOOL WINAPI
CRYPT_AsnDecodeDerBlob(DWORD dwCertEncodingType
,
649 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
650 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
655 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
657 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
658 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
660 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
661 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
664 *pcbStructInfo
= bytesNeeded
;
665 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
666 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
668 CRYPT_DER_BLOB
*blob
;
670 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
671 pvStructInfo
= *(BYTE
**)pvStructInfo
;
672 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
673 blob
->cbData
= 1 + lenBytes
+ dataLen
;
676 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
677 blob
->pbData
= (BYTE
*)pbEncoded
;
680 assert(blob
->pbData
);
681 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
686 SetLastError(CRYPT_E_ASN1_CORRUPT
);
694 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
695 static BOOL WINAPI
CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType
,
696 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
697 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
701 TRACE("(%p, %ld, 0x%08lx, %p, %p, %ld)\n", pbEncoded
, cbEncoded
, dwFlags
,
702 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
704 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
707 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
, lpszStructType
,
708 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pDecodePara
,
709 pvStructInfo
, pcbStructInfo
);
710 if (ret
&& pvStructInfo
)
712 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
719 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
721 temp
= blob
->pbData
[i
];
722 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
723 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
727 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
731 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
732 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
733 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
737 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
738 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
742 struct AsnDecodeSequenceItem items
[] = {
743 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
744 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
745 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
746 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
747 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
748 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
749 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
750 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
751 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
752 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
755 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
756 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
757 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
758 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
759 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
763 SetLastError(STATUS_ACCESS_VIOLATION
);
770 /* Internal function */
771 static BOOL WINAPI
CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType
,
772 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
773 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
778 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
780 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
782 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
783 pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
, pDecodePara
,
784 pvStructInfo
, pcbStructInfo
);
789 static BOOL WINAPI
CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType
,
790 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
791 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
795 struct AsnDecodeSequenceItem items
[] = {
796 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
797 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
798 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
799 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
802 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
803 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
804 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
808 /* Internal function */
809 static BOOL WINAPI
CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType
,
810 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
811 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
816 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
818 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
820 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
821 X509_EXTENSIONS
, pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
,
822 pDecodePara
, pvStructInfo
, pcbStructInfo
);
827 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
828 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
829 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
833 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
834 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
838 struct AsnDecodeSequenceItem items
[] = {
839 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
840 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
841 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
842 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
843 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
844 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
845 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
846 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
847 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
848 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
850 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
851 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
853 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
854 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
856 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
857 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
858 FALSE
, TRUE
, offsetof(CERT_INFO
,
859 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
860 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
861 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
862 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
863 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
864 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
865 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
866 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
867 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
868 offsetof(CERT_INFO
, rgExtension
), 0 },
871 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
872 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
873 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
877 SetLastError(STATUS_ACCESS_VIOLATION
);
884 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntry(DWORD dwCertEncodingType
,
885 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
886 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
889 struct AsnDecodeSequenceItem items
[] = {
890 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
891 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
892 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
893 { 0, offsetof(CRL_ENTRY
, RevocationDate
), CRYPT_AsnDecodeChoiceOfTime
,
894 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
895 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
896 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
897 offsetof(CRL_ENTRY
, rgExtension
), 0 },
899 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
901 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
904 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
905 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
906 NULL
, entry
, pcbStructInfo
, entry
? entry
->SerialNumber
.pbData
: NULL
);
910 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
911 * been set prior to calling.
913 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType
,
914 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
915 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
918 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
919 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
920 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
921 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
923 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
924 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
926 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
927 pDecodePara
, pvStructInfo
, pcbStructInfo
,
928 entries
? entries
->rgItems
: NULL
);
929 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
933 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
934 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
935 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
939 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
940 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
944 struct AsnDecodeSequenceItem items
[] = {
945 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CRL_INFO
, dwVersion
),
946 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
947 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
948 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
949 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
950 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
951 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
953 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
954 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
955 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
956 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
957 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
958 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
959 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
960 /* Note that the extensions are ignored by MS, so I'll ignore them too
962 { 0, offsetof(CRL_INFO
, cExtension
), NULL
,
963 sizeof(CERT_EXTENSIONS
), TRUE
, FALSE
, 0 },
966 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
967 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
968 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
972 SetLastError(STATUS_ACCESS_VIOLATION
);
977 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
981 static BOOL WINAPI
CRYPT_AsnDecodeOidInternal(DWORD dwCertEncodingType
,
982 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
983 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
987 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
988 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
990 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
994 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
996 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
997 DWORD bytesNeeded
= sizeof(LPSTR
);
1001 /* The largest possible string for the first two components
1002 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1007 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1008 pbEncoded
[1 + lenBytes
] / 40,
1009 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1011 bytesNeeded
+= strlen(firstTwo
) + 1;
1012 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1013 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1015 /* large enough for ".4000000" */
1019 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1026 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1029 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1036 snprintf(str
, sizeof(str
), ".%d", val
);
1037 bytesNeeded
+= strlen(str
);
1042 *pcbStructInfo
= bytesNeeded
;
1043 else if (*pcbStructInfo
< bytesNeeded
)
1045 *pcbStructInfo
= bytesNeeded
;
1046 SetLastError(ERROR_MORE_DATA
);
1054 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1057 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1058 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1060 pszObjId
+= strlen(pszObjId
);
1061 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1062 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1066 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1075 sprintf(pszObjId
, ".%d", val
);
1076 pszObjId
+= strlen(pszObjId
);
1080 *(LPSTR
*)pvStructInfo
= NULL
;
1081 *pcbStructInfo
= bytesNeeded
;
1088 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1091 static BOOL WINAPI
CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType
,
1092 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1093 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1095 struct AsnDecodeSequenceItem items
[] = {
1096 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1097 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1098 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1099 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1100 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1101 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1102 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1103 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1106 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1108 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1112 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1113 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1114 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1115 ext
, pcbStructInfo
, ext
? ext
->pszObjId
: NULL
);
1117 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1118 debugstr_a(ext
->pszObjId
));
1119 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1123 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
1124 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1125 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1128 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1129 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1130 offsetof(CERT_EXTENSION
, pszObjId
) };
1131 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1133 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1134 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1136 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1137 pDecodePara
, pvStructInfo
, pcbStructInfo
, exts
? exts
->rgExtension
: NULL
);
1141 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1142 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1143 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1149 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1150 lpszStructType
, pbEncoded
, cbEncoded
,
1151 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1152 if (ret
&& pvStructInfo
)
1154 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1155 pcbStructInfo
, *pcbStructInfo
);
1158 CERT_EXTENSIONS
*exts
;
1160 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1161 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1162 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1163 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1164 sizeof(CERT_EXTENSIONS
));
1165 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1166 lpszStructType
, pbEncoded
, cbEncoded
,
1167 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1174 SetLastError(STATUS_ACCESS_VIOLATION
);
1181 /* Warning: this assumes the address of value->Value.pbData is already set, in
1182 * order to avoid overwriting memory. (In some cases, it may change it, if it
1183 * doesn't copy anything to memory.) Be sure to set it correctly!
1185 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1186 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1187 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1194 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1196 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1198 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1200 switch (pbEncoded
[0])
1202 case ASN_NUMERICSTRING
:
1203 case ASN_PRINTABLESTRING
:
1207 FIXME("Unimplemented string type %02x\n", pbEncoded
[0]);
1208 SetLastError(OSS_UNIMPLEMENTED
);
1213 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
);
1215 switch (pbEncoded
[0])
1217 case ASN_NUMERICSTRING
:
1218 case ASN_PRINTABLESTRING
:
1220 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1221 bytesNeeded
+= dataLen
;
1225 *pcbStructInfo
= bytesNeeded
;
1226 else if (*pcbStructInfo
< bytesNeeded
)
1228 *pcbStructInfo
= bytesNeeded
;
1229 SetLastError(ERROR_MORE_DATA
);
1234 *pcbStructInfo
= bytesNeeded
;
1235 switch (pbEncoded
[0])
1237 case ASN_NUMERICSTRING
:
1238 value
->dwValueType
= CERT_RDN_NUMERIC_STRING
;
1240 case ASN_PRINTABLESTRING
:
1241 value
->dwValueType
= CERT_RDN_PRINTABLE_STRING
;
1244 value
->dwValueType
= CERT_RDN_IA5_STRING
;
1249 switch (pbEncoded
[0])
1251 case ASN_NUMERICSTRING
:
1252 case ASN_PRINTABLESTRING
:
1254 value
->Value
.cbData
= dataLen
;
1255 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1256 value
->Value
.pbData
= (BYTE
*)pbEncoded
+ 1 +
1260 assert(value
->Value
.pbData
);
1261 memcpy(value
->Value
.pbData
,
1262 pbEncoded
+ 1 + lenBytes
, dataLen
);
1269 value
->Value
.cbData
= 0;
1270 value
->Value
.pbData
= NULL
;
1278 SetLastError(STATUS_ACCESS_VIOLATION
);
1285 static BOOL WINAPI
CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType
,
1286 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1287 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1291 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1292 pvStructInfo
, *pcbStructInfo
);
1296 struct AsnDecodeSequenceItem items
[] = {
1297 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1298 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1299 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1300 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
), CRYPT_AsnDecodeNameValue
,
1301 sizeof(CERT_NAME_VALUE
), FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
,
1304 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1307 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1308 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1309 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1310 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1313 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1314 debugstr_a(attr
->pszObjId
));
1315 TRACE("attr->dwValueType is %ld\n", attr
->dwValueType
);
1317 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1321 SetLastError(STATUS_ACCESS_VIOLATION
);
1328 static BOOL WINAPI
CRYPT_AsnDecodeRdn(DWORD dwCertEncodingType
,
1329 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1330 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1336 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1337 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1338 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1339 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1341 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1342 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1346 SetLastError(STATUS_ACCESS_VIOLATION
);
1353 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1354 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1355 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1361 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1362 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1363 offsetof(CERT_RDN
, rgRDNAttr
) };
1365 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1366 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1370 SetLastError(STATUS_ACCESS_VIOLATION
);
1377 static BOOL WINAPI
CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType
,
1378 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1379 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1382 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
1384 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1385 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1387 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1388 bytesNeeded
+= cbEncoded
;
1390 *pcbStructInfo
= bytesNeeded
;
1391 else if (*pcbStructInfo
< bytesNeeded
)
1393 SetLastError(ERROR_MORE_DATA
);
1394 *pcbStructInfo
= bytesNeeded
;
1399 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1401 *pcbStructInfo
= bytesNeeded
;
1402 blob
->cbData
= cbEncoded
;
1403 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1404 blob
->pbData
= (LPBYTE
)pbEncoded
;
1407 assert(blob
->pbData
);
1408 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1414 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
1415 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1416 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1418 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
1419 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
1421 struct AsnDecodeSequenceItem items
[] = {
1422 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
1423 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1424 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
1425 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
1426 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
1427 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
1430 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1431 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1433 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1434 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1435 pDecodePara
, pvStructInfo
, pcbStructInfo
, algo
? algo
->pszObjId
: NULL
);
1436 if (ret
&& pvStructInfo
)
1438 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
1439 debugstr_a(algo
->pszObjId
));
1444 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
1445 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1446 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1449 struct AsnDecodeSequenceItem items
[] = {
1450 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
1451 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1452 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
1453 Algorithm
.pszObjId
) },
1454 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
1455 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
1456 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
1458 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
1460 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1461 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1462 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
?
1463 info
->Algorithm
.Parameters
.pbData
: NULL
);
1467 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
1468 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1469 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1477 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
1478 lpszStructType
, pbEncoded
, cbEncoded
,
1479 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
1482 *pcbStructInfo
= bytesNeeded
;
1483 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1484 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1486 PCERT_PUBLIC_KEY_INFO info
;
1488 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1489 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1490 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
1491 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
1492 sizeof(CERT_PUBLIC_KEY_INFO
);
1493 ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
1494 lpszStructType
, pbEncoded
, cbEncoded
,
1495 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1502 SetLastError(STATUS_ACCESS_VIOLATION
);
1509 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
1510 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1511 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1517 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1520 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
1522 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1525 if (pbEncoded
[1] > 1)
1527 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1532 *pcbStructInfo
= sizeof(BOOL
);
1535 else if (*pcbStructInfo
< sizeof(BOOL
))
1537 *pcbStructInfo
= sizeof(BOOL
);
1538 SetLastError(ERROR_MORE_DATA
);
1543 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
1546 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1550 static BOOL WINAPI
CRYPT_AsnDecodeAltNameEntry(DWORD dwCertEncodingType
,
1551 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1552 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1554 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
1555 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
1558 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1559 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1563 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1566 if ((pbEncoded
[0] & ASN_FLAGS_MASK
) != ASN_CONTEXT
)
1568 SetLastError(CRYPT_E_ASN1_BADTAG
);
1571 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1572 if (1 + lenBytes
> cbEncoded
)
1574 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1577 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1579 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
1581 case 1: /* rfc822Name */
1582 case 2: /* dNSName */
1583 case 6: /* uniformResourceIdentifier */
1584 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
1586 case 7: /* iPAddress */
1587 bytesNeeded
+= dataLen
;
1589 case 8: /* registeredID */
1590 /* FIXME: decode as OID */
1591 case 0: /* otherName */
1592 case 4: /* directoryName */
1594 SetLastError(CRYPT_E_ASN1_BADTAG
);
1597 case 3: /* x400Address, unimplemented */
1598 case 5: /* ediPartyName, unimplemented */
1599 SetLastError(CRYPT_E_ASN1_BADTAG
);
1603 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1609 *pcbStructInfo
= bytesNeeded
;
1610 else if (*pcbStructInfo
< bytesNeeded
)
1612 *pcbStructInfo
= bytesNeeded
;
1613 SetLastError(ERROR_MORE_DATA
);
1618 *pcbStructInfo
= bytesNeeded
;
1619 /* MS used values one greater than the asn1 ones.. sigh */
1620 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
1621 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
1623 case 1: /* rfc822Name */
1624 case 2: /* dNSName */
1625 case 6: /* uniformResourceIdentifier */
1629 for (i
= 0; i
< dataLen
; i
++)
1630 entry
->u
.pwszURL
[i
] =
1631 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
1632 entry
->u
.pwszURL
[i
] = 0;
1633 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
1634 debugstr_w(entry
->u
.pwszURL
));
1637 case 7: /* iPAddress */
1638 /* The next data pointer is in the pwszURL spot, that is,
1639 * the first 4 bytes. Need to move it to the next spot.
1641 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
1642 entry
->u
.IPAddress
.cbData
= dataLen
;
1643 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
1653 static BOOL WINAPI
CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType
,
1654 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1655 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1658 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1659 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
1660 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
1661 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
1663 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1664 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1667 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
1668 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1669 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->rgAltEntry
: NULL
);
1673 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
1674 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1675 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1679 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1680 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1684 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1685 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
1686 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
1688 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1689 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1693 SetLastError(STATUS_ACCESS_VIOLATION
);
1700 struct PATH_LEN_CONSTRAINT
1702 BOOL fPathLenConstraint
;
1703 DWORD dwPathLenConstraint
;
1706 static BOOL WINAPI
CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType
,
1707 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1708 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1712 TRACE("%p, %ld, %08lx, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1713 pvStructInfo
, *pcbStructInfo
);
1717 if (pbEncoded
[0] == ASN_INTEGER
)
1719 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
);
1722 *pcbStructInfo
= bytesNeeded
;
1723 else if (*pcbStructInfo
< bytesNeeded
)
1725 SetLastError(ERROR_MORE_DATA
);
1726 *pcbStructInfo
= bytesNeeded
;
1731 struct PATH_LEN_CONSTRAINT
*constraint
=
1732 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
1733 DWORD size
= sizeof(constraint
->dwPathLenConstraint
);
1735 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
1736 pbEncoded
, cbEncoded
, 0, NULL
,
1737 &constraint
->dwPathLenConstraint
, &size
);
1739 constraint
->fPathLenConstraint
= TRUE
;
1740 TRACE("got an int, dwPathLenConstraint is %ld\n",
1741 constraint
->dwPathLenConstraint
);
1746 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1750 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
1754 static BOOL WINAPI
CRYPT_AsnDecodeSubtreeConstraints(DWORD dwCertEncodingType
,
1755 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1756 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1759 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1760 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
1761 offsetof(CERT_NAME_BLOB
, pbData
) };
1762 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
1764 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1765 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1767 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1768 pDecodePara
, pvStructInfo
, pcbStructInfo
,
1769 entries
? entries
->rgItems
: NULL
);
1770 TRACE("Returning %d (%08lx)\n", ret
, GetLastError());
1774 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
1775 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1776 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1782 struct AsnDecodeSequenceItem items
[] = {
1783 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
1784 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
1785 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
1786 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
1787 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
1788 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
1789 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
1790 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
1791 sizeof(struct GenericArray
), TRUE
, TRUE
,
1792 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
1795 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1796 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1797 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1801 SetLastError(STATUS_ACCESS_VIOLATION
);
1808 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
1809 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1810 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1816 struct AsnDecodeSequenceItem items
[] = {
1817 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
1818 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1819 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
1820 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
1821 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
1824 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1825 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1826 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1830 SetLastError(STATUS_ACCESS_VIOLATION
);
1837 #define RSA1_MAGIC 0x31415352
1839 struct DECODED_RSA_PUB_KEY
1842 CRYPT_INTEGER_BLOB modulus
;
1845 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
1846 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1847 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1853 struct AsnDecodeSequenceItem items
[] = {
1854 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
1855 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
1856 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
1858 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
1859 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
1861 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
1864 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1865 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
1866 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
, &size
, NULL
);
1869 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
1870 decodedKey
->modulus
.cbData
;
1874 *pcbStructInfo
= bytesNeeded
;
1877 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1878 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1881 RSAPUBKEY
*rsaPubKey
;
1883 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1884 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1885 hdr
= (BLOBHEADER
*)pvStructInfo
;
1886 hdr
->bType
= PUBLICKEYBLOB
;
1887 hdr
->bVersion
= CUR_BLOB_VERSION
;
1889 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
1890 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
1891 sizeof(BLOBHEADER
));
1892 rsaPubKey
->magic
= RSA1_MAGIC
;
1893 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
1894 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
1895 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
1896 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
1897 decodedKey
->modulus
.cbData
);
1899 LocalFree(decodedKey
);
1904 SetLastError(STATUS_ACCESS_VIOLATION
);
1911 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
1912 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1913 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1916 DWORD bytesNeeded
, dataLen
;
1918 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1919 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1921 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1923 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1924 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
1926 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
1928 *pcbStructInfo
= bytesNeeded
;
1929 else if (*pcbStructInfo
< bytesNeeded
)
1931 SetLastError(ERROR_MORE_DATA
);
1932 *pcbStructInfo
= bytesNeeded
;
1937 CRYPT_DATA_BLOB
*blob
;
1938 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1940 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
1941 blob
->cbData
= dataLen
;
1942 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1943 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
1946 assert(blob
->pbData
);
1948 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
1956 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
1957 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1958 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1962 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
1963 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1971 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1974 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
1976 SetLastError(CRYPT_E_ASN1_BADTAG
);
1979 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
1980 lpszStructType
, pbEncoded
, cbEncoded
,
1981 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
1984 *pcbStructInfo
= bytesNeeded
;
1985 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1986 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1988 CRYPT_DATA_BLOB
*blob
;
1990 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1991 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1992 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
1993 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
1994 ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
1995 lpszStructType
, pbEncoded
, cbEncoded
,
1996 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2003 SetLastError(STATUS_ACCESS_VIOLATION
);
2010 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
2011 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2012 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2016 TRACE("(%p, %ld, 0x%08lx, %p, %p, %ld)\n", pbEncoded
, cbEncoded
, dwFlags
,
2017 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2019 if (pbEncoded
[0] == ASN_BITSTRING
)
2021 DWORD bytesNeeded
, dataLen
;
2023 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2025 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2026 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
2028 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
2030 *pcbStructInfo
= bytesNeeded
;
2031 else if (*pcbStructInfo
< bytesNeeded
)
2033 *pcbStructInfo
= bytesNeeded
;
2034 SetLastError(ERROR_MORE_DATA
);
2039 CRYPT_BIT_BLOB
*blob
;
2041 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2042 blob
->cbData
= dataLen
- 1;
2043 blob
->cUnusedBits
= *(pbEncoded
+ 1 +
2044 GET_LEN_BYTES(pbEncoded
[1]));
2045 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2047 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 +
2048 GET_LEN_BYTES(pbEncoded
[1]);
2052 assert(blob
->pbData
);
2055 BYTE mask
= 0xff << blob
->cUnusedBits
;
2057 memcpy(blob
->pbData
, pbEncoded
+ 2 +
2058 GET_LEN_BYTES(pbEncoded
[1]), blob
->cbData
);
2059 blob
->pbData
[blob
->cbData
- 1] &= mask
;
2067 SetLastError(CRYPT_E_ASN1_BADTAG
);
2070 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
2074 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
2075 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2076 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2080 TRACE("(%p, %ld, 0x%08lx, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2081 pDecodePara
, pvStructInfo
, pcbStructInfo
);
2087 if ((ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2088 lpszStructType
, pbEncoded
, cbEncoded
,
2089 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2092 *pcbStructInfo
= bytesNeeded
;
2093 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2094 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2096 CRYPT_BIT_BLOB
*blob
;
2098 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2099 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2100 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2101 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
2102 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2103 lpszStructType
, pbEncoded
, cbEncoded
,
2104 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2111 SetLastError(STATUS_ACCESS_VIOLATION
);
2115 TRACE("returning %d (%08lx)\n", ret
, GetLastError());
2119 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
2120 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2121 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2127 *pcbStructInfo
= sizeof(int);
2132 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
2133 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
2134 DWORD size
= sizeof(buf
);
2136 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
2137 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2138 X509_MULTI_BYTE_INTEGER
, pbEncoded
, cbEncoded
, 0, NULL
, &buf
, &size
);
2141 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2142 pvStructInfo
, pcbStructInfo
, sizeof(int))))
2146 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2147 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2148 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
2150 /* initialize to a negative value to sign-extend */
2155 for (i
= 0; i
< blob
->cbData
; i
++)
2158 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
2160 memcpy(pvStructInfo
, &val
, sizeof(int));
2163 else if (GetLastError() == ERROR_MORE_DATA
)
2164 SetLastError(CRYPT_E_ASN1_LARGE
);
2168 SetLastError(STATUS_ACCESS_VIOLATION
);
2175 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
2176 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2177 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2181 if (pbEncoded
[0] == ASN_INTEGER
)
2183 DWORD bytesNeeded
, dataLen
;
2185 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2187 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2189 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2191 *pcbStructInfo
= bytesNeeded
;
2192 else if (*pcbStructInfo
< bytesNeeded
)
2194 *pcbStructInfo
= bytesNeeded
;
2195 SetLastError(ERROR_MORE_DATA
);
2200 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2202 blob
->cbData
= dataLen
;
2203 assert(blob
->pbData
);
2208 for (i
= 0; i
< blob
->cbData
; i
++)
2210 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2219 SetLastError(CRYPT_E_ASN1_BADTAG
);
2225 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
2226 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2227 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2235 if ((ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2236 lpszStructType
, pbEncoded
, cbEncoded
,
2237 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2240 *pcbStructInfo
= bytesNeeded
;
2241 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2242 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2244 CRYPT_INTEGER_BLOB
*blob
;
2246 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2247 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2248 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2249 blob
->pbData
= (BYTE
*)pvStructInfo
+
2250 sizeof(CRYPT_INTEGER_BLOB
);
2251 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2252 lpszStructType
, pbEncoded
, cbEncoded
,
2253 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2260 SetLastError(STATUS_ACCESS_VIOLATION
);
2267 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
2268 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2269 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2270 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2274 if (pbEncoded
[0] == ASN_INTEGER
)
2276 DWORD bytesNeeded
, dataLen
;
2278 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2280 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2282 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2284 *pcbStructInfo
= bytesNeeded
;
2285 else if (*pcbStructInfo
< bytesNeeded
)
2287 *pcbStructInfo
= bytesNeeded
;
2288 SetLastError(ERROR_MORE_DATA
);
2293 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2295 blob
->cbData
= dataLen
;
2296 assert(blob
->pbData
);
2297 /* remove leading zero byte if it exists */
2298 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
2307 for (i
= 0; i
< blob
->cbData
; i
++)
2309 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2318 SetLastError(CRYPT_E_ASN1_BADTAG
);
2324 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
2325 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2326 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2334 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
2335 lpszStructType
, pbEncoded
, cbEncoded
,
2336 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2339 *pcbStructInfo
= bytesNeeded
;
2340 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2341 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2343 CRYPT_INTEGER_BLOB
*blob
;
2345 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2346 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2347 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2348 blob
->pbData
= (BYTE
*)pvStructInfo
+
2349 sizeof(CRYPT_INTEGER_BLOB
);
2350 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
2351 lpszStructType
, pbEncoded
, cbEncoded
,
2352 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2359 SetLastError(STATUS_ACCESS_VIOLATION
);
2366 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
2367 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2368 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2374 *pcbStructInfo
= sizeof(int);
2379 if (pbEncoded
[0] == ASN_ENUMERATED
)
2381 unsigned int val
= 0, i
;
2385 SetLastError(CRYPT_E_ASN1_EOD
);
2388 else if (pbEncoded
[1] == 0)
2390 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2395 /* A little strange looking, but we have to accept a sign byte:
2396 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
2397 * assuming a small length is okay here, it has to be in short
2400 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
2402 SetLastError(CRYPT_E_ASN1_LARGE
);
2405 for (i
= 0; i
< pbEncoded
[1]; i
++)
2408 val
|= pbEncoded
[2 + i
];
2410 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2411 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
2413 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2414 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2415 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
2421 SetLastError(CRYPT_E_ASN1_BADTAG
);
2427 SetLastError(STATUS_ACCESS_VIOLATION
);
2434 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
2437 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
2442 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
2444 if (!isdigit(*(pbEncoded))) \
2446 SetLastError(CRYPT_E_ASN1_CORRUPT); \
2452 (word) += *(pbEncoded)++ - '0'; \
2457 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
2458 SYSTEMTIME
*sysTime
)
2465 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
2467 WORD hours
, minutes
= 0;
2468 BYTE sign
= *pbEncoded
++;
2471 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
2472 if (ret
&& hours
>= 24)
2474 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2479 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
2480 if (ret
&& minutes
>= 60)
2482 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2490 sysTime
->wHour
+= hours
;
2491 sysTime
->wMinute
+= minutes
;
2495 if (hours
> sysTime
->wHour
)
2498 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
2501 sysTime
->wHour
-= hours
;
2502 if (minutes
> sysTime
->wMinute
)
2505 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
2508 sysTime
->wMinute
-= minutes
;
2515 SetLastError(STATUS_ACCESS_VIOLATION
);
2522 #define MIN_ENCODED_TIME_LENGTH 10
2524 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
2525 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2526 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2532 *pcbStructInfo
= sizeof(FILETIME
);
2538 if (pbEncoded
[0] == ASN_UTCTIME
)
2542 SetLastError(CRYPT_E_ASN1_EOD
);
2545 else if (pbEncoded
[1] > 0x7f)
2547 /* long-form date strings really can't be valid */
2548 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2553 SYSTEMTIME sysTime
= { 0 };
2554 BYTE len
= pbEncoded
[1];
2556 if (len
< MIN_ENCODED_TIME_LENGTH
)
2558 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2564 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
2565 if (sysTime
.wYear
>= 50)
2566 sysTime
.wYear
+= 1900;
2568 sysTime
.wYear
+= 2000;
2569 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
2570 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
2571 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
2572 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
2575 if (len
>= 2 && isdigit(*pbEncoded
) &&
2576 isdigit(*(pbEncoded
+ 1)))
2577 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
2579 else if (isdigit(*pbEncoded
))
2580 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
2583 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
2586 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
2587 pDecodePara
, pvStructInfo
, pcbStructInfo
,
2590 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2591 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2592 ret
= SystemTimeToFileTime(&sysTime
,
2593 (FILETIME
*)pvStructInfo
);
2600 SetLastError(CRYPT_E_ASN1_BADTAG
);
2606 SetLastError(STATUS_ACCESS_VIOLATION
);
2613 static BOOL WINAPI
CRYPT_AsnDecodeGeneralizedTime(DWORD dwCertEncodingType
,
2614 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2615 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2621 *pcbStructInfo
= sizeof(FILETIME
);
2627 if (pbEncoded
[0] == ASN_GENERALTIME
)
2631 SetLastError(CRYPT_E_ASN1_EOD
);
2634 else if (pbEncoded
[1] > 0x7f)
2636 /* long-form date strings really can't be valid */
2637 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2642 BYTE len
= pbEncoded
[1];
2644 if (len
< MIN_ENCODED_TIME_LENGTH
)
2646 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2651 SYSTEMTIME sysTime
= { 0 };
2654 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
2655 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
2656 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
2657 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
2660 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
2663 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
2665 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
2672 /* workaround macro weirdness */
2673 digits
= min(len
, 3);
2674 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
2675 sysTime
.wMilliseconds
);
2678 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
2681 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
2682 pDecodePara
, pvStructInfo
, pcbStructInfo
,
2685 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2686 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2687 ret
= SystemTimeToFileTime(&sysTime
,
2688 (FILETIME
*)pvStructInfo
);
2695 SetLastError(CRYPT_E_ASN1_BADTAG
);
2701 SetLastError(STATUS_ACCESS_VIOLATION
);
2708 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
2709 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2710 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2716 if (pbEncoded
[0] == ASN_UTCTIME
)
2717 ret
= CRYPT_AsnDecodeUtcTime(dwCertEncodingType
, lpszStructType
,
2718 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
2720 else if (pbEncoded
[0] == ASN_GENERALTIME
)
2721 ret
= CRYPT_AsnDecodeGeneralizedTime(dwCertEncodingType
,
2722 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
,
2723 pvStructInfo
, pcbStructInfo
);
2726 SetLastError(CRYPT_E_ASN1_BADTAG
);
2732 SetLastError(STATUS_ACCESS_VIOLATION
);
2739 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
2740 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2741 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2747 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
2749 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
2751 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2756 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2757 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
2759 ptr
= pbEncoded
+ 1 + lenBytes
;
2760 remainingLen
= dataLen
;
2761 while (ret
&& remainingLen
)
2765 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
2768 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
2770 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
2771 ptr
+= 1 + nextLenBytes
+ nextLen
;
2772 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
2773 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
2774 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
2780 CRYPT_SEQUENCE_OF_ANY
*seq
;
2784 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2785 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2787 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2788 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2789 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
2790 seq
->cValue
= cValue
;
2791 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
2793 nextPtr
= (BYTE
*)seq
->rgValue
+
2794 cValue
* sizeof(CRYPT_DER_BLOB
);
2795 ptr
= pbEncoded
+ 1 + lenBytes
;
2796 remainingLen
= dataLen
;
2798 while (ret
&& remainingLen
)
2802 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
2805 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
2807 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
2809 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2810 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
2813 seq
->rgValue
[i
].pbData
= nextPtr
;
2814 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
2816 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
2818 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
2819 ptr
+= 1 + nextLenBytes
+ nextLen
;
2829 SetLastError(CRYPT_E_ASN1_BADTAG
);
2835 SetLastError(STATUS_ACCESS_VIOLATION
);
2842 static BOOL WINAPI
CRYPT_AsnDecodeDistPoint(DWORD dwCertEncodingType
,
2843 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2844 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2846 struct AsnDecodeSequenceItem items
[] = {
2847 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
2848 DistPointName
), CRYPT_AsnDecodeAltNameInternal
,
2849 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
2850 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
2851 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
2852 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
2853 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
2854 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
2855 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
2856 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
2860 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2861 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
2862 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2866 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
2867 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2868 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2872 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2873 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2877 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2878 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
2879 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
2881 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2882 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2886 SetLastError(STATUS_ACCESS_VIOLATION
);
2893 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
2894 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2895 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2899 TRACE("%p, %ld, %08lx, %p, %p, %ld\n", pbEncoded
, cbEncoded
, dwFlags
,
2900 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2904 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2905 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
2907 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2908 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2912 SetLastError(STATUS_ACCESS_VIOLATION
);
2919 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
2920 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2921 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2923 static HCRYPTOIDFUNCSET set
= NULL
;
2925 CryptDecodeObjectExFunc decodeFunc
= NULL
;
2926 HCRYPTOIDFUNCADDR hFunc
= NULL
;
2928 TRACE("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p)\n",
2929 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
2930 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
2932 if (!pvStructInfo
&& !pcbStructInfo
)
2934 SetLastError(ERROR_INVALID_PARAMETER
);
2937 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
2938 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
2940 SetLastError(ERROR_FILE_NOT_FOUND
);
2945 SetLastError(CRYPT_E_ASN1_EOD
);
2948 if (cbEncoded
> MAX_ENCODED_LEN
)
2950 SetLastError(CRYPT_E_ASN1_LARGE
);
2954 SetLastError(NOERROR
);
2955 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
2956 *(BYTE
**)pvStructInfo
= NULL
;
2957 if (!HIWORD(lpszStructType
))
2959 switch (LOWORD(lpszStructType
))
2961 case (WORD
)X509_CERT
:
2962 decodeFunc
= CRYPT_AsnDecodeCert
;
2964 case (WORD
)X509_CERT_TO_BE_SIGNED
:
2965 decodeFunc
= CRYPT_AsnDecodeCertInfo
;
2967 case (WORD
)X509_CERT_CRL_TO_BE_SIGNED
:
2968 decodeFunc
= CRYPT_AsnDecodeCRLInfo
;
2970 case (WORD
)X509_EXTENSIONS
:
2971 decodeFunc
= CRYPT_AsnDecodeExtensions
;
2973 case (WORD
)X509_NAME
:
2974 decodeFunc
= CRYPT_AsnDecodeName
;
2976 case (WORD
)X509_PUBLIC_KEY_INFO
:
2977 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
2979 case (WORD
)X509_ALTERNATE_NAME
:
2980 decodeFunc
= CRYPT_AsnDecodeAltName
;
2982 case (WORD
)X509_BASIC_CONSTRAINTS
:
2983 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
2985 case (WORD
)X509_BASIC_CONSTRAINTS2
:
2986 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
2988 case (WORD
)RSA_CSP_PUBLICKEYBLOB
:
2989 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
2991 case (WORD
)X509_OCTET_STRING
:
2992 decodeFunc
= CRYPT_AsnDecodeOctets
;
2994 case (WORD
)X509_BITS
:
2995 case (WORD
)X509_KEY_USAGE
:
2996 decodeFunc
= CRYPT_AsnDecodeBits
;
2998 case (WORD
)X509_INTEGER
:
2999 decodeFunc
= CRYPT_AsnDecodeInt
;
3001 case (WORD
)X509_MULTI_BYTE_INTEGER
:
3002 decodeFunc
= CRYPT_AsnDecodeInteger
;
3004 case (WORD
)X509_MULTI_BYTE_UINT
:
3005 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
3007 case (WORD
)X509_ENUMERATED
:
3008 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3010 case (WORD
)X509_CHOICE_OF_TIME
:
3011 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
3013 case (WORD
)X509_SEQUENCE_OF_ANY
:
3014 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
3016 case (WORD
)PKCS_UTC_TIME
:
3017 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3019 case (WORD
)X509_CRL_DIST_POINTS
:
3020 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
3022 case (WORD
)X509_ENHANCED_KEY_USAGE
:
3023 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
3026 FIXME("%d: unimplemented\n", LOWORD(lpszStructType
));
3029 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
3030 decodeFunc
= CRYPT_AsnDecodeExtensions
;
3031 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
3032 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3033 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
3034 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3035 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
3036 decodeFunc
= CRYPT_AsnDecodeBits
;
3037 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
3038 decodeFunc
= CRYPT_AsnDecodeOctets
;
3039 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
3040 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
3041 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
3042 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
3043 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
3044 decodeFunc
= CRYPT_AsnDecodeAltName
;
3045 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
3046 decodeFunc
= CRYPT_AsnDecodeAltName
;
3047 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
3048 decodeFunc
= CRYPT_AsnDecodeAltName
;
3049 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
3050 decodeFunc
= CRYPT_AsnDecodeAltName
;
3051 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
3052 decodeFunc
= CRYPT_AsnDecodeAltName
;
3053 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
3054 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
3055 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
3056 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
3058 TRACE("OID %s not found or unimplemented, looking for DLL\n",
3059 debugstr_a(lpszStructType
));
3063 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
3064 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
3065 (void **)&decodeFunc
, &hFunc
);
3068 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
3069 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
3071 SetLastError(ERROR_FILE_NOT_FOUND
);
3073 CryptFreeOIDFunctionAddress(hFunc
, 0);