1 /* wintrust asn functions
3 * Copyright 2007 Juan Lang
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
27 #define NONAMELESSUNION
35 #include "wine/debug.h"
36 #include "wine/exception.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn
);
40 #ifdef WORDS_BIGENDIAN
47 #define hton16(x) RtlUshortByteSwap(x)
48 #define n16toh(x) RtlUshortByteSwap(x)
52 #define ASN_BOOL (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x01)
53 #define ASN_BITSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x03)
54 #define ASN_BMPSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x1e)
56 static BOOL
CRYPT_EncodeLen(DWORD len
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
58 DWORD bytesNeeded
, significantBytes
= 0;
66 for (temp
= len
, significantBytes
= sizeof(temp
); !(temp
& 0xff000000);
67 temp
<<= 8, significantBytes
--)
69 bytesNeeded
= significantBytes
+ 1;
73 *pcbEncoded
= bytesNeeded
;
76 if (*pcbEncoded
< bytesNeeded
)
78 SetLastError(ERROR_MORE_DATA
);
82 *pbEncoded
= (BYTE
)len
;
87 *pbEncoded
++ = significantBytes
| 0x80;
88 for (i
= 0; i
< significantBytes
; i
++)
90 *(pbEncoded
+ significantBytes
- i
- 1) = (BYTE
)(len
& 0xff);
94 *pcbEncoded
= bytesNeeded
;
98 static BOOL WINAPI
CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType
,
99 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
103 const CRYPT_DATA_BLOB
*blob
= (const CRYPT_DATA_BLOB
*)pvStructInfo
;
104 DWORD bytesNeeded
, lenBytes
;
106 TRACE("(%d, %p), %p, %d\n", blob
->cbData
, blob
->pbData
, pbEncoded
,
109 CRYPT_EncodeLen(blob
->cbData
, NULL
, &lenBytes
);
110 bytesNeeded
= 1 + lenBytes
+ blob
->cbData
;
112 *pcbEncoded
= bytesNeeded
;
113 else if (*pcbEncoded
< bytesNeeded
)
115 *pcbEncoded
= bytesNeeded
;
116 SetLastError(ERROR_MORE_DATA
);
121 *pbEncoded
++ = ASN_OCTETSTRING
;
122 CRYPT_EncodeLen(blob
->cbData
, pbEncoded
, &lenBytes
);
123 pbEncoded
+= lenBytes
;
125 memcpy(pbEncoded
, blob
->pbData
, blob
->cbData
);
127 TRACE("returning %d\n", ret
);
131 BOOL WINAPI
WVTAsn1SpcLinkEncode(DWORD dwCertEncodingType
,
132 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
137 TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
138 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
,
143 const SPC_LINK
*link
= (const SPC_LINK
*)pvStructInfo
;
144 DWORD bytesNeeded
, lenBytes
;
146 switch (link
->dwLinkChoice
)
148 case SPC_FILE_LINK_CHOICE
:
150 DWORD fileNameLen
, fileNameLenBytes
;
153 fileNameLen
= link
->u
.pwszFile
?
154 lstrlenW(link
->u
.pwszFile
) * sizeof(WCHAR
) : 0;
155 CRYPT_EncodeLen(fileNameLen
, NULL
, &fileNameLenBytes
);
156 CRYPT_EncodeLen(1 + fileNameLenBytes
+ fileNameLen
, NULL
,
158 bytesNeeded
= 2 + lenBytes
+ fileNameLenBytes
+ fileNameLen
;
161 *pcbEncoded
= bytesNeeded
;
164 else if (*pcbEncoded
< bytesNeeded
)
166 SetLastError(ERROR_MORE_DATA
);
167 *pcbEncoded
= bytesNeeded
;
171 *pcbEncoded
= bytesNeeded
;
172 *pbEncoded
++ = ASN_CONSTRUCTOR
| ASN_CONTEXT
| 2;
173 CRYPT_EncodeLen(1 + fileNameLenBytes
+ fileNameLen
, pbEncoded
,
175 pbEncoded
+= lenBytes
;
176 *pbEncoded
++ = ASN_CONTEXT
;
177 CRYPT_EncodeLen(fileNameLen
, pbEncoded
, &fileNameLenBytes
);
178 pbEncoded
+= fileNameLenBytes
;
179 for (ptr
= link
->u
.pwszFile
; ptr
&& *ptr
; ptr
++)
181 *(WCHAR
*)pbEncoded
= hton16(*ptr
);
182 pbEncoded
+= sizeof(WCHAR
);
188 case SPC_MONIKER_LINK_CHOICE
:
190 DWORD classIdLenBytes
, dataLenBytes
, dataLen
;
191 CRYPT_DATA_BLOB classId
= { sizeof(link
->u
.Moniker
.ClassId
),
192 (BYTE
*)link
->u
.Moniker
.ClassId
};
194 CRYPT_EncodeLen(classId
.cbData
, NULL
, &classIdLenBytes
);
195 CRYPT_EncodeLen(link
->u
.Moniker
.SerializedData
.cbData
, NULL
,
197 dataLen
= 2 + classIdLenBytes
+ classId
.cbData
+
198 dataLenBytes
+ link
->u
.Moniker
.SerializedData
.cbData
;
199 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
200 bytesNeeded
= 1 + dataLen
+ lenBytes
;
203 *pcbEncoded
= bytesNeeded
;
206 else if (*pcbEncoded
< bytesNeeded
)
208 SetLastError(ERROR_MORE_DATA
);
209 *pcbEncoded
= bytesNeeded
;
215 *pcbEncoded
= bytesNeeded
;
216 *pbEncoded
++ = ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1;
217 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
218 pbEncoded
+= lenBytes
;
219 size
= 1 + classIdLenBytes
+ classId
.cbData
;
220 CRYPT_AsnEncodeOctets(X509_ASN_ENCODING
, NULL
, &classId
,
223 size
= 1 + dataLenBytes
+ link
->u
.Moniker
.SerializedData
.cbData
;
224 CRYPT_AsnEncodeOctets(X509_ASN_ENCODING
, NULL
,
225 &link
->u
.Moniker
.SerializedData
, pbEncoded
, &size
);
231 case SPC_URL_LINK_CHOICE
:
236 /* Check for invalid characters in URL */
239 for (ptr
= link
->u
.pwszUrl
; ptr
&& *ptr
&& ret
; ptr
++)
243 SetLastError(CRYPT_E_INVALID_IA5_STRING
);
250 CRYPT_EncodeLen(urlLen
, NULL
, &lenBytes
);
251 bytesNeeded
= 1 + lenBytes
+ urlLen
;
253 *pcbEncoded
= bytesNeeded
;
254 else if (*pcbEncoded
< bytesNeeded
)
256 SetLastError(ERROR_MORE_DATA
);
257 *pcbEncoded
= bytesNeeded
;
262 *pcbEncoded
= bytesNeeded
;
263 *pbEncoded
++ = ASN_CONTEXT
;
264 CRYPT_EncodeLen(urlLen
, pbEncoded
, &lenBytes
);
265 pbEncoded
+= lenBytes
;
266 for (ptr
= link
->u
.pwszUrl
; ptr
&& *ptr
; ptr
++)
267 *pbEncoded
++ = (BYTE
)*ptr
;
273 SetLastError(E_INVALIDARG
);
278 SetLastError(STATUS_ACCESS_VIOLATION
);
281 TRACE("returning %d\n", ret
);
285 typedef BOOL (WINAPI
*CryptEncodeObjectFunc
)(DWORD
, LPCSTR
, const void *,
288 struct AsnEncodeSequenceItem
290 const void *pvStructInfo
;
291 CryptEncodeObjectFunc encodeFunc
;
292 DWORD size
; /* used during encoding, not for your use */
295 static BOOL WINAPI
CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType
,
296 struct AsnEncodeSequenceItem items
[], DWORD cItem
, BYTE
*pbEncoded
,
300 DWORD i
, dataLen
= 0;
302 TRACE("%p, %d, %p, %d\n", items
, cItem
, pbEncoded
, *pcbEncoded
);
303 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
305 ret
= items
[i
].encodeFunc(dwCertEncodingType
, NULL
,
306 items
[i
].pvStructInfo
, NULL
, &items
[i
].size
);
307 /* Some functions propagate their errors through the size */
309 *pcbEncoded
= items
[i
].size
;
310 dataLen
+= items
[i
].size
;
314 DWORD lenBytes
, bytesNeeded
;
316 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
317 bytesNeeded
= 1 + lenBytes
+ dataLen
;
319 *pcbEncoded
= bytesNeeded
;
320 else if (*pcbEncoded
< bytesNeeded
)
322 *pcbEncoded
= bytesNeeded
;
323 SetLastError(ERROR_MORE_DATA
);
328 *pcbEncoded
= bytesNeeded
;
329 *pbEncoded
++ = ASN_SEQUENCE
;
330 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
331 pbEncoded
+= lenBytes
;
332 for (i
= 0; ret
&& i
< cItem
; i
++)
334 ret
= items
[i
].encodeFunc(dwCertEncodingType
, NULL
,
335 items
[i
].pvStructInfo
, pbEncoded
, &items
[i
].size
);
336 /* Some functions propagate their errors through the size */
338 *pcbEncoded
= items
[i
].size
;
339 pbEncoded
+= items
[i
].size
;
343 TRACE("returning %d\n", ret
);
347 static BOOL WINAPI
CRYPT_AsnEncodeBits(DWORD dwCertEncodingType
,
348 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
355 const CRYPT_BIT_BLOB
*blob
= (const CRYPT_BIT_BLOB
*)pvStructInfo
;
356 DWORD bytesNeeded
, lenBytes
, dataBytes
;
359 /* yep, MS allows cUnusedBits to be >= 8 */
360 if (!blob
->cUnusedBits
)
362 dataBytes
= blob
->cbData
;
365 else if (blob
->cbData
* 8 > blob
->cUnusedBits
)
367 dataBytes
= (blob
->cbData
* 8 - blob
->cUnusedBits
) / 8 + 1;
368 unusedBits
= blob
->cUnusedBits
>= 8 ? blob
->cUnusedBits
/ 8 :
376 CRYPT_EncodeLen(dataBytes
+ 1, NULL
, &lenBytes
);
377 bytesNeeded
= 1 + lenBytes
+ dataBytes
+ 1;
380 *pcbEncoded
= bytesNeeded
;
383 else if (*pcbEncoded
< bytesNeeded
)
385 *pcbEncoded
= bytesNeeded
;
386 SetLastError(ERROR_MORE_DATA
);
391 *pcbEncoded
= bytesNeeded
;
392 *pbEncoded
++ = ASN_BITSTRING
;
393 CRYPT_EncodeLen(dataBytes
+ 1, pbEncoded
, &lenBytes
);
394 pbEncoded
+= lenBytes
;
395 *pbEncoded
++ = unusedBits
;
398 BYTE mask
= 0xff << unusedBits
;
402 memcpy(pbEncoded
, blob
->pbData
, dataBytes
- 1);
403 pbEncoded
+= dataBytes
- 1;
405 *pbEncoded
= *(blob
->pbData
+ dataBytes
- 1) & mask
;
411 SetLastError(STATUS_ACCESS_VIOLATION
);
417 struct AsnConstructedItem
420 const void *pvStructInfo
;
421 CryptEncodeObjectFunc encodeFunc
;
424 static BOOL WINAPI
CRYPT_AsnEncodeConstructed(DWORD dwCertEncodingType
,
425 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
429 const struct AsnConstructedItem
*item
=
430 (const struct AsnConstructedItem
*)pvStructInfo
;
433 if ((ret
= item
->encodeFunc(dwCertEncodingType
, lpszStructType
,
434 item
->pvStructInfo
, NULL
, &len
)))
436 DWORD dataLen
, bytesNeeded
;
438 CRYPT_EncodeLen(len
, NULL
, &dataLen
);
439 bytesNeeded
= 1 + dataLen
+ len
;
441 *pcbEncoded
= bytesNeeded
;
442 else if (*pcbEncoded
< bytesNeeded
)
444 *pcbEncoded
= bytesNeeded
;
445 SetLastError(ERROR_MORE_DATA
);
450 *pcbEncoded
= bytesNeeded
;
451 *pbEncoded
++ = ASN_CONTEXT
| ASN_CONSTRUCTOR
| item
->tag
;
452 CRYPT_EncodeLen(len
, pbEncoded
, &dataLen
);
453 pbEncoded
+= dataLen
;
454 ret
= item
->encodeFunc(dwCertEncodingType
, lpszStructType
,
455 item
->pvStructInfo
, pbEncoded
, &len
);
458 /* Some functions propagate their errors through the size */
465 /* Some functions propagate their errors through the size */
472 BOOL WINAPI
WVTAsn1SpcPeImageDataEncode(DWORD dwCertEncodingType
,
473 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
476 const SPC_PE_IMAGE_DATA
*imageData
=
477 (const SPC_PE_IMAGE_DATA
*)pvStructInfo
;
480 TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
481 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
,
486 struct AsnEncodeSequenceItem items
[2] = {
489 struct AsnConstructedItem constructed
= { 0, imageData
->pFile
,
490 WVTAsn1SpcLinkEncode
};
493 if (imageData
->Flags
.cbData
)
495 items
[cItem
].pvStructInfo
= &imageData
->Flags
;
496 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeBits
;
499 if (imageData
->pFile
)
501 items
[cItem
].pvStructInfo
= &constructed
;
502 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeConstructed
;
506 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
507 pbEncoded
, pcbEncoded
);
511 SetLastError(STATUS_ACCESS_VIOLATION
);
514 TRACE("returning %d\n", ret
);
518 static BOOL WINAPI
CRYPT_AsnEncodeOid(DWORD dwCertEncodingType
,
519 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
522 LPCSTR pszObjId
= (LPCSTR
)pvStructInfo
;
523 DWORD bytesNeeded
= 0, lenBytes
;
528 TRACE("%s\n", debugstr_a(pszObjId
));
535 if (sscanf(pszObjId
, "%d.%d.%n", &val1
, &val2
, &firstPos
) != 2)
537 SetLastError(CRYPT_E_ASN1_ERROR
);
541 firstByte
= val1
* 40 + val2
;
542 ptr
= pszObjId
+ firstPos
;
547 /* note I assume each component is at most 32-bits long in base 2 */
548 if (sscanf(ptr
, "%d%n", &val1
, &pos
) == 1)
550 if (val1
>= 0x10000000)
552 else if (val1
>= 0x200000)
554 else if (val1
>= 0x4000)
556 else if (val1
>= 0x80)
566 SetLastError(CRYPT_E_ASN1_ERROR
);
570 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
574 bytesNeeded
+= 1 + lenBytes
;
577 if (*pcbEncoded
< bytesNeeded
)
579 SetLastError(ERROR_MORE_DATA
);
584 *pbEncoded
++ = ASN_OBJECTIDENTIFIER
;
585 CRYPT_EncodeLen(bytesNeeded
- 1 - lenBytes
, pbEncoded
, &lenBytes
);
586 pbEncoded
+= lenBytes
;
592 *pbEncoded
++ = firstByte
;
593 ptr
= pszObjId
+ firstPos
;
596 sscanf(ptr
, "%d%n", &val
, &pos
);
598 unsigned char outBytes
[5];
601 if (val
>= 0x10000000)
603 else if (val
>= 0x200000)
605 else if (val
>= 0x4000)
607 else if (val
>= 0x80)
611 for (i
= numBytes
; i
> 0; i
--)
613 outBytes
[i
- 1] = val
& 0x7f;
616 for (i
= 0; i
< numBytes
- 1; i
++)
617 *pbEncoded
++ = outBytes
[i
] | 0x80;
618 *pbEncoded
++ = outBytes
[i
];
627 *pcbEncoded
= bytesNeeded
;
631 static BOOL WINAPI
CRYPT_CopyEncodedBlob(DWORD dwCertEncodingType
,
632 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
635 const CRYPT_DER_BLOB
*blob
= (const CRYPT_DER_BLOB
*)pvStructInfo
;
639 *pcbEncoded
= blob
->cbData
;
640 else if (*pcbEncoded
< blob
->cbData
)
642 *pcbEncoded
= blob
->cbData
;
643 SetLastError(ERROR_MORE_DATA
);
649 memcpy(pbEncoded
, blob
->pbData
, blob
->cbData
);
650 *pcbEncoded
= blob
->cbData
;
655 static BOOL WINAPI
CRYPT_AsnEncodeAlgorithmIdWithNullParams(
656 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const void *pvStructInfo
,
657 BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
659 const CRYPT_ALGORITHM_IDENTIFIER
*algo
=
660 (const CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
661 static const BYTE asn1Null
[] = { ASN_NULL
, 0 };
662 static const CRYPT_DATA_BLOB nullBlob
= { sizeof(asn1Null
),
665 struct AsnEncodeSequenceItem items
[2] = {
666 { algo
->pszObjId
, CRYPT_AsnEncodeOid
, 0 },
667 { NULL
, CRYPT_CopyEncodedBlob
, 0 },
670 if (algo
->Parameters
.cbData
)
671 items
[1].pvStructInfo
= &algo
->Parameters
;
673 items
[1].pvStructInfo
= &nullBlob
;
674 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
675 sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
679 static BOOL WINAPI
CRYPT_AsnEncodeAttributeTypeValue(DWORD dwCertEncodingType
,
680 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
683 const CRYPT_ATTRIBUTE_TYPE_VALUE
*typeValue
=
684 (const CRYPT_ATTRIBUTE_TYPE_VALUE
*)pvStructInfo
;
685 struct AsnEncodeSequenceItem items
[] = {
686 { &typeValue
->pszObjId
, CRYPT_AsnEncodeOid
, 0 },
687 { &typeValue
->Value
, CRYPT_CopyEncodedBlob
, 0 },
690 return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
,
691 items
, sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
696 CRYPT_ALGORITHM_IDENTIFIER DigestAlgorithm
;
697 CRYPT_HASH_BLOB Digest
;
700 static BOOL WINAPI
CRYPT_AsnEncodeSPCDigest(DWORD dwCertEncodingType
,
701 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
704 const struct SPCDigest
*digest
= (const struct SPCDigest
*)pvStructInfo
;
705 struct AsnEncodeSequenceItem items
[] = {
706 { &digest
->DigestAlgorithm
, CRYPT_AsnEncodeAlgorithmIdWithNullParams
, 0 },
707 { &digest
->Digest
, CRYPT_CopyEncodedBlob
, 0 },
710 return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
,
711 items
, sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
714 BOOL WINAPI
WVTAsn1SpcIndirectDataContentEncode(DWORD dwCertEncodingType
,
715 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
720 TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
721 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
, pcbEncoded
);
725 const SPC_INDIRECT_DATA_CONTENT
*data
=
726 (const SPC_INDIRECT_DATA_CONTENT
*)pvStructInfo
;
727 struct AsnEncodeSequenceItem items
[] = {
728 { &data
->Data
, CRYPT_AsnEncodeAttributeTypeValue
, 0 },
729 { &data
->DigestAlgorithm
, CRYPT_AsnEncodeSPCDigest
, 0 },
732 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
,
733 items
, sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
737 SetLastError(STATUS_ACCESS_VIOLATION
);
743 static BOOL WINAPI
CRYPT_AsnEncodeBMPString(DWORD dwCertEncodingType
,
744 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
748 LPCWSTR str
= (LPCWSTR
)pvStructInfo
;
749 DWORD bytesNeeded
, lenBytes
, strLen
;
752 strLen
= lstrlenW(str
);
755 CRYPT_EncodeLen(strLen
* 2, NULL
, &lenBytes
);
756 bytesNeeded
= 1 + lenBytes
+ strLen
* 2;
758 *pcbEncoded
= bytesNeeded
;
759 else if (*pcbEncoded
< bytesNeeded
)
761 *pcbEncoded
= bytesNeeded
;
762 SetLastError(ERROR_MORE_DATA
);
769 *pcbEncoded
= bytesNeeded
;
770 *pbEncoded
++ = ASN_BMPSTRING
;
771 CRYPT_EncodeLen(strLen
* 2, pbEncoded
, &lenBytes
);
772 pbEncoded
+= lenBytes
;
773 for (i
= 0; i
< strLen
; i
++)
775 *pbEncoded
++ = (str
[i
] & 0xff00) >> 8;
776 *pbEncoded
++ = str
[i
] & 0x00ff;
782 static BOOL WINAPI
CRYPT_AsnEncodeInteger(DWORD dwCertEncodingType
,
783 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
790 DWORD significantBytes
, lenBytes
, bytesNeeded
;
793 const CRYPT_INTEGER_BLOB
*blob
=
794 (const CRYPT_INTEGER_BLOB
*)pvStructInfo
;
796 significantBytes
= blob
->cbData
;
797 if (significantBytes
)
799 if (blob
->pbData
[significantBytes
- 1] & 0x80)
801 /* negative, lop off leading (little-endian) 0xffs */
802 for (; significantBytes
> 0 &&
803 blob
->pbData
[significantBytes
- 1] == 0xff; significantBytes
--)
805 if (blob
->pbData
[significantBytes
- 1] < 0x80)
813 /* positive, lop off leading (little-endian) zeroes */
814 for (; significantBytes
> 0 &&
815 !blob
->pbData
[significantBytes
- 1]; significantBytes
--)
817 if (significantBytes
== 0)
818 significantBytes
= 1;
819 if (blob
->pbData
[significantBytes
- 1] > 0x7f)
827 CRYPT_EncodeLen(significantBytes
+ 1, NULL
, &lenBytes
);
829 CRYPT_EncodeLen(significantBytes
, NULL
, &lenBytes
);
830 bytesNeeded
= 1 + lenBytes
+ significantBytes
;
835 *pcbEncoded
= bytesNeeded
;
838 else if (*pcbEncoded
< bytesNeeded
)
840 *pcbEncoded
= bytesNeeded
;
841 SetLastError(ERROR_MORE_DATA
);
846 *pcbEncoded
= bytesNeeded
;
847 *pbEncoded
++ = ASN_INTEGER
;
850 CRYPT_EncodeLen(significantBytes
+ 1, pbEncoded
, &lenBytes
);
851 pbEncoded
+= lenBytes
;
852 *pbEncoded
++ = padByte
;
856 CRYPT_EncodeLen(significantBytes
, pbEncoded
, &lenBytes
);
857 pbEncoded
+= lenBytes
;
859 for (; significantBytes
> 0; significantBytes
--)
860 *(pbEncoded
++) = blob
->pbData
[significantBytes
- 1];
866 SetLastError(STATUS_ACCESS_VIOLATION
);
873 BOOL WINAPI
CRYPT_AsnEncodeInt(DWORD dwCertEncodingType
,
874 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
877 CRYPT_INTEGER_BLOB blob
= { sizeof(INT
), (BYTE
*)pvStructInfo
};
879 return CRYPT_AsnEncodeInteger(dwCertEncodingType
, X509_MULTI_BYTE_INTEGER
,
880 &blob
, pbEncoded
, pcbEncoded
);
883 BOOL WINAPI
WVTAsn1CatMemberInfoEncode(DWORD dwCertEncodingType
,
884 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
889 TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
890 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
, pcbEncoded
);
894 const CAT_MEMBERINFO
*info
= (const CAT_MEMBERINFO
*)pvStructInfo
;
895 struct AsnEncodeSequenceItem items
[] = {
896 { info
->pwszSubjGuid
, CRYPT_AsnEncodeBMPString
, 0 },
897 { &info
->dwCertVersion
, CRYPT_AsnEncodeInt
, 0 },
900 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
,
901 items
, sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
905 SetLastError(STATUS_ACCESS_VIOLATION
);
911 BOOL WINAPI
WVTAsn1CatNameValueEncode(DWORD dwCertEncodingType
,
912 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
917 TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
918 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
, pcbEncoded
);
922 const CAT_NAMEVALUE
*value
= (const CAT_NAMEVALUE
*)pvStructInfo
;
923 struct AsnEncodeSequenceItem items
[] = {
924 { value
->pwszTag
, CRYPT_AsnEncodeBMPString
, 0 },
925 { &value
->fdwFlags
, CRYPT_AsnEncodeInt
, 0 },
926 { &value
->Value
, CRYPT_AsnEncodeOctets
, 0 },
929 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
,
930 items
, sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
934 SetLastError(STATUS_ACCESS_VIOLATION
);
940 static BOOL WINAPI
CRYPT_AsnEncodeBool(DWORD dwCertEncodingType
,
941 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
944 BOOL val
= *(const BOOL
*)pvStructInfo
, ret
;
953 else if (*pcbEncoded
< 3)
956 SetLastError(ERROR_MORE_DATA
);
962 *pbEncoded
++ = ASN_BOOL
;
964 *pbEncoded
++ = val
? 0xff : 0;
967 TRACE("returning %d (%08x)\n", ret
, GetLastError());
971 BOOL WINAPI
WVTAsn1SpcFinancialCriteriaInfoEncode(DWORD dwCertEncodingType
,
972 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
977 TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
978 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
, pcbEncoded
);
982 const SPC_FINANCIAL_CRITERIA
*criteria
= pvStructInfo
;
983 struct AsnEncodeSequenceItem items
[] = {
984 { &criteria
->fFinancialInfoAvailable
, CRYPT_AsnEncodeBool
, 0 },
985 { &criteria
->fMeetsCriteria
, CRYPT_AsnEncodeBool
, 0 },
988 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
,
989 items
, sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
993 SetLastError(STATUS_ACCESS_VIOLATION
);
999 /* Gets the number of length bytes from the given (leading) length byte */
1000 #define GET_LEN_BYTES(b) ((b) <= 0x7f ? 1 : 1 + ((b) & 0x7f))
1002 /* Helper function to get the encoded length of the data starting at pbEncoded,
1003 * where pbEncoded[0] is the tag. If the data are too short to contain a
1004 * length or if the length is too large for cbEncoded, sets an appropriate
1005 * error code and returns FALSE.
1007 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
1013 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1016 else if (pbEncoded
[1] <= 0x7f)
1018 if (pbEncoded
[1] + 1 > cbEncoded
)
1020 SetLastError(CRYPT_E_ASN1_EOD
);
1025 *len
= pbEncoded
[1];
1029 else if (pbEncoded
[1] == 0x80)
1031 FIXME("unimplemented for indefinite-length encoding\n");
1032 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1037 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
1039 if (lenLen
> sizeof(DWORD
) + 1)
1041 SetLastError(CRYPT_E_ASN1_LARGE
);
1044 else if (lenLen
+ 2 > cbEncoded
)
1046 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1057 out
|= *pbEncoded
++;
1059 if (out
+ lenLen
+ 1 > cbEncoded
)
1061 SetLastError(CRYPT_E_ASN1_EOD
);
1074 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
1075 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1076 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1079 DWORD bytesNeeded
, dataLen
;
1081 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1082 pvStructInfo
, *pcbStructInfo
);
1086 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1089 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
1091 SetLastError(CRYPT_E_ASN1_BADTAG
);
1094 else if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1096 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1097 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
1099 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
1101 *pcbStructInfo
= bytesNeeded
;
1102 else if (*pcbStructInfo
< bytesNeeded
)
1104 SetLastError(ERROR_MORE_DATA
);
1105 *pcbStructInfo
= bytesNeeded
;
1110 CRYPT_DATA_BLOB
*blob
;
1111 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1113 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
1114 blob
->cbData
= dataLen
;
1115 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1116 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
1119 assert(blob
->pbData
);
1121 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
1129 static BOOL WINAPI
CRYPT_AsnDecodeSPCLinkInternal(DWORD dwCertEncodingType
,
1130 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1131 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1134 DWORD bytesNeeded
= sizeof(SPC_LINK
), dataLen
;
1136 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1137 pvStructInfo
, *pcbStructInfo
);
1139 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1141 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1144 switch (pbEncoded
[0])
1147 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
1149 *pcbStructInfo
= bytesNeeded
;
1150 else if (*pcbStructInfo
< bytesNeeded
)
1152 *pcbStructInfo
= bytesNeeded
;
1153 SetLastError(ERROR_MORE_DATA
);
1158 PSPC_LINK link
= (PSPC_LINK
)pvStructInfo
;
1161 link
->dwLinkChoice
= SPC_URL_LINK_CHOICE
;
1162 for (i
= 0; i
< dataLen
; i
++)
1163 link
->u
.pwszUrl
[i
] =
1164 *(pbEncoded
+ 1 + lenBytes
+ i
);
1165 link
->u
.pwszUrl
[i
] = '\0';
1166 TRACE("returning url %s\n", debugstr_w(link
->u
.pwszUrl
));
1169 case ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1:
1171 CRYPT_DATA_BLOB classId
;
1172 DWORD size
= sizeof(classId
);
1174 if ((ret
= CRYPT_AsnDecodeOctets(dwCertEncodingType
, NULL
,
1175 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
1176 CRYPT_DECODE_NOCOPY_FLAG
, &classId
, &size
)))
1178 if (classId
.cbData
!= sizeof(SPC_UUID
))
1180 SetLastError(CRYPT_E_BAD_ENCODE
);
1185 CRYPT_DATA_BLOB data
;
1187 /* The tag length for the classId must be 1 since the
1188 * length is correct.
1190 size
= sizeof(data
);
1191 if ((ret
= CRYPT_AsnDecodeOctets(dwCertEncodingType
, NULL
,
1192 pbEncoded
+ 3 + lenBytes
+ classId
.cbData
,
1193 cbEncoded
- 3 - lenBytes
- classId
.cbData
,
1194 CRYPT_DECODE_NOCOPY_FLAG
, &data
, &size
)))
1196 bytesNeeded
+= data
.cbData
;
1198 *pcbStructInfo
= bytesNeeded
;
1199 else if (*pcbStructInfo
< bytesNeeded
)
1201 *pcbStructInfo
= bytesNeeded
;
1202 SetLastError(ERROR_MORE_DATA
);
1207 PSPC_LINK link
= (PSPC_LINK
)pvStructInfo
;
1209 link
->dwLinkChoice
= SPC_MONIKER_LINK_CHOICE
;
1210 /* pwszFile pointer was set by caller, copy it
1211 * before overwriting it
1213 link
->u
.Moniker
.SerializedData
.pbData
=
1214 (BYTE
*)link
->u
.pwszFile
;
1215 memcpy(link
->u
.Moniker
.ClassId
, classId
.pbData
,
1217 memcpy(link
->u
.Moniker
.SerializedData
.pbData
,
1218 data
.pbData
, data
.cbData
);
1219 link
->u
.Moniker
.SerializedData
.cbData
= data
.cbData
;
1226 case ASN_CONSTRUCTOR
| ASN_CONTEXT
| 2:
1227 if (dataLen
&& pbEncoded
[1 + lenBytes
] != ASN_CONTEXT
)
1228 SetLastError(CRYPT_E_ASN1_BADTAG
);
1229 else if ((ret
= CRYPT_GetLen(pbEncoded
+ 1 + lenBytes
, dataLen
,
1232 BYTE realLenBytes
= GET_LEN_BYTES(pbEncoded
[2 + lenBytes
]);
1234 bytesNeeded
+= realDataLen
+ sizeof(WCHAR
);
1236 *pcbStructInfo
= bytesNeeded
;
1237 else if (*pcbStructInfo
< bytesNeeded
)
1239 *pcbStructInfo
= bytesNeeded
;
1240 SetLastError(ERROR_MORE_DATA
);
1245 PSPC_LINK link
= (PSPC_LINK
)pvStructInfo
;
1247 const BYTE
*ptr
= pbEncoded
+ 2 + lenBytes
+ realLenBytes
;
1249 link
->dwLinkChoice
= SPC_FILE_LINK_CHOICE
;
1250 for (i
= 0; i
< dataLen
/ sizeof(WCHAR
); i
++)
1251 link
->u
.pwszFile
[i
] =
1252 hton16(*(WORD
*)(ptr
+ i
* sizeof(WCHAR
)));
1253 link
->u
.pwszFile
[realDataLen
/ sizeof(WCHAR
)] = '\0';
1254 TRACE("returning file %s\n", debugstr_w(link
->u
.pwszFile
));
1259 bytesNeeded
+= sizeof(WCHAR
);
1261 *pcbStructInfo
= bytesNeeded
;
1262 else if (*pcbStructInfo
< bytesNeeded
)
1264 *pcbStructInfo
= bytesNeeded
;
1265 SetLastError(ERROR_MORE_DATA
);
1270 PSPC_LINK link
= (PSPC_LINK
)pvStructInfo
;
1272 link
->dwLinkChoice
= SPC_FILE_LINK_CHOICE
;
1273 link
->u
.pwszFile
[0] = '\0';
1279 SetLastError(CRYPT_E_ASN1_BADTAG
);
1282 TRACE("returning %d\n", ret
);
1286 BOOL WINAPI
WVTAsn1SpcLinkDecode(DWORD dwCertEncodingType
,
1287 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1288 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1292 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1293 pvStructInfo
, *pcbStructInfo
);
1299 ret
= CRYPT_AsnDecodeSPCLinkInternal(dwCertEncodingType
,
1300 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, NULL
, &bytesNeeded
);
1304 *pcbStructInfo
= bytesNeeded
;
1305 else if (*pcbStructInfo
< bytesNeeded
)
1307 *pcbStructInfo
= bytesNeeded
;
1308 SetLastError(ERROR_MORE_DATA
);
1313 SPC_LINK
*link
= (SPC_LINK
*)pvStructInfo
;
1316 (LPWSTR
)((BYTE
*)pvStructInfo
+ sizeof(SPC_LINK
));
1317 ret
= CRYPT_AsnDecodeSPCLinkInternal(dwCertEncodingType
,
1318 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
1325 SetLastError(STATUS_ACCESS_VIOLATION
);
1328 TRACE("returning %d\n", ret
);
1332 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
1333 DWORD
, DWORD
, void *, DWORD
*);
1336 * The expected tag of the item. If tag is 0, decodeFunc is called
1337 * regardless of the tag value seen.
1339 * A sequence is decoded into a struct. The offset member is the
1340 * offset of this item within that struct.
1342 * The decoder function to use. If this is NULL, then the member isn't
1343 * decoded, but minSize space is reserved for it.
1345 * The minimum amount of space occupied after decoding. You must set this.
1347 * If true, and the tag doesn't match the expected tag for this item,
1348 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
1349 * filled with 0 for this member.
1350 * hasPointer, pointerOffset:
1351 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
1352 * the offset within the struct of the data pointer (or to the
1353 * first data pointer, if more than one exist).
1355 * Used by CRYPT_AsnDecodeSequence, not for your use.
1357 struct AsnDecodeSequenceItem
1361 CryptDecodeObjectFunc decodeFunc
;
1365 DWORD pointerOffset
;
1369 /* Decodes the items in a sequence, where the items are described in items,
1370 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
1371 * pvStructInfo. nextData is a pointer to the memory location at which the
1372 * first decoded item with a dynamic pointer should point.
1373 * Upon decoding, *cbDecoded is the total number of bytes decoded.
1375 static BOOL
CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType
,
1376 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
1377 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, BYTE
*nextData
,
1381 DWORD i
, decoded
= 0;
1382 const BYTE
*ptr
= pbEncoded
;
1384 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
1385 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
1387 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
1389 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
1393 if ((ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
1396 BYTE nextItemLenBytes
= GET_LEN_BYTES(ptr
[1]);
1398 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
1400 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
1402 TRACE("Setting next pointer to %p\n",
1404 *(BYTE
**)((BYTE
*)pvStructInfo
+
1405 items
[i
].pointerOffset
) = nextData
;
1407 if (items
[i
].decodeFunc
)
1410 TRACE("decoding item %d\n", i
);
1412 TRACE("sizing item %d\n", i
);
1413 ret
= items
[i
].decodeFunc(dwCertEncodingType
,
1414 NULL
, ptr
, 1 + nextItemLenBytes
+ nextItemLen
,
1415 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
1416 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
1417 : NULL
, &items
[i
].size
);
1420 /* Account for alignment padding */
1421 if (items
[i
].size
% sizeof(DWORD
))
1422 items
[i
].size
+= sizeof(DWORD
) -
1423 items
[i
].size
% sizeof(DWORD
);
1424 TRACE("item %d size: %d\n", i
, items
[i
].size
);
1425 if (nextData
&& items
[i
].hasPointer
&&
1426 items
[i
].size
> items
[i
].minSize
)
1427 nextData
+= items
[i
].size
- items
[i
].minSize
;
1428 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
1429 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
1430 TRACE("item %d: decoded %d bytes\n", i
,
1431 1 + nextItemLenBytes
+ nextItemLen
);
1433 else if (items
[i
].optional
&&
1434 GetLastError() == CRYPT_E_ASN1_BADTAG
)
1436 TRACE("skipping optional item %d\n", i
);
1437 items
[i
].size
= items
[i
].minSize
;
1438 SetLastError(NOERROR
);
1442 TRACE("item %d failed: %08x\n", i
,
1447 TRACE("item %d: decoded %d bytes\n", i
,
1448 1 + nextItemLenBytes
+ nextItemLen
);
1449 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
1450 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
1451 items
[i
].size
= items
[i
].minSize
;
1454 else if (items
[i
].optional
)
1456 TRACE("skipping optional item %d\n", i
);
1457 items
[i
].size
= items
[i
].minSize
;
1461 TRACE("item %d: tag %02x doesn't match expected %02x\n",
1462 i
, ptr
[0], items
[i
].tag
);
1463 SetLastError(CRYPT_E_ASN1_BADTAG
);
1468 else if (items
[i
].optional
)
1470 TRACE("missing optional item %d, skipping\n", i
);
1471 items
[i
].size
= items
[i
].minSize
;
1475 TRACE("not enough bytes for item %d, failing\n", i
);
1476 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1481 *cbDecoded
= decoded
;
1482 TRACE("returning %d\n", ret
);
1486 /* This decodes an arbitrary sequence into a contiguous block of memory
1487 * (basically, a struct.) Each element being decoded is described by a struct
1488 * AsnDecodeSequenceItem, see above.
1489 * startingPointer is an optional pointer to the first place where dynamic
1490 * data will be stored. If you know the starting offset, you may pass it
1491 * here. Otherwise, pass NULL, and one will be inferred from the items.
1493 static BOOL
CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType
,
1494 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
1495 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1496 void *startingPointer
)
1500 TRACE("%p, %d, %p, %d, %08x, %p, %d, %p\n", items
, cItem
, pbEncoded
,
1501 cbEncoded
, dwFlags
, pvStructInfo
, *pcbStructInfo
, startingPointer
);
1503 if (pbEncoded
[0] == ASN_SEQUENCE
)
1507 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1509 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
1510 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
1512 cbEncoded
-= 1 + lenBytes
;
1513 if (cbEncoded
< dataLen
)
1515 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
1517 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1521 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
, ptr
,
1522 cbEncoded
, dwFlags
, NULL
, NULL
, &cbDecoded
);
1523 if (ret
&& cbDecoded
!= dataLen
)
1525 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
1527 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1532 DWORD i
, bytesNeeded
= 0, structSize
= 0;
1534 for (i
= 0; i
< cItem
; i
++)
1536 bytesNeeded
+= items
[i
].size
;
1537 structSize
+= items
[i
].minSize
;
1540 *pcbStructInfo
= bytesNeeded
;
1541 else if (*pcbStructInfo
< bytesNeeded
)
1543 SetLastError(ERROR_MORE_DATA
);
1544 *pcbStructInfo
= bytesNeeded
;
1551 *pcbStructInfo
= bytesNeeded
;
1552 if (startingPointer
)
1553 nextData
= (BYTE
*)startingPointer
;
1555 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
1556 memset(pvStructInfo
, 0, structSize
);
1557 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
,
1558 ptr
, cbEncoded
, dwFlags
, pvStructInfo
, nextData
,
1566 SetLastError(CRYPT_E_ASN1_BADTAG
);
1569 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1573 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
1574 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1575 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1579 TRACE("(%p, %d, 0x%08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
1580 pvStructInfo
, *pcbStructInfo
);
1582 if (pbEncoded
[0] == ASN_BITSTRING
)
1584 DWORD bytesNeeded
, dataLen
;
1586 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1588 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1589 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
1591 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
1593 *pcbStructInfo
= bytesNeeded
;
1594 else if (*pcbStructInfo
< bytesNeeded
)
1596 *pcbStructInfo
= bytesNeeded
;
1597 SetLastError(ERROR_MORE_DATA
);
1602 CRYPT_BIT_BLOB
*blob
;
1604 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
1605 blob
->cbData
= dataLen
- 1;
1606 blob
->cUnusedBits
= *(pbEncoded
+ 1 +
1607 GET_LEN_BYTES(pbEncoded
[1]));
1608 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1610 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 +
1611 GET_LEN_BYTES(pbEncoded
[1]);
1615 assert(blob
->pbData
);
1618 BYTE mask
= 0xff << blob
->cUnusedBits
;
1620 memcpy(blob
->pbData
, pbEncoded
+ 2 +
1621 GET_LEN_BYTES(pbEncoded
[1]), blob
->cbData
);
1622 blob
->pbData
[blob
->cbData
- 1] &= mask
;
1630 SetLastError(CRYPT_E_ASN1_BADTAG
);
1633 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1637 static BOOL WINAPI
CRYPT_AsnDecodeSPCLinkPointer(DWORD dwCertEncodingType
,
1638 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1639 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1644 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1646 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1648 SPC_LINK
**pLink
= (SPC_LINK
**)pvStructInfo
;
1650 ret
= CRYPT_AsnDecodeSPCLinkInternal(dwCertEncodingType
, lpszStructType
,
1651 pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
, NULL
, &size
);
1655 *pcbStructInfo
= size
+ sizeof(PSPC_LINK
);
1656 else if (*pcbStructInfo
< size
+ sizeof(PSPC_LINK
))
1658 *pcbStructInfo
= size
+ sizeof(PSPC_LINK
);
1659 SetLastError(ERROR_MORE_DATA
);
1664 *pcbStructInfo
= size
+ sizeof(PSPC_LINK
);
1665 /* Set imageData's pointer if necessary */
1666 if (size
> sizeof(SPC_LINK
))
1668 (*pLink
)->u
.pwszUrl
=
1669 (LPWSTR
)((BYTE
*)*pLink
+ sizeof(SPC_LINK
));
1671 ret
= CRYPT_AsnDecodeSPCLinkInternal(dwCertEncodingType
,
1672 lpszStructType
, pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
,
1673 *pLink
, pcbStructInfo
);
1680 BOOL WINAPI
WVTAsn1SpcPeImageDataDecode(DWORD dwCertEncodingType
,
1681 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1682 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1686 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1687 pvStructInfo
, *pcbStructInfo
);
1691 struct AsnDecodeSequenceItem items
[] = {
1692 { ASN_BITSTRING
, offsetof(SPC_PE_IMAGE_DATA
, Flags
),
1693 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1694 offsetof(SPC_PE_IMAGE_DATA
, Flags
.pbData
), 0 },
1695 { ASN_CONSTRUCTOR
| ASN_CONTEXT
, offsetof(SPC_PE_IMAGE_DATA
, pFile
),
1696 CRYPT_AsnDecodeSPCLinkPointer
, sizeof(PSPC_LINK
), TRUE
, TRUE
,
1697 offsetof(SPC_PE_IMAGE_DATA
, pFile
), 0 },
1700 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1701 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1702 pvStructInfo
, pcbStructInfo
, NULL
);
1706 SetLastError(STATUS_ACCESS_VIOLATION
);
1709 TRACE("returning %d\n", ret
);
1713 static BOOL WINAPI
CRYPT_AsnDecodeOidIgnoreTag(DWORD dwCertEncodingType
,
1714 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1715 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1720 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1721 pvStructInfo
, *pcbStructInfo
);
1723 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1725 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1726 DWORD bytesNeeded
= sizeof(LPSTR
);
1730 /* The largest possible string for the first two components
1731 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1736 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1737 pbEncoded
[1 + lenBytes
] / 40,
1738 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1740 bytesNeeded
+= strlen(firstTwo
) + 1;
1741 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1742 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1744 /* large enough for ".4000000" */
1748 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1755 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1758 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1765 snprintf(str
, sizeof(str
), ".%d", val
);
1766 bytesNeeded
+= strlen(str
);
1771 *pcbStructInfo
= bytesNeeded
;
1772 else if (*pcbStructInfo
< bytesNeeded
)
1774 *pcbStructInfo
= bytesNeeded
;
1775 SetLastError(ERROR_MORE_DATA
);
1783 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1786 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1787 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1789 pszObjId
+= strlen(pszObjId
);
1790 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1791 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1795 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1804 sprintf(pszObjId
, ".%d", val
);
1805 pszObjId
+= strlen(pszObjId
);
1809 *(LPSTR
*)pvStructInfo
= NULL
;
1810 *pcbStructInfo
= bytesNeeded
;
1816 static BOOL WINAPI
CRYPT_AsnDecodeOid(DWORD dwCertEncodingType
,
1817 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1818 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1822 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1823 pvStructInfo
, *pcbStructInfo
);
1826 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1827 else if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1828 ret
= CRYPT_AsnDecodeOidIgnoreTag(dwCertEncodingType
, lpszStructType
,
1829 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
1831 SetLastError(CRYPT_E_ASN1_BADTAG
);
1835 static BOOL WINAPI
CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType
,
1836 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1837 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1840 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
1842 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1843 pvStructInfo
, *pcbStructInfo
);
1845 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1846 bytesNeeded
+= cbEncoded
;
1848 *pcbStructInfo
= bytesNeeded
;
1849 else if (*pcbStructInfo
< bytesNeeded
)
1851 SetLastError(ERROR_MORE_DATA
);
1852 *pcbStructInfo
= bytesNeeded
;
1857 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1859 *pcbStructInfo
= bytesNeeded
;
1860 blob
->cbData
= cbEncoded
;
1861 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1862 blob
->pbData
= (LPBYTE
)pbEncoded
;
1865 assert(blob
->pbData
);
1866 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1872 static BOOL WINAPI
CRYPT_AsnDecodeAttributeTypeValue(DWORD dwCertEncodingType
,
1873 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1874 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1876 CRYPT_ATTRIBUTE_TYPE_VALUE
*typeValue
=
1877 (CRYPT_ATTRIBUTE_TYPE_VALUE
*)pvStructInfo
;
1878 struct AsnDecodeSequenceItem items
[] = {
1879 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE_TYPE_VALUE
, pszObjId
),
1880 CRYPT_AsnDecodeOid
, sizeof(LPSTR
), FALSE
, TRUE
,
1881 offsetof(CRYPT_ATTRIBUTE_TYPE_VALUE
, pszObjId
), 0 },
1882 { 0, offsetof(CRYPT_ATTRIBUTE_TYPE_VALUE
, Value
),
1883 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
1884 offsetof(CRYPT_ATTRIBUTE_TYPE_VALUE
, Value
.pbData
), 0 },
1887 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1888 pvStructInfo
, *pcbStructInfo
);
1890 return CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1891 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1892 pvStructInfo
, pcbStructInfo
,
1893 typeValue
? typeValue
->pszObjId
: NULL
);
1896 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
1897 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1898 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1900 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
1901 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
1903 struct AsnDecodeSequenceItem items
[] = {
1904 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
1905 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1906 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
1907 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
1908 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
1909 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
1912 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1913 pvStructInfo
, *pcbStructInfo
);
1915 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1916 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1917 pvStructInfo
, pcbStructInfo
, algo
? algo
->pszObjId
: NULL
);
1918 if (ret
&& pvStructInfo
)
1920 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
1921 debugstr_a(algo
->pszObjId
));
1926 static BOOL WINAPI
CRYPT_AsnDecodeSPCDigest(DWORD dwCertEncodingType
,
1927 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1928 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1930 struct SPCDigest
*digest
=
1931 (struct SPCDigest
*)pvStructInfo
;
1932 struct AsnDecodeSequenceItem items
[] = {
1933 { ASN_SEQUENCEOF
, offsetof(struct SPCDigest
, DigestAlgorithm
),
1934 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1936 offsetof(struct SPCDigest
, DigestAlgorithm
.pszObjId
), 0 },
1937 { ASN_OCTETSTRING
, offsetof(struct SPCDigest
, Digest
),
1938 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
1939 FALSE
, TRUE
, offsetof(struct SPCDigest
, Digest
.pbData
), 0 },
1942 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1943 pvStructInfo
, *pcbStructInfo
);
1945 return CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1946 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1947 pvStructInfo
, pcbStructInfo
,
1948 digest
? digest
->DigestAlgorithm
.pszObjId
: NULL
);
1951 BOOL WINAPI
WVTAsn1SpcIndirectDataContentDecode(DWORD dwCertEncodingType
,
1952 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1953 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1957 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1958 pvStructInfo
, *pcbStructInfo
);
1962 struct AsnDecodeSequenceItem items
[] = {
1963 { ASN_SEQUENCEOF
, offsetof(SPC_INDIRECT_DATA_CONTENT
, Data
),
1964 CRYPT_AsnDecodeAttributeTypeValue
,
1965 sizeof(CRYPT_ATTRIBUTE_TYPE_VALUE
), FALSE
, TRUE
,
1966 offsetof(SPC_INDIRECT_DATA_CONTENT
, Data
.pszObjId
), 0 },
1967 { ASN_SEQUENCEOF
, offsetof(SPC_INDIRECT_DATA_CONTENT
, DigestAlgorithm
),
1968 CRYPT_AsnDecodeSPCDigest
, sizeof(struct SPCDigest
),
1970 offsetof(SPC_INDIRECT_DATA_CONTENT
, DigestAlgorithm
.pszObjId
), 0 },
1973 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1974 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1975 pvStructInfo
, pcbStructInfo
, NULL
);
1979 SetLastError(STATUS_ACCESS_VIOLATION
);
1982 TRACE("returning %d\n", ret
);
1986 BOOL WINAPI
WVTAsn1SpcSpOpusInfoDecode(DWORD dwCertEncodingType
,
1987 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1988 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1990 FIXME("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1991 pvStructInfo
, *pcbStructInfo
);
1995 static BOOL WINAPI
CRYPT_AsnDecodeBMPString(DWORD dwCertEncodingType
,
1996 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1997 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2000 DWORD bytesNeeded
, dataLen
;
2002 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2004 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2006 bytesNeeded
= dataLen
+ 2 + sizeof(LPWSTR
);
2008 *pcbStructInfo
= bytesNeeded
;
2009 else if (*pcbStructInfo
< bytesNeeded
)
2011 *pcbStructInfo
= bytesNeeded
;
2012 SetLastError(ERROR_MORE_DATA
);
2020 *pcbStructInfo
= bytesNeeded
;
2021 assert(pvStructInfo
);
2022 str
= *(LPWSTR
*)pvStructInfo
;
2023 for (i
= 0; i
< dataLen
/ 2; i
++)
2024 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
2025 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
2026 /* Decoded string is always NULL-terminated */
2033 static BOOL
CRYPT_AsnDecodeInteger(const BYTE
*pbEncoded
,
2034 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
2037 DWORD bytesNeeded
, dataLen
;
2039 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
2041 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
2043 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
2045 *pcbStructInfo
= bytesNeeded
;
2046 else if (*pcbStructInfo
< bytesNeeded
)
2048 *pcbStructInfo
= bytesNeeded
;
2049 SetLastError(ERROR_MORE_DATA
);
2054 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
2056 *pcbStructInfo
= bytesNeeded
;
2057 blob
->cbData
= dataLen
;
2058 assert(blob
->pbData
);
2063 for (i
= 0; i
< blob
->cbData
; i
++)
2065 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2074 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
2075 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
2076 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2077 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2080 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
2081 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
2082 DWORD size
= sizeof(buf
);
2084 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
2085 ret
= CRYPT_AsnDecodeInteger(pbEncoded
, cbEncoded
, 0, buf
, &size
);
2089 *pcbStructInfo
= sizeof(int);
2090 else if (*pcbStructInfo
< sizeof(int))
2092 *pcbStructInfo
= sizeof(int);
2093 SetLastError(ERROR_MORE_DATA
);
2100 *pcbStructInfo
= sizeof(int);
2101 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
2103 /* initialize to a negative value to sign-extend */
2108 for (i
= 0; i
< blob
->cbData
; i
++)
2111 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
2113 memcpy(pvStructInfo
, &val
, sizeof(int));
2116 else if (GetLastError() == ERROR_MORE_DATA
)
2117 SetLastError(CRYPT_E_ASN1_LARGE
);
2121 BOOL WINAPI
WVTAsn1CatMemberInfoDecode(DWORD dwCertEncodingType
,
2122 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2123 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2127 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2128 pvStructInfo
, *pcbStructInfo
);
2132 struct AsnDecodeSequenceItem items
[] = {
2133 { ASN_BMPSTRING
, offsetof(CAT_MEMBERINFO
, pwszSubjGuid
),
2134 CRYPT_AsnDecodeBMPString
, sizeof(LPWSTR
), FALSE
, TRUE
,
2135 offsetof(CAT_MEMBERINFO
, pwszSubjGuid
), 0 },
2136 { ASN_INTEGER
, offsetof(CAT_MEMBERINFO
, dwCertVersion
),
2137 CRYPT_AsnDecodeInt
, sizeof(DWORD
),
2138 FALSE
, FALSE
, 0, 0 },
2141 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2142 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2143 pvStructInfo
, pcbStructInfo
, NULL
);
2147 SetLastError(STATUS_ACCESS_VIOLATION
);
2150 TRACE("returning %d\n", ret
);
2154 BOOL WINAPI
WVTAsn1CatNameValueDecode(DWORD dwCertEncodingType
,
2155 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2156 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2160 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2161 pvStructInfo
, *pcbStructInfo
);
2165 struct AsnDecodeSequenceItem items
[] = {
2166 { ASN_BMPSTRING
, offsetof(CAT_NAMEVALUE
, pwszTag
),
2167 CRYPT_AsnDecodeBMPString
, sizeof(LPWSTR
), FALSE
, TRUE
,
2168 offsetof(CAT_NAMEVALUE
, pwszTag
), 0 },
2169 { ASN_INTEGER
, offsetof(CAT_NAMEVALUE
, fdwFlags
),
2170 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2171 { ASN_OCTETSTRING
, offsetof(CAT_NAMEVALUE
, Value
),
2172 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
2173 offsetof(CAT_NAMEVALUE
, Value
.pbData
), 0 },
2176 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2177 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2178 pvStructInfo
, pcbStructInfo
, NULL
);
2182 SetLastError(STATUS_ACCESS_VIOLATION
);
2185 TRACE("returning %d\n", ret
);
2189 static BOOL WINAPI
CRYPT_AsnDecodeBool(DWORD dwCertEncodingType
,
2190 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2191 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2197 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2200 if (GET_LEN_BYTES(pbEncoded
[1]) > 1)
2202 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2205 if (pbEncoded
[1] > 1)
2207 SetLastError(CRYPT_E_ASN1_CORRUPT
);
2212 *pcbStructInfo
= sizeof(BOOL
);
2215 else if (*pcbStructInfo
< sizeof(BOOL
))
2217 *pcbStructInfo
= sizeof(BOOL
);
2218 SetLastError(ERROR_MORE_DATA
);
2223 *pcbStructInfo
= sizeof(BOOL
);
2224 *(BOOL
*)pvStructInfo
= pbEncoded
[2] ? TRUE
: FALSE
;
2227 TRACE("returning %d (%08x)\n", ret
, GetLastError());
2231 BOOL WINAPI
WVTAsn1SpcFinancialCriteriaInfoDecode(DWORD dwCertEncodingType
,
2232 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2233 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2237 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
2238 pvStructInfo
, *pcbStructInfo
);
2242 struct AsnDecodeSequenceItem items
[] = {
2243 { ASN_BOOL
, offsetof(SPC_FINANCIAL_CRITERIA
, fFinancialInfoAvailable
),
2244 CRYPT_AsnDecodeBool
, sizeof(BOOL
), FALSE
, FALSE
, 0, 0 },
2245 { ASN_BOOL
, offsetof(SPC_FINANCIAL_CRITERIA
, fMeetsCriteria
),
2246 CRYPT_AsnDecodeBool
, sizeof(BOOL
), FALSE
, FALSE
, 0, 0 },
2249 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2250 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2251 pvStructInfo
, pcbStructInfo
, NULL
);
2255 SetLastError(STATUS_ACCESS_VIOLATION
);
2258 TRACE("returning %d\n", ret
);