[xmlsec] fix search for non-english cert subject
- From: Aleksey Sanin <aleksey src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [xmlsec] fix search for non-english cert subject
- Date: Fri, 23 Apr 2010 05:31:18 +0000 (UTC)
commit a29eb470627ade19488041a347d1fff61cf22518
Author: Aleksey Sanin <aleksey aleksey com>
Date: Thu Apr 22 22:30:48 2010 -0700
fix search for non-english cert subject
include/xmlsec/mscrypto/crypto.h | 8 ++
src/mscrypto/app.c | 38 ----------
src/mscrypto/crypto.c | 143 ++++++++++++++++++++++++++++++++++++++
src/mscrypto/keysstore.c | 132 +++++++++++++----------------------
src/mscrypto/x509vfy.c | 72 ++++++++++++++-----
5 files changed, 253 insertions(+), 140 deletions(-)
---
diff --git a/include/xmlsec/mscrypto/crypto.h b/include/xmlsec/mscrypto/crypto.h
index c8d704a..a528da1 100644
--- a/include/xmlsec/mscrypto/crypto.h
+++ b/include/xmlsec/mscrypto/crypto.h
@@ -44,11 +44,19 @@ XMLSEC_CRYPTO_EXPORT void xmlSecMSCryptoErrorsDefaultCallback(cons
/**
* Utils
*/
+XMLSEC_CRYPTO_EXPORT LPWSTR xmlSecMSCryptoConvertUtf8ToUnicode (const xmlChar* str);
+XMLSEC_CRYPTO_EXPORT LPWSTR xmlSecMSCryptoConvertLocaleToUnicode(const char* str);
+
+
XMLSEC_CRYPTO_EXPORT BYTE* xmlSecMSCryptoCertStrToName (DWORD dwCertEncodingType,
LPCTSTR pszX500,
DWORD dwStrType,
DWORD* len);
+XMLSEC_CRYPTO_EXPORT BYTE* xmlSecMSCryptoCertStrToNameW (DWORD dwCertEncodingType,
+ LPWSTR pszX500,
+ DWORD dwStrType,
+ DWORD* len);
/********************************************************************
diff --git a/src/mscrypto/app.c b/src/mscrypto/app.c
index 2e36dbb..7f3f921 100644
--- a/src/mscrypto/app.c
+++ b/src/mscrypto/app.c
@@ -30,44 +30,6 @@
#endif
-static LPWSTR
-xmlSecMSCryptoConvertLocaleToUnicode(const char* str) {
- LPWSTR res = NULL;
- int len;
- int ret;
-
- xmlSecAssert2(str != NULL, NULL);
-
- /* call MultiByteToWideChar first to get the buffer size */
- ret = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
- if(ret <= 0) {
- return(NULL);
- }
- len = ret;
-
- /* allocate buffer */
- res = (LPWSTR)xmlMalloc(sizeof(WCHAR) * len);
- if(res == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- NULL,
- XMLSEC_ERRORS_R_MALLOC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(NULL);
- }
-
- /* convert */
- ret = MultiByteToWideChar(CP_ACP, 0, str, -1, res, len);
- if(ret <= 0) {
- xmlFree(res);
- return(NULL);
- }
-
- /* done */
- return(res);
-}
-
-
/* I don't see any other way then to use a global var to get the
* config info to the mscrypto keysstore :( WK
*/
diff --git a/src/mscrypto/crypto.c b/src/mscrypto/crypto.c
index 374ca56..d25a8b6 100644
--- a/src/mscrypto/crypto.c
+++ b/src/mscrypto/crypto.c
@@ -384,4 +384,147 @@ xmlSecMSCryptoCertStrToName(DWORD dwCertEncodingType, LPCTSTR pszX500, DWORD dwS
return(str);
}
+/**
+ * xmlSecMSCryptoCertStrToNameW:
+ * @dwCertEncodingType: the encoding used.
+ * @pszX500: the string to convert.
+ * @dwStrType: the string type.
+ * @len: the result len.
+ *
+ * Converts input string to name by calling @CertStrToName function.
+ *
+ * Returns: a pointer to newly allocated string or NULL if an error occurs.
+ */
+BYTE*
+xmlSecMSCryptoCertStrToNameW(DWORD dwCertEncodingType, LPWSTR pszX500, DWORD dwStrType, DWORD* len) {
+ BYTE* str = NULL;
+ LPCWSTR ppszError = NULL;
+
+ xmlSecAssert2(pszX500 != NULL, NULL);
+ xmlSecAssert2(len != NULL, NULL);
+
+ if (!CertStrToNameW(dwCertEncodingType, pszX500, dwStrType,
+ NULL, NULL, len, &ppszError)) {
+ /* this might not be an error, string might just not exist */
+ DWORD dw = GetLastError();
+ return(NULL);
+ }
+
+ str = (BYTE *)xmlMalloc((*len) + 1);
+ if(str == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ "len=%ld", (*len));
+ return(NULL);
+ }
+ memset(str, 0, (*len) + 1);
+
+ if (!CertStrToNameW(dwCertEncodingType, pszX500, dwStrType,
+ NULL, str, len, NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "CertStrToName",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(str);
+ return(NULL);
+ }
+
+ return(str);
+}
+
+/**
+ * xmlSecMSCryptoConvertUtf8ToUnicode:
+ * @str: the string to convert.
+ *
+ * Converts input string from UTF8 to Unicode.
+ *
+ * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs.
+ */
+LPWSTR
+xmlSecMSCryptoConvertUtf8ToUnicode(const xmlChar* str) {
+ LPWSTR res = NULL;
+ int len;
+ int ret;
+
+ xmlSecAssert2(str != NULL, NULL);
+
+ /* call MultiByteToWideChar first to get the buffer size */
+ ret = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
+ if(ret <= 0) {
+ return(NULL);
+ }
+ len = ret;
+
+ /* allocate buffer */
+ res = (LPWSTR)xmlMalloc(sizeof(WCHAR) * len);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ /* convert */
+ ret = MultiByteToWideChar(CP_UTF8, 0, str, -1, res, len);
+ if(ret <= 0) {
+ xmlFree(res);
+ return(NULL);
+ }
+
+ /* done */
+ return(res);
+}
+
+/**
+ * xmlSecMSCryptoConvertLocaleToUnicode:
+ * @str: the string to convert.
+ *
+ * Converts input string from current system locale to Unicode.
+ *
+ * Returns: a pointer to newly allocated string (must be freed with xmlFree) or NULL if an error occurs.
+ */
+LPWSTR
+xmlSecMSCryptoConvertLocaleToUnicode(const char* str) {
+ LPWSTR res = NULL;
+ int len;
+ int ret;
+
+ xmlSecAssert2(str != NULL, NULL);
+
+ /* call MultiByteToWideChar first to get the buffer size */
+ ret = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+ if(ret <= 0) {
+ return(NULL);
+ }
+ len = ret;
+
+ /* allocate buffer */
+ res = (LPWSTR)xmlMalloc(sizeof(WCHAR) * len);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(NULL);
+ }
+
+ /* convert */
+ ret = MultiByteToWideChar(CP_ACP, 0, str, -1, res, len);
+ if(ret <= 0) {
+ xmlFree(res);
+ return(NULL);
+ }
+
+ /* done */
+ return(res);
+}
+
+
+
diff --git a/src/mscrypto/keysstore.c b/src/mscrypto/keysstore.c
index 4afba44..05efda3 100644
--- a/src/mscrypto/keysstore.c
+++ b/src/mscrypto/keysstore.c
@@ -302,50 +302,13 @@ xmlSecMSCryptoKeysStoreFinalize(xmlSecKeyStorePtr store) {
xmlSecKeyStoreDestroy(*ss);
}
-static LPWSTR
-xmlSecMSCryptoConvertUtf8ToUnicode(const xmlChar* str) {
- LPWSTR res = NULL;
- int len;
- int ret;
-
- xmlSecAssert2(str != NULL, NULL);
-
- /* call MultiByteToWideChar first to get the buffer size */
- ret = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
- if(ret <= 0) {
- return(NULL);
- }
- len = ret;
-
- /* allocate buffer */
- res = (LPWSTR)xmlMalloc(sizeof(WCHAR) * len);
- if(res == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- NULL,
- XMLSEC_ERRORS_R_MALLOC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(NULL);
- }
-
- /* convert */
- ret = MultiByteToWideChar(CP_UTF8, 0, str, -1, res, len);
- if(ret <= 0) {
- xmlFree(res);
- return(NULL);
- }
-
- /* done */
- return(res);
-}
-
static PCCERT_CONTEXT
xmlSecMSCryptoKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name,
- xmlSecKeyInfoCtxPtr keyInfoCtx) {
+ xmlSecKeyInfoCtxPtr keyInfoCtx) {
const char* storeName;
HCERTSTORE hStoreHandle = NULL;
PCCERT_CONTEXT pCertContext = NULL;
- LPWSTR wcName = NULL;
+ LPWSTR wcName = NULL;
xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecMSCryptoKeysStoreId), NULL);
xmlSecAssert2(name != NULL, NULL);
@@ -367,18 +330,18 @@ xmlSecMSCryptoKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name,
return(NULL);
}
- wcName = xmlSecMSCryptoConvertUtf8ToUnicode(name);
- if(wcName == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
- "xmlSecMSCryptoConvertUtf8ToUnicode",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- "wcName");
- CertCloseStore(hStoreHandle, 0);
- return(NULL);
- }
+ wcName = xmlSecMSCryptoConvertUtf8ToUnicode(name);
+ if(wcName == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
+ "xmlSecMSCryptoConvertUtf8ToUnicode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "wcName");
+ CertCloseStore(hStoreHandle, 0);
+ return(NULL);
+ }
- /* first attempt: search by cert id == name */
+ /* first attempt: search by cert id == name */
if(pCertContext == NULL) {
pCertContext = CertFindCertificateInStore(
hStoreHandle,
@@ -396,8 +359,8 @@ xmlSecMSCryptoKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name,
BYTE* bdata;
DWORD len;
- bdata = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- name,
+ bdata = xmlSecMSCryptoCertStrToNameW(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ wcName,
CERT_OID_NAME_STR,
&len);
if(bdata != NULL) {
@@ -423,8 +386,8 @@ xmlSecMSCryptoKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name,
BYTE* bdata;
DWORD len;
- bdata = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- name,
+ bdata = xmlSecMSCryptoCertStrToNameW(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ wcName,
CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
&len);
if(bdata != NULL) {
@@ -447,46 +410,47 @@ xmlSecMSCryptoKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name,
* Try ro find certificate with name="Friendly Name"
*/
if (NULL == pCertContext) {
- DWORD dwPropSize;
- PBYTE pbFriendlyName;
- PCCERT_CONTEXT pCertCtxIter = NULL;
+ DWORD dwPropSize;
+ PBYTE pbFriendlyName;
+ PCCERT_CONTEXT pCertCtxIter = NULL;
- while (pCertCtxIter = CertEnumCertificatesInStore(hStoreHandle, pCertCtxIter)) {
- if (TRUE != CertGetCertificateContextProperty(pCertCtxIter,
+ while (pCertCtxIter = CertEnumCertificatesInStore(hStoreHandle, pCertCtxIter)) {
+ if (TRUE != CertGetCertificateContextProperty(pCertCtxIter,
CERT_FRIENDLY_NAME_PROP_ID,
NULL,
&dwPropSize)) {
- continue;
- }
+ continue;
+ }
- pbFriendlyName = xmlMalloc(dwPropSize);
- if(pbFriendlyName == NULL) {
- xmlSecError(XMLSEC_ERRORS_HERE,
- xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
- NULL,
- XMLSEC_ERRORS_R_MALLOC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
- xmlFree(wcName);
- CertCloseStore(hStoreHandle, 0);
- return(NULL);
- }
- if (TRUE != CertGetCertificateContextProperty(pCertCtxIter,
+ pbFriendlyName = xmlMalloc(dwPropSize);
+ if(pbFriendlyName == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
+ NULL,
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(wcName);
+ CertCloseStore(hStoreHandle, 0);
+ return(NULL);
+ }
+
+ if (TRUE != CertGetCertificateContextProperty(pCertCtxIter,
CERT_FRIENDLY_NAME_PROP_ID,
pbFriendlyName,
&dwPropSize)) {
- xmlFree(pbFriendlyName);
- continue;
- }
+ xmlFree(pbFriendlyName);
+ continue;
+ }
- /* Compare FriendlyName to name */
- if (!wcscmp(wcName, (const wchar_t *)pbFriendlyName)) {
- pCertContext = pCertCtxIter;
- xmlFree(pbFriendlyName);
- break;
+ /* Compare FriendlyName to name */
+ if (!wcscmp(wcName, (const wchar_t *)pbFriendlyName)) {
+ pCertContext = pCertCtxIter;
+ xmlFree(pbFriendlyName);
+ break;
+ }
+ xmlFree(pbFriendlyName);
}
- xmlFree(pbFriendlyName);
- }
}
/* We could do the following here:
@@ -501,7 +465,7 @@ xmlSecMSCryptoKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name,
/* aleksey todo: is it a right idea to close store if we have a handle to
* a cert in this store? */
- xmlFree(wcName);
+ xmlFree(wcName);
CertCloseStore(hStoreHandle, 0);
return(pCertContext);
}
diff --git a/src/mscrypto/x509vfy.c b/src/mscrypto/x509vfy.c
index c33b66e..d3f2b7c 100644
--- a/src/mscrypto/x509vfy.c
+++ b/src/mscrypto/x509vfy.c
@@ -84,10 +84,10 @@ static xmlSecKeyDataStoreKlass xmlSecMSCryptoX509StoreKlass = {
};
static PCCERT_CONTEXT xmlSecMSCryptoX509FindCert(HCERTSTORE store,
- xmlChar *subjectName,
- xmlChar *issuerName,
- xmlChar *issuerSerial,
- xmlChar *ski);
+ const xmlChar *subjectName,
+ const xmlChar *issuerName,
+ const xmlChar *issuerSerial,
+ const xmlChar *ski);
/**
@@ -885,8 +885,11 @@ xmlSecMSCryptoX509StoreFinalize(xmlSecKeyDataStorePtr store) {
*
*****************************************************************************/
static PCCERT_CONTEXT
-xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issuerName,
- xmlChar *issuerSerial, xmlChar *ski) {
+xmlSecMSCryptoX509FindCert(HCERTSTORE store,
+ const xmlChar *subjectName,
+ const xmlChar *issuerName,
+ const xmlChar *issuerSerial,
+ const xmlChar *ski) {
PCCERT_CONTEXT pCert = NULL;
int ret;
@@ -894,30 +897,49 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
if((pCert == NULL) && (NULL != subjectName)) {
CERT_NAME_BLOB cnb;
- BYTE *cName;
+ LPWSTR wcSubjectName = NULL;
+ BYTE *cName = NULL;
DWORD cNameLen;
- cName = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- subjectName,
+ /* get subject name */
+ wcSubjectName = xmlSecMSCryptoConvertUtf8ToUnicode(subjectName);
+ if(wcSubjectName == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecMSCryptoConvertUtf8ToUnicode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "wcSubjectName");
+ return(NULL);
+ }
+
+
+ cName = xmlSecMSCryptoCertStrToNameW(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ wcSubjectName,
CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
&cNameLen);
if(cName == NULL) {
xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlSecMSCryptoCertStrToName",
- XMLSEC_ERRORS_R_XMLSEC_FAILED,
- XMLSEC_ERRORS_NO_MESSAGE);
+ NULL,
+ "xmlSecMSCryptoCertStrToName",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(wcSubjectName);
return (NULL);
}
cnb.pbData = cName;
cnb.cbData = cNameLen;
+
+ /* search */
pCert = CertFindCertificateInStore(store,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_NAME,
&cnb,
NULL);
+
+ /* cleanup */
xmlFree(cName);
+ xmlFree(wcSubjectName);
}
if((pCert == NULL) && (NULL != issuerName) && (NULL != issuerSerial)) {
@@ -925,6 +947,7 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
xmlChar * p;
CERT_INFO certInfo;
CERT_NAME_BLOB cnb;
+ LPWSTR wcIssuerName = NULL;
BYTE *cName = NULL;
DWORD cNameLen = 0;
@@ -938,11 +961,19 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
memcpy(p, " Email=", 13);
}
-
-
/* get issuer name */
- cName = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- issuerName,
+ wcIssuerName = xmlSecMSCryptoConvertUtf8ToUnicode(issuerName);
+ if(wcIssuerName == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecMSCryptoConvertUtf8ToUnicode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "wcIssuerName");
+ return(NULL);
+ }
+
+ cName = xmlSecMSCryptoCertStrToNameW(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
+ wcIssuerName,
CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG | CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG,
&cNameLen);
if(cName == NULL) {
@@ -951,6 +982,7 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
"xmlSecMSCryptoCertStrToName",
XMLSEC_ERRORS_R_XMLSEC_FAILED,
XMLSEC_ERRORS_NO_MESSAGE);
+ xmlFree(wcIssuerName);
return (NULL);
}
cnb.pbData = cName;
@@ -965,6 +997,7 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
XMLSEC_ERRORS_R_XMLSEC_FAILED,
XMLSEC_ERRORS_NO_MESSAGE);
xmlFree(cName);
+ xmlFree(wcIssuerName);
return(NULL);
}
@@ -977,6 +1010,7 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
XMLSEC_ERRORS_NO_MESSAGE);
xmlSecBnFinalize(&issuerSerialBn);
xmlFree(cName);
+ xmlFree(wcIssuerName);
return(NULL);
}
@@ -993,6 +1027,7 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
XMLSEC_ERRORS_NO_MESSAGE);
xmlSecBnFinalize(&issuerSerialBn);
xmlFree(cName);
+ xmlFree(wcIssuerName);
return(NULL);
}
@@ -1010,8 +1045,9 @@ xmlSecMSCryptoX509FindCert(HCERTSTORE store, xmlChar *subjectName, xmlChar *issu
NULL
) ;
- xmlFree(cName);
xmlSecBnFinalize(&issuerSerialBn);
+ xmlFree(cName);
+ xmlFree(wcIssuerName);
}
if((pCert == NULL) && (ski != NULL)) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]