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_BITSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x03)
53 #define ASN_BMPSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x1e)
55 static BOOL
CRYPT_EncodeLen(DWORD len
, BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
57 DWORD bytesNeeded
, significantBytes
= 0;
65 for (temp
= len
, significantBytes
= sizeof(temp
); !(temp
& 0xff000000);
66 temp
<<= 8, significantBytes
--)
68 bytesNeeded
= significantBytes
+ 1;
72 *pcbEncoded
= bytesNeeded
;
75 if (*pcbEncoded
< bytesNeeded
)
77 SetLastError(ERROR_MORE_DATA
);
81 *pbEncoded
= (BYTE
)len
;
86 *pbEncoded
++ = significantBytes
| 0x80;
87 for (i
= 0; i
< significantBytes
; i
++)
89 *(pbEncoded
+ significantBytes
- i
- 1) = (BYTE
)(len
& 0xff);
93 *pcbEncoded
= bytesNeeded
;
97 static BOOL WINAPI
CRYPT_AsnEncodeOctets(DWORD dwCertEncodingType
,
98 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
102 const CRYPT_DATA_BLOB
*blob
= (const CRYPT_DATA_BLOB
*)pvStructInfo
;
103 DWORD bytesNeeded
, lenBytes
;
105 TRACE("(%d, %p), %p, %d\n", blob
->cbData
, blob
->pbData
, pbEncoded
,
108 CRYPT_EncodeLen(blob
->cbData
, NULL
, &lenBytes
);
109 bytesNeeded
= 1 + lenBytes
+ blob
->cbData
;
111 *pcbEncoded
= bytesNeeded
;
112 else if (*pcbEncoded
< bytesNeeded
)
114 *pcbEncoded
= bytesNeeded
;
115 SetLastError(ERROR_MORE_DATA
);
120 *pbEncoded
++ = ASN_OCTETSTRING
;
121 CRYPT_EncodeLen(blob
->cbData
, pbEncoded
, &lenBytes
);
122 pbEncoded
+= lenBytes
;
124 memcpy(pbEncoded
, blob
->pbData
, blob
->cbData
);
126 TRACE("returning %d\n", ret
);
130 BOOL WINAPI
WVTAsn1SpcLinkEncode(DWORD dwCertEncodingType
,
131 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
136 TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
137 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
,
142 const SPC_LINK
*link
= (const SPC_LINK
*)pvStructInfo
;
143 DWORD bytesNeeded
, lenBytes
;
145 switch (link
->dwLinkChoice
)
147 case SPC_FILE_LINK_CHOICE
:
149 DWORD fileNameLen
, fileNameLenBytes
;
152 fileNameLen
= link
->u
.pwszFile
?
153 lstrlenW(link
->u
.pwszFile
) * sizeof(WCHAR
) : 0;
154 CRYPT_EncodeLen(fileNameLen
, NULL
, &fileNameLenBytes
);
155 CRYPT_EncodeLen(1 + fileNameLenBytes
+ fileNameLen
, NULL
,
157 bytesNeeded
= 2 + lenBytes
+ fileNameLenBytes
+ fileNameLen
;
160 *pcbEncoded
= bytesNeeded
;
163 else if (*pcbEncoded
< bytesNeeded
)
165 SetLastError(ERROR_MORE_DATA
);
166 *pcbEncoded
= bytesNeeded
;
170 *pcbEncoded
= bytesNeeded
;
171 *pbEncoded
++ = ASN_CONSTRUCTOR
| ASN_CONTEXT
| 2;
172 CRYPT_EncodeLen(1 + fileNameLenBytes
+ fileNameLen
, pbEncoded
,
174 pbEncoded
+= lenBytes
;
175 *pbEncoded
++ = ASN_CONTEXT
;
176 CRYPT_EncodeLen(fileNameLen
, pbEncoded
, &fileNameLenBytes
);
177 pbEncoded
+= fileNameLenBytes
;
178 for (ptr
= link
->u
.pwszFile
; ptr
&& *ptr
; ptr
++)
180 *(WCHAR
*)pbEncoded
= hton16(*ptr
);
181 pbEncoded
+= sizeof(WCHAR
);
187 case SPC_MONIKER_LINK_CHOICE
:
189 DWORD classIdLenBytes
, dataLenBytes
, dataLen
;
190 CRYPT_DATA_BLOB classId
= { sizeof(link
->u
.Moniker
.ClassId
),
191 (BYTE
*)link
->u
.Moniker
.ClassId
};
193 CRYPT_EncodeLen(classId
.cbData
, NULL
, &classIdLenBytes
);
194 CRYPT_EncodeLen(link
->u
.Moniker
.SerializedData
.cbData
, NULL
,
196 dataLen
= 2 + classIdLenBytes
+ classId
.cbData
+
197 dataLenBytes
+ link
->u
.Moniker
.SerializedData
.cbData
;
198 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
199 bytesNeeded
= 1 + dataLen
+ lenBytes
;
202 *pcbEncoded
= bytesNeeded
;
205 else if (*pcbEncoded
< bytesNeeded
)
207 SetLastError(ERROR_MORE_DATA
);
208 *pcbEncoded
= bytesNeeded
;
214 *pcbEncoded
= bytesNeeded
;
215 *pbEncoded
++ = ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1;
216 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
217 pbEncoded
+= lenBytes
;
218 size
= 1 + classIdLenBytes
+ classId
.cbData
;
219 CRYPT_AsnEncodeOctets(X509_ASN_ENCODING
, NULL
, &classId
,
222 size
= 1 + dataLenBytes
+ link
->u
.Moniker
.SerializedData
.cbData
;
223 CRYPT_AsnEncodeOctets(X509_ASN_ENCODING
, NULL
,
224 &link
->u
.Moniker
.SerializedData
, pbEncoded
, &size
);
230 case SPC_URL_LINK_CHOICE
:
235 /* Check for invalid characters in URL */
238 for (ptr
= link
->u
.pwszUrl
; ptr
&& *ptr
&& ret
; ptr
++)
242 SetLastError(CRYPT_E_INVALID_IA5_STRING
);
249 CRYPT_EncodeLen(urlLen
, NULL
, &lenBytes
);
250 bytesNeeded
= 1 + lenBytes
+ urlLen
;
252 *pcbEncoded
= bytesNeeded
;
253 else if (*pcbEncoded
< bytesNeeded
)
255 SetLastError(ERROR_MORE_DATA
);
256 *pcbEncoded
= bytesNeeded
;
261 *pcbEncoded
= bytesNeeded
;
262 *pbEncoded
++ = ASN_CONTEXT
;
263 CRYPT_EncodeLen(urlLen
, pbEncoded
, &lenBytes
);
264 pbEncoded
+= lenBytes
;
265 for (ptr
= link
->u
.pwszUrl
; ptr
&& *ptr
; ptr
++)
266 *pbEncoded
++ = (BYTE
)*ptr
;
272 SetLastError(E_INVALIDARG
);
277 SetLastError(STATUS_ACCESS_VIOLATION
);
280 TRACE("returning %d\n", ret
);
284 typedef BOOL (WINAPI
*CryptEncodeObjectFunc
)(DWORD
, LPCSTR
, const void *,
287 struct AsnEncodeSequenceItem
289 const void *pvStructInfo
;
290 CryptEncodeObjectFunc encodeFunc
;
291 DWORD size
; /* used during encoding, not for your use */
294 static BOOL WINAPI
CRYPT_AsnEncodeSequence(DWORD dwCertEncodingType
,
295 struct AsnEncodeSequenceItem items
[], DWORD cItem
, BYTE
*pbEncoded
,
299 DWORD i
, dataLen
= 0;
301 TRACE("%p, %d, %p, %d\n", items
, cItem
, pbEncoded
, *pcbEncoded
);
302 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
304 ret
= items
[i
].encodeFunc(dwCertEncodingType
, NULL
,
305 items
[i
].pvStructInfo
, NULL
, &items
[i
].size
);
306 /* Some functions propagate their errors through the size */
308 *pcbEncoded
= items
[i
].size
;
309 dataLen
+= items
[i
].size
;
313 DWORD lenBytes
, bytesNeeded
;
315 CRYPT_EncodeLen(dataLen
, NULL
, &lenBytes
);
316 bytesNeeded
= 1 + lenBytes
+ dataLen
;
318 *pcbEncoded
= bytesNeeded
;
319 else if (*pcbEncoded
< bytesNeeded
)
321 *pcbEncoded
= bytesNeeded
;
322 SetLastError(ERROR_MORE_DATA
);
327 *pcbEncoded
= bytesNeeded
;
328 *pbEncoded
++ = ASN_SEQUENCE
;
329 CRYPT_EncodeLen(dataLen
, pbEncoded
, &lenBytes
);
330 pbEncoded
+= lenBytes
;
331 for (i
= 0; ret
&& i
< cItem
; i
++)
333 ret
= items
[i
].encodeFunc(dwCertEncodingType
, NULL
,
334 items
[i
].pvStructInfo
, pbEncoded
, &items
[i
].size
);
335 /* Some functions propagate their errors through the size */
337 *pcbEncoded
= items
[i
].size
;
338 pbEncoded
+= items
[i
].size
;
342 TRACE("returning %d\n", ret
);
346 static BOOL WINAPI
CRYPT_AsnEncodeBits(DWORD dwCertEncodingType
,
347 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
354 const CRYPT_BIT_BLOB
*blob
= (const CRYPT_BIT_BLOB
*)pvStructInfo
;
355 DWORD bytesNeeded
, lenBytes
, dataBytes
;
358 /* yep, MS allows cUnusedBits to be >= 8 */
359 if (!blob
->cUnusedBits
)
361 dataBytes
= blob
->cbData
;
364 else if (blob
->cbData
* 8 > blob
->cUnusedBits
)
366 dataBytes
= (blob
->cbData
* 8 - blob
->cUnusedBits
) / 8 + 1;
367 unusedBits
= blob
->cUnusedBits
>= 8 ? blob
->cUnusedBits
/ 8 :
375 CRYPT_EncodeLen(dataBytes
+ 1, NULL
, &lenBytes
);
376 bytesNeeded
= 1 + lenBytes
+ dataBytes
+ 1;
379 *pcbEncoded
= bytesNeeded
;
382 else if (*pcbEncoded
< bytesNeeded
)
384 *pcbEncoded
= bytesNeeded
;
385 SetLastError(ERROR_MORE_DATA
);
390 *pcbEncoded
= bytesNeeded
;
391 *pbEncoded
++ = ASN_BITSTRING
;
392 CRYPT_EncodeLen(dataBytes
+ 1, pbEncoded
, &lenBytes
);
393 pbEncoded
+= lenBytes
;
394 *pbEncoded
++ = unusedBits
;
397 BYTE mask
= 0xff << unusedBits
;
401 memcpy(pbEncoded
, blob
->pbData
, dataBytes
- 1);
402 pbEncoded
+= dataBytes
- 1;
404 *pbEncoded
= *(blob
->pbData
+ dataBytes
- 1) & mask
;
410 SetLastError(STATUS_ACCESS_VIOLATION
);
416 struct AsnConstructedItem
419 const void *pvStructInfo
;
420 CryptEncodeObjectFunc encodeFunc
;
423 static BOOL WINAPI
CRYPT_AsnEncodeConstructed(DWORD dwCertEncodingType
,
424 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
428 const struct AsnConstructedItem
*item
=
429 (const struct AsnConstructedItem
*)pvStructInfo
;
432 if ((ret
= item
->encodeFunc(dwCertEncodingType
, lpszStructType
,
433 item
->pvStructInfo
, NULL
, &len
)))
435 DWORD dataLen
, bytesNeeded
;
437 CRYPT_EncodeLen(len
, NULL
, &dataLen
);
438 bytesNeeded
= 1 + dataLen
+ len
;
440 *pcbEncoded
= bytesNeeded
;
441 else if (*pcbEncoded
< bytesNeeded
)
443 *pcbEncoded
= bytesNeeded
;
444 SetLastError(ERROR_MORE_DATA
);
449 *pcbEncoded
= bytesNeeded
;
450 *pbEncoded
++ = ASN_CONTEXT
| ASN_CONSTRUCTOR
| item
->tag
;
451 CRYPT_EncodeLen(len
, pbEncoded
, &dataLen
);
452 pbEncoded
+= dataLen
;
453 ret
= item
->encodeFunc(dwCertEncodingType
, lpszStructType
,
454 item
->pvStructInfo
, pbEncoded
, &len
);
457 /* Some functions propagate their errors through the size */
464 /* Some functions propagate their errors through the size */
471 BOOL WINAPI
WVTAsn1SpcPeImageDataEncode(DWORD dwCertEncodingType
,
472 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
475 const SPC_PE_IMAGE_DATA
*imageData
=
476 (const SPC_PE_IMAGE_DATA
*)pvStructInfo
;
479 TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
480 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
,
485 struct AsnEncodeSequenceItem items
[2] = {
488 struct AsnConstructedItem constructed
= { 0, imageData
->pFile
,
489 WVTAsn1SpcLinkEncode
};
492 if (imageData
->Flags
.cbData
)
494 items
[cItem
].pvStructInfo
= &imageData
->Flags
;
495 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeBits
;
498 if (imageData
->pFile
)
500 items
[cItem
].pvStructInfo
= &constructed
;
501 items
[cItem
].encodeFunc
= CRYPT_AsnEncodeConstructed
;
505 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
, cItem
,
506 pbEncoded
, pcbEncoded
);
510 SetLastError(STATUS_ACCESS_VIOLATION
);
513 TRACE("returning %d\n", ret
);
517 static BOOL WINAPI
CRYPT_AsnEncodeOid(DWORD dwCertEncodingType
,
518 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
521 LPCSTR pszObjId
= (LPCSTR
)pvStructInfo
;
522 DWORD bytesNeeded
= 0, lenBytes
;
527 TRACE("%s\n", debugstr_a(pszObjId
));
534 if (sscanf(pszObjId
, "%d.%d.%n", &val1
, &val2
, &firstPos
) != 2)
536 SetLastError(CRYPT_E_ASN1_ERROR
);
540 firstByte
= val1
* 40 + val2
;
541 ptr
= pszObjId
+ firstPos
;
546 /* note I assume each component is at most 32-bits long in base 2 */
547 if (sscanf(ptr
, "%d%n", &val1
, &pos
) == 1)
549 if (val1
>= 0x10000000)
551 else if (val1
>= 0x200000)
553 else if (val1
>= 0x4000)
555 else if (val1
>= 0x80)
565 SetLastError(CRYPT_E_ASN1_ERROR
);
569 CRYPT_EncodeLen(bytesNeeded
, NULL
, &lenBytes
);
573 bytesNeeded
+= 1 + lenBytes
;
576 if (*pcbEncoded
< bytesNeeded
)
578 SetLastError(ERROR_MORE_DATA
);
583 *pbEncoded
++ = ASN_OBJECTIDENTIFIER
;
584 CRYPT_EncodeLen(bytesNeeded
- 1 - lenBytes
, pbEncoded
, &lenBytes
);
585 pbEncoded
+= lenBytes
;
591 *pbEncoded
++ = firstByte
;
592 ptr
= pszObjId
+ firstPos
;
595 sscanf(ptr
, "%d%n", &val
, &pos
);
597 unsigned char outBytes
[5];
600 if (val
>= 0x10000000)
602 else if (val
>= 0x200000)
604 else if (val
>= 0x4000)
606 else if (val
>= 0x80)
610 for (i
= numBytes
; i
> 0; i
--)
612 outBytes
[i
- 1] = val
& 0x7f;
615 for (i
= 0; i
< numBytes
- 1; i
++)
616 *pbEncoded
++ = outBytes
[i
] | 0x80;
617 *pbEncoded
++ = outBytes
[i
];
626 *pcbEncoded
= bytesNeeded
;
630 static BOOL WINAPI
CRYPT_CopyEncodedBlob(DWORD dwCertEncodingType
,
631 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
634 const CRYPT_DER_BLOB
*blob
= (const CRYPT_DER_BLOB
*)pvStructInfo
;
638 *pcbEncoded
= blob
->cbData
;
639 else if (*pcbEncoded
< blob
->cbData
)
641 *pcbEncoded
= blob
->cbData
;
642 SetLastError(ERROR_MORE_DATA
);
648 memcpy(pbEncoded
, blob
->pbData
, blob
->cbData
);
649 *pcbEncoded
= blob
->cbData
;
654 static BOOL WINAPI
CRYPT_AsnEncodeAlgorithmIdWithNullParams(
655 DWORD dwCertEncodingType
, LPCSTR lpszStructType
, const void *pvStructInfo
,
656 BYTE
*pbEncoded
, DWORD
*pcbEncoded
)
658 const CRYPT_ALGORITHM_IDENTIFIER
*algo
=
659 (const CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
660 static const BYTE asn1Null
[] = { ASN_NULL
, 0 };
661 static const CRYPT_DATA_BLOB nullBlob
= { sizeof(asn1Null
),
664 struct AsnEncodeSequenceItem items
[2] = {
665 { algo
->pszObjId
, CRYPT_AsnEncodeOid
, 0 },
666 { NULL
, CRYPT_CopyEncodedBlob
, 0 },
669 if (algo
->Parameters
.cbData
)
670 items
[1].pvStructInfo
= &algo
->Parameters
;
672 items
[1].pvStructInfo
= &nullBlob
;
673 ret
= CRYPT_AsnEncodeSequence(dwCertEncodingType
, items
,
674 sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
678 static BOOL WINAPI
CRYPT_AsnEncodeAttributeTypeValue(DWORD dwCertEncodingType
,
679 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
682 const CRYPT_ATTRIBUTE_TYPE_VALUE
*typeValue
=
683 (const CRYPT_ATTRIBUTE_TYPE_VALUE
*)pvStructInfo
;
684 struct AsnEncodeSequenceItem items
[] = {
685 { &typeValue
->pszObjId
, CRYPT_AsnEncodeOid
, 0 },
686 { &typeValue
->Value
, CRYPT_CopyEncodedBlob
, 0 },
689 return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
,
690 items
, sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
695 CRYPT_ALGORITHM_IDENTIFIER DigestAlgorithm
;
696 CRYPT_HASH_BLOB Digest
;
699 static BOOL WINAPI
CRYPT_AsnEncodeSPCDigest(DWORD dwCertEncodingType
,
700 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
703 const struct SPCDigest
*digest
= (const struct SPCDigest
*)pvStructInfo
;
704 struct AsnEncodeSequenceItem items
[] = {
705 { &digest
->DigestAlgorithm
, CRYPT_AsnEncodeAlgorithmIdWithNullParams
, 0 },
706 { &digest
->Digest
, CRYPT_CopyEncodedBlob
, 0 },
709 return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
,
710 items
, sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
713 BOOL WINAPI
WVTAsn1SpcIndirectDataContentEncode(DWORD dwCertEncodingType
,
714 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
719 TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
720 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
, pcbEncoded
);
724 const SPC_INDIRECT_DATA_CONTENT
*data
=
725 (const SPC_INDIRECT_DATA_CONTENT
*)pvStructInfo
;
726 struct AsnEncodeSequenceItem items
[] = {
727 { &data
->Data
, CRYPT_AsnEncodeAttributeTypeValue
, 0 },
728 { &data
->DigestAlgorithm
, CRYPT_AsnEncodeSPCDigest
, 0 },
731 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
,
732 items
, sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
736 SetLastError(STATUS_ACCESS_VIOLATION
);
742 static BOOL WINAPI
CRYPT_AsnEncodeBMPString(DWORD dwCertEncodingType
,
743 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
747 LPCWSTR str
= (LPCWSTR
)pvStructInfo
;
748 DWORD bytesNeeded
, lenBytes
, strLen
;
751 strLen
= lstrlenW(str
);
754 CRYPT_EncodeLen(strLen
* 2, NULL
, &lenBytes
);
755 bytesNeeded
= 1 + lenBytes
+ strLen
* 2;
757 *pcbEncoded
= bytesNeeded
;
758 else if (*pcbEncoded
< bytesNeeded
)
760 *pcbEncoded
= bytesNeeded
;
761 SetLastError(ERROR_MORE_DATA
);
768 *pcbEncoded
= bytesNeeded
;
769 *pbEncoded
++ = ASN_BMPSTRING
;
770 CRYPT_EncodeLen(strLen
* 2, pbEncoded
, &lenBytes
);
771 pbEncoded
+= lenBytes
;
772 for (i
= 0; i
< strLen
; i
++)
774 *pbEncoded
++ = (str
[i
] & 0xff00) >> 8;
775 *pbEncoded
++ = str
[i
] & 0x00ff;
781 static BOOL WINAPI
CRYPT_AsnEncodeInteger(DWORD dwCertEncodingType
,
782 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
789 DWORD significantBytes
, lenBytes
, bytesNeeded
;
792 const CRYPT_INTEGER_BLOB
*blob
=
793 (const CRYPT_INTEGER_BLOB
*)pvStructInfo
;
795 significantBytes
= blob
->cbData
;
796 if (significantBytes
)
798 if (blob
->pbData
[significantBytes
- 1] & 0x80)
800 /* negative, lop off leading (little-endian) 0xffs */
801 for (; significantBytes
> 0 &&
802 blob
->pbData
[significantBytes
- 1] == 0xff; significantBytes
--)
804 if (blob
->pbData
[significantBytes
- 1] < 0x80)
812 /* positive, lop off leading (little-endian) zeroes */
813 for (; significantBytes
> 0 &&
814 !blob
->pbData
[significantBytes
- 1]; significantBytes
--)
816 if (significantBytes
== 0)
817 significantBytes
= 1;
818 if (blob
->pbData
[significantBytes
- 1] > 0x7f)
826 CRYPT_EncodeLen(significantBytes
+ 1, NULL
, &lenBytes
);
828 CRYPT_EncodeLen(significantBytes
, NULL
, &lenBytes
);
829 bytesNeeded
= 1 + lenBytes
+ significantBytes
;
834 *pcbEncoded
= bytesNeeded
;
837 else if (*pcbEncoded
< bytesNeeded
)
839 *pcbEncoded
= bytesNeeded
;
840 SetLastError(ERROR_MORE_DATA
);
845 *pcbEncoded
= bytesNeeded
;
846 *pbEncoded
++ = ASN_INTEGER
;
849 CRYPT_EncodeLen(significantBytes
+ 1, pbEncoded
, &lenBytes
);
850 pbEncoded
+= lenBytes
;
851 *pbEncoded
++ = padByte
;
855 CRYPT_EncodeLen(significantBytes
, pbEncoded
, &lenBytes
);
856 pbEncoded
+= lenBytes
;
858 for (; significantBytes
> 0; significantBytes
--)
859 *(pbEncoded
++) = blob
->pbData
[significantBytes
- 1];
865 SetLastError(STATUS_ACCESS_VIOLATION
);
872 BOOL WINAPI
CRYPT_AsnEncodeInt(DWORD dwCertEncodingType
,
873 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
876 CRYPT_INTEGER_BLOB blob
= { sizeof(INT
), (BYTE
*)pvStructInfo
};
878 return CRYPT_AsnEncodeInteger(dwCertEncodingType
, X509_MULTI_BYTE_INTEGER
,
879 &blob
, pbEncoded
, pcbEncoded
);
882 BOOL WINAPI
WVTAsn1CatMemberInfoEncode(DWORD dwCertEncodingType
,
883 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
888 TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
889 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
, pcbEncoded
);
893 const CAT_MEMBERINFO
*info
= (const CAT_MEMBERINFO
*)pvStructInfo
;
894 struct AsnEncodeSequenceItem items
[] = {
895 { info
->pwszSubjGuid
, CRYPT_AsnEncodeBMPString
, 0 },
896 { &info
->dwCertVersion
, CRYPT_AsnEncodeInt
, 0 },
899 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
,
900 items
, sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
904 SetLastError(STATUS_ACCESS_VIOLATION
);
910 BOOL WINAPI
WVTAsn1CatNameValueEncode(DWORD dwCertEncodingType
,
911 LPCSTR lpszStructType
, const void *pvStructInfo
, BYTE
*pbEncoded
,
916 TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType
,
917 debugstr_a(lpszStructType
), pvStructInfo
, pbEncoded
, pcbEncoded
);
921 const CAT_NAMEVALUE
*value
= (const CAT_NAMEVALUE
*)pvStructInfo
;
922 struct AsnEncodeSequenceItem items
[] = {
923 { value
->pwszTag
, CRYPT_AsnEncodeBMPString
, 0 },
924 { &value
->fdwFlags
, CRYPT_AsnEncodeInt
, 0 },
925 { &value
->Value
, CRYPT_AsnEncodeOctets
, 0 },
928 ret
= CRYPT_AsnEncodeSequence(X509_ASN_ENCODING
,
929 items
, sizeof(items
) / sizeof(items
[0]), pbEncoded
, pcbEncoded
);
933 SetLastError(STATUS_ACCESS_VIOLATION
);
939 /* Gets the number of length bytes from the given (leading) length byte */
940 #define GET_LEN_BYTES(b) ((b) <= 0x7f ? 1 : 1 + ((b) & 0x7f))
942 /* Helper function to get the encoded length of the data starting at pbEncoded,
943 * where pbEncoded[0] is the tag. If the data are too short to contain a
944 * length or if the length is too large for cbEncoded, sets an appropriate
945 * error code and returns FALSE.
947 static BOOL
CRYPT_GetLen(const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD
*len
)
953 SetLastError(CRYPT_E_ASN1_CORRUPT
);
956 else if (pbEncoded
[1] <= 0x7f)
958 if (pbEncoded
[1] + 1 > cbEncoded
)
960 SetLastError(CRYPT_E_ASN1_EOD
);
969 else if (pbEncoded
[1] == 0x80)
971 FIXME("unimplemented for indefinite-length encoding\n");
972 SetLastError(CRYPT_E_ASN1_CORRUPT
);
977 BYTE lenLen
= GET_LEN_BYTES(pbEncoded
[1]);
979 if (lenLen
> sizeof(DWORD
) + 1)
981 SetLastError(CRYPT_E_ASN1_LARGE
);
984 else if (lenLen
+ 2 > cbEncoded
)
986 SetLastError(CRYPT_E_ASN1_CORRUPT
);
999 if (out
+ lenLen
+ 1 > cbEncoded
)
1001 SetLastError(CRYPT_E_ASN1_EOD
);
1014 static BOOL WINAPI
CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType
,
1015 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1016 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1019 DWORD bytesNeeded
, dataLen
;
1021 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1022 pvStructInfo
, *pcbStructInfo
);
1026 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1029 else if (pbEncoded
[0] != ASN_OCTETSTRING
)
1031 SetLastError(CRYPT_E_ASN1_BADTAG
);
1034 else if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1036 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1037 bytesNeeded
= sizeof(CRYPT_DATA_BLOB
);
1039 bytesNeeded
= dataLen
+ sizeof(CRYPT_DATA_BLOB
);
1041 *pcbStructInfo
= bytesNeeded
;
1042 else if (*pcbStructInfo
< bytesNeeded
)
1044 SetLastError(ERROR_MORE_DATA
);
1045 *pcbStructInfo
= bytesNeeded
;
1050 CRYPT_DATA_BLOB
*blob
;
1051 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1053 blob
= (CRYPT_DATA_BLOB
*)pvStructInfo
;
1054 blob
->cbData
= dataLen
;
1055 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1056 blob
->pbData
= (BYTE
*)pbEncoded
+ 1 + lenBytes
;
1059 assert(blob
->pbData
);
1061 memcpy(blob
->pbData
, pbEncoded
+ 1 + lenBytes
,
1069 static BOOL WINAPI
CRYPT_AsnDecodeSPCLinkInternal(DWORD dwCertEncodingType
,
1070 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1071 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1074 DWORD bytesNeeded
= sizeof(SPC_LINK
), dataLen
;
1076 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1077 pvStructInfo
, *pcbStructInfo
);
1079 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1081 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1084 switch (pbEncoded
[0])
1087 bytesNeeded
+= (dataLen
+ 1) * sizeof(WCHAR
);
1089 *pcbStructInfo
= bytesNeeded
;
1090 else if (*pcbStructInfo
< bytesNeeded
)
1092 *pcbStructInfo
= bytesNeeded
;
1093 SetLastError(ERROR_MORE_DATA
);
1098 PSPC_LINK link
= (PSPC_LINK
)pvStructInfo
;
1101 link
->dwLinkChoice
= SPC_URL_LINK_CHOICE
;
1102 for (i
= 0; i
< dataLen
; i
++)
1103 link
->u
.pwszUrl
[i
] =
1104 *(pbEncoded
+ 1 + lenBytes
+ i
);
1105 link
->u
.pwszUrl
[i
] = '\0';
1106 TRACE("returning url %s\n", debugstr_w(link
->u
.pwszUrl
));
1109 case ASN_CONSTRUCTOR
| ASN_CONTEXT
| 1:
1111 CRYPT_DATA_BLOB classId
;
1112 DWORD size
= sizeof(classId
);
1114 if ((ret
= CRYPT_AsnDecodeOctets(dwCertEncodingType
, NULL
,
1115 pbEncoded
+ 1 + lenBytes
, cbEncoded
- 1 - lenBytes
,
1116 CRYPT_DECODE_NOCOPY_FLAG
, &classId
, &size
)))
1118 if (classId
.cbData
!= sizeof(SPC_UUID
))
1120 SetLastError(CRYPT_E_BAD_ENCODE
);
1125 CRYPT_DATA_BLOB data
;
1127 /* The tag length for the classId must be 1 since the
1128 * length is correct.
1130 size
= sizeof(data
);
1131 if ((ret
= CRYPT_AsnDecodeOctets(dwCertEncodingType
, NULL
,
1132 pbEncoded
+ 3 + lenBytes
+ classId
.cbData
,
1133 cbEncoded
- 3 - lenBytes
- classId
.cbData
,
1134 CRYPT_DECODE_NOCOPY_FLAG
, &data
, &size
)))
1136 bytesNeeded
+= data
.cbData
;
1138 *pcbStructInfo
= bytesNeeded
;
1139 else if (*pcbStructInfo
< bytesNeeded
)
1141 *pcbStructInfo
= bytesNeeded
;
1142 SetLastError(ERROR_MORE_DATA
);
1147 PSPC_LINK link
= (PSPC_LINK
)pvStructInfo
;
1149 link
->dwLinkChoice
= SPC_MONIKER_LINK_CHOICE
;
1150 /* pwszFile pointer was set by caller, copy it
1151 * before overwriting it
1153 link
->u
.Moniker
.SerializedData
.pbData
=
1154 (BYTE
*)link
->u
.pwszFile
;
1155 memcpy(link
->u
.Moniker
.ClassId
, classId
.pbData
,
1157 memcpy(link
->u
.Moniker
.SerializedData
.pbData
,
1158 data
.pbData
, data
.cbData
);
1159 link
->u
.Moniker
.SerializedData
.cbData
= data
.cbData
;
1166 case ASN_CONSTRUCTOR
| ASN_CONTEXT
| 2:
1167 if (dataLen
&& pbEncoded
[1 + lenBytes
] != ASN_CONTEXT
)
1168 SetLastError(CRYPT_E_ASN1_BADTAG
);
1169 else if ((ret
= CRYPT_GetLen(pbEncoded
+ 1 + lenBytes
, dataLen
,
1172 BYTE realLenBytes
= GET_LEN_BYTES(pbEncoded
[2 + lenBytes
]);
1174 bytesNeeded
+= realDataLen
+ sizeof(WCHAR
);
1176 *pcbStructInfo
= bytesNeeded
;
1177 else if (*pcbStructInfo
< bytesNeeded
)
1179 *pcbStructInfo
= bytesNeeded
;
1180 SetLastError(ERROR_MORE_DATA
);
1185 PSPC_LINK link
= (PSPC_LINK
)pvStructInfo
;
1187 const BYTE
*ptr
= pbEncoded
+ 2 + lenBytes
+ realLenBytes
;
1189 link
->dwLinkChoice
= SPC_FILE_LINK_CHOICE
;
1190 for (i
= 0; i
< dataLen
/ sizeof(WCHAR
); i
++)
1191 link
->u
.pwszFile
[i
] =
1192 hton16(*(WORD
*)(ptr
+ i
* sizeof(WCHAR
)));
1193 link
->u
.pwszFile
[realDataLen
/ sizeof(WCHAR
)] = '\0';
1194 TRACE("returning file %s\n", debugstr_w(link
->u
.pwszFile
));
1199 bytesNeeded
+= sizeof(WCHAR
);
1201 *pcbStructInfo
= bytesNeeded
;
1202 else if (*pcbStructInfo
< bytesNeeded
)
1204 *pcbStructInfo
= bytesNeeded
;
1205 SetLastError(ERROR_MORE_DATA
);
1210 PSPC_LINK link
= (PSPC_LINK
)pvStructInfo
;
1212 link
->dwLinkChoice
= SPC_FILE_LINK_CHOICE
;
1213 link
->u
.pwszFile
[0] = '\0';
1219 SetLastError(CRYPT_E_ASN1_BADTAG
);
1222 TRACE("returning %d\n", ret
);
1226 BOOL WINAPI
WVTAsn1SpcLinkDecode(DWORD dwCertEncodingType
,
1227 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1228 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1232 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1233 pvStructInfo
, *pcbStructInfo
);
1239 ret
= CRYPT_AsnDecodeSPCLinkInternal(dwCertEncodingType
,
1240 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, NULL
, &bytesNeeded
);
1244 *pcbStructInfo
= bytesNeeded
;
1245 else if (*pcbStructInfo
< bytesNeeded
)
1247 *pcbStructInfo
= bytesNeeded
;
1248 SetLastError(ERROR_MORE_DATA
);
1253 SPC_LINK
*link
= (SPC_LINK
*)pvStructInfo
;
1256 (LPWSTR
)((BYTE
*)pvStructInfo
+ sizeof(SPC_LINK
));
1257 ret
= CRYPT_AsnDecodeSPCLinkInternal(dwCertEncodingType
,
1258 lpszStructType
, pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
,
1265 SetLastError(STATUS_ACCESS_VIOLATION
);
1268 TRACE("returning %d\n", ret
);
1272 typedef BOOL (WINAPI
*CryptDecodeObjectFunc
)(DWORD
, LPCSTR
, const BYTE
*,
1273 DWORD
, DWORD
, void *, DWORD
*);
1276 * The expected tag of the item. If tag is 0, decodeFunc is called
1277 * regardless of the tag value seen.
1279 * A sequence is decoded into a struct. The offset member is the
1280 * offset of this item within that struct.
1282 * The decoder function to use. If this is NULL, then the member isn't
1283 * decoded, but minSize space is reserved for it.
1285 * The minimum amount of space occupied after decoding. You must set this.
1287 * If true, and the tag doesn't match the expected tag for this item,
1288 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
1289 * filled with 0 for this member.
1290 * hasPointer, pointerOffset:
1291 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
1292 * the offset within the struct of the data pointer (or to the
1293 * first data pointer, if more than one exist).
1295 * Used by CRYPT_AsnDecodeSequence, not for your use.
1297 struct AsnDecodeSequenceItem
1301 CryptDecodeObjectFunc decodeFunc
;
1305 DWORD pointerOffset
;
1309 /* Decodes the items in a sequence, where the items are described in items,
1310 * the encoded data are in pbEncoded with length cbEncoded. Decodes into
1311 * pvStructInfo. nextData is a pointer to the memory location at which the
1312 * first decoded item with a dynamic pointer should point.
1313 * Upon decoding, *cbDecoded is the total number of bytes decoded.
1315 static BOOL
CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType
,
1316 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
1317 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, BYTE
*nextData
,
1321 DWORD i
, decoded
= 0;
1322 const BYTE
*ptr
= pbEncoded
;
1324 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items
, cItem
, pbEncoded
,
1325 cbEncoded
, dwFlags
, pvStructInfo
, nextData
, cbDecoded
);
1327 for (i
= 0, ret
= TRUE
; ret
&& i
< cItem
; i
++)
1329 if (cbEncoded
- (ptr
- pbEncoded
) != 0)
1333 if ((ret
= CRYPT_GetLen(ptr
, cbEncoded
- (ptr
- pbEncoded
),
1336 BYTE nextItemLenBytes
= GET_LEN_BYTES(ptr
[1]);
1338 if (ptr
[0] == items
[i
].tag
|| !items
[i
].tag
)
1340 if (nextData
&& pvStructInfo
&& items
[i
].hasPointer
)
1342 TRACE("Setting next pointer to %p\n",
1344 *(BYTE
**)((BYTE
*)pvStructInfo
+
1345 items
[i
].pointerOffset
) = nextData
;
1347 if (items
[i
].decodeFunc
)
1350 TRACE("decoding item %d\n", i
);
1352 TRACE("sizing item %d\n", i
);
1353 ret
= items
[i
].decodeFunc(dwCertEncodingType
,
1354 NULL
, ptr
, 1 + nextItemLenBytes
+ nextItemLen
,
1355 dwFlags
& ~CRYPT_DECODE_ALLOC_FLAG
,
1356 pvStructInfo
? (BYTE
*)pvStructInfo
+ items
[i
].offset
1357 : NULL
, &items
[i
].size
);
1360 /* Account for alignment padding */
1361 if (items
[i
].size
% sizeof(DWORD
))
1362 items
[i
].size
+= sizeof(DWORD
) -
1363 items
[i
].size
% sizeof(DWORD
);
1364 TRACE("item %d size: %d\n", i
, items
[i
].size
);
1365 if (nextData
&& items
[i
].hasPointer
&&
1366 items
[i
].size
> items
[i
].minSize
)
1367 nextData
+= items
[i
].size
- items
[i
].minSize
;
1368 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
1369 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
1370 TRACE("item %d: decoded %d bytes\n", i
,
1371 1 + nextItemLenBytes
+ nextItemLen
);
1373 else if (items
[i
].optional
&&
1374 GetLastError() == CRYPT_E_ASN1_BADTAG
)
1376 TRACE("skipping optional item %d\n", i
);
1377 items
[i
].size
= items
[i
].minSize
;
1378 SetLastError(NOERROR
);
1382 TRACE("item %d failed: %08x\n", i
,
1387 TRACE("item %d: decoded %d bytes\n", i
,
1388 1 + nextItemLenBytes
+ nextItemLen
);
1389 ptr
+= 1 + nextItemLenBytes
+ nextItemLen
;
1390 decoded
+= 1 + nextItemLenBytes
+ nextItemLen
;
1391 items
[i
].size
= items
[i
].minSize
;
1394 else if (items
[i
].optional
)
1396 TRACE("skipping optional item %d\n", i
);
1397 items
[i
].size
= items
[i
].minSize
;
1401 TRACE("item %d: tag %02x doesn't match expected %02x\n",
1402 i
, ptr
[0], items
[i
].tag
);
1403 SetLastError(CRYPT_E_ASN1_BADTAG
);
1408 else if (items
[i
].optional
)
1410 TRACE("missing optional item %d, skipping\n", i
);
1411 items
[i
].size
= items
[i
].minSize
;
1415 TRACE("not enough bytes for item %d, failing\n", i
);
1416 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1421 *cbDecoded
= decoded
;
1422 TRACE("returning %d\n", ret
);
1426 /* This decodes an arbitrary sequence into a contiguous block of memory
1427 * (basically, a struct.) Each element being decoded is described by a struct
1428 * AsnDecodeSequenceItem, see above.
1429 * startingPointer is an optional pointer to the first place where dynamic
1430 * data will be stored. If you know the starting offset, you may pass it
1431 * here. Otherwise, pass NULL, and one will be inferred from the items.
1433 static BOOL
CRYPT_AsnDecodeSequence(DWORD dwCertEncodingType
,
1434 struct AsnDecodeSequenceItem items
[], DWORD cItem
, const BYTE
*pbEncoded
,
1435 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
,
1436 void *startingPointer
)
1440 TRACE("%p, %d, %p, %d, %08x, %p, %d, %p\n", items
, cItem
, pbEncoded
,
1441 cbEncoded
, dwFlags
, pvStructInfo
, *pcbStructInfo
, startingPointer
);
1443 if (pbEncoded
[0] == ASN_SEQUENCE
)
1447 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1449 DWORD lenBytes
= GET_LEN_BYTES(pbEncoded
[1]), cbDecoded
;
1450 const BYTE
*ptr
= pbEncoded
+ 1 + lenBytes
;
1452 cbEncoded
-= 1 + lenBytes
;
1453 if (cbEncoded
< dataLen
)
1455 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen
,
1457 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1461 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
, ptr
,
1462 cbEncoded
, dwFlags
, NULL
, NULL
, &cbDecoded
);
1463 if (ret
&& cbDecoded
!= dataLen
)
1465 TRACE("expected %d decoded, got %d, failing\n", dataLen
,
1467 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1472 DWORD i
, bytesNeeded
= 0, structSize
= 0;
1474 for (i
= 0; i
< cItem
; i
++)
1476 bytesNeeded
+= items
[i
].size
;
1477 structSize
+= items
[i
].minSize
;
1480 *pcbStructInfo
= bytesNeeded
;
1481 else if (*pcbStructInfo
< bytesNeeded
)
1483 SetLastError(ERROR_MORE_DATA
);
1484 *pcbStructInfo
= bytesNeeded
;
1491 *pcbStructInfo
= bytesNeeded
;
1492 if (startingPointer
)
1493 nextData
= (BYTE
*)startingPointer
;
1495 nextData
= (BYTE
*)pvStructInfo
+ structSize
;
1496 memset(pvStructInfo
, 0, structSize
);
1497 ret
= CRYPT_AsnDecodeSequenceItems(dwFlags
, items
, cItem
,
1498 ptr
, cbEncoded
, dwFlags
, pvStructInfo
, nextData
,
1506 SetLastError(CRYPT_E_ASN1_BADTAG
);
1509 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1513 static BOOL WINAPI
CRYPT_AsnDecodeBitsInternal(DWORD dwCertEncodingType
,
1514 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1515 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1519 TRACE("(%p, %d, 0x%08x, %p, %d)\n", pbEncoded
, cbEncoded
, dwFlags
,
1520 pvStructInfo
, *pcbStructInfo
);
1522 if (pbEncoded
[0] == ASN_BITSTRING
)
1524 DWORD bytesNeeded
, dataLen
;
1526 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1528 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1529 bytesNeeded
= sizeof(CRYPT_BIT_BLOB
);
1531 bytesNeeded
= dataLen
- 1 + sizeof(CRYPT_BIT_BLOB
);
1533 *pcbStructInfo
= bytesNeeded
;
1534 else if (*pcbStructInfo
< bytesNeeded
)
1536 *pcbStructInfo
= bytesNeeded
;
1537 SetLastError(ERROR_MORE_DATA
);
1542 CRYPT_BIT_BLOB
*blob
;
1544 blob
= (CRYPT_BIT_BLOB
*)pvStructInfo
;
1545 blob
->cbData
= dataLen
- 1;
1546 blob
->cUnusedBits
= *(pbEncoded
+ 1 +
1547 GET_LEN_BYTES(pbEncoded
[1]));
1548 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1550 blob
->pbData
= (BYTE
*)pbEncoded
+ 2 +
1551 GET_LEN_BYTES(pbEncoded
[1]);
1555 assert(blob
->pbData
);
1558 BYTE mask
= 0xff << blob
->cUnusedBits
;
1560 memcpy(blob
->pbData
, pbEncoded
+ 2 +
1561 GET_LEN_BYTES(pbEncoded
[1]), blob
->cbData
);
1562 blob
->pbData
[blob
->cbData
- 1] &= mask
;
1570 SetLastError(CRYPT_E_ASN1_BADTAG
);
1573 TRACE("returning %d (%08x)\n", ret
, GetLastError());
1577 static BOOL WINAPI
CRYPT_AsnDecodeSPCLinkPointer(DWORD dwCertEncodingType
,
1578 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1579 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1584 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1586 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1588 SPC_LINK
**pLink
= (SPC_LINK
**)pvStructInfo
;
1590 ret
= CRYPT_AsnDecodeSPCLinkInternal(dwCertEncodingType
, lpszStructType
,
1591 pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
, NULL
, &size
);
1595 *pcbStructInfo
= size
+ sizeof(PSPC_LINK
);
1596 else if (*pcbStructInfo
< size
+ sizeof(PSPC_LINK
))
1598 *pcbStructInfo
= size
+ sizeof(PSPC_LINK
);
1599 SetLastError(ERROR_MORE_DATA
);
1604 *pcbStructInfo
= size
+ sizeof(PSPC_LINK
);
1605 /* Set imageData's pointer if necessary */
1606 if (size
> sizeof(SPC_LINK
))
1608 (*pLink
)->u
.pwszUrl
=
1609 (LPWSTR
)((BYTE
*)*pLink
+ sizeof(SPC_LINK
));
1611 ret
= CRYPT_AsnDecodeSPCLinkInternal(dwCertEncodingType
,
1612 lpszStructType
, pbEncoded
+ 1 + lenBytes
, dataLen
, dwFlags
,
1613 *pLink
, pcbStructInfo
);
1620 BOOL WINAPI
WVTAsn1SpcPeImageDataDecode(DWORD dwCertEncodingType
,
1621 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1622 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1626 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1627 pvStructInfo
, *pcbStructInfo
);
1631 struct AsnDecodeSequenceItem items
[] = {
1632 { ASN_BITSTRING
, offsetof(SPC_PE_IMAGE_DATA
, Flags
),
1633 CRYPT_AsnDecodeBitsInternal
, sizeof(CRYPT_BIT_BLOB
), TRUE
, TRUE
,
1634 offsetof(SPC_PE_IMAGE_DATA
, Flags
.pbData
), 0 },
1635 { ASN_CONSTRUCTOR
| ASN_CONTEXT
, offsetof(SPC_PE_IMAGE_DATA
, pFile
),
1636 CRYPT_AsnDecodeSPCLinkPointer
, sizeof(PSPC_LINK
), TRUE
, TRUE
,
1637 offsetof(SPC_PE_IMAGE_DATA
, pFile
), 0 },
1640 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1641 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1642 pvStructInfo
, pcbStructInfo
, NULL
);
1646 SetLastError(STATUS_ACCESS_VIOLATION
);
1649 TRACE("returning %d\n", ret
);
1653 static BOOL WINAPI
CRYPT_AsnDecodeOidIgnoreTag(DWORD dwCertEncodingType
,
1654 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1655 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1660 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1661 pvStructInfo
, *pcbStructInfo
);
1663 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1665 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1666 DWORD bytesNeeded
= sizeof(LPSTR
);
1670 /* The largest possible string for the first two components
1671 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough.
1676 snprintf(firstTwo
, sizeof(firstTwo
), "%d.%d",
1677 pbEncoded
[1 + lenBytes
] / 40,
1678 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] / 40)
1680 bytesNeeded
+= strlen(firstTwo
) + 1;
1681 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1682 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1684 /* large enough for ".4000000" */
1688 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1695 if (ptr
- pbEncoded
- 1 - lenBytes
>= dataLen
||
1698 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1705 snprintf(str
, sizeof(str
), ".%d", val
);
1706 bytesNeeded
+= strlen(str
);
1711 *pcbStructInfo
= bytesNeeded
;
1712 else if (*pcbStructInfo
< bytesNeeded
)
1714 *pcbStructInfo
= bytesNeeded
;
1715 SetLastError(ERROR_MORE_DATA
);
1723 LPSTR pszObjId
= *(LPSTR
*)pvStructInfo
;
1726 sprintf(pszObjId
, "%d.%d", pbEncoded
[1 + lenBytes
] / 40,
1727 pbEncoded
[1 + lenBytes
] - (pbEncoded
[1 + lenBytes
] /
1729 pszObjId
+= strlen(pszObjId
);
1730 for (ptr
= pbEncoded
+ 2 + lenBytes
; ret
&&
1731 ptr
- pbEncoded
- 1 - lenBytes
< dataLen
; )
1735 while (ptr
- pbEncoded
- 1 - lenBytes
< dataLen
&&
1744 sprintf(pszObjId
, ".%d", val
);
1745 pszObjId
+= strlen(pszObjId
);
1749 *(LPSTR
*)pvStructInfo
= NULL
;
1750 *pcbStructInfo
= bytesNeeded
;
1756 static BOOL WINAPI
CRYPT_AsnDecodeOid(DWORD dwCertEncodingType
,
1757 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1758 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1762 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1763 pvStructInfo
, *pcbStructInfo
);
1766 SetLastError(CRYPT_E_ASN1_CORRUPT
);
1767 else if (pbEncoded
[0] == ASN_OBJECTIDENTIFIER
)
1768 ret
= CRYPT_AsnDecodeOidIgnoreTag(dwCertEncodingType
, lpszStructType
,
1769 pbEncoded
, cbEncoded
, dwFlags
, pvStructInfo
, pcbStructInfo
);
1771 SetLastError(CRYPT_E_ASN1_BADTAG
);
1775 static BOOL WINAPI
CRYPT_AsnDecodeCopyBytes(DWORD dwCertEncodingType
,
1776 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1777 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1780 DWORD bytesNeeded
= sizeof(CRYPT_OBJID_BLOB
);
1782 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1783 pvStructInfo
, *pcbStructInfo
);
1785 if (!(dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
))
1786 bytesNeeded
+= cbEncoded
;
1788 *pcbStructInfo
= bytesNeeded
;
1789 else if (*pcbStructInfo
< bytesNeeded
)
1791 SetLastError(ERROR_MORE_DATA
);
1792 *pcbStructInfo
= bytesNeeded
;
1797 PCRYPT_OBJID_BLOB blob
= (PCRYPT_OBJID_BLOB
)pvStructInfo
;
1799 *pcbStructInfo
= bytesNeeded
;
1800 blob
->cbData
= cbEncoded
;
1801 if (dwFlags
& CRYPT_DECODE_NOCOPY_FLAG
)
1802 blob
->pbData
= (LPBYTE
)pbEncoded
;
1805 assert(blob
->pbData
);
1806 memcpy(blob
->pbData
, pbEncoded
, blob
->cbData
);
1812 static BOOL WINAPI
CRYPT_AsnDecodeAttributeTypeValue(DWORD dwCertEncodingType
,
1813 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1814 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1816 CRYPT_ATTRIBUTE_TYPE_VALUE
*typeValue
=
1817 (CRYPT_ATTRIBUTE_TYPE_VALUE
*)pvStructInfo
;
1818 struct AsnDecodeSequenceItem items
[] = {
1819 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ATTRIBUTE_TYPE_VALUE
, pszObjId
),
1820 CRYPT_AsnDecodeOid
, sizeof(LPSTR
), FALSE
, TRUE
,
1821 offsetof(CRYPT_ATTRIBUTE_TYPE_VALUE
, pszObjId
), 0 },
1822 { 0, offsetof(CRYPT_ATTRIBUTE_TYPE_VALUE
, Value
),
1823 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_DATA_BLOB
), TRUE
, TRUE
,
1824 offsetof(CRYPT_ATTRIBUTE_TYPE_VALUE
, Value
.pbData
), 0 },
1827 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1828 pvStructInfo
, *pcbStructInfo
);
1830 return CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1831 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1832 pvStructInfo
, pcbStructInfo
,
1833 typeValue
? typeValue
->pszObjId
: NULL
);
1836 static BOOL WINAPI
CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType
,
1837 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1838 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1840 CRYPT_ALGORITHM_IDENTIFIER
*algo
=
1841 (CRYPT_ALGORITHM_IDENTIFIER
*)pvStructInfo
;
1843 struct AsnDecodeSequenceItem items
[] = {
1844 { ASN_OBJECTIDENTIFIER
, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
),
1845 CRYPT_AsnDecodeOidIgnoreTag
, sizeof(LPSTR
), FALSE
, TRUE
,
1846 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, pszObjId
), 0 },
1847 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
),
1848 CRYPT_AsnDecodeCopyBytes
, sizeof(CRYPT_OBJID_BLOB
), TRUE
, TRUE
,
1849 offsetof(CRYPT_ALGORITHM_IDENTIFIER
, Parameters
.pbData
), 0 },
1852 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1853 pvStructInfo
, *pcbStructInfo
);
1855 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1856 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1857 pvStructInfo
, pcbStructInfo
, algo
? algo
->pszObjId
: NULL
);
1858 if (ret
&& pvStructInfo
)
1860 TRACE("pszObjId is %p (%s)\n", algo
->pszObjId
,
1861 debugstr_a(algo
->pszObjId
));
1866 static BOOL WINAPI
CRYPT_AsnDecodeSPCDigest(DWORD dwCertEncodingType
,
1867 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1868 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1870 struct SPCDigest
*digest
=
1871 (struct SPCDigest
*)pvStructInfo
;
1872 struct AsnDecodeSequenceItem items
[] = {
1873 { ASN_SEQUENCEOF
, offsetof(struct SPCDigest
, DigestAlgorithm
),
1874 CRYPT_AsnDecodeAlgorithmId
, sizeof(CRYPT_ALGORITHM_IDENTIFIER
),
1876 offsetof(struct SPCDigest
, DigestAlgorithm
.pszObjId
), 0 },
1877 { ASN_OCTETSTRING
, offsetof(struct SPCDigest
, Digest
),
1878 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
),
1879 FALSE
, TRUE
, offsetof(struct SPCDigest
, Digest
.pbData
), 0 },
1882 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1883 pvStructInfo
, *pcbStructInfo
);
1885 return CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1886 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1887 pvStructInfo
, pcbStructInfo
,
1888 digest
? digest
->DigestAlgorithm
.pszObjId
: NULL
);
1891 BOOL WINAPI
WVTAsn1SpcIndirectDataContentDecode(DWORD dwCertEncodingType
,
1892 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1893 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1897 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1898 pvStructInfo
, *pcbStructInfo
);
1902 struct AsnDecodeSequenceItem items
[] = {
1903 { ASN_SEQUENCEOF
, offsetof(SPC_INDIRECT_DATA_CONTENT
, Data
),
1904 CRYPT_AsnDecodeAttributeTypeValue
,
1905 sizeof(CRYPT_ATTRIBUTE_TYPE_VALUE
), FALSE
, TRUE
,
1906 offsetof(SPC_INDIRECT_DATA_CONTENT
, Data
.pszObjId
), 0 },
1907 { ASN_SEQUENCEOF
, offsetof(SPC_INDIRECT_DATA_CONTENT
, DigestAlgorithm
),
1908 CRYPT_AsnDecodeSPCDigest
, sizeof(struct SPCDigest
),
1910 offsetof(SPC_INDIRECT_DATA_CONTENT
, DigestAlgorithm
.pszObjId
), 0 },
1913 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
1914 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
1915 pvStructInfo
, pcbStructInfo
, NULL
);
1919 SetLastError(STATUS_ACCESS_VIOLATION
);
1922 TRACE("returning %d\n", ret
);
1926 BOOL WINAPI
WVTAsn1SpcSpOpusInfoDecode(DWORD dwCertEncodingType
,
1927 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1928 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1930 FIXME("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
1931 pvStructInfo
, *pcbStructInfo
);
1935 static BOOL WINAPI
CRYPT_AsnDecodeBMPString(DWORD dwCertEncodingType
,
1936 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
1937 void *pvStructInfo
, DWORD
*pcbStructInfo
)
1940 DWORD bytesNeeded
, dataLen
;
1942 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1944 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1946 bytesNeeded
= dataLen
+ 2 + sizeof(LPWSTR
);
1948 *pcbStructInfo
= bytesNeeded
;
1949 else if (*pcbStructInfo
< bytesNeeded
)
1951 *pcbStructInfo
= bytesNeeded
;
1952 SetLastError(ERROR_MORE_DATA
);
1960 *pcbStructInfo
= bytesNeeded
;
1961 assert(pvStructInfo
);
1962 str
= *(LPWSTR
*)pvStructInfo
;
1963 for (i
= 0; i
< dataLen
/ 2; i
++)
1964 str
[i
] = (pbEncoded
[1 + lenBytes
+ 2 * i
] << 8) |
1965 pbEncoded
[1 + lenBytes
+ 2 * i
+ 1];
1966 /* Decoded string is always NULL-terminated */
1973 static BOOL
CRYPT_AsnDecodeInteger(const BYTE
*pbEncoded
,
1974 DWORD cbEncoded
, DWORD dwFlags
, void *pvStructInfo
, DWORD
*pcbStructInfo
)
1977 DWORD bytesNeeded
, dataLen
;
1979 if ((ret
= CRYPT_GetLen(pbEncoded
, cbEncoded
, &dataLen
)))
1981 BYTE lenBytes
= GET_LEN_BYTES(pbEncoded
[1]);
1983 bytesNeeded
= dataLen
+ sizeof(CRYPT_INTEGER_BLOB
);
1985 *pcbStructInfo
= bytesNeeded
;
1986 else if (*pcbStructInfo
< bytesNeeded
)
1988 *pcbStructInfo
= bytesNeeded
;
1989 SetLastError(ERROR_MORE_DATA
);
1994 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)pvStructInfo
;
1996 *pcbStructInfo
= bytesNeeded
;
1997 blob
->cbData
= dataLen
;
1998 assert(blob
->pbData
);
2003 for (i
= 0; i
< blob
->cbData
; i
++)
2005 blob
->pbData
[i
] = *(pbEncoded
+ 1 + lenBytes
+
2014 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */
2015 static BOOL WINAPI
CRYPT_AsnDecodeInt(DWORD dwCertEncodingType
,
2016 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2017 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2020 BYTE buf
[sizeof(CRYPT_INTEGER_BLOB
) + sizeof(int)];
2021 CRYPT_INTEGER_BLOB
*blob
= (CRYPT_INTEGER_BLOB
*)buf
;
2022 DWORD size
= sizeof(buf
);
2024 blob
->pbData
= buf
+ sizeof(CRYPT_INTEGER_BLOB
);
2025 ret
= CRYPT_AsnDecodeInteger(pbEncoded
, cbEncoded
, 0, buf
, &size
);
2029 *pcbStructInfo
= sizeof(int);
2030 else if (*pcbStructInfo
< sizeof(int))
2032 *pcbStructInfo
= sizeof(int);
2033 SetLastError(ERROR_MORE_DATA
);
2040 *pcbStructInfo
= sizeof(int);
2041 if (blob
->pbData
[blob
->cbData
- 1] & 0x80)
2043 /* initialize to a negative value to sign-extend */
2048 for (i
= 0; i
< blob
->cbData
; i
++)
2051 val
|= blob
->pbData
[blob
->cbData
- i
- 1];
2053 memcpy(pvStructInfo
, &val
, sizeof(int));
2056 else if (GetLastError() == ERROR_MORE_DATA
)
2057 SetLastError(CRYPT_E_ASN1_LARGE
);
2061 BOOL WINAPI
WVTAsn1CatMemberInfoDecode(DWORD dwCertEncodingType
,
2062 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2063 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2067 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2068 pvStructInfo
, *pcbStructInfo
);
2072 struct AsnDecodeSequenceItem items
[] = {
2073 { ASN_BMPSTRING
, offsetof(CAT_MEMBERINFO
, pwszSubjGuid
),
2074 CRYPT_AsnDecodeBMPString
, sizeof(LPWSTR
), FALSE
, TRUE
,
2075 offsetof(CAT_MEMBERINFO
, pwszSubjGuid
), 0 },
2076 { ASN_INTEGER
, offsetof(CAT_MEMBERINFO
, dwCertVersion
),
2077 CRYPT_AsnDecodeInt
, sizeof(DWORD
),
2078 FALSE
, FALSE
, 0, 0 },
2081 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2082 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2083 pvStructInfo
, pcbStructInfo
, NULL
);
2087 SetLastError(STATUS_ACCESS_VIOLATION
);
2090 TRACE("returning %d\n", ret
);
2094 BOOL WINAPI
WVTAsn1CatNameValueDecode(DWORD dwCertEncodingType
,
2095 LPCSTR lpszStructType
, const BYTE
*pbEncoded
, DWORD cbEncoded
, DWORD dwFlags
,
2096 void *pvStructInfo
, DWORD
*pcbStructInfo
)
2100 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded
, cbEncoded
, dwFlags
,
2101 pvStructInfo
, *pcbStructInfo
);
2105 struct AsnDecodeSequenceItem items
[] = {
2106 { ASN_BMPSTRING
, offsetof(CAT_NAMEVALUE
, pwszTag
),
2107 CRYPT_AsnDecodeBMPString
, sizeof(LPWSTR
), FALSE
, TRUE
,
2108 offsetof(CAT_NAMEVALUE
, pwszTag
), 0 },
2109 { ASN_INTEGER
, offsetof(CAT_NAMEVALUE
, fdwFlags
),
2110 CRYPT_AsnDecodeInt
, sizeof(DWORD
), FALSE
, FALSE
, 0, 0 },
2111 { ASN_OCTETSTRING
, offsetof(CAT_NAMEVALUE
, Value
),
2112 CRYPT_AsnDecodeOctets
, sizeof(CRYPT_DER_BLOB
), FALSE
, TRUE
,
2113 offsetof(CAT_NAMEVALUE
, Value
.pbData
), 0 },
2116 ret
= CRYPT_AsnDecodeSequence(dwCertEncodingType
, items
,
2117 sizeof(items
) / sizeof(items
[0]), pbEncoded
, cbEncoded
, dwFlags
,
2118 pvStructInfo
, pcbStructInfo
, NULL
);
2122 SetLastError(STATUS_ACCESS_VIOLATION
);
2125 TRACE("returning %d\n", ret
);