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 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
322 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
324 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
326 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
330 if ((ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
333 BYTE nextItemLenBytes
= GET_LEN_BYTES(ptr
[1]);
335 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
337 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
339 TRACE("Setting next pointer to %p\n",
341 *(BYTE
**)((BYTE
*)pvStructInfo
+
342 items
[i
].pointerOffset
) = nextData
;
344 if (items
[i
].decodeFunc
)
347 TRACE("decoding item %d\n", i
);
349 TRACE("sizing item %d\n", i
);
350 ret
= items
[i
].decodeFunc(dwCertEncodingType
,
351 NULL
, ptr
, 1 + nextItemLenBytes
+ nextItemLen
,
352 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
353 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
354 : NULL
, &items
[i
].size
);
357 /* Account for alignment padding */
358 if (items
[i
].size
% sizeof(DWORD
))
359 items
[i
].size
+= sizeof(DWORD
) -
360 items
[i
].size
% sizeof(DWORD
);
361 TRACE("item %d size: %d\n", i
, items
[i
].size
);
362 if (nextData
&& items
[i
].hasPointer
&&
363 items
[i
].size
> items
[i
].minSize
)
364 nextData
+= items
[i
].size
- items
[i
].minSize
;
365 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
366 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
367 TRACE("item %d: decoded %d bytes\n", i
,
368 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 TRACE("item %d: decoded %d bytes\n", i
,
385 1 + nextItemLenBytes
+ nextItemLen
);
386 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
387 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
388 items
[i
].size
= items
[i
].minSize
;
391 else if (items
[i
].optional
)
393 TRACE("skipping optional item %d\n", i
);
394 items
[i
].size
= items
[i
].minSize
;
398 TRACE("item %d: tag %02x doesn't match expected %02x\n",
399 i
, ptr
[0], items
[i
].tag
);
400 SetLastError(CRYPT_E_ASN1_BADTAG
);
405 else if (items
[i
].optional
)
407 TRACE("missing optional item %d, skipping\n", i
);
408 items
[i
].size
= items
[i
].minSize
;
412 TRACE("not enough bytes for item %d, failing\n", i
);
413 SetLastError(CRYPT_E_ASN1_CORRUPT
);
418 *cbDecoded
= decoded
;
419 TRACE("returning %d\n", ret
);
423 /* This decodes an arbitrary sequence into a contiguous block of memory
424 * (basically, a struct.) Each element being decoded is described by a struct
425 * AsnDecodeSequenceItem, see above.
426 * startingPointer is an optional pointer to the first place where dynamic
427 * data will be stored. If you know the starting offset, you may pass it
428 * here. Otherwise, pass NULL, and one will be inferred from the items.
429 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set.
431 static BOOL
CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType
,
432 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
433 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
434 void *pvStructInfo
, DWORD
*pcbStructInfo
, void *startingPointer
)
438 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items
, cItem
, pbEncoded
,
439 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
442 if (pbEncoded
[0] == ASN_SEQUENCE
)
446 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
448 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
449 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
451 cbEncoded
-= 1 + lenBytes
;
452 if (cbEncoded
< dataLen
)
454 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
456 SetLastError(CRYPT_E_ASN1_CORRUPT
);
460 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
, ptr
,
461 cbEncoded
, dwFlags
, NULL
, NULL
, &cbDecoded
);
462 if (ret
&& cbDecoded
!= dataLen
)
464 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
466 SetLastError(CRYPT_E_ASN1_CORRUPT
);
471 DWORD i
, bytesNeeded
= 0, structSize
= 0;
473 for (i
= 0; i
< cItem
; i
++)
475 bytesNeeded
+= items
[i
].size
;
476 structSize
+= items
[i
].minSize
;
479 *pcbStructInfo
= bytesNeeded
;
480 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
481 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
485 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
486 pvStructInfo
= *(BYTE
**)pvStructInfo
;
488 nextData
= (BYTE
*)startingPointer
;
490 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
491 memset(pvStructInfo
, 0, structSize
);
492 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
,
493 ptr
, cbEncoded
, dwFlags
, pvStructInfo
, nextData
,
501 SetLastError(CRYPT_E_ASN1_BADTAG
);
504 TRACE("returning %d (%08x)\n", ret
, GetLastError());
509 * The expected tag of the entire encoded array (usually a variant
510 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called
511 * regardless of the tag seen.
513 * used to decode each item in the array
515 * is the minimum size of each decoded item
517 * indicates whether each item has a dynamic pointer
519 * indicates the offset within itemSize at which the pointer exists
521 struct AsnArrayDescriptor
524 CryptDecodeObjectExFunc decodeFunc
;
530 struct AsnArrayItemSize
536 /* Decodes an array of like types into a struct GenericArray.
537 * The layout and decoding of the array are described by a struct
538 * AsnArrayDescriptor.
540 static BOOL
CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor
*arrayDesc
,
541 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
542 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
543 void *startingPointer
)
547 TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc
, pbEncoded
,
548 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, *pcbStructInfo
,
551 if (!arrayDesc
->tag
|| pbEncoded
[0] == arrayDesc
->tag
)
555 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
557 DWORD bytesNeeded
, cItems
= 0;
558 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
559 /* There can be arbitrarily many items, but there is often only one.
561 struct AsnArrayItemSize itemSize
= { 0 }, *itemSizes
= &itemSize
;
563 bytesNeeded
= sizeof(struct GenericArray
);
568 for (ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
569 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
571 DWORD itemLenBytes
, itemDataLen
, size
= 0;
573 itemLenBytes
= GET_LEN_BYTES(ptr
[1]);
574 /* Each item decoded may not tolerate extraneous bytes, so
575 * get the length of the next element and pass it directly.
577 ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
580 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
581 1 + itemLenBytes
+ itemDataLen
,
582 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
,
589 if (itemSizes
!= &itemSize
)
590 itemSizes
= CryptMemRealloc(itemSizes
,
591 cItems
* sizeof(struct AsnArrayItemSize
));
596 cItems
* sizeof(struct AsnArrayItemSize
));
598 memcpy(itemSizes
, &itemSize
, sizeof(itemSize
));
602 itemSizes
[cItems
- 1].encodedLen
= 1 + itemLenBytes
604 itemSizes
[cItems
- 1].size
= size
;
606 ret
= CRYPT_GetLen(ptr
,
607 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
609 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
619 *pcbStructInfo
= bytesNeeded
;
620 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
621 pDecodePara
, pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
626 struct GenericArray
*array
;
628 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
629 pvStructInfo
= *(BYTE
**)pvStructInfo
;
630 array
= (struct GenericArray
*)pvStructInfo
;
631 array
->cItems
= cItems
;
633 array
->rgItems
= startingPointer
;
635 array
->rgItems
= (BYTE
*)array
+
636 sizeof(struct GenericArray
);
637 nextData
= (BYTE
*)array
->rgItems
+
638 array
->cItems
* arrayDesc
->itemSize
;
639 for (i
= 0, ptr
= pbEncoded
+ 1 + lenBytes
; ret
&&
640 i
< cItems
&& ptr
- pbEncoded
- 1 - lenBytes
<
643 if (arrayDesc
->hasPointer
)
644 *(BYTE
**)(array
->rgItems
+ i
* arrayDesc
->itemSize
645 + arrayDesc
->pointerOffset
) = nextData
;
646 ret
= arrayDesc
->decodeFunc(X509_ASN_ENCODING
, 0, ptr
,
647 itemSizes
[i
].encodedLen
,
648 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
,
649 array
->rgItems
+ i
* arrayDesc
->itemSize
,
655 nextData
+= itemSizes
[i
].size
- arrayDesc
->itemSize
;
656 ret
= CRYPT_GetLen(ptr
,
657 cbEncoded
- (ptr
- pbEncoded
), &nextLen
);
659 ptr
+= nextLen
+ 1 + GET_LEN_BYTES(ptr
[1]);
664 if (itemSizes
!= &itemSize
)
665 CryptMemFree(itemSizes
);
670 SetLastError(CRYPT_E_ASN1_BADTAG
);
676 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by
677 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set
678 * to CRYPT_E_ASN1_CORRUPT.
679 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData
682 static BOOL WINAPI
CRYPT_AsnDecodeDerBlob(DWORD dwCertEncodingType
,
683 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
684 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
689 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
691 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
692 DWORD bytesNeeded
= sizeof(CRYPT_DER_BLOB
);
694 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
695 bytesNeeded
+= 1 + lenBytes
+ dataLen
;
698 *pcbStructInfo
= bytesNeeded
;
699 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
700 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
702 CRYPT_DER_BLOB
*blob
;
704 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
705 pvStructInfo
= *(BYTE
**)pvStructInfo
;
706 blob
= (CRYPT_DER_BLOB
*)pvStructInfo
;
707 blob
->cbData
= 1 + lenBytes
+ dataLen
;
710 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
711 blob
->pbData
= (BYTE
*)pbEncoded
;
714 assert(blob
->pbData
);
715 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
720 SetLastError(CRYPT_E_ASN1_CORRUPT
);
728 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */
729 static BOOL WINAPI
CRYPT_AsnDecodeBitsSwapBytes(DWORD dwCertEncodingType
,
730 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
731 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
735 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
736 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
738 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in-
741 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
, lpszStructType
,
742 pbEncoded
, cbEncoded
, dwFlags
& ~CRYPT_DECODE_NOCOPY_FLAG
, pDecodePara
,
743 pvStructInfo
, pcbStructInfo
);
744 if (ret
&& pvStructInfo
)
746 CRYPT_BIT_BLOB
*blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
753 for (i
= 0; i
< blob
->cbData
/ 2; i
++)
755 temp
= blob
->pbData
[i
];
756 blob
->pbData
[i
] = blob
->pbData
[blob
->cbData
- i
- 1];
757 blob
->pbData
[blob
->cbData
- i
- 1] = temp
;
761 TRACE("returning %d (%08x)\n", ret
, GetLastError());
765 static BOOL WINAPI
CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType
,
766 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
767 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
771 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
772 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
776 struct AsnDecodeSequenceItem items
[] = {
777 { 0, offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
),
778 CRYPT_AsnDecodeDerBlob
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
779 offsetof(CERT_SIGNED_CONTENT_INFO
, ToBeSigned
.pbData
), 0 },
780 { ASN_SEQUENCEOF
, offsetof(CERT_SIGNED_CONTENT_INFO
,
781 SignatureAlgorithm
), CRYPT_AsnDecodeAlgorithmId
,
782 sizeof(CRYPT_ALGORITHM_IDENTIFIER
), FALSE
, TRUE
,
783 offsetof(CERT_SIGNED_CONTENT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
784 { ASN_BITSTRING
, offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
),
785 CRYPT_AsnDecodeBitsSwapBytes
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
786 offsetof(CERT_SIGNED_CONTENT_INFO
, Signature
.pbData
), 0 },
789 if (dwFlags
& CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG
)
790 items
[2].decodeFunc
= CRYPT_AsnDecodeBitsInternal
;
791 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
792 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
793 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
797 SetLastError(STATUS_ACCESS_VIOLATION
);
802 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
806 /* Internal function */
807 static BOOL WINAPI
CRYPT_AsnDecodeCertVersion(DWORD dwCertEncodingType
,
808 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
809 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
814 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
816 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
818 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
819 pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
, pDecodePara
,
820 pvStructInfo
, pcbStructInfo
);
825 static BOOL WINAPI
CRYPT_AsnDecodeValidity(DWORD dwCertEncodingType
,
826 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
827 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
831 struct AsnDecodeSequenceItem items
[] = {
832 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotBefore
),
833 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
834 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY
, NotAfter
),
835 CRYPT_AsnDecodeChoiceOfTime
, sizeof(FILETIME
), FALSE
, FALSE
, 0 },
838 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
839 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
840 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
844 /* Internal function */
845 static BOOL WINAPI
CRYPT_AsnDecodeCertExtensions(DWORD dwCertEncodingType
,
846 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
847 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
852 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
854 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
856 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
857 X509_EXTENSIONS
, pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
,
858 pDecodePara
, pvStructInfo
, pcbStructInfo
);
863 static BOOL WINAPI
CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType
,
864 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
865 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
868 struct AsnDecodeSequenceItem items
[] = {
869 { ASN_CONTEXT
| ASN_CONSTRUCTOR
, offsetof(CERT_INFO
, dwVersion
),
870 CRYPT_AsnDecodeCertVersion
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
871 { ASN_INTEGER
, offsetof(CERT_INFO
, SerialNumber
),
872 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
873 TRUE
, offsetof(CERT_INFO
, SerialNumber
.pbData
), 0 },
874 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SignatureAlgorithm
),
875 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
876 FALSE
, TRUE
, offsetof(CERT_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
877 { 0, offsetof(CERT_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
878 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
880 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, NotBefore
),
881 CRYPT_AsnDecodeValidity
, sizeof(CERT_PRIVATE_KEY_VALIDITY
), FALSE
,
883 { 0, offsetof(CERT_INFO
, Subject
), CRYPT_AsnDecodeDerBlob
,
884 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_INFO
,
886 { ASN_SEQUENCEOF
, offsetof(CERT_INFO
, SubjectPublicKeyInfo
),
887 CRYPT_AsnDecodePubKeyInfoInternal
, sizeof(CERT_PUBLIC_KEY_INFO
),
888 FALSE
, TRUE
, offsetof(CERT_INFO
,
889 SubjectPublicKeyInfo
.Algorithm
.Parameters
.pbData
), 0 },
890 { ASN_BITSTRING
, offsetof(CERT_INFO
, IssuerUniqueId
),
891 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
892 offsetof(CERT_INFO
, IssuerUniqueId
.pbData
), 0 },
893 { ASN_BITSTRING
, offsetof(CERT_INFO
, SubjectUniqueId
),
894 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
895 offsetof(CERT_INFO
, SubjectUniqueId
.pbData
), 0 },
896 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 3, offsetof(CERT_INFO
, cExtension
),
897 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
898 offsetof(CERT_INFO
, rgExtension
), 0 },
901 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
902 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
904 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
905 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
906 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
907 if (ret
&& pvStructInfo
)
911 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
912 info
= *(CERT_INFO
**)pvStructInfo
;
914 info
= (CERT_INFO
*)pvStructInfo
;
915 if (!info
->SerialNumber
.cbData
|| !info
->Issuer
.cbData
||
916 !info
->Subject
.cbData
)
918 SetLastError(CRYPT_E_ASN1_CORRUPT
);
919 /* Don't need to deallocate, because it should have failed on the
920 * first pass (and no memory was allocated.)
926 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
930 static BOOL WINAPI
CRYPT_AsnDecodeCert(DWORD dwCertEncodingType
,
931 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
932 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
936 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
937 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
941 PCERT_SIGNED_CONTENT_INFO signedCert
= NULL
;
944 /* First try to decode it as a signed cert. */
945 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
946 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
947 (BYTE
*)&signedCert
, &size
);
951 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
952 X509_CERT_TO_BE_SIGNED
, signedCert
->ToBeSigned
.pbData
,
953 signedCert
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
, pvStructInfo
,
955 LocalFree(signedCert
);
957 /* Failing that, try it as an unsigned cert */
961 ret
= CRYPT_AsnDecodeCertInfo(dwCertEncodingType
,
962 X509_CERT_TO_BE_SIGNED
, pbEncoded
, cbEncoded
, dwFlags
,
963 pDecodePara
, pvStructInfo
, pcbStructInfo
);
968 SetLastError(STATUS_ACCESS_VIOLATION
);
973 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
977 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntry(DWORD dwCertEncodingType
,
978 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
979 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
982 struct AsnDecodeSequenceItem items
[] = {
983 { ASN_INTEGER
, offsetof(CRL_ENTRY
, SerialNumber
),
984 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
, TRUE
,
985 offsetof(CRL_ENTRY
, SerialNumber
.pbData
), 0 },
986 { 0, offsetof(CRL_ENTRY
, RevocationDate
), CRYPT_AsnDecodeChoiceOfTime
,
987 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
988 { ASN_SEQUENCEOF
, offsetof(CRL_ENTRY
, cExtension
),
989 CRYPT_AsnDecodeExtensionsInternal
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
990 offsetof(CRL_ENTRY
, rgExtension
), 0 },
992 PCRL_ENTRY entry
= (PCRL_ENTRY
)pvStructInfo
;
994 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, entry
,
997 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
998 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
999 NULL
, entry
, pcbStructInfo
, entry
? entry
->SerialNumber
.pbData
: NULL
);
1003 /* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has
1004 * been set prior to calling.
1006 static BOOL WINAPI
CRYPT_AsnDecodeCRLEntries(DWORD dwCertEncodingType
,
1007 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1008 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1011 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1012 CRYPT_AsnDecodeCRLEntry
, sizeof(CRL_ENTRY
), TRUE
,
1013 offsetof(CRL_ENTRY
, SerialNumber
.pbData
) };
1014 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
1016 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1017 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1019 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1020 pDecodePara
, pvStructInfo
, pcbStructInfo
,
1021 entries
? entries
->rgItems
: NULL
);
1022 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1026 static BOOL WINAPI
CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType
,
1027 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1028 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1030 struct AsnDecodeSequenceItem items
[] = {
1031 { ASN_INTEGER
, offsetof(CRL_INFO
, dwVersion
),
1032 CRYPT_AsnDecodeInt
, sizeof(DWORD
), TRUE
, FALSE
, 0, 0 },
1033 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, SignatureAlgorithm
),
1034 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1035 FALSE
, TRUE
, offsetof(CRL_INFO
, SignatureAlgorithm
.pszObjId
), 0 },
1036 { 0, offsetof(CRL_INFO
, Issuer
), CRYPT_AsnDecodeDerBlob
,
1037 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CRL_INFO
,
1039 { 0, offsetof(CRL_INFO
, ThisUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
1040 sizeof(FILETIME
), FALSE
, FALSE
, 0 },
1041 { 0, offsetof(CRL_INFO
, NextUpdate
), CRYPT_AsnDecodeChoiceOfTime
,
1042 sizeof(FILETIME
), TRUE
, FALSE
, 0 },
1043 { ASN_SEQUENCEOF
, offsetof(CRL_INFO
, cCRLEntry
),
1044 CRYPT_AsnDecodeCRLEntries
, sizeof(struct GenericArray
), TRUE
, TRUE
,
1045 offsetof(CRL_INFO
, rgCRLEntry
), 0 },
1046 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_INFO
, cExtension
),
1047 CRYPT_AsnDecodeCertExtensions
, sizeof(CERT_EXTENSIONS
), TRUE
, TRUE
,
1048 offsetof(CRL_INFO
, rgExtension
), 0 },
1052 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1053 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1055 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1056 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1057 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1059 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1063 static BOOL WINAPI
CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType
,
1064 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1065 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1069 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1070 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1074 PCERT_SIGNED_CONTENT_INFO signedCrl
= NULL
;
1077 /* First try to decode it as a signed crl. */
1078 ret
= CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType
, X509_CERT
,
1079 pbEncoded
, cbEncoded
, CRYPT_DECODE_ALLOC_FLAG
, NULL
,
1080 (BYTE
*)&signedCrl
, &size
);
1084 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1085 X509_CERT_CRL_TO_BE_SIGNED
, signedCrl
->ToBeSigned
.pbData
,
1086 signedCrl
->ToBeSigned
.cbData
, dwFlags
, pDecodePara
,
1087 pvStructInfo
, pcbStructInfo
);
1088 LocalFree(signedCrl
);
1090 /* Failing that, try it as an unsigned crl */
1094 ret
= CRYPT_AsnDecodeCRLInfo(dwCertEncodingType
,
1095 X509_CERT_CRL_TO_BE_SIGNED
, pbEncoded
, cbEncoded
,
1096 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
1101 SetLastError(STATUS_ACCESS_VIOLATION
);
1106 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
1110 static BOOL WINAPI
CRYPT_AsnDecodeOidInternal(DWORD dwCertEncodingType
,
1111 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1112 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1116 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1117 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1119 if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1123 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1125 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1126 DWORD bytesNeeded
= sizeof(LPSTR
);
1130 /* The largest possible string for the first two components
1131 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1136 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1137 pbEncoded
[1 + lenBytes
] / 40,
1138 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1140 bytesNeeded
+= strlen(firstTwo
) + 1;
1141 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1142 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1144 /* large enough for ".4000000" */
1148 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1155 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1158 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1165 snprintf(str
, sizeof(str
), ".%d", val
);
1166 bytesNeeded
+= strlen(str
);
1171 *pcbStructInfo
= bytesNeeded
;
1172 else if (*pcbStructInfo
< bytesNeeded
)
1174 *pcbStructInfo
= bytesNeeded
;
1175 SetLastError(ERROR_MORE_DATA
);
1183 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1186 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1187 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1189 pszObjId
+= strlen(pszObjId
);
1190 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1191 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1195 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1204 sprintf(pszObjId
, ".%d", val
);
1205 pszObjId
+= strlen(pszObjId
);
1209 *(LPSTR
*)pvStructInfo
= NULL
;
1210 *pcbStructInfo
= bytesNeeded
;
1217 /* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set
1220 static BOOL WINAPI
CRYPT_AsnDecodeExtension(DWORD dwCertEncodingType
,
1221 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1222 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1224 struct AsnDecodeSequenceItem items
[] = {
1225 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_EXTENSION
, pszObjId
),
1226 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1227 offsetof(CERT_EXTENSION
, pszObjId
), 0 },
1228 { ASN_BOOL
, offsetof(CERT_EXTENSION
, fCritical
), CRYPT_AsnDecodeBool
,
1229 sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
1230 { ASN_OCTETSTRING
, offsetof(CERT_EXTENSION
, Value
),
1231 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_OBJID_BLOB
), FALSE
, TRUE
,
1232 offsetof(CERT_EXTENSION
, Value
.pbData
) },
1235 PCERT_EXTENSION ext
= (PCERT_EXTENSION
)pvStructInfo
;
1237 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
, ext
,
1241 TRACE("ext->pszObjId is %p\n", ext
->pszObjId
);
1242 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1243 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1244 ext
, pcbStructInfo
, ext
? ext
->pszObjId
: NULL
);
1246 TRACE("ext->pszObjId is %p (%s)\n", ext
->pszObjId
,
1247 debugstr_a(ext
->pszObjId
));
1248 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1252 static BOOL WINAPI
CRYPT_AsnDecodeExtensionsInternal(DWORD dwCertEncodingType
,
1253 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1254 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1257 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1258 CRYPT_AsnDecodeExtension
, sizeof(CERT_EXTENSION
), TRUE
,
1259 offsetof(CERT_EXTENSION
, pszObjId
) };
1260 PCERT_EXTENSIONS exts
= (PCERT_EXTENSIONS
)pvStructInfo
;
1262 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1263 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1265 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1266 pDecodePara
, pvStructInfo
, pcbStructInfo
, exts
? exts
->rgExtension
: NULL
);
1270 static BOOL WINAPI
CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType
,
1271 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1272 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1278 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1279 lpszStructType
, pbEncoded
, cbEncoded
,
1280 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1281 if (ret
&& pvStructInfo
)
1283 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1284 pcbStructInfo
, *pcbStructInfo
);
1287 CERT_EXTENSIONS
*exts
;
1289 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1290 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1291 exts
= (CERT_EXTENSIONS
*)pvStructInfo
;
1292 exts
->rgExtension
= (CERT_EXTENSION
*)((BYTE
*)exts
+
1293 sizeof(CERT_EXTENSIONS
));
1294 ret
= CRYPT_AsnDecodeExtensionsInternal(dwCertEncodingType
,
1295 lpszStructType
, pbEncoded
, cbEncoded
,
1296 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1303 SetLastError(STATUS_ACCESS_VIOLATION
);
1310 /* Warning: this assumes the address of value->Value.pbData is already set, in
1311 * order to avoid overwriting memory. (In some cases, it may change it, if it
1312 * doesn't copy anything to memory.) Be sure to set it correctly!
1314 static BOOL WINAPI
CRYPT_AsnDecodeNameValueInternal(DWORD dwCertEncodingType
,
1315 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1316 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1320 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1322 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1324 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1325 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1327 switch (pbEncoded
[0])
1329 case ASN_OCTETSTRING
:
1330 valueType
= CERT_RDN_OCTET_STRING
;
1331 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1332 bytesNeeded
+= dataLen
;
1334 case ASN_NUMERICSTRING
:
1335 valueType
= CERT_RDN_NUMERIC_STRING
;
1336 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1337 bytesNeeded
+= dataLen
;
1339 case ASN_PRINTABLESTRING
:
1340 valueType
= CERT_RDN_PRINTABLE_STRING
;
1341 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1342 bytesNeeded
+= dataLen
;
1345 valueType
= CERT_RDN_IA5_STRING
;
1346 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1347 bytesNeeded
+= dataLen
;
1350 valueType
= CERT_RDN_T61_STRING
;
1351 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1352 bytesNeeded
+= dataLen
;
1354 case ASN_VIDEOTEXSTRING
:
1355 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1356 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1357 bytesNeeded
+= dataLen
;
1359 case ASN_GRAPHICSTRING
:
1360 valueType
= CERT_RDN_GRAPHIC_STRING
;
1361 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1362 bytesNeeded
+= dataLen
;
1364 case ASN_VISIBLESTRING
:
1365 valueType
= CERT_RDN_VISIBLE_STRING
;
1366 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1367 bytesNeeded
+= dataLen
;
1369 case ASN_GENERALSTRING
:
1370 valueType
= CERT_RDN_GENERAL_STRING
;
1371 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1372 bytesNeeded
+= dataLen
;
1374 case ASN_UNIVERSALSTRING
:
1375 FIXME("ASN_UNIVERSALSTRING: unimplemented\n");
1376 SetLastError(CRYPT_E_ASN1_BADTAG
);
1379 valueType
= CERT_RDN_BMP_STRING
;
1380 bytesNeeded
+= dataLen
;
1382 case ASN_UTF8STRING
:
1383 valueType
= CERT_RDN_UTF8_STRING
;
1384 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1385 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1388 SetLastError(CRYPT_E_ASN1_BADTAG
);
1393 *pcbStructInfo
= bytesNeeded
;
1394 else if (*pcbStructInfo
< bytesNeeded
)
1396 *pcbStructInfo
= bytesNeeded
;
1397 SetLastError(ERROR_MORE_DATA
);
1402 *pcbStructInfo
= bytesNeeded
;
1403 value
->dwValueType
= valueType
;
1408 assert(value
->Value
.pbData
);
1409 switch (pbEncoded
[0])
1411 case ASN_OCTETSTRING
:
1412 case ASN_NUMERICSTRING
:
1413 case ASN_PRINTABLESTRING
:
1416 case ASN_VIDEOTEXSTRING
:
1417 case ASN_GRAPHICSTRING
:
1418 case ASN_VISIBLESTRING
:
1419 case ASN_GENERALSTRING
:
1420 value
->Value
.cbData
= dataLen
;
1423 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1424 memcpy(value
->Value
.pbData
,
1425 pbEncoded
+ 1 + lenBytes
, dataLen
);
1427 value
->Value
.pbData
= (LPBYTE
)pbEncoded
+ 1 +
1433 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1435 value
->Value
.cbData
= dataLen
;
1436 for (i
= 0; i
< dataLen
/ 2; i
++)
1437 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1438 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1441 case ASN_UTF8STRING
:
1443 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1445 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1446 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1447 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1454 value
->Value
.cbData
= 0;
1455 value
->Value
.pbData
= NULL
;
1462 static BOOL WINAPI
CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType
,
1463 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1464 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1470 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1471 lpszStructType
, pbEncoded
, cbEncoded
,
1472 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1473 if (ret
&& pvStructInfo
)
1475 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1476 pcbStructInfo
, *pcbStructInfo
);
1479 CERT_NAME_VALUE
*value
;
1481 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1482 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1483 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1484 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1485 ret
= CRYPT_AsnDecodeNameValueInternal(dwCertEncodingType
,
1486 lpszStructType
, pbEncoded
, cbEncoded
,
1487 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1494 SetLastError(STATUS_ACCESS_VIOLATION
);
1501 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValueInternal(
1502 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1503 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1504 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1508 CERT_NAME_VALUE
*value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1510 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1512 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1513 DWORD bytesNeeded
= sizeof(CERT_NAME_VALUE
), valueType
;
1515 switch (pbEncoded
[0])
1517 case ASN_NUMERICSTRING
:
1518 valueType
= CERT_RDN_NUMERIC_STRING
;
1519 bytesNeeded
+= dataLen
* 2;
1521 case ASN_PRINTABLESTRING
:
1522 valueType
= CERT_RDN_PRINTABLE_STRING
;
1523 bytesNeeded
+= dataLen
* 2;
1526 valueType
= CERT_RDN_IA5_STRING
;
1527 bytesNeeded
+= dataLen
* 2;
1530 valueType
= CERT_RDN_T61_STRING
;
1531 bytesNeeded
+= dataLen
* 2;
1533 case ASN_VIDEOTEXSTRING
:
1534 valueType
= CERT_RDN_VIDEOTEX_STRING
;
1535 bytesNeeded
+= dataLen
* 2;
1537 case ASN_GRAPHICSTRING
:
1538 valueType
= CERT_RDN_GRAPHIC_STRING
;
1539 bytesNeeded
+= dataLen
* 2;
1541 case ASN_VISIBLESTRING
:
1542 valueType
= CERT_RDN_VISIBLE_STRING
;
1543 bytesNeeded
+= dataLen
* 2;
1545 case ASN_GENERALSTRING
:
1546 valueType
= CERT_RDN_GENERAL_STRING
;
1547 bytesNeeded
+= dataLen
* 2;
1549 case ASN_UNIVERSALSTRING
:
1550 valueType
= CERT_RDN_UNIVERSAL_STRING
;
1551 bytesNeeded
+= dataLen
/ 2;
1554 valueType
= CERT_RDN_BMP_STRING
;
1555 bytesNeeded
+= dataLen
;
1557 case ASN_UTF8STRING
:
1558 valueType
= CERT_RDN_UTF8_STRING
;
1559 bytesNeeded
+= MultiByteToWideChar(CP_UTF8
, 0,
1560 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
, NULL
, 0) * 2;
1563 SetLastError(CRYPT_E_ASN1_BADTAG
);
1568 *pcbStructInfo
= bytesNeeded
;
1569 else if (*pcbStructInfo
< bytesNeeded
)
1571 *pcbStructInfo
= bytesNeeded
;
1572 SetLastError(ERROR_MORE_DATA
);
1577 *pcbStructInfo
= bytesNeeded
;
1578 value
->dwValueType
= valueType
;
1582 LPWSTR str
= (LPWSTR
)value
->Value
.pbData
;
1584 assert(value
->Value
.pbData
);
1585 switch (pbEncoded
[0])
1587 case ASN_NUMERICSTRING
:
1588 case ASN_PRINTABLESTRING
:
1591 case ASN_VIDEOTEXSTRING
:
1592 case ASN_GRAPHICSTRING
:
1593 case ASN_VISIBLESTRING
:
1594 case ASN_GENERALSTRING
:
1595 value
->Value
.cbData
= dataLen
* 2;
1596 for (i
= 0; i
< dataLen
; i
++)
1597 str
[i
] = pbEncoded
[1 + lenBytes
+ i
];
1599 case ASN_UNIVERSALSTRING
:
1600 value
->Value
.cbData
= dataLen
/ 2;
1601 for (i
= 0; i
< dataLen
/ 4; i
++)
1602 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
+ 2] << 8)
1603 | pbEncoded
[1 + lenBytes
+ 2 * i
+ 3];
1606 value
->Value
.cbData
= dataLen
;
1607 for (i
= 0; i
< dataLen
/ 2; i
++)
1608 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1609 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1611 case ASN_UTF8STRING
:
1612 value
->Value
.cbData
= MultiByteToWideChar(CP_UTF8
, 0,
1613 (LPCSTR
)pbEncoded
+ 1 + lenBytes
, dataLen
,
1614 str
, bytesNeeded
- sizeof(CERT_NAME_VALUE
)) * 2;
1620 value
->Value
.cbData
= 0;
1621 value
->Value
.pbData
= NULL
;
1628 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType
,
1629 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1630 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1636 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(dwCertEncodingType
,
1637 lpszStructType
, pbEncoded
, cbEncoded
,
1638 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
1639 if (ret
&& pvStructInfo
)
1641 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
1642 pcbStructInfo
, *pcbStructInfo
);
1645 CERT_NAME_VALUE
*value
;
1647 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1648 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1649 value
= (CERT_NAME_VALUE
*)pvStructInfo
;
1650 value
->Value
.pbData
= ((BYTE
*)value
+ sizeof(CERT_NAME_VALUE
));
1651 ret
= CRYPT_AsnDecodeUnicodeNameValueInternal(
1652 dwCertEncodingType
, lpszStructType
, pbEncoded
, cbEncoded
,
1653 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1660 SetLastError(STATUS_ACCESS_VIOLATION
);
1667 static BOOL WINAPI
CRYPT_AsnDecodeRdnAttr(DWORD dwCertEncodingType
,
1668 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1669 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1672 struct AsnDecodeSequenceItem items
[] = {
1673 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1674 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1675 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1676 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1677 CRYPT_AsnDecodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1678 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1680 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1682 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1683 pvStructInfo
, *pcbStructInfo
);
1686 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1687 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1688 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1689 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1692 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1693 debugstr_a(attr
->pszObjId
));
1694 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1696 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1700 static BOOL WINAPI
CRYPT_AsnDecodeRdn(DWORD dwCertEncodingType
,
1701 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1702 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1705 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1706 CRYPT_AsnDecodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1707 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1708 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1710 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1711 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1715 static BOOL WINAPI
CRYPT_AsnDecodeName(DWORD dwCertEncodingType
,
1716 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1717 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1723 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1724 CRYPT_AsnDecodeRdn
, sizeof(CERT_RDN
), TRUE
,
1725 offsetof(CERT_RDN
, rgRDNAttr
) };
1727 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1728 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1732 SetLastError(STATUS_ACCESS_VIOLATION
);
1739 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdnAttr(DWORD dwCertEncodingType
,
1740 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1741 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1744 struct AsnDecodeSequenceItem items
[] = {
1745 { ASN_OBJECTIDENTIFIER
, offsetof(CERT_RDN_ATTR
, pszObjId
),
1746 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1747 offsetof(CERT_RDN_ATTR
, pszObjId
), 0 },
1748 { 0, offsetof(CERT_RDN_ATTR
, dwValueType
),
1749 CRYPT_AsnDecodeUnicodeNameValueInternal
, sizeof(CERT_NAME_VALUE
),
1750 FALSE
, TRUE
, offsetof(CERT_RDN_ATTR
, Value
.pbData
), 0 },
1752 CERT_RDN_ATTR
*attr
= (CERT_RDN_ATTR
*)pvStructInfo
;
1754 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1755 pvStructInfo
, *pcbStructInfo
);
1758 TRACE("attr->pszObjId is %p\n", attr
->pszObjId
);
1759 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
1760 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
, NULL
,
1761 attr
, pcbStructInfo
, attr
? attr
->pszObjId
: NULL
);
1764 TRACE("attr->pszObjId is %p (%s)\n", attr
->pszObjId
,
1765 debugstr_a(attr
->pszObjId
));
1766 TRACE("attr->dwValueType is %d\n", attr
->dwValueType
);
1768 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1772 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeRdn(DWORD dwCertEncodingType
,
1773 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1774 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1777 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
1778 CRYPT_AsnDecodeUnicodeRdnAttr
, sizeof(CERT_RDN_ATTR
), TRUE
,
1779 offsetof(CERT_RDN_ATTR
, pszObjId
) };
1780 PCERT_RDN rdn
= (PCERT_RDN
)pvStructInfo
;
1782 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1783 pDecodePara
, pvStructInfo
, pcbStructInfo
, rdn
? rdn
->rgRDNAttr
: NULL
);
1787 static BOOL WINAPI
CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType
,
1788 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1789 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1795 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
1796 CRYPT_AsnDecodeUnicodeRdn
, sizeof(CERT_RDN
), TRUE
,
1797 offsetof(CERT_RDN
, rgRDNAttr
) };
1799 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1800 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
1804 SetLastError(STATUS_ACCESS_VIOLATION
);
1811 static BOOL WINAPI
CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType
,
1812 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1813 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1816 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
1818 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1819 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1821 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1822 bytesNeeded
+= cbEncoded
;
1824 *pcbStructInfo
= bytesNeeded
;
1825 else if (*pcbStructInfo
< bytesNeeded
)
1827 SetLastError(ERROR_MORE_DATA
);
1828 *pcbStructInfo
= bytesNeeded
;
1833 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1835 *pcbStructInfo
= bytesNeeded
;
1836 blob
->cbData
= cbEncoded
;
1837 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1838 blob
->pbData
= (LPBYTE
)pbEncoded
;
1841 assert(blob
->pbData
);
1842 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1848 static BOOL WINAPI
CRYPT_DecodeDERArray(DWORD dwCertEncodingType
,
1849 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1850 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1853 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodeCopyBytes
,
1854 sizeof(CRYPT_DER_BLOB
), TRUE
, offsetof(CRYPT_DER_BLOB
, pbData
) };
1855 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
1857 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1858 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1860 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1861 pDecodePara
, pvStructInfo
, pcbStructInfo
, array
? array
->rgItems
: NULL
);
1865 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType
,
1866 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1867 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1873 struct AsnDecodeSequenceItem items
[] = {
1874 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
),
1875 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1876 offsetof(CRYPT_ATTRIBUTE
, pszObjId
), 0 },
1877 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_ATTRIBUTE
, cValue
),
1878 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), FALSE
, TRUE
,
1879 offsetof(CRYPT_ATTRIBUTE
, rgValue
), 0 },
1881 PCRYPT_ATTRIBUTE attr
= (PCRYPT_ATTRIBUTE
)pvStructInfo
;
1883 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1884 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1885 pDecodePara
, pvStructInfo
, pcbStructInfo
, attr
? attr
->pszObjId
:
1890 SetLastError(STATUS_ACCESS_VIOLATION
);
1893 TRACE("returning %d\n", ret
);
1897 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributesInternal(
1898 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
1899 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
1900 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1902 struct AsnArrayDescriptor arrayDesc
= { 0, CRYPT_AsnDecodePKCSAttribute
,
1903 sizeof(CRYPT_ATTRIBUTE
), TRUE
, offsetof(CRYPT_ATTRIBUTE
, pszObjId
) };
1904 PCRYPT_ATTRIBUTES attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
1907 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
1908 pDecodePara
, pvStructInfo
, pcbStructInfo
, attrs
? attrs
->rgAttr
:
1913 static BOOL WINAPI
CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType
,
1914 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1915 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1919 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1920 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1927 SetLastError(CRYPT_E_ASN1_EOD
);
1928 else if (pbEncoded
[0] != (ASN_CONSTRUCTOR
| ASN_SETOF
))
1929 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1930 else if ((ret
= CRYPT_AsnDecodePKCSAttributesInternal(
1931 dwCertEncodingType
, lpszStructType
, pbEncoded
, cbEncoded
,
1932 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
1935 *pcbStructInfo
= bytesNeeded
;
1936 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
1937 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
1939 PCRYPT_ATTRIBUTES attrs
;
1941 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
1942 pvStructInfo
= *(BYTE
**)pvStructInfo
;
1943 attrs
= (PCRYPT_ATTRIBUTES
)pvStructInfo
;
1944 attrs
->rgAttr
= (PCRYPT_ATTRIBUTE
)((BYTE
*)pvStructInfo
+
1945 sizeof(CRYPT_ATTRIBUTES
));
1946 ret
= CRYPT_AsnDecodePKCSAttributesInternal(dwCertEncodingType
,
1947 lpszStructType
, pbEncoded
, cbEncoded
,
1948 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
1955 SetLastError(STATUS_ACCESS_VIOLATION
);
1958 TRACE("returning %d\n", ret
);
1962 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
1963 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1964 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1966 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
1967 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
1969 struct AsnDecodeSequenceItem items
[] = {
1970 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
1971 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
1972 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
1973 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
1974 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
1975 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
1978 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1979 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
1981 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1982 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1983 pDecodePara
, pvStructInfo
, pcbStructInfo
, algo
? algo
->pszObjId
: NULL
);
1984 if (ret
&& pvStructInfo
)
1986 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
1987 debugstr_a(algo
->pszObjId
));
1992 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfoInternal(DWORD dwCertEncodingType
,
1993 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1994 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1997 struct AsnDecodeSequenceItem items
[] = {
1998 { ASN_SEQUENCEOF
, offsetof(CERT_PUBLIC_KEY_INFO
, Algorithm
),
1999 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2000 FALSE
, TRUE
, offsetof(CERT_PUBLIC_KEY_INFO
,
2001 Algorithm
.pszObjId
) },
2002 { ASN_BITSTRING
, offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
),
2003 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2004 offsetof(CERT_PUBLIC_KEY_INFO
, PublicKey
.pbData
) },
2006 PCERT_PUBLIC_KEY_INFO info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2008 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2009 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2010 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
?
2011 info
->Algorithm
.Parameters
.pbData
: NULL
);
2015 static BOOL WINAPI
CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType
,
2016 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2017 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2025 if ((ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
2026 lpszStructType
, pbEncoded
, cbEncoded
,
2027 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2030 *pcbStructInfo
= bytesNeeded
;
2031 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2032 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2034 PCERT_PUBLIC_KEY_INFO info
;
2036 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2037 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2038 info
= (PCERT_PUBLIC_KEY_INFO
)pvStructInfo
;
2039 info
->Algorithm
.Parameters
.pbData
= (BYTE
*)pvStructInfo
+
2040 sizeof(CERT_PUBLIC_KEY_INFO
);
2041 ret
= CRYPT_AsnDecodePubKeyInfoInternal(dwCertEncodingType
,
2042 lpszStructType
, pbEncoded
, cbEncoded
,
2043 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2050 SetLastError(STATUS_ACCESS_VIOLATION
);
2057 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
2058 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2059 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2065 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2068 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2070 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2073 if (pbEncoded
[1] > 1)
2075 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2080 *pcbStructInfo
= sizeof(BOOL
);
2083 else if (*pcbStructInfo
< sizeof(BOOL
))
2085 *pcbStructInfo
= sizeof(BOOL
);
2086 SetLastError(ERROR_MORE_DATA
);
2091 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2094 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2098 static BOOL WINAPI
CRYPT_AsnDecodeAltNameEntry(DWORD dwCertEncodingType
,
2099 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2100 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2102 PCERT_ALT_NAME_ENTRY entry
= (PCERT_ALT_NAME_ENTRY
)pvStructInfo
;
2103 DWORD dataLen
, lenBytes
, bytesNeeded
= sizeof(CERT_ALT_NAME_ENTRY
);
2106 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2107 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2111 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2114 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2115 if (1 + lenBytes
> cbEncoded
)
2117 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2120 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2122 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2124 case 1: /* rfc822Name */
2125 case 2: /* dNSName */
2126 case 6: /* uniformResourceIdentifier */
2127 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
2129 case 7: /* iPAddress */
2130 bytesNeeded
+= dataLen
;
2132 case 8: /* registeredID */
2133 /* FIXME: decode as OID */
2134 case 0: /* otherName */
2135 case 4: /* directoryName */
2136 FIXME("%d: stub\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2137 SetLastError(CRYPT_E_ASN1_BADTAG
);
2140 case 3: /* x400Address, unimplemented */
2141 case 5: /* ediPartyName, unimplemented */
2142 TRACE("type %d unimplemented\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2143 SetLastError(CRYPT_E_ASN1_BADTAG
);
2147 TRACE("type %d bad\n", pbEncoded
[0] & ASN_TYPE_MASK
);
2148 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2154 *pcbStructInfo
= bytesNeeded
;
2155 else if (*pcbStructInfo
< bytesNeeded
)
2157 *pcbStructInfo
= bytesNeeded
;
2158 SetLastError(ERROR_MORE_DATA
);
2163 *pcbStructInfo
= bytesNeeded
;
2164 /* MS used values one greater than the asn1 ones.. sigh */
2165 entry
->dwAltNameChoice
= (pbEncoded
[0] & 0x7f) + 1;
2166 switch (pbEncoded
[0] & ASN_TYPE_MASK
)
2168 case 1: /* rfc822Name */
2169 case 2: /* dNSName */
2170 case 6: /* uniformResourceIdentifier */
2174 for (i
= 0; i
< dataLen
; i
++)
2175 entry
->u
.pwszURL
[i
] =
2176 (WCHAR
)pbEncoded
[1 + lenBytes
+ i
];
2177 entry
->u
.pwszURL
[i
] = 0;
2178 TRACE("URL is %p (%s)\n", entry
->u
.pwszURL
,
2179 debugstr_w(entry
->u
.pwszURL
));
2182 case 7: /* iPAddress */
2183 /* The next data pointer is in the pwszURL spot, that is,
2184 * the first 4 bytes. Need to move it to the next spot.
2186 entry
->u
.IPAddress
.pbData
= (LPBYTE
)entry
->u
.pwszURL
;
2187 entry
->u
.IPAddress
.cbData
= dataLen
;
2188 memcpy(entry
->u
.IPAddress
.pbData
, pbEncoded
+ 1 + lenBytes
,
2198 static BOOL WINAPI
CRYPT_AsnDecodeAltNameInternal(DWORD dwCertEncodingType
,
2199 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2200 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2203 struct AsnArrayDescriptor arrayDesc
= { 0,
2204 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2205 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2206 PCERT_ALT_NAME_INFO info
= (PCERT_ALT_NAME_INFO
)pvStructInfo
;
2208 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2209 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2212 TRACE("info->rgAltEntry is %p\n", info
->rgAltEntry
);
2213 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2214 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->rgAltEntry
: NULL
);
2218 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType
,
2219 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2220 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2226 struct AsnDecodeSequenceItem items
[] = {
2227 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
),
2228 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_DATA_BLOB
),
2229 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID_INFO
, KeyId
.pbData
), 0 },
2230 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2231 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
),
2232 CRYPT_AsnDecodeOctetsInternal
, sizeof(CERT_NAME_BLOB
), TRUE
, TRUE
,
2233 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertIssuer
.pbData
), 0 },
2234 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO
,
2235 CertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2236 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2237 offsetof(CERT_AUTHORITY_KEY_ID_INFO
, CertSerialNumber
.pbData
), 0 },
2240 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2241 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2242 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2246 SetLastError(STATUS_ACCESS_VIOLATION
);
2253 static BOOL WINAPI
CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType
,
2254 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2255 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2261 struct AsnDecodeSequenceItem items
[] = {
2262 { ASN_CONTEXT
| 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
),
2263 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_DATA_BLOB
),
2264 TRUE
, TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, KeyId
.pbData
), 0 },
2265 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 1,
2266 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
, AuthorityCertIssuer
),
2267 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
,
2268 TRUE
, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2269 AuthorityCertIssuer
.rgAltEntry
), 0 },
2270 { ASN_CONTEXT
| 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2271 AuthorityCertSerialNumber
), CRYPT_AsnDecodeIntegerInternal
,
2272 sizeof(CRYPT_INTEGER_BLOB
), TRUE
, TRUE
,
2273 offsetof(CERT_AUTHORITY_KEY_ID2_INFO
,
2274 AuthorityCertSerialNumber
.pbData
), 0 },
2277 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2278 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2279 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2283 SetLastError(STATUS_ACCESS_VIOLATION
);
2290 static BOOL WINAPI
CRYPT_AsnDecodePKCSContent(DWORD dwCertEncodingType
,
2291 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2292 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2297 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2298 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2300 /* The caller has already checked the tag, no need to check it again.
2301 * Check the outer length is valid by calling CRYPT_GetLen:
2303 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2305 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2308 pbEncoded
+= 1 + lenBytes
;
2309 /* Check the inner length is valid by calling CRYPT_GetLen again: */
2310 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &innerLen
)))
2312 ret
= CRYPT_AsnDecodeCopyBytes(dwCertEncodingType
, NULL
,
2313 pbEncoded
, dataLen
, dwFlags
, pDecodePara
, pvStructInfo
,
2320 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfoInternal(
2321 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
2322 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2323 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2325 CRYPT_CONTENT_INFO
*info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2326 struct AsnDecodeSequenceItem items
[] = {
2327 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_CONTENT_INFO
, pszObjId
),
2328 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), FALSE
, TRUE
,
2329 offsetof(CRYPT_CONTENT_INFO
, pszObjId
), 0 },
2330 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0,
2331 offsetof(CRYPT_CONTENT_INFO
, Content
), CRYPT_AsnDecodePKCSContent
,
2332 sizeof(CRYPT_DER_BLOB
), TRUE
, TRUE
,
2333 offsetof(CRYPT_CONTENT_INFO
, Content
.pbData
), 0 },
2337 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2338 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2340 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2341 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2342 pDecodePara
, pvStructInfo
, pcbStructInfo
, info
? info
->pszObjId
: NULL
);
2346 static BOOL WINAPI
CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType
,
2347 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2348 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2352 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2353 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2357 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(dwCertEncodingType
,
2358 lpszStructType
, pbEncoded
, cbEncoded
,
2359 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
2360 if (ret
&& pvStructInfo
)
2362 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
2363 pcbStructInfo
, *pcbStructInfo
);
2366 CRYPT_CONTENT_INFO
*info
;
2368 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2369 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2370 info
= (CRYPT_CONTENT_INFO
*)pvStructInfo
;
2371 info
->pszObjId
= (LPSTR
)((BYTE
*)info
+
2372 sizeof(CRYPT_CONTENT_INFO
));
2373 ret
= CRYPT_AsnDecodePKCSContentInfoInternal(dwCertEncodingType
,
2374 lpszStructType
, pbEncoded
, cbEncoded
,
2375 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2382 SetLastError(STATUS_ACCESS_VIOLATION
);
2388 BOOL
CRYPT_AsnDecodePKCSDigestedData(const BYTE
*pbEncoded
, DWORD cbEncoded
,
2389 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
2390 CRYPT_DIGESTED_DATA
*digestedData
, DWORD
*pcbDigestedData
)
2393 struct AsnDecodeSequenceItem items
[] = {
2394 { ASN_INTEGER
, offsetof(CRYPT_DIGESTED_DATA
, version
), CRYPT_AsnDecodeInt
,
2395 sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2396 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
),
2397 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
2398 FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
, DigestAlgorithm
.pszObjId
),
2400 { ASN_SEQUENCEOF
, offsetof(CRYPT_DIGESTED_DATA
, ContentInfo
),
2401 CRYPT_AsnDecodePKCSContentInfoInternal
,
2402 sizeof(CRYPT_CONTENT_INFO
), FALSE
, TRUE
, offsetof(CRYPT_DIGESTED_DATA
,
2403 ContentInfo
.pszObjId
), 0 },
2404 { ASN_OCTETSTRING
, offsetof(CRYPT_DIGESTED_DATA
, hash
),
2405 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_HASH_BLOB
), FALSE
, TRUE
,
2406 offsetof(CRYPT_DIGESTED_DATA
, hash
.pbData
), 0 },
2409 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
2410 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2411 pDecodePara
, digestedData
, pcbDigestedData
, NULL
);
2415 static BOOL WINAPI
CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType
,
2416 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2417 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2421 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2422 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2426 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2427 CRYPT_AsnDecodeAltNameEntry
, sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
2428 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
2430 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2431 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2435 SetLastError(STATUS_ACCESS_VIOLATION
);
2442 struct PATH_LEN_CONSTRAINT
2444 BOOL fPathLenConstraint
;
2445 DWORD dwPathLenConstraint
;
2448 static BOOL WINAPI
CRYPT_AsnDecodePathLenConstraint(DWORD dwCertEncodingType
,
2449 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2450 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2454 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2455 pvStructInfo
, *pcbStructInfo
);
2459 if (pbEncoded
[0] == ASN_INTEGER
)
2461 DWORD bytesNeeded
= sizeof(struct PATH_LEN_CONSTRAINT
);
2464 *pcbStructInfo
= bytesNeeded
;
2465 else if (*pcbStructInfo
< bytesNeeded
)
2467 SetLastError(ERROR_MORE_DATA
);
2468 *pcbStructInfo
= bytesNeeded
;
2473 struct PATH_LEN_CONSTRAINT
*constraint
=
2474 (struct PATH_LEN_CONSTRAINT
*)pvStructInfo
;
2475 DWORD size
= sizeof(constraint
->dwPathLenConstraint
);
2477 ret
= CRYPT_AsnDecodeInt(dwCertEncodingType
, X509_INTEGER
,
2478 pbEncoded
, cbEncoded
, 0, NULL
,
2479 &constraint
->dwPathLenConstraint
, &size
);
2481 constraint
->fPathLenConstraint
= TRUE
;
2482 TRACE("got an int, dwPathLenConstraint is %d\n",
2483 constraint
->dwPathLenConstraint
);
2488 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2492 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2496 static BOOL WINAPI
CRYPT_AsnDecodeSubtreeConstraints(DWORD dwCertEncodingType
,
2497 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2498 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2501 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
2502 CRYPT_AsnDecodeCopyBytes
, sizeof(CERT_NAME_BLOB
), TRUE
,
2503 offsetof(CERT_NAME_BLOB
, pbData
) };
2504 struct GenericArray
*entries
= (struct GenericArray
*)pvStructInfo
;
2506 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2507 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2509 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
2510 pDecodePara
, pvStructInfo
, pcbStructInfo
,
2511 entries
? entries
->rgItems
: NULL
);
2512 TRACE("Returning %d (%08x)\n", ret
, GetLastError());
2516 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType
,
2517 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2518 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2524 struct AsnDecodeSequenceItem items
[] = {
2525 { ASN_BITSTRING
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
),
2526 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), FALSE
, TRUE
,
2527 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, SubjectType
.pbData
), 0 },
2528 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2529 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2530 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2531 { ASN_SEQUENCEOF
, offsetof(CERT_BASIC_CONSTRAINTS_INFO
,
2532 cSubtreesConstraint
), CRYPT_AsnDecodeSubtreeConstraints
,
2533 sizeof(struct GenericArray
), TRUE
, TRUE
,
2534 offsetof(CERT_BASIC_CONSTRAINTS_INFO
, rgSubtreesConstraint
), 0 },
2537 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2538 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2539 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2543 SetLastError(STATUS_ACCESS_VIOLATION
);
2550 static BOOL WINAPI
CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType
,
2551 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2552 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2558 struct AsnDecodeSequenceItem items
[] = {
2559 { ASN_BOOL
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
, fCA
),
2560 CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0, 0 },
2561 { ASN_INTEGER
, offsetof(CERT_BASIC_CONSTRAINTS2_INFO
,
2562 fPathLenConstraint
), CRYPT_AsnDecodePathLenConstraint
,
2563 sizeof(struct PATH_LEN_CONSTRAINT
), TRUE
, FALSE
, 0, 0 },
2566 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2567 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2568 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
2572 SetLastError(STATUS_ACCESS_VIOLATION
);
2579 #define RSA1_MAGIC 0x31415352
2581 struct DECODED_RSA_PUB_KEY
2584 CRYPT_INTEGER_BLOB modulus
;
2587 static BOOL WINAPI
CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType
,
2588 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2589 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2595 struct AsnDecodeSequenceItem items
[] = {
2596 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
),
2597 CRYPT_AsnDecodeUnsignedIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
),
2598 FALSE
, TRUE
, offsetof(struct DECODED_RSA_PUB_KEY
, modulus
.pbData
),
2600 { ASN_INTEGER
, offsetof(struct DECODED_RSA_PUB_KEY
, pubexp
),
2601 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2603 struct DECODED_RSA_PUB_KEY
*decodedKey
= NULL
;
2606 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2607 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
2608 CRYPT_DECODE_ALLOC_FLAG
, NULL
, &decodedKey
, &size
, NULL
);
2611 DWORD bytesNeeded
= sizeof(BLOBHEADER
) + sizeof(RSAPUBKEY
) +
2612 decodedKey
->modulus
.cbData
;
2616 *pcbStructInfo
= bytesNeeded
;
2619 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2620 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2623 RSAPUBKEY
*rsaPubKey
;
2625 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2626 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2627 hdr
= (BLOBHEADER
*)pvStructInfo
;
2628 hdr
->bType
= PUBLICKEYBLOB
;
2629 hdr
->bVersion
= CUR_BLOB_VERSION
;
2631 hdr
->aiKeyAlg
= CALG_RSA_KEYX
;
2632 rsaPubKey
= (RSAPUBKEY
*)((BYTE
*)pvStructInfo
+
2633 sizeof(BLOBHEADER
));
2634 rsaPubKey
->magic
= RSA1_MAGIC
;
2635 rsaPubKey
->pubexp
= decodedKey
->pubexp
;
2636 rsaPubKey
->bitlen
= decodedKey
->modulus
.cbData
* 8;
2637 memcpy((BYTE
*)pvStructInfo
+ sizeof(BLOBHEADER
) +
2638 sizeof(RSAPUBKEY
), decodedKey
->modulus
.pbData
,
2639 decodedKey
->modulus
.cbData
);
2641 LocalFree(decodedKey
);
2646 SetLastError(STATUS_ACCESS_VIOLATION
);
2653 static BOOL WINAPI
CRYPT_AsnDecodeOctetsInternal(DWORD dwCertEncodingType
,
2654 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2655 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2658 DWORD bytesNeeded
, dataLen
;
2660 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2661 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2663 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2665 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2666 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
2668 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
2670 *pcbStructInfo
= bytesNeeded
;
2671 else if (*pcbStructInfo
< bytesNeeded
)
2673 SetLastError(ERROR_MORE_DATA
);
2674 *pcbStructInfo
= bytesNeeded
;
2679 CRYPT_DATA_BLOB
*blob
;
2680 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2682 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2683 blob
->cbData
= dataLen
;
2684 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2685 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
2688 assert(blob
->pbData
);
2690 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
2698 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
2699 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2700 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2704 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2705 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2713 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2716 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
2718 SetLastError(CRYPT_E_ASN1_BADTAG
);
2721 else if ((ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2722 lpszStructType
, pbEncoded
, cbEncoded
,
2723 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2726 *pcbStructInfo
= bytesNeeded
;
2727 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2728 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2730 CRYPT_DATA_BLOB
*blob
;
2732 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2733 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2734 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
2735 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_DATA_BLOB
);
2736 ret
= CRYPT_AsnDecodeOctetsInternal(dwCertEncodingType
,
2737 lpszStructType
, pbEncoded
, cbEncoded
,
2738 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2745 SetLastError(STATUS_ACCESS_VIOLATION
);
2752 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
2753 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2754 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2758 TRACE("(%p, %d, 0x%08x, %p, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2759 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
2761 if (pbEncoded
[0] == ASN_BITSTRING
)
2763 DWORD bytesNeeded
, dataLen
;
2765 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2767 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2768 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
2770 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
2772 *pcbStructInfo
= bytesNeeded
;
2773 else if (*pcbStructInfo
< bytesNeeded
)
2775 *pcbStructInfo
= bytesNeeded
;
2776 SetLastError(ERROR_MORE_DATA
);
2781 CRYPT_BIT_BLOB
*blob
;
2783 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2784 blob
->cbData
= dataLen
- 1;
2785 blob
->cUnusedBits
= *(pbEncoded
+ 1 +
2786 GET_LEN_BYTES(pbEncoded
[1]));
2787 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
2789 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 +
2790 GET_LEN_BYTES(pbEncoded
[1]);
2794 assert(blob
->pbData
);
2797 BYTE mask
= 0xff << blob
->cUnusedBits
;
2799 memcpy(blob
->pbData
, pbEncoded
+ 2 +
2800 GET_LEN_BYTES(pbEncoded
[1]), blob
->cbData
);
2801 blob
->pbData
[blob
->cbData
- 1] &= mask
;
2809 SetLastError(CRYPT_E_ASN1_BADTAG
);
2812 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2816 static BOOL WINAPI
CRYPT_AsnDecodeBits(DWORD dwCertEncodingType
,
2817 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2818 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2822 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded
, cbEncoded
, dwFlags
,
2823 pDecodePara
, pvStructInfo
, pcbStructInfo
);
2829 if ((ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2830 lpszStructType
, pbEncoded
, cbEncoded
,
2831 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
2834 *pcbStructInfo
= bytesNeeded
;
2835 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2836 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2838 CRYPT_BIT_BLOB
*blob
;
2840 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2841 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2842 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
2843 blob
->pbData
= (BYTE
*)pvStructInfo
+ sizeof(CRYPT_BIT_BLOB
);
2844 ret
= CRYPT_AsnDecodeBitsInternal(dwCertEncodingType
,
2845 lpszStructType
, pbEncoded
, cbEncoded
,
2846 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
2853 SetLastError(STATUS_ACCESS_VIOLATION
);
2857 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2861 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
2862 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2863 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2869 *pcbStructInfo
= sizeof(int);
2874 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
2875 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
2876 DWORD size
= sizeof(buf
);
2878 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
2879 if (pbEncoded
[0] != ASN_INTEGER
)
2881 SetLastError(CRYPT_E_ASN1_BADTAG
);
2885 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2886 X509_MULTI_BYTE_INTEGER
, pbEncoded
, cbEncoded
, 0, NULL
, &buf
,
2890 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2891 pvStructInfo
, pcbStructInfo
, sizeof(int))))
2895 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2896 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2897 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
2899 /* initialize to a negative value to sign-extend */
2904 for (i
= 0; i
< blob
->cbData
; i
++)
2907 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
2909 memcpy(pvStructInfo
, &val
, sizeof(int));
2912 else if (GetLastError() == ERROR_MORE_DATA
)
2913 SetLastError(CRYPT_E_ASN1_LARGE
);
2917 SetLastError(STATUS_ACCESS_VIOLATION
);
2924 static BOOL WINAPI
CRYPT_AsnDecodeIntegerInternal(DWORD dwCertEncodingType
,
2925 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2926 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2929 DWORD bytesNeeded
, dataLen
;
2931 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2933 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2935 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2937 *pcbStructInfo
= bytesNeeded
;
2938 else if (*pcbStructInfo
< bytesNeeded
)
2940 *pcbStructInfo
= bytesNeeded
;
2941 SetLastError(ERROR_MORE_DATA
);
2946 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2948 blob
->cbData
= dataLen
;
2949 assert(blob
->pbData
);
2954 for (i
= 0; i
< blob
->cbData
; i
++)
2956 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2965 static BOOL WINAPI
CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType
,
2966 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2967 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2975 if (pbEncoded
[0] != ASN_INTEGER
)
2977 SetLastError(CRYPT_E_ASN1_BADTAG
);
2981 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2982 lpszStructType
, pbEncoded
, cbEncoded
,
2983 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
);
2987 *pcbStructInfo
= bytesNeeded
;
2988 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
2989 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
2991 CRYPT_INTEGER_BLOB
*blob
;
2993 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
2994 pvStructInfo
= *(BYTE
**)pvStructInfo
;
2995 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2996 blob
->pbData
= (BYTE
*)pvStructInfo
+
2997 sizeof(CRYPT_INTEGER_BLOB
);
2998 ret
= CRYPT_AsnDecodeIntegerInternal(dwCertEncodingType
,
2999 lpszStructType
, pbEncoded
, cbEncoded
,
3000 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3007 SetLastError(STATUS_ACCESS_VIOLATION
);
3014 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedIntegerInternal(
3015 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3016 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3017 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3021 if (pbEncoded
[0] == ASN_INTEGER
)
3023 DWORD bytesNeeded
, dataLen
;
3025 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3027 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3029 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
3031 *pcbStructInfo
= bytesNeeded
;
3032 else if (*pcbStructInfo
< bytesNeeded
)
3034 *pcbStructInfo
= bytesNeeded
;
3035 SetLastError(ERROR_MORE_DATA
);
3040 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3042 blob
->cbData
= dataLen
;
3043 assert(blob
->pbData
);
3044 /* remove leading zero byte if it exists */
3045 if (blob
->cbData
&& *(pbEncoded
+ 1 + lenBytes
) == 0)
3054 for (i
= 0; i
< blob
->cbData
; i
++)
3056 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
3065 SetLastError(CRYPT_E_ASN1_BADTAG
);
3071 static BOOL WINAPI
CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType
,
3072 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3073 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3081 if ((ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
3082 lpszStructType
, pbEncoded
, cbEncoded
,
3083 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, NULL
, &bytesNeeded
)))
3086 *pcbStructInfo
= bytesNeeded
;
3087 else if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3088 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3090 CRYPT_INTEGER_BLOB
*blob
;
3092 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3093 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3094 blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
3095 blob
->pbData
= (BYTE
*)pvStructInfo
+
3096 sizeof(CRYPT_INTEGER_BLOB
);
3097 ret
= CRYPT_AsnDecodeUnsignedIntegerInternal(dwCertEncodingType
,
3098 lpszStructType
, pbEncoded
, cbEncoded
,
3099 dwFlags
& ~CRYPT_ENCODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3106 SetLastError(STATUS_ACCESS_VIOLATION
);
3113 static BOOL WINAPI
CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType
,
3114 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3115 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3121 *pcbStructInfo
= sizeof(int);
3126 if (pbEncoded
[0] == ASN_ENUMERATED
)
3128 unsigned int val
= 0, i
;
3132 SetLastError(CRYPT_E_ASN1_EOD
);
3135 else if (pbEncoded
[1] == 0)
3137 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3142 /* A little strange looking, but we have to accept a sign byte:
3143 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also,
3144 * assuming a small length is okay here, it has to be in short
3147 if (pbEncoded
[1] > sizeof(unsigned int) + 1)
3149 SetLastError(CRYPT_E_ASN1_LARGE
);
3152 for (i
= 0; i
< pbEncoded
[1]; i
++)
3155 val
|= pbEncoded
[2 + i
];
3157 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3158 pvStructInfo
, pcbStructInfo
, sizeof(unsigned int))))
3160 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3161 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3162 memcpy(pvStructInfo
, &val
, sizeof(unsigned int));
3168 SetLastError(CRYPT_E_ASN1_BADTAG
);
3174 SetLastError(STATUS_ACCESS_VIOLATION
);
3181 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE
3184 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \
3189 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \
3191 if (!isdigit(*(pbEncoded))) \
3193 SetLastError(CRYPT_E_ASN1_CORRUPT); \
3199 (word) += *(pbEncoded)++ - '0'; \
3204 static BOOL
CRYPT_AsnDecodeTimeZone(const BYTE
*pbEncoded
, DWORD len
,
3205 SYSTEMTIME
*sysTime
)
3212 if (len
>= 3 && (*pbEncoded
== '+' || *pbEncoded
== '-'))
3214 WORD hours
, minutes
= 0;
3215 BYTE sign
= *pbEncoded
++;
3218 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, hours
);
3219 if (ret
&& hours
>= 24)
3221 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3226 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, minutes
);
3227 if (ret
&& minutes
>= 60)
3229 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3237 sysTime
->wHour
+= hours
;
3238 sysTime
->wMinute
+= minutes
;
3242 if (hours
> sysTime
->wHour
)
3245 sysTime
->wHour
= 24 - (hours
- sysTime
->wHour
);
3248 sysTime
->wHour
-= hours
;
3249 if (minutes
> sysTime
->wMinute
)
3252 sysTime
->wMinute
= 60 - (minutes
- sysTime
->wMinute
);
3255 sysTime
->wMinute
-= minutes
;
3262 SetLastError(STATUS_ACCESS_VIOLATION
);
3269 #define MIN_ENCODED_TIME_LENGTH 10
3271 static BOOL WINAPI
CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType
,
3272 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3273 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3279 *pcbStructInfo
= sizeof(FILETIME
);
3285 if (pbEncoded
[0] == ASN_UTCTIME
)
3289 SetLastError(CRYPT_E_ASN1_EOD
);
3292 else if (pbEncoded
[1] > 0x7f)
3294 /* long-form date strings really can't be valid */
3295 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3300 SYSTEMTIME sysTime
= { 0 };
3301 BYTE len
= pbEncoded
[1];
3303 if (len
< MIN_ENCODED_TIME_LENGTH
)
3305 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3311 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wYear
);
3312 if (sysTime
.wYear
>= 50)
3313 sysTime
.wYear
+= 1900;
3315 sysTime
.wYear
+= 2000;
3316 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3317 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3318 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3319 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMinute
);
3322 if (len
>= 2 && isdigit(*pbEncoded
) &&
3323 isdigit(*(pbEncoded
+ 1)))
3324 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3326 else if (isdigit(*pbEncoded
))
3327 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 1,
3330 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3333 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3334 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3337 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3338 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3339 ret
= SystemTimeToFileTime(&sysTime
,
3340 (FILETIME
*)pvStructInfo
);
3347 SetLastError(CRYPT_E_ASN1_BADTAG
);
3353 SetLastError(STATUS_ACCESS_VIOLATION
);
3360 static BOOL WINAPI
CRYPT_AsnDecodeGeneralizedTime(DWORD dwCertEncodingType
,
3361 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3362 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3368 *pcbStructInfo
= sizeof(FILETIME
);
3374 if (pbEncoded
[0] == ASN_GENERALTIME
)
3378 SetLastError(CRYPT_E_ASN1_EOD
);
3381 else if (pbEncoded
[1] > 0x7f)
3383 /* long-form date strings really can't be valid */
3384 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3389 BYTE len
= pbEncoded
[1];
3391 if (len
< MIN_ENCODED_TIME_LENGTH
)
3393 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3398 SYSTEMTIME sysTime
= { 0 };
3401 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 4, sysTime
.wYear
);
3402 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wMonth
);
3403 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wDay
);
3404 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2, sysTime
.wHour
);
3407 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3410 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, 2,
3412 if (ret
&& len
> 0 && (*pbEncoded
== '.' ||
3419 /* workaround macro weirdness */
3420 digits
= min(len
, 3);
3421 CRYPT_TIME_GET_DIGITS(pbEncoded
, len
, digits
,
3422 sysTime
.wMilliseconds
);
3425 ret
= CRYPT_AsnDecodeTimeZone(pbEncoded
, len
,
3428 if (ret
&& (ret
= CRYPT_DecodeEnsureSpace(dwFlags
,
3429 pDecodePara
, pvStructInfo
, pcbStructInfo
,
3432 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3433 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3434 ret
= SystemTimeToFileTime(&sysTime
,
3435 (FILETIME
*)pvStructInfo
);
3442 SetLastError(CRYPT_E_ASN1_BADTAG
);
3448 SetLastError(STATUS_ACCESS_VIOLATION
);
3455 static BOOL WINAPI
CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType
,
3456 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3457 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3463 if (pbEncoded
[0] == ASN_UTCTIME
)
3464 ret
= CRYPT_AsnDecodeUtcTime(dwCertEncodingType
, lpszStructType
,
3465 pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
,
3467 else if (pbEncoded
[0] == ASN_GENERALTIME
)
3468 ret
= CRYPT_AsnDecodeGeneralizedTime(dwCertEncodingType
,
3469 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, pDecodePara
,
3470 pvStructInfo
, pcbStructInfo
);
3473 SetLastError(CRYPT_E_ASN1_BADTAG
);
3479 SetLastError(STATUS_ACCESS_VIOLATION
);
3486 static BOOL WINAPI
CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType
,
3487 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3488 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3494 if (pbEncoded
[0] == ASN_SEQUENCEOF
)
3496 DWORD bytesNeeded
, dataLen
, remainingLen
, cValue
;
3498 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3503 lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3504 bytesNeeded
= sizeof(CRYPT_SEQUENCE_OF_ANY
);
3506 ptr
= pbEncoded
+ 1 + lenBytes
;
3507 remainingLen
= dataLen
;
3508 while (ret
&& remainingLen
)
3512 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3515 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3517 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3518 ptr
+= 1 + nextLenBytes
+ nextLen
;
3519 bytesNeeded
+= sizeof(CRYPT_DER_BLOB
);
3520 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
3521 bytesNeeded
+= 1 + nextLenBytes
+ nextLen
;
3527 CRYPT_SEQUENCE_OF_ANY
*seq
;
3531 if ((ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
,
3532 pvStructInfo
, pcbStructInfo
, bytesNeeded
)))
3534 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3535 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3536 seq
= (CRYPT_SEQUENCE_OF_ANY
*)pvStructInfo
;
3537 seq
->cValue
= cValue
;
3538 seq
->rgValue
= (CRYPT_DER_BLOB
*)((BYTE
*)seq
+
3540 nextPtr
= (BYTE
*)seq
->rgValue
+
3541 cValue
* sizeof(CRYPT_DER_BLOB
);
3542 ptr
= pbEncoded
+ 1 + lenBytes
;
3543 remainingLen
= dataLen
;
3545 while (ret
&& remainingLen
)
3549 ret
= CRYPT_GetLen(ptr
, remainingLen
, &nextLen
);
3552 DWORD nextLenBytes
= GET_LEN_BYTES(ptr
[1]);
3554 seq
->rgValue
[i
].cbData
= 1 + nextLenBytes
+
3556 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
3557 seq
->rgValue
[i
].pbData
= (BYTE
*)ptr
;
3560 seq
->rgValue
[i
].pbData
= nextPtr
;
3561 memcpy(nextPtr
, ptr
, 1 + nextLenBytes
+
3563 nextPtr
+= 1 + nextLenBytes
+ nextLen
;
3565 remainingLen
-= 1 + nextLenBytes
+ nextLen
;
3566 ptr
+= 1 + nextLenBytes
+ nextLen
;
3576 SetLastError(CRYPT_E_ASN1_BADTAG
);
3582 SetLastError(STATUS_ACCESS_VIOLATION
);
3589 static BOOL WINAPI
CRYPT_AsnDecodeDistPointName(DWORD dwCertEncodingType
,
3590 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3591 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3595 if (pbEncoded
[0] == (ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0))
3597 DWORD bytesNeeded
, dataLen
;
3599 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
3601 struct AsnArrayDescriptor arrayDesc
= {
3602 ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, CRYPT_AsnDecodeAltNameEntry
,
3603 sizeof(CERT_ALT_NAME_ENTRY
), TRUE
,
3604 offsetof(CERT_ALT_NAME_ENTRY
, u
.pwszURL
) };
3605 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
3611 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3612 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3613 0, NULL
, NULL
, &nameLen
, NULL
);
3614 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
) + nameLen
;
3617 bytesNeeded
= sizeof(CRL_DIST_POINT_NAME
);
3619 *pcbStructInfo
= bytesNeeded
;
3620 else if (*pcbStructInfo
< bytesNeeded
)
3622 *pcbStructInfo
= bytesNeeded
;
3623 SetLastError(ERROR_MORE_DATA
);
3628 CRL_DIST_POINT_NAME
*name
= (CRL_DIST_POINT_NAME
*)pvStructInfo
;
3632 name
->dwDistPointNameChoice
= CRL_DIST_POINT_FULL_NAME
;
3633 ret
= CRYPT_AsnDecodeArray(&arrayDesc
,
3634 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
3635 0, NULL
, &name
->u
.FullName
, pcbStructInfo
,
3636 name
->u
.FullName
.rgAltEntry
);
3639 name
->dwDistPointNameChoice
= CRL_DIST_POINT_NO_NAME
;
3645 SetLastError(CRYPT_E_ASN1_BADTAG
);
3651 static BOOL WINAPI
CRYPT_AsnDecodeDistPoint(DWORD dwCertEncodingType
,
3652 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3653 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3655 struct AsnDecodeSequenceItem items
[] = {
3656 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_DIST_POINT
,
3657 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3658 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
, offsetof(CRL_DIST_POINT
,
3659 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3660 { ASN_CONTEXT
| 1, offsetof(CRL_DIST_POINT
, ReasonFlags
),
3661 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
3662 offsetof(CRL_DIST_POINT
, ReasonFlags
.pbData
), 0 },
3663 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 2, offsetof(CRL_DIST_POINT
, CRLIssuer
),
3664 CRYPT_AsnDecodeAltNameInternal
, sizeof(CERT_ALT_NAME_INFO
), TRUE
, TRUE
,
3665 offsetof(CRL_DIST_POINT
, CRLIssuer
.rgAltEntry
), 0 },
3669 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3670 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3671 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3675 static BOOL WINAPI
CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType
,
3676 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3677 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3681 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3682 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3686 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3687 CRYPT_AsnDecodeDistPoint
, sizeof(CRL_DIST_POINT
), TRUE
,
3688 offsetof(CRL_DIST_POINT
, DistPointName
.u
.FullName
.rgAltEntry
) };
3690 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3691 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3695 SetLastError(STATUS_ACCESS_VIOLATION
);
3702 static BOOL WINAPI
CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType
,
3703 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3704 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3708 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3709 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3713 struct AsnArrayDescriptor arrayDesc
= { ASN_SEQUENCEOF
,
3714 CRYPT_AsnDecodeOidInternal
, sizeof(LPSTR
), TRUE
, 0 };
3716 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3717 pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3721 SetLastError(STATUS_ACCESS_VIOLATION
);
3728 static BOOL WINAPI
CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType
,
3729 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3730 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3734 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3735 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3739 struct AsnDecodeSequenceItem items
[] = {
3740 { ASN_CONTEXT
| ASN_CONSTRUCTOR
| 0, offsetof(CRL_ISSUING_DIST_POINT
,
3741 DistPointName
), CRYPT_AsnDecodeDistPointName
,
3742 sizeof(CRL_DIST_POINT_NAME
), TRUE
, TRUE
,
3743 offsetof(CRL_ISSUING_DIST_POINT
,
3744 DistPointName
.u
.FullName
.rgAltEntry
), 0 },
3745 { ASN_CONTEXT
| 1, offsetof(CRL_ISSUING_DIST_POINT
,
3746 fOnlyContainsUserCerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3748 { ASN_CONTEXT
| 2, offsetof(CRL_ISSUING_DIST_POINT
,
3749 fOnlyContainsCACerts
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
,
3751 { ASN_CONTEXT
| 3, offsetof(CRL_ISSUING_DIST_POINT
,
3752 OnlySomeReasonFlags
), CRYPT_AsnDecodeBitsInternal
,
3753 sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
, offsetof(CRL_ISSUING_DIST_POINT
,
3754 OnlySomeReasonFlags
.pbData
), 0 },
3755 { ASN_CONTEXT
| 4, offsetof(CRL_ISSUING_DIST_POINT
,
3756 fIndirectCRL
), CRYPT_AsnDecodeBool
, sizeof(BOOL
), TRUE
, FALSE
, 0 },
3759 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3760 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3761 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
, NULL
);
3765 SetLastError(STATUS_ACCESS_VIOLATION
);
3772 static BOOL WINAPI
CRYPT_AsnDecodeIssuerSerialNumber(DWORD dwCertEncodingType
,
3773 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3774 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3777 struct AsnDecodeSequenceItem items
[] = {
3778 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER
, Issuer
), CRYPT_AsnDecodeDerBlob
,
3779 sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
,
3781 { ASN_INTEGER
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
),
3782 CRYPT_AsnDecodeIntegerInternal
, sizeof(CRYPT_INTEGER_BLOB
), FALSE
,
3783 TRUE
, offsetof(CERT_ISSUER_SERIAL_NUMBER
, SerialNumber
.pbData
), 0 },
3785 CERT_ISSUER_SERIAL_NUMBER
*issuerSerial
=
3786 (CERT_ISSUER_SERIAL_NUMBER
*)pvStructInfo
;
3788 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3789 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3791 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3792 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3793 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
3794 issuerSerial
? issuerSerial
->Issuer
.pbData
: NULL
);
3795 if (ret
&& issuerSerial
&& !issuerSerial
->SerialNumber
.cbData
)
3797 SetLastError(CRYPT_E_ASN1_CORRUPT
);
3800 TRACE("returning %d\n", ret
);
3804 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfoInternal(
3805 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const BYTE
*pbEncoded
,
3806 DWORD cbEncoded
, DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3807 void *pvStructInfo
, DWORD
*pcbStructInfo
)
3809 CMSG_SIGNER_INFO
*info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
3810 struct AsnDecodeSequenceItem items
[] = {
3811 { ASN_INTEGER
, offsetof(CMSG_SIGNER_INFO
, dwVersion
),
3812 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3813 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, Issuer
),
3814 CRYPT_AsnDecodeIssuerSerialNumber
, sizeof(CERT_ISSUER_SERIAL_NUMBER
),
3815 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
), 0 },
3816 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
),
3817 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3818 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, HashAlgorithm
.pszObjId
), 0 },
3819 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
3820 offsetof(CMSG_SIGNER_INFO
, AuthAttrs
),
3821 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
3822 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, AuthAttrs
.rgAttr
), 0 },
3823 { ASN_SEQUENCEOF
, offsetof(CMSG_SIGNER_INFO
, HashEncryptionAlgorithm
),
3824 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
3825 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
,
3826 HashEncryptionAlgorithm
.pszObjId
), 0 },
3827 { ASN_OCTETSTRING
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
),
3828 CRYPT_AsnDecodeOctetsInternal
, sizeof(CRYPT_DER_BLOB
),
3829 FALSE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, EncryptedHash
.pbData
), 0 },
3830 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
3831 offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
),
3832 CRYPT_AsnDecodePKCSAttributesInternal
, sizeof(CRYPT_ATTRIBUTES
),
3833 TRUE
, TRUE
, offsetof(CMSG_SIGNER_INFO
, UnauthAttrs
.rgAttr
), 0 },
3837 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3838 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3840 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
3841 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
,
3842 dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
,
3843 info
? info
->Issuer
.pbData
: NULL
);
3847 static BOOL WINAPI
CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType
,
3848 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3849 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3853 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3854 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3858 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(dwCertEncodingType
,
3859 lpszStructType
, pbEncoded
, cbEncoded
,
3860 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, NULL
, pcbStructInfo
);
3861 if (ret
&& pvStructInfo
)
3863 ret
= CRYPT_DecodeEnsureSpace(dwFlags
, pDecodePara
, pvStructInfo
,
3864 pcbStructInfo
, *pcbStructInfo
);
3867 CMSG_SIGNER_INFO
*info
;
3869 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
)
3870 pvStructInfo
= *(BYTE
**)pvStructInfo
;
3871 info
= (CMSG_SIGNER_INFO
*)pvStructInfo
;
3872 info
->Issuer
.pbData
= ((BYTE
*)info
+
3873 sizeof(CMSG_SIGNER_INFO
));
3874 ret
= CRYPT_AsnDecodePKCSSignerInfoInternal(dwCertEncodingType
,
3875 lpszStructType
, pbEncoded
, cbEncoded
,
3876 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
, NULL
, pvStructInfo
,
3883 SetLastError(STATUS_ACCESS_VIOLATION
);
3886 TRACE("returning %d\n", ret
);
3890 static BOOL WINAPI
CRYPT_DecodeSignerArray(DWORD dwCertEncodingType
,
3891 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3892 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3895 struct AsnArrayDescriptor arrayDesc
= { ASN_CONSTRUCTOR
| ASN_SETOF
,
3896 CRYPT_AsnDecodePKCSSignerInfoInternal
, sizeof(CMSG_SIGNER_INFO
), TRUE
,
3897 offsetof(CMSG_SIGNER_INFO
, Issuer
.pbData
) };
3898 struct GenericArray
*array
= (struct GenericArray
*)pvStructInfo
;
3900 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3901 pDecodePara
, pvStructInfo
, *pcbStructInfo
);
3903 ret
= CRYPT_AsnDecodeArray(&arrayDesc
, pbEncoded
, cbEncoded
, dwFlags
,
3904 pDecodePara
, pvStructInfo
, pcbStructInfo
, array
? array
->rgItems
: NULL
);
3908 BOOL
CRYPT_AsnDecodePKCSSignedInfo(const BYTE
*pbEncoded
, DWORD cbEncoded
,
3909 DWORD dwFlags
, PCRYPT_DECODE_PARA pDecodePara
,
3910 CRYPT_SIGNED_INFO
*signedInfo
, DWORD
*pcbSignedInfo
)
3913 struct AsnDecodeSequenceItem items
[] = {
3914 { ASN_INTEGER
, offsetof(CRYPT_SIGNED_INFO
, version
), CRYPT_AsnDecodeInt
,
3915 sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
3916 /* Placeholder for the hash algorithms - redundant with those in the
3917 * signers, so just ignore them.
3919 { ASN_CONSTRUCTOR
| ASN_SETOF
, 0, NULL
, 0, TRUE
, FALSE
, 0, 0 },
3920 { ASN_SEQUENCE
, offsetof(CRYPT_SIGNED_INFO
, content
),
3921 CRYPT_AsnDecodePKCSContentInfoInternal
, sizeof(CRYPT_CONTENT_INFO
),
3922 FALSE
, TRUE
, offsetof(CRYPT_SIGNED_INFO
, content
.pszObjId
), 0 },
3923 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 0,
3924 offsetof(CRYPT_SIGNED_INFO
, cCertEncoded
),
3925 CRYPT_DecodeDERArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
3926 offsetof(CRYPT_SIGNED_INFO
, rgCertEncoded
), 0 },
3927 { ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1,
3928 offsetof(CRYPT_SIGNED_INFO
, cCrlEncoded
), CRYPT_DecodeDERArray
,
3929 sizeof(struct GenericArray
), TRUE
, TRUE
,
3930 offsetof(CRYPT_SIGNED_INFO
, rgCrlEncoded
), 0 },
3931 { ASN_CONSTRUCTOR
| ASN_SETOF
, offsetof(CRYPT_SIGNED_INFO
, cSignerInfo
),
3932 CRYPT_DecodeSignerArray
, sizeof(struct GenericArray
), TRUE
, TRUE
,
3933 offsetof(CRYPT_SIGNED_INFO
, rgSignerInfo
), 0 },
3936 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
3937 pDecodePara
, signedInfo
, *pcbSignedInfo
);
3939 ret
= CRYPT_AsnDecodeSequence(X509_ASN_ENCODING
, items
,
3940 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
3941 pDecodePara
, signedInfo
, pcbSignedInfo
, NULL
);
3942 TRACE("returning %d\n", ret
);
3946 BOOL WINAPI
CryptDecodeObjectEx(DWORD dwCertEncodingType
, LPCSTR lpszStructType
,
3947 const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
3948 PCRYPT_DECODE_PARA pDecodePara
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
3950 static HCRYPTOIDFUNCSET set
= NULL
;
3952 CryptDecodeObjectExFunc decodeFunc
= NULL
;
3953 HCRYPTOIDFUNCADDR hFunc
= NULL
;
3955 TRACE("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n",
3956 dwCertEncodingType
, debugstr_a(lpszStructType
), pbEncoded
,
3957 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
3959 if (!pvStructInfo
&& !pcbStructInfo
)
3961 SetLastError(ERROR_INVALID_PARAMETER
);
3964 if ((dwCertEncodingType
& CERT_ENCODING_TYPE_MASK
) != X509_ASN_ENCODING
3965 && (dwCertEncodingType
& CMSG_ENCODING_TYPE_MASK
) != PKCS_7_ASN_ENCODING
)
3967 SetLastError(ERROR_FILE_NOT_FOUND
);
3972 SetLastError(CRYPT_E_ASN1_EOD
);
3975 if (cbEncoded
> MAX_ENCODED_LEN
)
3977 SetLastError(CRYPT_E_ASN1_LARGE
);
3981 SetLastError(NOERROR
);
3982 if (dwFlags
& CRYPT_DECODE_ALLOC_FLAG
&& pvStructInfo
)
3983 *(BYTE
**)pvStructInfo
= NULL
;
3984 if (!HIWORD(lpszStructType
))
3986 switch (LOWORD(lpszStructType
))
3988 case (WORD
)X509_CERT
:
3989 decodeFunc
= CRYPT_AsnDecodeCertSignedContent
;
3991 case (WORD
)X509_CERT_TO_BE_SIGNED
:
3992 decodeFunc
= CRYPT_AsnDecodeCert
;
3994 case (WORD
)X509_CERT_CRL_TO_BE_SIGNED
:
3995 decodeFunc
= CRYPT_AsnDecodeCRL
;
3997 case (WORD
)X509_EXTENSIONS
:
3998 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4000 case (WORD
)X509_NAME_VALUE
:
4001 decodeFunc
= CRYPT_AsnDecodeNameValue
;
4003 case (WORD
)X509_NAME
:
4004 decodeFunc
= CRYPT_AsnDecodeName
;
4006 case (WORD
)X509_PUBLIC_KEY_INFO
:
4007 decodeFunc
= CRYPT_AsnDecodePubKeyInfo
;
4009 case (WORD
)X509_AUTHORITY_KEY_ID
:
4010 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4012 case (WORD
)X509_ALTERNATE_NAME
:
4013 decodeFunc
= CRYPT_AsnDecodeAltName
;
4015 case (WORD
)X509_BASIC_CONSTRAINTS
:
4016 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4018 case (WORD
)X509_BASIC_CONSTRAINTS2
:
4019 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4021 case (WORD
)RSA_CSP_PUBLICKEYBLOB
:
4022 decodeFunc
= CRYPT_AsnDecodeRsaPubKey
;
4024 case (WORD
)X509_UNICODE_NAME
:
4025 decodeFunc
= CRYPT_AsnDecodeUnicodeName
;
4027 case (WORD
)PKCS_ATTRIBUTE
:
4028 decodeFunc
= CRYPT_AsnDecodePKCSAttribute
;
4030 case (WORD
)X509_UNICODE_NAME_VALUE
:
4031 decodeFunc
= CRYPT_AsnDecodeUnicodeNameValue
;
4033 case (WORD
)X509_OCTET_STRING
:
4034 decodeFunc
= CRYPT_AsnDecodeOctets
;
4036 case (WORD
)X509_BITS
:
4037 case (WORD
)X509_KEY_USAGE
:
4038 decodeFunc
= CRYPT_AsnDecodeBits
;
4040 case (WORD
)X509_INTEGER
:
4041 decodeFunc
= CRYPT_AsnDecodeInt
;
4043 case (WORD
)X509_MULTI_BYTE_INTEGER
:
4044 decodeFunc
= CRYPT_AsnDecodeInteger
;
4046 case (WORD
)X509_MULTI_BYTE_UINT
:
4047 decodeFunc
= CRYPT_AsnDecodeUnsignedInteger
;
4049 case (WORD
)X509_ENUMERATED
:
4050 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4052 case (WORD
)X509_CHOICE_OF_TIME
:
4053 decodeFunc
= CRYPT_AsnDecodeChoiceOfTime
;
4055 case (WORD
)X509_AUTHORITY_KEY_ID2
:
4056 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4058 case (WORD
)PKCS_CONTENT_INFO
:
4059 decodeFunc
= CRYPT_AsnDecodePKCSContentInfo
;
4061 case (WORD
)X509_SEQUENCE_OF_ANY
:
4062 decodeFunc
= CRYPT_AsnDecodeSequenceOfAny
;
4064 case (WORD
)PKCS_UTC_TIME
:
4065 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4067 case (WORD
)X509_CRL_DIST_POINTS
:
4068 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4070 case (WORD
)X509_ENHANCED_KEY_USAGE
:
4071 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4073 case (WORD
)PKCS_ATTRIBUTES
:
4074 decodeFunc
= CRYPT_AsnDecodePKCSAttributes
;
4076 case (WORD
)X509_ISSUING_DIST_POINT
:
4077 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4079 case (WORD
)PKCS7_SIGNER_INFO
:
4080 decodeFunc
= CRYPT_AsnDecodePKCSSignerInfo
;
4083 FIXME("%d: unimplemented\n", LOWORD(lpszStructType
));
4086 else if (!strcmp(lpszStructType
, szOID_CERT_EXTENSIONS
))
4087 decodeFunc
= CRYPT_AsnDecodeExtensions
;
4088 else if (!strcmp(lpszStructType
, szOID_RSA_signingTime
))
4089 decodeFunc
= CRYPT_AsnDecodeUtcTime
;
4090 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER
))
4091 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId
;
4092 else if (!strcmp(lpszStructType
, szOID_AUTHORITY_KEY_IDENTIFIER2
))
4093 decodeFunc
= CRYPT_AsnDecodeAuthorityKeyId2
;
4094 else if (!strcmp(lpszStructType
, szOID_CRL_REASON_CODE
))
4095 decodeFunc
= CRYPT_AsnDecodeEnumerated
;
4096 else if (!strcmp(lpszStructType
, szOID_KEY_USAGE
))
4097 decodeFunc
= CRYPT_AsnDecodeBits
;
4098 else if (!strcmp(lpszStructType
, szOID_SUBJECT_KEY_IDENTIFIER
))
4099 decodeFunc
= CRYPT_AsnDecodeOctets
;
4100 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS
))
4101 decodeFunc
= CRYPT_AsnDecodeBasicConstraints
;
4102 else if (!strcmp(lpszStructType
, szOID_BASIC_CONSTRAINTS2
))
4103 decodeFunc
= CRYPT_AsnDecodeBasicConstraints2
;
4104 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME
))
4105 decodeFunc
= CRYPT_AsnDecodeAltName
;
4106 else if (!strcmp(lpszStructType
, szOID_ISSUER_ALT_NAME2
))
4107 decodeFunc
= CRYPT_AsnDecodeAltName
;
4108 else if (!strcmp(lpszStructType
, szOID_NEXT_UPDATE_LOCATION
))
4109 decodeFunc
= CRYPT_AsnDecodeAltName
;
4110 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME
))
4111 decodeFunc
= CRYPT_AsnDecodeAltName
;
4112 else if (!strcmp(lpszStructType
, szOID_SUBJECT_ALT_NAME2
))
4113 decodeFunc
= CRYPT_AsnDecodeAltName
;
4114 else if (!strcmp(lpszStructType
, szOID_CRL_DIST_POINTS
))
4115 decodeFunc
= CRYPT_AsnDecodeCRLDistPoints
;
4116 else if (!strcmp(lpszStructType
, szOID_ENHANCED_KEY_USAGE
))
4117 decodeFunc
= CRYPT_AsnDecodeEnhancedKeyUsage
;
4118 else if (!strcmp(lpszStructType
, szOID_ISSUING_DIST_POINT
))
4119 decodeFunc
= CRYPT_AsnDecodeIssuingDistPoint
;
4121 TRACE("OID %s not found or unimplemented, looking for DLL\n",
4122 debugstr_a(lpszStructType
));
4126 set
= CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC
, 0);
4127 CryptGetOIDFunctionAddress(set
, dwCertEncodingType
, lpszStructType
, 0,
4128 (void **)&decodeFunc
, &hFunc
);
4131 ret
= decodeFunc(dwCertEncodingType
, lpszStructType
, pbEncoded
,
4132 cbEncoded
, dwFlags
, pDecodePara
, pvStructInfo
, pcbStructInfo
);
4134 SetLastError(ERROR_FILE_NOT_FOUND
);
4136 CryptFreeOIDFunctionAddress(hFunc
, 0);