Juan Lang : wintrust: Implement WVTAsn1CatMemberInfoEncode.
Alexandre Julliard
julliard at winehq.org
Sat Oct 18 13:38:43 CDT 2008
Module: wine
Branch: master
Commit: d3d7dfa7ff9c7b2a891e529f8728a225ee4e5a69
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d3d7dfa7ff9c7b2a891e529f8728a225ee4e5a69
Author: Juan Lang <juan.lang at gmail.com>
Date: Fri Oct 17 14:07:03 2008 -0700
wintrust: Implement WVTAsn1CatMemberInfoEncode.
---
dlls/wintrust/asn.c | 164 ++++++++++++++++++++++++++++++++++++++++++++-
dlls/wintrust/tests/asn.c | 3 -
2 files changed, 162 insertions(+), 5 deletions(-)
diff --git a/dlls/wintrust/asn.c b/dlls/wintrust/asn.c
index 76ac8a8..364e7c2 100644
--- a/dlls/wintrust/asn.c
+++ b/dlls/wintrust/asn.c
@@ -50,6 +50,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(cryptasn);
#endif
#define ASN_BITSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x03)
+#define ASN_BMPSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x1e)
static BOOL CRYPT_EncodeLen(DWORD len, BYTE *pbEncoded, DWORD *pcbEncoded)
{
@@ -738,13 +739,172 @@ BOOL WINAPI WVTAsn1SpcIndirectDataContentEncode(DWORD dwCertEncodingType,
return ret;
}
+static BOOL WINAPI CRYPT_AsnEncodeBMPString(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+ BOOL ret = TRUE;
+ LPCWSTR str = (LPCWSTR)pvStructInfo;
+ DWORD bytesNeeded, lenBytes, strLen;
+
+ if (str)
+ strLen = lstrlenW(str);
+ else
+ strLen = 0;
+ CRYPT_EncodeLen(strLen * 2, NULL, &lenBytes);
+ bytesNeeded = 1 + lenBytes + strLen * 2;
+ if (!pbEncoded)
+ *pcbEncoded = bytesNeeded;
+ else if (*pcbEncoded < bytesNeeded)
+ {
+ *pcbEncoded = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ DWORD i;
+
+ *pcbEncoded = bytesNeeded;
+ *pbEncoded++ = ASN_BMPSTRING;
+ CRYPT_EncodeLen(strLen * 2, pbEncoded, &lenBytes);
+ pbEncoded += lenBytes;
+ for (i = 0; i < strLen; i++)
+ {
+ *pbEncoded++ = (str[i] & 0xff00) >> 8;
+ *pbEncoded++ = str[i] & 0x00ff;
+ }
+ }
+ return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnEncodeInteger(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+ BOOL ret;
+
+ __TRY
+ {
+ DWORD significantBytes, lenBytes, bytesNeeded;
+ BYTE padByte = 0;
+ BOOL pad = FALSE;
+ const CRYPT_INTEGER_BLOB *blob =
+ (const CRYPT_INTEGER_BLOB *)pvStructInfo;
+
+ significantBytes = blob->cbData;
+ if (significantBytes)
+ {
+ if (blob->pbData[significantBytes - 1] & 0x80)
+ {
+ /* negative, lop off leading (little-endian) 0xffs */
+ for (; significantBytes > 0 &&
+ blob->pbData[significantBytes - 1] == 0xff; significantBytes--)
+ ;
+ if (blob->pbData[significantBytes - 1] < 0x80)
+ {
+ padByte = 0xff;
+ pad = TRUE;
+ }
+ }
+ else
+ {
+ /* positive, lop off leading (little-endian) zeroes */
+ for (; significantBytes > 0 &&
+ !blob->pbData[significantBytes - 1]; significantBytes--)
+ ;
+ if (significantBytes == 0)
+ significantBytes = 1;
+ if (blob->pbData[significantBytes - 1] > 0x7f)
+ {
+ padByte = 0;
+ pad = TRUE;
+ }
+ }
+ }
+ if (pad)
+ CRYPT_EncodeLen(significantBytes + 1, NULL, &lenBytes);
+ else
+ CRYPT_EncodeLen(significantBytes, NULL, &lenBytes);
+ bytesNeeded = 1 + lenBytes + significantBytes;
+ if (pad)
+ bytesNeeded++;
+ if (!pbEncoded)
+ {
+ *pcbEncoded = bytesNeeded;
+ ret = TRUE;
+ }
+ else if (*pcbEncoded < bytesNeeded)
+ {
+ *pcbEncoded = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ *pcbEncoded = bytesNeeded;
+ *pbEncoded++ = ASN_INTEGER;
+ if (pad)
+ {
+ CRYPT_EncodeLen(significantBytes + 1, pbEncoded, &lenBytes);
+ pbEncoded += lenBytes;
+ *pbEncoded++ = padByte;
+ }
+ else
+ {
+ CRYPT_EncodeLen(significantBytes, pbEncoded, &lenBytes);
+ pbEncoded += lenBytes;
+ }
+ for (; significantBytes > 0; significantBytes--)
+ *(pbEncoded++) = blob->pbData[significantBytes - 1];
+ ret = TRUE;
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ ret = FALSE;
+ }
+ __ENDTRY
+ return ret;
+}
+
+BOOL WINAPI CRYPT_AsnEncodeInt(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
+ DWORD *pcbEncoded)
+{
+ CRYPT_INTEGER_BLOB blob = { sizeof(INT), (BYTE *)pvStructInfo };
+
+ return CRYPT_AsnEncodeInteger(dwCertEncodingType, X509_MULTI_BYTE_INTEGER,
+ &blob, pbEncoded, pcbEncoded);
+}
+
BOOL WINAPI WVTAsn1CatMemberInfoEncode(DWORD dwCertEncodingType,
LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded,
DWORD *pcbEncoded)
{
- FIXME("(0x%08x, %s, %p, %p, %p): stub\n", dwCertEncodingType,
+ BOOL ret = FALSE;
+
+ TRACE("(0x%08x, %s, %p, %p, %p)\n", dwCertEncodingType,
debugstr_a(lpszStructType), pvStructInfo, pbEncoded, pcbEncoded);
- return FALSE;
+
+ __TRY
+ {
+ const CAT_MEMBERINFO *info = (const CAT_MEMBERINFO *)pvStructInfo;
+ struct AsnEncodeSequenceItem items[] = {
+ { info->pwszSubjGuid, CRYPT_AsnEncodeBMPString, 0 },
+ { &info->dwCertVersion, CRYPT_AsnEncodeInt, 0 },
+ };
+
+ ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING,
+ items, sizeof(items) / sizeof(items[0]), pbEncoded, pcbEncoded);
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ }
+ __ENDTRY
+ return ret;
}
/* Gets the number of length bytes from the given (leading) length byte */
diff --git a/dlls/wintrust/tests/asn.c b/dlls/wintrust/tests/asn.c
index 28cc6f6..5dd4eff 100644
--- a/dlls/wintrust/tests/asn.c
+++ b/dlls/wintrust/tests/asn.c
@@ -497,7 +497,6 @@ static void test_encodeCatMemberInfo(void)
ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, CAT_MEMBERINFO_STRUCT,
&info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
- todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
@@ -509,7 +508,6 @@ static void test_encodeCatMemberInfo(void)
info.pwszSubjGuid = foo;
ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, CAT_MEMBERINFO_STRUCT,
(LPBYTE)&info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
- todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
@@ -522,7 +520,6 @@ static void test_encodeCatMemberInfo(void)
info.pwszSubjGuid = guidStr;
ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, CAT_MEMBERINFO_STRUCT,
(LPBYTE)&info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
- todo_wine
ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
More information about the wine-cvs
mailing list