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
46 #include "wine/debug.h"
47 #include "wine/exception.h"
48 #include "crypt32_private.h"
50 /* This is a bit arbitrary, but to set some limit: */
51 #define MAX_ENCODED_LEN 0x02000000
53 #define ASN_FLAGS_MASK 0xe0
54 #define ASN_TYPE_MASK 0x1f
56 WINE_DEFAULT_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 /* Prototypes for built-in decoders. They follow the Ex style prototypes.
70 * The dwCertEncodingType and lpszStructType are ignored by the built-in
71 * functions, but the parameters are retained to simplify CryptDecodeObjectEx,
72 * since it must call functions in external DLLs that follow these signatures.
74 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
75 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
76 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
77 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
78 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
79 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
80 /* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of
81 * time, doesn't do memory allocation, and doesn't do exception handling.
82 * (This isn't intended to be the externally-called one.)
84 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
85 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
86 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
87 /* Assumes algo->Parameters.pbData is set ahead of time. Internal func. */
88 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
89 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
90 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
91 /* Internal function */
92 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
93 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
94 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
95 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */
96 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
97 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
98 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
99 /* Like CRYPT_AsnDecodeBits, but assumes the CRYPT_INTEGER_BLOB's pbData
100 * member has been initialized, doesn't do exception handling, and doesn't do
103 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
104 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
105 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
106 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
107 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
108 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
109 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
110 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
111 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
);
112 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData
113 * member has been initialized, doesn't do exception handling, and doesn't do
114 * memory allocation. Also doesn't check tag, assumes the caller has checked
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%08x, %s, %p, %d, 0x%08x, %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
);
196 else if (pbEncoded
[1] == 0x80)
198 FIXME("unimplemented for indefinite-length encoding\n");
199 SetLastError(CRYPT_E_ASN1_CORRUPT
);
204 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
206 if (lenLen
> sizeof(DWORD
) + 1)
208 SetLastError(CRYPT_E_ASN1_LARGE
);
211 else if (lenLen
+ 2 > cbEncoded
)
213 SetLastError(CRYPT_E_ASN1_CORRUPT
);
226 if (out
+ lenLen
+ 1 > cbEncoded
)
228 SetLastError(CRYPT_E_ASN1_EOD
);
241 /* Helper function to check *pcbStructInfo, set it to the required size, and
242 * optionally to allocate memory. Assumes pvStructInfo is not NULL.
243 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a
244 * pointer to the newly allocated memory.
246 static BOOL
CRYPT_DecodeEnsureSpace(DWORD dwFlags
,
247 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
252 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
254 if (pDecodePara
&& pDecodePara
->pfnAlloc
)
255 *(BYTE
**)pvStructInfo
= pDecodePara
->pfnAlloc(bytesNeeded
);
257 *(BYTE
**)pvStructInfo
= LocalAlloc(0, bytesNeeded
);
258 if (!*(BYTE
**)pvStructInfo
)
261 *pcbStructInfo
= bytesNeeded
;
263 else if (*pcbStructInfo
< bytesNeeded
)
265 *pcbStructInfo
= bytesNeeded
;
266 SetLastError(ERROR_MORE_DATA
);
273 * The expected tag of the item. If tag is 0, decodeFunc is called
274 * regardless of the tag value seen.
276 * A sequence is decoded into a struct. The offset member is the
277 * offset of this item within that struct.
279 * The decoder function to use. If this is NULL, then the member isn't
280 * decoded, but minSize space is reserved for it.
282 * The minimum amount of space occupied after decoding. You must set this.
284 * If true, and the tag doesn't match the expected tag for this item,
285 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
286 * filled with 0 for this member.
287 * hasPointer, pointerOffset:
288 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
289 * the offset within the struct of the data pointer (or to the
290 * first data pointer, if more than one exist).
292 * Used by CRYPT_AsnDecodeSequence, not for your use.
294 struct AsnDecodeSequenceItem
298 CryptDecodeObjectExFunc decodeFunc
;
306 /* Decodes the items in a sequence, where the items are described in items,
307 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
308 * pvStructInfo. nextData is a pointer to the memory location at which the
309 * first decoded item with a dynamic pointer should point.
310 * Upon decoding, *cbDecoded is the total number of bytes decoded.
312 static BOOL
CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType
,
313 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
314 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, BYTE
*nextData
,
318 DWORD i
, decoded
= 0;
319 const BYTE
*ptr
= pbEncoded
;
321 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
323 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
327 if ((ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
330 BYTE nextItemLenBytes
= GET_LEN_BYTES(ptr
[1]);
332 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
334 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
336 TRACE("Setting next pointer to %p\n",
338 *(BYTE
**)((BYTE
*)pvStructInfo
+
339 items
[i
].pointerOffset
) = nextData
;
341 if (items
[i
].decodeFunc
)
344 TRACE("decoding item %d\n", i
);
346 TRACE("sizing item %d\n", i
);
347 ret
= items
[i
].decodeFunc(dwCertEncodingType
,
348 NULL
, ptr
, 1 + nextItemLenBytes
+ nextItemLen
,
349 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
350 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
351 : NULL
, &items
[i
].size
);
354 if (nextData
&& items
[i
].hasPointer
&&
355 items
[i
].size
> items
[i
].minSize
)
357 nextData
+= items
[i
].size
- items
[i
].minSize
;
358 /* align nextData to DWORD boundaries */
359 if (items
[i
].size
% sizeof(DWORD
))
360 nextData
+= sizeof(DWORD
) - items
[i
].size
%
363 /* Account for alignment padding */
364 if (items
[i
].size
% sizeof(DWORD
))
365 items
[i
].size
+= sizeof(DWORD
) -
366 items
[i
].size
% sizeof(DWORD
);
367 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
368 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
370 else if (items
[i
].optional
&&
371 GetLastError() == CRYPT_E_ASN1_BADTAG
)
373 TRACE("skipping optional item %d\n", i
);
374 items
[i
].size
= items
[i
].minSize
;
375 SetLastError(NOERROR
);
379 TRACE("item %d failed: %08x\n", i
,
384 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
385 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
386 items
[i
].size
= items
[i
].minSize
;
389 else if (items
[i
].optional
)
391 TRACE("skipping optional item %d\n", i
);
392 items
[i
].size
= items
[i
].minSize
;
396 TRACE("tag %02x doesn't match expected %02x\n",
397 ptr
[0], items
[i
].tag
);
398 SetLastError(CRYPT_E_ASN1_BADTAG
);
403 else if (items
[i
].optional
)
405 TRACE("missing optional item %d, skipping\n", i
);
406 items
[i
].size
= items
[i
].minSize
;
410 TRACE("not enough bytes for item %d, failing\n", i
);
411 SetLastError(CRYPT_E_ASN1_CORRUPT
);
416 *cbDecoded
= decoded
;
420 /* This decodes an arbitrary sequence into a contiguous block of memory
421 * (basically, a struct.) Each element being decoded is described by a struct
422 * AsnDecodeSequenceItem, see above.
423 * startingPointer is an optional pointer to the first place where dynamic
424 * data will be stored. If you know the starting offset, you may pass it
425 * here. Otherwise, pass NULL, and one will be inferred from the items.
426 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
428 static BOOL
CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType
,
429 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
430 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
431 void *pvStructInfo
, DWORD
*pcbStructInfo
, void *startingPointer
)
435 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
436 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
439 if (pbEncoded
[0] == ASN_SEQUENCE
)
443 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
445 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
446 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
448 cbEncoded
-= 1 + lenBytes
;
449 if (cbEncoded
< dataLen
)
451 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
453 SetLastError(CRYPT_E_ASN1_CORRUPT
);
457 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
, ptr
,
458 cbEncoded
, dwFlags
, NULL
, NULL
, &cbDecoded
);
459 if (ret
&& cbDecoded
!= dataLen
)
461 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
463 SetLastError(CRYPT_E_ASN1_CORRUPT
);
468 DWORD i
, bytesNeeded
= 0, structSize
= 0;
470 for (i
= 0; i
< cItem
; i
++)
472 bytesNeeded
+= items
[i
].size
;
473 structSize
+= items
[i
].minSize
;
476 *pcbStructInfo
= bytesNeeded
;
477 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
478 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
482 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
483 pvStructInfo
= *(BYTE
**)pvStructInfo
;
485 nextData
= (BYTE
*)startingPointer
;
487 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
488 memset(pvStructInfo
, 0, structSize
);
489 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
,
490 ptr
, cbEncoded
, dwFlags
, pvStructInfo
, nextData
,
498 SetLastError(CRYPT_E_ASN1_BADTAG
);
501 TRACE("returning %d (%08x)\n", ret
, GetLastError());
506 * The expected tag of the entire encoded array (usually a variant
507 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
508 * regardless of the tag seen.
510 * used to decode each item in the array
512 * is the minimum size of each decoded item
514 * indicates whether each item has a dynamic pointer
516 * indicates the offset within itemSize at which the pointer exists
518 struct AsnArrayDescriptor
521 CryptDecodeObjectExFunc decodeFunc
;
527 struct AsnArrayItemSize
533 /* Decodes an array of like types into a struct GenericArray.
534 * The layout and decoding of the array are described by a struct
535 * AsnArrayDescriptor.
537 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
538 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
539 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
540 void *startingPointer
)
544 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
545 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
548 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
552 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
554 DWORD bytesNeeded
, cItems
= 0;
555 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
556 /* There can be arbitrarily many items, but there is often only one.
558 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
560 bytesNeeded
= sizeof(struct GenericArray
);
565 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
566 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
568 DWORD itemLenBytes
, itemDataLen
, size
= 0;
570 itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
571 /* Each item decoded may not tolerate extraneous bytes, so
572 * get the length of the next element and pass it directly.
574 ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
577 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
578 1 + itemLenBytes
+ itemDataLen
,
579 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
,
586 if (itemSizes
!= &itemSize
)
587 itemSizes
= CryptMemRealloc(itemSizes
,
588 cItems
* sizeof(struct AsnArrayItemSize
));
593 cItems
* sizeof(struct AsnArrayItemSize
));
595 memcpy(itemSizes
, &itemSize
, sizeof(itemSize
));
599 itemSizes
[cItems
- 1].encodedLen
= 1 + itemLenBytes
601 itemSizes
[cItems
- 1].size
= size
;
603 ret
= CRYPT_GetLen(ptr
,
604 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
606 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
616 *pcbStructInfo
= bytesNeeded
;
617 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
618 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
623 struct GenericArray
*array
;
625 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
626 pvStructInfo
= *(BYTE
**)pvStructInfo
;
627 array
= (struct GenericArray
*)pvStructInfo
;
628 array
->cItems
= cItems
;
630 array
->rgItems
= startingPointer
;
632 array
->rgItems
= (BYTE
*)array
+
633 sizeof(struct GenericArray
);
634 nextData
= (BYTE
*)array
->rgItems
+
635 array
->cItems
* arrayDesc
->itemSize
;
636 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
637 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
640 if (arrayDesc
->hasPointer
)
641 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
642 + arrayDesc
->pointerOffset
) = nextData
;
643 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
644 itemSizes
[i
].encodedLen
,
645 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
646 array
->rgItems
+ i
* arrayDesc
->itemSize
,
652 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
653 ret
= CRYPT_GetLen(ptr
,
654 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
656 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
661 if (itemSizes
!= &itemSize
)
662 CryptMemFree(itemSizes
);
667 SetLastError(CRYPT_E_ASN1_BADTAG
);
673 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
674 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
675 * to CRYPT_E_ASN1_CORRUPT.
676 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
679 static BOOL WINAPI
CRYPT_AsnDecodeDerBlob(DWORD dwCertEncodingType
,
680 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
681 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
686 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
688 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
689 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
691 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
692 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
695 *pcbStructInfo
= bytesNeeded
;
696 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
697 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
699 CRYPT_DER_BLOB
*blob
;
701 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
702 pvStructInfo
= *(BYTE
**)pvStructInfo
;
703 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
704 blob
->cbData
= 1 + lenBytes
+ dataLen
;
707 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
708 blob
->pbData
= (BYTE
*)pbEncoded
;
711 assert(blob
->pbData
);
712 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
717 SetLastError(CRYPT_E_ASN1_CORRUPT
);
725 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
726 static BOOL WINAPI
CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType
,
727 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
728 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
732 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
733 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
735 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
738 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
, lpszStructType
,
739 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pDecodePara
,
740 pvStructInfo
, pcbStructInfo
);
741 if (ret
&& pvStructInfo
)
743 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
750 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
752 temp
= blob
->pbData
[i
];
753 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
754 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
758 TRACE("returning %d (%08x)\n", ret
, GetLastError());
762 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
763 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
764 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
768 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
769 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
773 struct AsnDecodeSequenceItem items
[] = {
774 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
775 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
776 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
777 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
778 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
779 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
780 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
781 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
782 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
783 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
786 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
787 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
788 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
789 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
790 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
794 SetLastError(STATUS_ACCESS_VIOLATION
);
799 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
803 /* Internal function */
804 static BOOL WINAPI
CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType
,
805 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
806 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
811 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
813 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
815 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
816 pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
, pDecodePara
,
817 pvStructInfo
, pcbStructInfo
);
822 static BOOL WINAPI
CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType
,
823 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
824 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
828 struct AsnDecodeSequenceItem items
[] = {
829 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
830 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
831 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
832 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
835 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
836 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
837 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
841 /* Internal function */
842 static BOOL WINAPI
CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType
,
843 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
844 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
849 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
851 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
853 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
854 X509_EXTENSIONS
, pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
,
855 pDecodePara
, pvStructInfo
, pcbStructInfo
);
860 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
861 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
862 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
865 struct AsnDecodeSequenceItem items
[] = {
866 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
867 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
868 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
869 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
870 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
871 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
872 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
873 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
874 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
875 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
877 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
878 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
880 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
881 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
883 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
884 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
885 FALSE
, TRUE
, offsetof(CERT_INFO
,
886 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
887 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
888 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
889 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
890 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
891 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
892 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
893 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
894 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
895 offsetof(CERT_INFO
, rgExtension
), 0 },
898 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
899 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
901 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
902 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
903 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
904 if (ret
&& pvStructInfo
)
908 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
909 info
= *(CERT_INFO
**)pvStructInfo
;
911 info
= (CERT_INFO
*)pvStructInfo
;
912 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
913 !info
->Subject
.cbData
)
915 SetLastError(CRYPT_E_ASN1_CORRUPT
);
916 /* Don't need to deallocate, because it should have failed on the
917 * first pass (and no memory was allocated.)
923 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
927 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
928 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
929 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
933 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
934 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
938 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
941 /* First try to decode it as a signed cert. */
942 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
943 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
944 (BYTE
*)&signedCert
, &size
);
948 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
949 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
950 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
, pvStructInfo
,
952 LocalFree(signedCert
);
954 /* Failing that, try it as an unsigned cert */
958 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
959 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
960 pDecodePara
, pvStructInfo
, pcbStructInfo
);
965 SetLastError(STATUS_ACCESS_VIOLATION
);
970 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
974 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntry(DWORD dwCertEncodingType
,
975 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
976 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
979 struct AsnDecodeSequenceItem items
[] = {
980 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
981 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
982 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
983 { 0, offsetof(CRL_ENTRY
, RevocationDate
), CRYPT_AsnDecodeChoiceOfTime
,
984 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
985 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
986 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
987 offsetof(CRL_ENTRY
, rgExtension
), 0 },
989 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
991 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
994 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
995 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
996 NULL
, entry
, pcbStructInfo
, entry
? entry
->SerialNumber
.pbData
: NULL
);
1000 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1001 * been set prior to calling.
1003 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType
,
1004 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1005 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1008 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1009 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1010 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1011 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
1013 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1014 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1016 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1017 pDecodePara
, pvStructInfo
, pcbStructInfo
,
1018 entries
? entries
->rgItems
: NULL
);
1019 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1023 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1024 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1025 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1027 struct AsnDecodeSequenceItem items
[] = {
1028 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1029 CRYPT_AsnDecodeInt
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1030 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1031 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1032 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1033 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1034 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1036 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
1037 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1038 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
1039 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1040 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1041 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1042 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1043 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1044 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1045 offsetof(CRL_INFO
, rgExtension
), 0 },
1049 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1050 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1052 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1053 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1054 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1056 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1060 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1061 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1062 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1066 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1067 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1071 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1074 /* First try to decode it as a signed crl. */
1075 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
1076 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1077 (BYTE
*)&signedCrl
, &size
);
1081 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1082 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1083 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1084 pvStructInfo
, pcbStructInfo
);
1085 LocalFree(signedCrl
);
1087 /* Failing that, try it as an unsigned crl */
1091 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1092 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1093 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1098 SetLastError(STATUS_ACCESS_VIOLATION
);
1103 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1107 static BOOL WINAPI
CRYPT_AsnDecodeOidInternal(DWORD dwCertEncodingType
,
1108 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1109 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1113 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1114 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1116 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1120 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1122 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1123 DWORD bytesNeeded
= sizeof(LPSTR
);
1127 /* The largest possible string for the first two components
1128 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1133 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1134 pbEncoded
[1 + lenBytes
] / 40,
1135 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1137 bytesNeeded
+= strlen(firstTwo
) + 1;
1138 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1139 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1141 /* large enough for ".4000000" */
1145 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1152 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1155 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1162 snprintf(str
, sizeof(str
), ".%d", val
);
1163 bytesNeeded
+= strlen(str
);
1168 *pcbStructInfo
= bytesNeeded
;
1169 else if (*pcbStructInfo
< bytesNeeded
)
1171 *pcbStructInfo
= bytesNeeded
;
1172 SetLastError(ERROR_MORE_DATA
);
1180 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1183 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1184 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1186 pszObjId
+= strlen(pszObjId
);
1187 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1188 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1192 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1201 sprintf(pszObjId
, ".%d", val
);
1202 pszObjId
+= strlen(pszObjId
);
1206 *(LPSTR
*)pvStructInfo
= NULL
;
1207 *pcbStructInfo
= bytesNeeded
;
1214 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1217 static BOOL WINAPI
CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType
,
1218 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1219 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1221 struct AsnDecodeSequenceItem items
[] = {
1222 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1223 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1224 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1225 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1226 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1227 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1228 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1229 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1232 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1234 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1238 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1239 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1240 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1241 ext
, pcbStructInfo
, ext
? ext
->pszObjId
: NULL
);
1243 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1244 debugstr_a(ext
->pszObjId
));
1245 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1249 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
1250 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1251 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1254 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1255 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1256 offsetof(CERT_EXTENSION
, pszObjId
) };
1257 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1259 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1260 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1262 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1263 pDecodePara
, pvStructInfo
, pcbStructInfo
, exts
? exts
->rgExtension
: NULL
);
1267 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1268 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1269 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1275 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1276 lpszStructType
, pbEncoded
, cbEncoded
,
1277 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1278 if (ret
&& pvStructInfo
)
1280 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1281 pcbStructInfo
, *pcbStructInfo
);
1284 CERT_EXTENSIONS
*exts
;
1286 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1287 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1288 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1289 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1290 sizeof(CERT_EXTENSIONS
));
1291 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1292 lpszStructType
, pbEncoded
, cbEncoded
,
1293 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1300 SetLastError(STATUS_ACCESS_VIOLATION
);
1307 /* Warning: this assumes the address of value->Value.pbData is already set, in
1308 * order to avoid overwriting memory. (In some cases, it may change it, if it
1309 * doesn't copy anything to memory.) Be sure to set it correctly!
1311 static BOOL WINAPI
CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType
,
1312 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1313 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1317 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1319 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1321 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1322 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1324 switch (pbEncoded
[0])
1326 case ASN_OCTETSTRING
:
1327 valueType
= CERT_RDN_OCTET_STRING
;
1328 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1329 bytesNeeded
+= dataLen
;
1331 case ASN_NUMERICSTRING
:
1332 valueType
= CERT_RDN_NUMERIC_STRING
;
1333 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1334 bytesNeeded
+= dataLen
;
1336 case ASN_PRINTABLESTRING
:
1337 valueType
= CERT_RDN_PRINTABLE_STRING
;
1338 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1339 bytesNeeded
+= dataLen
;
1342 valueType
= CERT_RDN_IA5_STRING
;
1343 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1344 bytesNeeded
+= dataLen
;
1347 valueType
= CERT_RDN_T61_STRING
;
1348 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1349 bytesNeeded
+= dataLen
;
1351 case ASN_VIDEOTEXSTRING
:
1352 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1353 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1354 bytesNeeded
+= dataLen
;
1356 case ASN_GRAPHICSTRING
:
1357 valueType
= CERT_RDN_GRAPHIC_STRING
;
1358 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1359 bytesNeeded
+= dataLen
;
1361 case ASN_VISIBLESTRING
:
1362 valueType
= CERT_RDN_VISIBLE_STRING
;
1363 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1364 bytesNeeded
+= dataLen
;
1366 case ASN_GENERALSTRING
:
1367 valueType
= CERT_RDN_GENERAL_STRING
;
1368 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1369 bytesNeeded
+= dataLen
;
1371 case ASN_UNIVERSALSTRING
:
1372 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1373 SetLastError(CRYPT_E_ASN1_BADTAG
);
1376 valueType
= CERT_RDN_BMP_STRING
;
1377 bytesNeeded
+= dataLen
;
1379 case ASN_UTF8STRING
:
1380 valueType
= CERT_RDN_UTF8_STRING
;
1381 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1382 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1385 SetLastError(CRYPT_E_ASN1_BADTAG
);
1390 *pcbStructInfo
= bytesNeeded
;
1391 else if (*pcbStructInfo
< bytesNeeded
)
1393 *pcbStructInfo
= bytesNeeded
;
1394 SetLastError(ERROR_MORE_DATA
);
1399 *pcbStructInfo
= bytesNeeded
;
1400 value
->dwValueType
= valueType
;
1405 assert(value
->Value
.pbData
);
1406 switch (pbEncoded
[0])
1408 case ASN_OCTETSTRING
:
1409 case ASN_NUMERICSTRING
:
1410 case ASN_PRINTABLESTRING
:
1413 case ASN_VIDEOTEXSTRING
:
1414 case ASN_GRAPHICSTRING
:
1415 case ASN_VISIBLESTRING
:
1416 case ASN_GENERALSTRING
:
1417 value
->Value
.cbData
= dataLen
;
1420 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1421 memcpy(value
->Value
.pbData
,
1422 pbEncoded
+ 1 + lenBytes
, dataLen
);
1424 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1430 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1432 value
->Value
.cbData
= dataLen
;
1433 for (i
= 0; i
< dataLen
/ 2; i
++)
1434 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1435 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1438 case ASN_UTF8STRING
:
1440 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1442 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1443 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1444 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1451 value
->Value
.cbData
= 0;
1452 value
->Value
.pbData
= NULL
;
1459 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1460 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1461 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1467 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1468 lpszStructType
, pbEncoded
, cbEncoded
,
1469 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1470 if (ret
&& pvStructInfo
)
1472 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1473 pcbStructInfo
, *pcbStructInfo
);
1476 CERT_NAME_VALUE
*value
;
1478 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1479 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1480 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1481 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1482 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1483 lpszStructType
, pbEncoded
, cbEncoded
,
1484 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1491 SetLastError(STATUS_ACCESS_VIOLATION
);
1498 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValueInternal(
1499 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1500 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1501 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1505 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1507 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1509 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1510 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1512 switch (pbEncoded
[0])
1514 case ASN_NUMERICSTRING
:
1515 valueType
= CERT_RDN_NUMERIC_STRING
;
1516 bytesNeeded
+= dataLen
* 2;
1518 case ASN_PRINTABLESTRING
:
1519 valueType
= CERT_RDN_PRINTABLE_STRING
;
1520 bytesNeeded
+= dataLen
* 2;
1523 valueType
= CERT_RDN_IA5_STRING
;
1524 bytesNeeded
+= dataLen
* 2;
1527 valueType
= CERT_RDN_T61_STRING
;
1528 bytesNeeded
+= dataLen
* 2;
1530 case ASN_VIDEOTEXSTRING
:
1531 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1532 bytesNeeded
+= dataLen
* 2;
1534 case ASN_GRAPHICSTRING
:
1535 valueType
= CERT_RDN_GRAPHIC_STRING
;
1536 bytesNeeded
+= dataLen
* 2;
1538 case ASN_VISIBLESTRING
:
1539 valueType
= CERT_RDN_VISIBLE_STRING
;
1540 bytesNeeded
+= dataLen
* 2;
1542 case ASN_GENERALSTRING
:
1543 valueType
= CERT_RDN_GENERAL_STRING
;
1544 bytesNeeded
+= dataLen
* 2;
1546 case ASN_UNIVERSALSTRING
:
1547 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1548 bytesNeeded
+= dataLen
/ 2;
1551 valueType
= CERT_RDN_BMP_STRING
;
1552 bytesNeeded
+= dataLen
;
1554 case ASN_UTF8STRING
:
1555 valueType
= CERT_RDN_UTF8_STRING
;
1556 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1557 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1560 SetLastError(CRYPT_E_ASN1_BADTAG
);
1565 *pcbStructInfo
= bytesNeeded
;
1566 else if (*pcbStructInfo
< bytesNeeded
)
1568 *pcbStructInfo
= bytesNeeded
;
1569 SetLastError(ERROR_MORE_DATA
);
1574 *pcbStructInfo
= bytesNeeded
;
1575 value
->dwValueType
= valueType
;
1579 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1581 assert(value
->Value
.pbData
);
1582 switch (pbEncoded
[0])
1584 case ASN_NUMERICSTRING
:
1585 case ASN_PRINTABLESTRING
:
1588 case ASN_VIDEOTEXSTRING
:
1589 case ASN_GRAPHICSTRING
:
1590 case ASN_VISIBLESTRING
:
1591 case ASN_GENERALSTRING
:
1592 value
->Value
.cbData
= dataLen
* 2;
1593 for (i
= 0; i
< dataLen
; i
++)
1594 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1596 case ASN_UNIVERSALSTRING
:
1597 value
->Value
.cbData
= dataLen
/ 2;
1598 for (i
= 0; i
< dataLen
/ 4; i
++)
1599 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1600 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1603 value
->Value
.cbData
= dataLen
;
1604 for (i
= 0; i
< dataLen
/ 2; i
++)
1605 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1606 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1608 case ASN_UTF8STRING
:
1609 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1610 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1611 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1617 value
->Value
.cbData
= 0;
1618 value
->Value
.pbData
= NULL
;
1625 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1626 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1627 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1633 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(dwCertEncodingType
,
1634 lpszStructType
, pbEncoded
, cbEncoded
,
1635 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1636 if (ret
&& pvStructInfo
)
1638 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1639 pcbStructInfo
, *pcbStructInfo
);
1642 CERT_NAME_VALUE
*value
;
1644 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1645 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1646 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1647 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1648 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(
1649 dwCertEncodingType
, lpszStructType
, pbEncoded
, cbEncoded
,
1650 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1657 SetLastError(STATUS_ACCESS_VIOLATION
);
1664 static BOOL WINAPI
CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType
,
1665 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1666 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1669 struct AsnDecodeSequenceItem items
[] = {
1670 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1671 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1672 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1673 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1674 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1675 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1677 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1679 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1680 pvStructInfo
, *pcbStructInfo
);
1683 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1684 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1685 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1686 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1689 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1690 debugstr_a(attr
->pszObjId
));
1691 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1693 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1697 static BOOL WINAPI
CRYPT_AsnDecodeRdn(DWORD dwCertEncodingType
,
1698 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1699 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1702 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1703 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1704 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1705 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1707 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1708 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1712 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1713 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1714 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1720 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1721 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1722 offsetof(CERT_RDN
, rgRDNAttr
) };
1724 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1725 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1729 SetLastError(STATUS_ACCESS_VIOLATION
);
1736 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdnAttr(DWORD dwCertEncodingType
,
1737 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1738 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1741 struct AsnDecodeSequenceItem items
[] = {
1742 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1743 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1744 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1745 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1746 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1747 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1749 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1751 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1752 pvStructInfo
, *pcbStructInfo
);
1755 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1756 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1757 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1758 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1761 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1762 debugstr_a(attr
->pszObjId
));
1763 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1765 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1769 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdn(DWORD dwCertEncodingType
,
1770 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1771 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1774 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1775 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1776 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1777 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1779 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1780 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1784 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1785 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1786 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1792 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1793 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1794 offsetof(CERT_RDN
, rgRDNAttr
) };
1796 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1797 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1801 SetLastError(STATUS_ACCESS_VIOLATION
);
1808 static BOOL WINAPI
CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType
,
1809 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1810 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1813 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
1815 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1816 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1818 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1819 bytesNeeded
+= cbEncoded
;
1821 *pcbStructInfo
= bytesNeeded
;
1822 else if (*pcbStructInfo
< bytesNeeded
)
1824 SetLastError(ERROR_MORE_DATA
);
1825 *pcbStructInfo
= bytesNeeded
;
1830 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1832 *pcbStructInfo
= bytesNeeded
;
1833 blob
->cbData
= cbEncoded
;
1834 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1835 blob
->pbData
= (LPBYTE
)pbEncoded
;
1838 assert(blob
->pbData
);
1839 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1845 static BOOL WINAPI
CRYPT_DecodeDERArray(DWORD dwCertEncodingType
,
1846 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1847 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1850 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
1851 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
1852 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
1854 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1855 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1857 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1858 pDecodePara
, pvStructInfo
, pcbStructInfo
, array
? array
->rgItems
: NULL
);
1862 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
1863 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1864 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1870 struct AsnDecodeSequenceItem items
[] = {
1871 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
1872 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1873 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
1874 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
1875 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
1876 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
1878 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
1880 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1881 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1882 pDecodePara
, pvStructInfo
, pcbStructInfo
, attr
? attr
->pszObjId
:
1887 SetLastError(STATUS_ACCESS_VIOLATION
);
1890 TRACE("returning %d\n", ret
);
1894 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributesInternal(
1895 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1896 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1897 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1899 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1900 CRYPT_AsnDecodePKCSAttribute
, sizeof(CRYPT_ATTRIBUTE
), TRUE
,
1901 offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
1902 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
1905 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1906 pDecodePara
, pvStructInfo
, pcbStructInfo
, attrs
? attrs
->rgAttr
:
1911 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
1912 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1913 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1917 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1918 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1924 if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType
,
1925 lpszStructType
, pbEncoded
, cbEncoded
,
1926 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
1929 *pcbStructInfo
= bytesNeeded
;
1930 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1931 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1933 PCRYPT_ATTRIBUTES attrs
;
1935 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1936 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1937 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
1938 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
1939 sizeof(CRYPT_ATTRIBUTES
));
1940 ret
= CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType
,
1941 lpszStructType
, pbEncoded
, cbEncoded
,
1942 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1949 SetLastError(STATUS_ACCESS_VIOLATION
);
1952 TRACE("returning %d\n", ret
);
1956 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
1957 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1958 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1960 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
1961 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
1963 struct AsnDecodeSequenceItem items
[] = {
1964 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
1965 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1966 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
1967 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
1968 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
1969 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
1972 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1973 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1975 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1976 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1977 pDecodePara
, pvStructInfo
, pcbStructInfo
, algo
? algo
->pszObjId
: NULL
);
1978 if (ret
&& pvStructInfo
)
1980 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
1981 debugstr_a(algo
->pszObjId
));
1986 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
1987 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1988 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1991 struct AsnDecodeSequenceItem items
[] = {
1992 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
1993 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1994 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
1995 Algorithm
.pszObjId
) },
1996 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
1997 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
1998 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2000 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2002 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2003 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2004 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
?
2005 info
->Algorithm
.Parameters
.pbData
: NULL
);
2009 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2010 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2011 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2019 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
2020 lpszStructType
, pbEncoded
, cbEncoded
,
2021 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2024 *pcbStructInfo
= bytesNeeded
;
2025 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2026 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2028 PCERT_PUBLIC_KEY_INFO info
;
2030 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2031 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2032 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2033 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2034 sizeof(CERT_PUBLIC_KEY_INFO
);
2035 ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
2036 lpszStructType
, pbEncoded
, cbEncoded
,
2037 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2044 SetLastError(STATUS_ACCESS_VIOLATION
);
2051 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
2052 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2053 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2059 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2062 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2064 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2067 if (pbEncoded
[1] > 1)
2069 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2074 *pcbStructInfo
= sizeof(BOOL
);
2077 else if (*pcbStructInfo
< sizeof(BOOL
))
2079 *pcbStructInfo
= sizeof(BOOL
);
2080 SetLastError(ERROR_MORE_DATA
);
2085 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2088 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2092 static BOOL WINAPI
CRYPT_AsnDecodeAltNameEntry(DWORD dwCertEncodingType
,
2093 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2094 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2096 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2097 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2100 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2101 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2105 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2108 if ((pbEncoded
[0] & ASN_FLAGS_MASK
) != ASN_CONTEXT
)
2110 SetLastError(CRYPT_E_ASN1_BADTAG
);
2113 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2114 if (1 + lenBytes
> cbEncoded
)
2116 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2119 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2121 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2123 case 1: /* rfc822Name */
2124 case 2: /* dNSName */
2125 case 6: /* uniformResourceIdentifier */
2126 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2128 case 7: /* iPAddress */
2129 bytesNeeded
+= dataLen
;
2131 case 8: /* registeredID */
2132 /* FIXME: decode as OID */
2133 case 0: /* otherName */
2134 case 4: /* directoryName */
2136 SetLastError(CRYPT_E_ASN1_BADTAG
);
2139 case 3: /* x400Address, unimplemented */
2140 case 5: /* ediPartyName, unimplemented */
2141 SetLastError(CRYPT_E_ASN1_BADTAG
);
2145 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2151 *pcbStructInfo
= bytesNeeded
;
2152 else if (*pcbStructInfo
< bytesNeeded
)
2154 *pcbStructInfo
= bytesNeeded
;
2155 SetLastError(ERROR_MORE_DATA
);
2160 *pcbStructInfo
= bytesNeeded
;
2161 /* MS used values one greater than the asn1 ones.. sigh */
2162 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
2163 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2165 case 1: /* rfc822Name */
2166 case 2: /* dNSName */
2167 case 6: /* uniformResourceIdentifier */
2171 for (i
= 0; i
< dataLen
; i
++)
2172 entry
->u
.pwszURL
[i
] =
2173 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2174 entry
->u
.pwszURL
[i
] = 0;
2175 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2176 debugstr_w(entry
->u
.pwszURL
));
2179 case 7: /* iPAddress */
2180 /* The next data pointer is in the pwszURL spot, that is,
2181 * the first 4 bytes. Need to move it to the next spot.
2183 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2184 entry
->u
.IPAddress
.cbData
= dataLen
;
2185 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2195 static BOOL WINAPI
CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType
,
2196 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2197 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2200 struct AsnArrayDescriptor arrayDesc
= { 0,
2201 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2202 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2203 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2205 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2206 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2209 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2210 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2211 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->rgAltEntry
: NULL
);
2215 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2216 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2217 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2223 struct AsnDecodeSequenceItem items
[] = {
2224 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2225 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_DATA_BLOB
),
2226 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2227 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2228 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2229 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2230 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2231 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2232 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2233 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2234 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2237 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2238 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2239 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2243 SetLastError(STATUS_ACCESS_VIOLATION
);
2250 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2251 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2252 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2258 struct AsnDecodeSequenceItem items
[] = {
2259 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
2260 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_DATA_BLOB
),
2261 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
2262 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2263 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
2264 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
2265 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2266 AuthorityCertIssuer
.rgAltEntry
), 0 },
2267 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2268 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2269 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2270 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2271 AuthorityCertSerialNumber
.pbData
), 0 },
2274 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2275 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2276 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2280 SetLastError(STATUS_ACCESS_VIOLATION
);
2287 static BOOL WINAPI
CRYPT_AsnDecodePKCSContent(DWORD dwCertEncodingType
,
2288 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2289 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2294 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2295 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2297 /* The caller has already checked the tag, no need to check it again.
2298 * Check the outer length is valid by calling CRYPT_GetLen:
2300 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2302 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2305 pbEncoded
+= 1 + lenBytes
;
2306 /* Check the inner length is valid by calling CRYPT_GetLen again: */
2307 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &innerLen
)))
2309 ret
= CRYPT_AsnDecodeCopyBytes(dwCertEncodingType
, NULL
,
2310 pbEncoded
, dataLen
, dwFlags
, pDecodePara
, pvStructInfo
,
2317 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfoInternal(
2318 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2319 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2320 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2322 CRYPT_CONTENT_INFO
*info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2323 struct AsnDecodeSequenceItem items
[] = {
2324 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
2325 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
2326 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
2327 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
2328 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
2329 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
2330 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
2333 return CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2334 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2335 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->pszObjId
: NULL
);
2338 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
2339 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2340 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2344 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2345 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2349 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(dwCertEncodingType
,
2350 lpszStructType
, pbEncoded
, cbEncoded
,
2351 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
2352 if (ret
&& pvStructInfo
)
2354 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
2355 pcbStructInfo
, *pcbStructInfo
);
2358 CRYPT_CONTENT_INFO
*info
;
2360 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2361 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2362 info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2363 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
2364 sizeof(CRYPT_CONTENT_INFO
));
2365 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(dwCertEncodingType
,
2366 lpszStructType
, pbEncoded
, cbEncoded
,
2367 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2374 SetLastError(STATUS_ACCESS_VIOLATION
);
2380 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2381 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2382 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
2385 struct AsnDecodeSequenceItem items
[] = {
2386 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
), CRYPT_AsnDecodeInt
,
2387 sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2388 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
2389 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2390 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
2392 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
2393 CRYPT_AsnDecodePKCSContentInfoInternal
,
2394 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
2395 ContentInfo
.pszObjId
), 0 },
2396 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
2397 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
2398 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
2401 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
2402 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2403 pDecodePara
, digestedData
, pcbDigestedData
, NULL
);
2407 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2408 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2409 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2413 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2414 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2418 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2419 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2420 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2422 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2423 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2427 SetLastError(STATUS_ACCESS_VIOLATION
);
2434 struct PATH_LEN_CONSTRAINT
2436 BOOL fPathLenConstraint
;
2437 DWORD dwPathLenConstraint
;
2440 static BOOL WINAPI
CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType
,
2441 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2442 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2446 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2447 pvStructInfo
, *pcbStructInfo
);
2451 if (pbEncoded
[0] == ASN_INTEGER
)
2453 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
);
2456 *pcbStructInfo
= bytesNeeded
;
2457 else if (*pcbStructInfo
< bytesNeeded
)
2459 SetLastError(ERROR_MORE_DATA
);
2460 *pcbStructInfo
= bytesNeeded
;
2465 struct PATH_LEN_CONSTRAINT
*constraint
=
2466 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
2467 DWORD size
= sizeof(constraint
->dwPathLenConstraint
);
2469 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
2470 pbEncoded
, cbEncoded
, 0, NULL
,
2471 &constraint
->dwPathLenConstraint
, &size
);
2473 constraint
->fPathLenConstraint
= TRUE
;
2474 TRACE("got an int, dwPathLenConstraint is %d\n",
2475 constraint
->dwPathLenConstraint
);
2480 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2484 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2488 static BOOL WINAPI
CRYPT_AsnDecodeSubtreeConstraints(DWORD dwCertEncodingType
,
2489 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2490 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2493 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2494 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
2495 offsetof(CERT_NAME_BLOB
, pbData
) };
2496 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2498 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2499 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2501 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2502 pDecodePara
, pvStructInfo
, pcbStructInfo
,
2503 entries
? entries
->rgItems
: NULL
);
2504 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
2508 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
2509 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2510 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2516 struct AsnDecodeSequenceItem items
[] = {
2517 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
2518 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2519 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
2520 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2521 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2522 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2523 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2524 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
2525 sizeof(struct GenericArray
), TRUE
, TRUE
,
2526 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
2529 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2530 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2531 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2535 SetLastError(STATUS_ACCESS_VIOLATION
);
2542 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
2543 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2544 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2550 struct AsnDecodeSequenceItem items
[] = {
2551 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
2552 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
2553 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
2554 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2555 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2558 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2559 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2560 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2564 SetLastError(STATUS_ACCESS_VIOLATION
);
2571 #define RSA1_MAGIC 0x31415352
2573 struct DECODED_RSA_PUB_KEY
2576 CRYPT_INTEGER_BLOB modulus
;
2579 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
2580 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2581 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2587 struct AsnDecodeSequenceItem items
[] = {
2588 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
2589 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2590 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
2592 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
2593 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2595 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
2598 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2599 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
2600 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
, &size
, NULL
);
2603 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2604 decodedKey
->modulus
.cbData
;
2608 *pcbStructInfo
= bytesNeeded
;
2611 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2612 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2615 RSAPUBKEY
*rsaPubKey
;
2617 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2618 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2619 hdr
= (BLOBHEADER
*)pvStructInfo
;
2620 hdr
->bType
= PUBLICKEYBLOB
;
2621 hdr
->bVersion
= CUR_BLOB_VERSION
;
2623 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2624 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
2625 sizeof(BLOBHEADER
));
2626 rsaPubKey
->magic
= RSA1_MAGIC
;
2627 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
2628 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
2629 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
2630 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
2631 decodedKey
->modulus
.cbData
);
2633 LocalFree(decodedKey
);
2638 SetLastError(STATUS_ACCESS_VIOLATION
);
2645 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
2646 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2647 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2650 DWORD bytesNeeded
, dataLen
;
2652 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2653 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2655 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2657 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2658 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
2660 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
2662 *pcbStructInfo
= bytesNeeded
;
2663 else if (*pcbStructInfo
< bytesNeeded
)
2665 SetLastError(ERROR_MORE_DATA
);
2666 *pcbStructInfo
= bytesNeeded
;
2671 CRYPT_DATA_BLOB
*blob
;
2672 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2674 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2675 blob
->cbData
= dataLen
;
2676 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2677 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
2680 assert(blob
->pbData
);
2682 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
2690 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
2691 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2692 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2696 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2697 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2705 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2708 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
2710 SetLastError(CRYPT_E_ASN1_BADTAG
);
2713 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2714 lpszStructType
, pbEncoded
, cbEncoded
,
2715 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2718 *pcbStructInfo
= bytesNeeded
;
2719 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2720 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2722 CRYPT_DATA_BLOB
*blob
;
2724 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2725 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2726 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2727 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
2728 ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2729 lpszStructType
, pbEncoded
, cbEncoded
,
2730 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2737 SetLastError(STATUS_ACCESS_VIOLATION
);
2744 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
2745 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2746 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2750 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2751 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2753 if (pbEncoded
[0] == ASN_BITSTRING
)
2755 DWORD bytesNeeded
, dataLen
;
2757 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2759 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2760 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
2762 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
2764 *pcbStructInfo
= bytesNeeded
;
2765 else if (*pcbStructInfo
< bytesNeeded
)
2767 *pcbStructInfo
= bytesNeeded
;
2768 SetLastError(ERROR_MORE_DATA
);
2773 CRYPT_BIT_BLOB
*blob
;
2775 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2776 blob
->cbData
= dataLen
- 1;
2777 blob
->cUnusedBits
= *(pbEncoded
+ 1 +
2778 GET_LEN_BYTES(pbEncoded
[1]));
2779 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2781 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 +
2782 GET_LEN_BYTES(pbEncoded
[1]);
2786 assert(blob
->pbData
);
2789 BYTE mask
= 0xff << blob
->cUnusedBits
;
2791 memcpy(blob
->pbData
, pbEncoded
+ 2 +
2792 GET_LEN_BYTES(pbEncoded
[1]), blob
->cbData
);
2793 blob
->pbData
[blob
->cbData
- 1] &= mask
;
2801 SetLastError(CRYPT_E_ASN1_BADTAG
);
2804 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2808 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
2809 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2810 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2814 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2815 pDecodePara
, pvStructInfo
, pcbStructInfo
);
2821 if ((ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2822 lpszStructType
, pbEncoded
, cbEncoded
,
2823 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2826 *pcbStructInfo
= bytesNeeded
;
2827 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2828 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2830 CRYPT_BIT_BLOB
*blob
;
2832 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2833 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2834 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2835 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
2836 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2837 lpszStructType
, pbEncoded
, cbEncoded
,
2838 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2845 SetLastError(STATUS_ACCESS_VIOLATION
);
2849 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2853 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
2854 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2855 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2861 *pcbStructInfo
= sizeof(int);
2866 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
2867 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
2868 DWORD size
= sizeof(buf
);
2870 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
2871 if (pbEncoded
[0] != ASN_INTEGER
)
2873 SetLastError(CRYPT_E_ASN1_BADTAG
);
2877 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2878 X509_MULTI_BYTE_INTEGER
, pbEncoded
, cbEncoded
, 0, NULL
, &buf
,
2882 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2883 pvStructInfo
, pcbStructInfo
, sizeof(int))))
2887 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2888 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2889 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
2891 /* initialize to a negative value to sign-extend */
2896 for (i
= 0; i
< blob
->cbData
; i
++)
2899 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
2901 memcpy(pvStructInfo
, &val
, sizeof(int));
2904 else if (GetLastError() == ERROR_MORE_DATA
)
2905 SetLastError(CRYPT_E_ASN1_LARGE
);
2909 SetLastError(STATUS_ACCESS_VIOLATION
);
2916 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
2917 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2918 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2921 DWORD bytesNeeded
, dataLen
;
2923 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2925 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2927 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2929 *pcbStructInfo
= bytesNeeded
;
2930 else if (*pcbStructInfo
< bytesNeeded
)
2932 *pcbStructInfo
= bytesNeeded
;
2933 SetLastError(ERROR_MORE_DATA
);
2938 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2940 blob
->cbData
= dataLen
;
2941 assert(blob
->pbData
);
2946 for (i
= 0; i
< blob
->cbData
; i
++)
2948 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2957 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
2958 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2959 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2967 if (pbEncoded
[0] != ASN_INTEGER
)
2969 SetLastError(CRYPT_E_ASN1_BADTAG
);
2973 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2974 lpszStructType
, pbEncoded
, cbEncoded
,
2975 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
);
2979 *pcbStructInfo
= bytesNeeded
;
2980 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2981 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2983 CRYPT_INTEGER_BLOB
*blob
;
2985 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2986 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2987 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2988 blob
->pbData
= (BYTE
*)pvStructInfo
+
2989 sizeof(CRYPT_INTEGER_BLOB
);
2990 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2991 lpszStructType
, pbEncoded
, cbEncoded
,
2992 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2999 SetLastError(STATUS_ACCESS_VIOLATION
);
3006 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
3007 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3008 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3009 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3013 if (pbEncoded
[0] == ASN_INTEGER
)
3015 DWORD bytesNeeded
, dataLen
;
3017 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3019 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3021 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3023 *pcbStructInfo
= bytesNeeded
;
3024 else if (*pcbStructInfo
< bytesNeeded
)
3026 *pcbStructInfo
= bytesNeeded
;
3027 SetLastError(ERROR_MORE_DATA
);
3032 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3034 blob
->cbData
= dataLen
;
3035 assert(blob
->pbData
);
3036 /* remove leading zero byte if it exists */
3037 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
3046 for (i
= 0; i
< blob
->cbData
; i
++)
3048 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3057 SetLastError(CRYPT_E_ASN1_BADTAG
);
3063 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
3064 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3065 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3073 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
3074 lpszStructType
, pbEncoded
, cbEncoded
,
3075 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
3078 *pcbStructInfo
= bytesNeeded
;
3079 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3080 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3082 CRYPT_INTEGER_BLOB
*blob
;
3084 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3085 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3086 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3087 blob
->pbData
= (BYTE
*)pvStructInfo
+
3088 sizeof(CRYPT_INTEGER_BLOB
);
3089 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
3090 lpszStructType
, pbEncoded
, cbEncoded
,
3091 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3098 SetLastError(STATUS_ACCESS_VIOLATION
);
3105 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
3106 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3107 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3113 *pcbStructInfo
= sizeof(int);
3118 if (pbEncoded
[0] == ASN_ENUMERATED
)
3120 unsigned int val
= 0, i
;
3124 SetLastError(CRYPT_E_ASN1_EOD
);
3127 else if (pbEncoded
[1] == 0)
3129 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3134 /* A little strange looking, but we have to accept a sign byte:
3135 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3136 * assuming a small length is okay here, it has to be in short
3139 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
3141 SetLastError(CRYPT_E_ASN1_LARGE
);
3144 for (i
= 0; i
< pbEncoded
[1]; i
++)
3147 val
|= pbEncoded
[2 + i
];
3149 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3150 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
3152 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3153 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3154 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
3160 SetLastError(CRYPT_E_ASN1_BADTAG
);
3166 SetLastError(STATUS_ACCESS_VIOLATION
);
3173 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3176 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3181 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3183 if (!isdigit(*(pbEncoded))) \
3185 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3191 (word) += *(pbEncoded)++ - '0'; \
3196 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
3197 SYSTEMTIME
*sysTime
)
3204 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
3206 WORD hours
, minutes
= 0;
3207 BYTE sign
= *pbEncoded
++;
3210 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
3211 if (ret
&& hours
>= 24)
3213 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3218 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
3219 if (ret
&& minutes
>= 60)
3221 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3229 sysTime
->wHour
+= hours
;
3230 sysTime
->wMinute
+= minutes
;
3234 if (hours
> sysTime
->wHour
)
3237 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
3240 sysTime
->wHour
-= hours
;
3241 if (minutes
> sysTime
->wMinute
)
3244 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
3247 sysTime
->wMinute
-= minutes
;
3254 SetLastError(STATUS_ACCESS_VIOLATION
);
3261 #define MIN_ENCODED_TIME_LENGTH 10
3263 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
3264 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3265 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3271 *pcbStructInfo
= sizeof(FILETIME
);
3277 if (pbEncoded
[0] == ASN_UTCTIME
)
3281 SetLastError(CRYPT_E_ASN1_EOD
);
3284 else if (pbEncoded
[1] > 0x7f)
3286 /* long-form date strings really can't be valid */
3287 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3292 SYSTEMTIME sysTime
= { 0 };
3293 BYTE len
= pbEncoded
[1];
3295 if (len
< MIN_ENCODED_TIME_LENGTH
)
3297 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3303 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
3304 if (sysTime
.wYear
>= 50)
3305 sysTime
.wYear
+= 1900;
3307 sysTime
.wYear
+= 2000;
3308 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3309 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3310 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3311 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3314 if (len
>= 2 && isdigit(*pbEncoded
) &&
3315 isdigit(*(pbEncoded
+ 1)))
3316 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3318 else if (isdigit(*pbEncoded
))
3319 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3322 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3325 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3326 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3329 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3330 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3331 ret
= SystemTimeToFileTime(&sysTime
,
3332 (FILETIME
*)pvStructInfo
);
3339 SetLastError(CRYPT_E_ASN1_BADTAG
);
3345 SetLastError(STATUS_ACCESS_VIOLATION
);
3352 static BOOL WINAPI
CRYPT_AsnDecodeGeneralizedTime(DWORD dwCertEncodingType
,
3353 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3354 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3360 *pcbStructInfo
= sizeof(FILETIME
);
3366 if (pbEncoded
[0] == ASN_GENERALTIME
)
3370 SetLastError(CRYPT_E_ASN1_EOD
);
3373 else if (pbEncoded
[1] > 0x7f)
3375 /* long-form date strings really can't be valid */
3376 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3381 BYTE len
= pbEncoded
[1];
3383 if (len
< MIN_ENCODED_TIME_LENGTH
)
3385 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3390 SYSTEMTIME sysTime
= { 0 };
3393 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3394 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3395 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3396 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3399 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3402 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3404 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3411 /* workaround macro weirdness */
3412 digits
= min(len
, 3);
3413 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3414 sysTime
.wMilliseconds
);
3417 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3420 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3421 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3424 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3425 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3426 ret
= SystemTimeToFileTime(&sysTime
,
3427 (FILETIME
*)pvStructInfo
);
3434 SetLastError(CRYPT_E_ASN1_BADTAG
);
3440 SetLastError(STATUS_ACCESS_VIOLATION
);
3447 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
3448 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3449 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3455 if (pbEncoded
[0] == ASN_UTCTIME
)
3456 ret
= CRYPT_AsnDecodeUtcTime(dwCertEncodingType
, lpszStructType
,
3457 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3459 else if (pbEncoded
[0] == ASN_GENERALTIME
)
3460 ret
= CRYPT_AsnDecodeGeneralizedTime(dwCertEncodingType
,
3461 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
,
3462 pvStructInfo
, pcbStructInfo
);
3465 SetLastError(CRYPT_E_ASN1_BADTAG
);
3471 SetLastError(STATUS_ACCESS_VIOLATION
);
3478 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
3479 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3480 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3486 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
3488 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
3490 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3495 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3496 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
3498 ptr
= pbEncoded
+ 1 + lenBytes
;
3499 remainingLen
= dataLen
;
3500 while (ret
&& remainingLen
)
3504 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3507 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3509 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3510 ptr
+= 1 + nextLenBytes
+ nextLen
;
3511 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
3512 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
3513 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
3519 CRYPT_SEQUENCE_OF_ANY
*seq
;
3523 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3524 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3526 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3527 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3528 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
3529 seq
->cValue
= cValue
;
3530 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
3532 nextPtr
= (BYTE
*)seq
->rgValue
+
3533 cValue
* sizeof(CRYPT_DER_BLOB
);
3534 ptr
= pbEncoded
+ 1 + lenBytes
;
3535 remainingLen
= dataLen
;
3537 while (ret
&& remainingLen
)
3541 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3544 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3546 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
3548 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3549 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
3552 seq
->rgValue
[i
].pbData
= nextPtr
;
3553 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
3555 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
3557 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3558 ptr
+= 1 + nextLenBytes
+ nextLen
;
3568 SetLastError(CRYPT_E_ASN1_BADTAG
);
3574 SetLastError(STATUS_ACCESS_VIOLATION
);
3581 static BOOL WINAPI
CRYPT_AsnDecodeDistPointName(DWORD dwCertEncodingType
,
3582 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3583 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3587 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
3589 DWORD bytesNeeded
, dataLen
;
3591 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3593 struct AsnArrayDescriptor arrayDesc
= {
3594 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
3595 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3596 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3597 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3603 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3604 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3605 0, NULL
, NULL
, &nameLen
, NULL
);
3606 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
;
3609 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
3611 *pcbStructInfo
= bytesNeeded
;
3612 else if (*pcbStructInfo
< bytesNeeded
)
3614 *pcbStructInfo
= bytesNeeded
;
3615 SetLastError(ERROR_MORE_DATA
);
3620 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
3624 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3625 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3626 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3627 0, NULL
, &name
->u
.FullName
, pcbStructInfo
,
3628 name
->u
.FullName
.rgAltEntry
);
3631 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3637 SetLastError(CRYPT_E_ASN1_BADTAG
);
3643 static BOOL WINAPI
CRYPT_AsnDecodeDistPoint(DWORD dwCertEncodingType
,
3644 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3645 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3647 struct AsnDecodeSequenceItem items
[] = {
3648 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
3649 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3650 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
3651 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3652 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
3653 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
3654 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
3655 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
3656 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
3657 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
3661 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3662 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3663 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3667 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
3668 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3669 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3673 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3674 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3678 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3679 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
3680 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
3682 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3683 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3687 SetLastError(STATUS_ACCESS_VIOLATION
);
3694 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
3695 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3696 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3700 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3701 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3705 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3706 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
3708 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3709 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3713 SetLastError(STATUS_ACCESS_VIOLATION
);
3720 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
3721 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3722 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3726 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3727 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3731 struct AsnDecodeSequenceItem items
[] = {
3732 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
3733 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3734 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
3735 offsetof(CRL_ISSUING_DIST_POINT
,
3736 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3737 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
3738 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3740 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
3741 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3743 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
3744 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
3745 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
3746 OnlySomeReasonFlags
.pbData
), 0 },
3747 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
3748 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
3751 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3752 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3753 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3757 SetLastError(STATUS_ACCESS_VIOLATION
);
3764 static BOOL WINAPI
CRYPT_AsnDecodeIssuerSerialNumber(DWORD dwCertEncodingType
,
3765 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3766 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3769 struct AsnDecodeSequenceItem items
[] = {
3770 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
3771 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
3773 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
3774 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
3775 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
3777 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
3778 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
3780 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3781 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3783 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3784 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3785 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
3786 issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
3787 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
3789 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3792 TRACE("returning %d\n", ret
);
3796 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
3797 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3798 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3802 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3803 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3807 struct AsnDecodeSequenceItem items
[] = {
3808 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
3809 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3810 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
3811 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
3812 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
3813 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
3814 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3815 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
3816 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
3817 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3818 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
3819 HashEncryptionAlgorithm
.pszObjId
), 0 },
3820 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
3821 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
3822 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
3823 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
3824 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
3825 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
3826 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
3827 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
3828 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
3831 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3832 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3833 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3837 SetLastError(STATUS_ACCESS_VIOLATION
);
3840 TRACE("returning %d\n", ret
);
3844 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
3845 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3846 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3848 static HCRYPTOIDFUNCSET set
= NULL
;
3850 CryptDecodeObjectExFunc decodeFunc
= NULL
;
3851 HCRYPTOIDFUNCADDR hFunc
= NULL
;
3853 TRACE("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
3854 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
3855 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
3857 if (!pvStructInfo
&& !pcbStructInfo
)
3859 SetLastError(ERROR_INVALID_PARAMETER
);
3862 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
3863 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
3865 SetLastError(ERROR_FILE_NOT_FOUND
);
3870 SetLastError(CRYPT_E_ASN1_EOD
);
3873 if (cbEncoded
> MAX_ENCODED_LEN
)
3875 SetLastError(CRYPT_E_ASN1_LARGE
);
3879 SetLastError(NOERROR
);
3880 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
3881 *(BYTE
**)pvStructInfo
= NULL
;
3882 if (!HIWORD(lpszStructType
))
3884 switch (LOWORD(lpszStructType
))
3886 case (WORD
)X509_CERT
:
3887 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
3889 case (WORD
)X509_CERT_TO_BE_SIGNED
:
3890 decodeFunc
= CRYPT_AsnDecodeCert
;
3892 case (WORD
)X509_CERT_CRL_TO_BE_SIGNED
:
3893 decodeFunc
= CRYPT_AsnDecodeCRL
;
3895 case (WORD
)X509_EXTENSIONS
:
3896 decodeFunc
= CRYPT_AsnDecodeExtensions
;
3898 case (WORD
)X509_NAME_VALUE
:
3899 decodeFunc
= CRYPT_AsnDecodeNameValue
;
3901 case (WORD
)X509_NAME
:
3902 decodeFunc
= CRYPT_AsnDecodeName
;
3904 case (WORD
)X509_PUBLIC_KEY_INFO
:
3905 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
3907 case (WORD
)X509_AUTHORITY_KEY_ID
:
3908 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
3910 case (WORD
)X509_ALTERNATE_NAME
:
3911 decodeFunc
= CRYPT_AsnDecodeAltName
;
3913 case (WORD
)X509_BASIC_CONSTRAINTS
:
3914 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
3916 case (WORD
)X509_BASIC_CONSTRAINTS2
:
3917 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
3919 case (WORD
)RSA_CSP_PUBLICKEYBLOB
:
3920 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
3922 case (WORD
)X509_UNICODE_NAME
:
3923 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
3925 case (WORD
)PKCS_ATTRIBUTE
:
3926 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
3928 case (WORD
)X509_UNICODE_NAME_VALUE
:
3929 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
3931 case (WORD
)X509_OCTET_STRING
:
3932 decodeFunc
= CRYPT_AsnDecodeOctets
;
3934 case (WORD
)X509_BITS
:
3935 case (WORD
)X509_KEY_USAGE
:
3936 decodeFunc
= CRYPT_AsnDecodeBits
;
3938 case (WORD
)X509_INTEGER
:
3939 decodeFunc
= CRYPT_AsnDecodeInt
;
3941 case (WORD
)X509_MULTI_BYTE_INTEGER
:
3942 decodeFunc
= CRYPT_AsnDecodeInteger
;
3944 case (WORD
)X509_MULTI_BYTE_UINT
:
3945 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
3947 case (WORD
)X509_ENUMERATED
:
3948 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3950 case (WORD
)X509_CHOICE_OF_TIME
:
3951 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
3953 case (WORD
)X509_AUTHORITY_KEY_ID2
:
3954 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
3956 case (WORD
)PKCS_CONTENT_INFO
:
3957 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
3959 case (WORD
)X509_SEQUENCE_OF_ANY
:
3960 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
3962 case (WORD
)PKCS_UTC_TIME
:
3963 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3965 case (WORD
)X509_CRL_DIST_POINTS
:
3966 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
3968 case (WORD
)X509_ENHANCED_KEY_USAGE
:
3969 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
3971 case (WORD
)PKCS_ATTRIBUTES
:
3972 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
3974 case (WORD
)X509_ISSUING_DIST_POINT
:
3975 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
3977 case (WORD
)PKCS7_SIGNER_INFO
:
3978 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
3981 FIXME("%d: unimplemented\n", LOWORD(lpszStructType
));
3984 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
3985 decodeFunc
= CRYPT_AsnDecodeExtensions
;
3986 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
3987 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
3988 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
3989 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
3990 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
3991 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
3992 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
3993 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
3994 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
3995 decodeFunc
= CRYPT_AsnDecodeBits
;
3996 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
3997 decodeFunc
= CRYPT_AsnDecodeOctets
;
3998 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
3999 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4000 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
4001 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4002 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
4003 decodeFunc
= CRYPT_AsnDecodeAltName
;
4004 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
4005 decodeFunc
= CRYPT_AsnDecodeAltName
;
4006 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
4007 decodeFunc
= CRYPT_AsnDecodeAltName
;
4008 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
4009 decodeFunc
= CRYPT_AsnDecodeAltName
;
4010 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
4011 decodeFunc
= CRYPT_AsnDecodeAltName
;
4012 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
4013 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4014 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
4015 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4016 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
4017 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4019 TRACE("OID %s not found or unimplemented, looking for DLL\n",
4020 debugstr_a(lpszStructType
));
4024 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
4025 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4026 (void **)&decodeFunc
, &hFunc
);
4029 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
4030 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
4032 SetLastError(ERROR_FILE_NOT_FOUND
);
4034 CryptFreeOIDFunctionAddress(hFunc
, 0);