Juan Lang : crypt32: Implement CryptFormatObject for szOID_KEY_USAGE.
Alexandre Julliard
julliard at winehq.org
Thu Nov 20 08:20:33 CST 2008
Module: wine
Branch: master
Commit: 5eb2a8318994ec2c88e8d2a17736037ce1562265
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5eb2a8318994ec2c88e8d2a17736037ce1562265
Author: Juan Lang <juan.lang at gmail.com>
Date: Wed Nov 19 11:42:34 2008 -0800
crypt32: Implement CryptFormatObject for szOID_KEY_USAGE.
---
dlls/crypt32/crypt32_En.rc | 10 ++
dlls/crypt32/cryptres.h | 10 ++
dlls/crypt32/object.c | 210 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 230 insertions(+), 0 deletions(-)
diff --git a/dlls/crypt32/crypt32_En.rc b/dlls/crypt32/crypt32_En.rc
index 66b56b4..301816e 100644
--- a/dlls/crypt32/crypt32_En.rc
+++ b/dlls/crypt32/crypt32_En.rc
@@ -217,4 +217,14 @@ STRINGTABLE DISCARDABLE
IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA "Meets Criteria="
IDS_YES "Yes"
IDS_NO "No"
+ IDS_DIGITAL_SIGNATURE "Digital Signature"
+ IDS_NON_REPUDIATION "Non-Repudiation"
+ IDS_KEY_ENCIPHERMENT "Key Encipherment"
+ IDS_DATA_ENCIPHERMENT "Data Encipherment"
+ IDS_KEY_AGREEMENT "Key Agreement"
+ IDS_CERT_SIGN "Certificate Signing"
+ IDS_OFFLINE_CRL_SIGN "Off-line CRL Signing"
+ IDS_CRL_SIGN "CRL Signing"
+ IDS_ENCIPHER_ONLY "Encipher Only"
+ IDS_DECIPHER_ONLY "Decipher Only"
}
diff --git a/dlls/crypt32/cryptres.h b/dlls/crypt32/cryptres.h
index 7480d46..58daa07 100644
--- a/dlls/crypt32/cryptres.h
+++ b/dlls/crypt32/cryptres.h
@@ -207,5 +207,15 @@
#define IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA 1240
#define IDS_YES 1241
#define IDS_NO 1242
+#define IDS_DIGITAL_SIGNATURE 1243
+#define IDS_NON_REPUDIATION 1244
+#define IDS_KEY_ENCIPHERMENT 1245
+#define IDS_DATA_ENCIPHERMENT 1246
+#define IDS_KEY_AGREEMENT 1247
+#define IDS_CERT_SIGN 1248
+#define IDS_OFFLINE_CRL_SIGN 1249
+#define IDS_CRL_SIGN 1250
+#define IDS_ENCIPHER_ONLY 1251
+#define IDS_DECIPHER_ONLY 1252
#endif /* ndef __WINE_CRYPTRES_H__ */
diff --git a/dlls/crypt32/object.c b/dlls/crypt32/object.c
index cb90332..2a556cb 100644
--- a/dlls/crypt32/object.c
+++ b/dlls/crypt32/object.c
@@ -607,6 +607,211 @@ static BOOL WINAPI CRYPT_FormatHexString(DWORD dwCertEncodingType,
static const WCHAR crlf[] = { '\r','\n',0 };
static const WCHAR commaSpace[] = { ',',' ',0 };
+struct BitToString
+{
+ BYTE bit;
+ int id;
+ WCHAR str[MAX_STRING_RESOURCE_LEN];
+};
+
+static BOOL CRYPT_FormatBits(DWORD dwFormatStrType, BYTE bits,
+ const struct BitToString *map, DWORD mapEntries, void *pbFormat,
+ DWORD *pcbFormat, BOOL *first)
+{
+ LPCWSTR sep;
+ DWORD sepLen, bytesNeeded = sizeof(WCHAR);
+ int i;
+ BOOL ret = TRUE, localFirst = *first;
+
+ if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+ {
+ sep = crlf;
+ sepLen = strlenW(crlf) * sizeof(WCHAR);
+ }
+ else
+ {
+ sep = commaSpace;
+ sepLen = strlenW(commaSpace) * sizeof(WCHAR);
+ }
+ for (i = 0; i < mapEntries; i++)
+ if (bits & map[i].bit)
+ {
+ if (!localFirst)
+ bytesNeeded += sepLen;
+ localFirst = FALSE;
+ bytesNeeded += strlenW(map[i].str) * sizeof(WCHAR);
+ }
+ if (!pbFormat)
+ {
+ *first = localFirst;
+ *pcbFormat = bytesNeeded;
+ }
+ else if (*pcbFormat < bytesNeeded)
+ {
+ *first = localFirst;
+ *pcbFormat = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ LPWSTR str = pbFormat;
+
+ localFirst = *first;
+ *pcbFormat = bytesNeeded;
+ for (i = 0; i < mapEntries; i++)
+ if (bits & map[i].bit)
+ {
+ if (!localFirst)
+ {
+ strcpyW(str, sep);
+ str += sepLen / sizeof(WCHAR);
+ }
+ localFirst = FALSE;
+ strcpyW(str, map[i].str);
+ str += strlenW(map[i].str);
+ }
+ *first = localFirst;
+ }
+ return ret;
+}
+
+static struct BitToString keyUsageByte0Map[] = {
+ { CERT_DIGITAL_SIGNATURE_KEY_USAGE, IDS_DIGITAL_SIGNATURE, { 0 } },
+ { CERT_NON_REPUDIATION_KEY_USAGE, IDS_NON_REPUDIATION, { 0 } },
+ { CERT_KEY_ENCIPHERMENT_KEY_USAGE, IDS_KEY_ENCIPHERMENT, { 0 } },
+ { CERT_DATA_ENCIPHERMENT_KEY_USAGE, IDS_DATA_ENCIPHERMENT, { 0 } },
+ { CERT_KEY_AGREEMENT_KEY_USAGE, IDS_KEY_AGREEMENT, { 0 } },
+ { CERT_KEY_CERT_SIGN_KEY_USAGE, IDS_CERT_SIGN, { 0 } },
+ { CERT_OFFLINE_CRL_SIGN_KEY_USAGE, IDS_OFFLINE_CRL_SIGN, { 0 } },
+ { CERT_CRL_SIGN_KEY_USAGE, IDS_CRL_SIGN, { 0 } },
+ { CERT_ENCIPHER_ONLY_KEY_USAGE, IDS_ENCIPHER_ONLY, { 0 } },
+};
+static struct BitToString keyUsageByte1Map[] = {
+ { CERT_DECIPHER_ONLY_KEY_USAGE, IDS_DECIPHER_ONLY, { 0 } },
+};
+
+static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+ DWORD size;
+ CRYPT_BIT_BLOB *bits;
+ BOOL ret;
+
+ if (!cbEncoded)
+ {
+ SetLastError(E_INVALIDARG);
+ return FALSE;
+ }
+ if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_KEY_USAGE,
+ pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &bits, &size)))
+ {
+ WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
+ DWORD bytesNeeded = sizeof(WCHAR);
+
+ LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
+ sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+ if (!bits->cbData || bits->cbData > 2)
+ {
+ bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
+ if (!pbFormat)
+ *pcbFormat = bytesNeeded;
+ else if (*pcbFormat < bytesNeeded)
+ {
+ *pcbFormat = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ LPWSTR str = pbFormat;
+
+ *pcbFormat = bytesNeeded;
+ strcpyW(str, infoNotAvailable);
+ }
+ }
+ else
+ {
+ static BOOL stringsLoaded = FALSE;
+ int i;
+ DWORD bitStringLen;
+ BOOL first = TRUE;
+
+ if (!stringsLoaded)
+ {
+ for (i = 0;
+ i < sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]);
+ i++)
+ LoadStringW(hInstance, keyUsageByte0Map[i].id,
+ keyUsageByte0Map[i].str, MAX_STRING_RESOURCE_LEN);
+ for (i = 0;
+ i < sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]);
+ i++)
+ LoadStringW(hInstance, keyUsageByte1Map[i].id,
+ keyUsageByte1Map[i].str, MAX_STRING_RESOURCE_LEN);
+ stringsLoaded = TRUE;
+ }
+ CRYPT_FormatBits(dwFormatStrType, bits->pbData[0],
+ keyUsageByte0Map,
+ sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]),
+ NULL, &bitStringLen, &first);
+ bytesNeeded += bitStringLen;
+ if (bits->cbData == 2)
+ {
+ CRYPT_FormatBits(dwFormatStrType, bits->pbData[1],
+ keyUsageByte1Map,
+ sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]),
+ NULL, &bitStringLen, &first);
+ bytesNeeded += bitStringLen;
+ }
+ bytesNeeded += 3 * sizeof(WCHAR); /* " (" + ")" */
+ CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
+ bits->cbData, NULL, &size);
+ bytesNeeded += size;
+ if (!pbFormat)
+ *pcbFormat = bytesNeeded;
+ else if (*pcbFormat < bytesNeeded)
+ {
+ *pcbFormat = bytesNeeded;
+ SetLastError(ERROR_MORE_DATA);
+ ret = FALSE;
+ }
+ else
+ {
+ LPWSTR str = pbFormat;
+
+ bitStringLen = bytesNeeded;
+ first = TRUE;
+ CRYPT_FormatBits(dwFormatStrType, bits->pbData[0],
+ keyUsageByte0Map,
+ sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]),
+ str, &bitStringLen, &first);
+ str += bitStringLen / sizeof(WCHAR) - 1;
+ if (bits->cbData == 2)
+ {
+ bitStringLen = bytesNeeded;
+ CRYPT_FormatBits(dwFormatStrType, bits->pbData[1],
+ keyUsageByte1Map,
+ sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]),
+ str, &bitStringLen, &first);
+ str += bitStringLen / sizeof(WCHAR) - 1;
+ }
+ *str++ = ' ';
+ *str++ = '(';
+ CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
+ bits->cbData, str, &size);
+ str += size / sizeof(WCHAR) - 1;
+ *str++ = ')';
+ *str = 0;
+ }
+ }
+ LocalFree(bits);
+ }
+ return ret;
+}
+
static WCHAR subjectTypeHeader[MAX_STRING_RESOURCE_LEN];
static WCHAR subjectTypeCA[MAX_STRING_RESOURCE_LEN];
static WCHAR subjectTypeEndCert[MAX_STRING_RESOURCE_LEN];
@@ -1974,6 +2179,9 @@ static CryptFormatObjectFunc CRYPT_GetBuiltinFormatFunction(DWORD encodingType,
{
switch (LOWORD(lpszStructType))
{
+ case LOWORD(X509_KEY_USAGE):
+ format = CRYPT_FormatKeyUsage;
+ break;
case LOWORD(X509_ALTERNATE_NAME):
format = CRYPT_FormatAltName;
break;
@@ -2001,6 +2209,8 @@ static CryptFormatObjectFunc CRYPT_GetBuiltinFormatFunction(DWORD encodingType,
format = CRYPT_FormatAltName;
else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
format = CRYPT_FormatAltName;
+ else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
+ format = CRYPT_FormatKeyUsage;
else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
format = CRYPT_FormatAltName;
else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
More information about the wine-cvs
mailing list