From 0833f7da453db9cd0fc3a78c793e7532663ab86b Mon Sep 17 00:00:00 2001
From: Alexey Melnikov <alexey.melnikov@isode.com>
Date: Wed, 7 Mar 2012 19:16:54 +0000
Subject: Fixed several bugs in CAPI/Schannel code on Windows

This patch includes the following fixes:
1) Correctly hex encode SHA1 hashes when generating certstore: URIs
2) Use the newly parsed certificate store reference, not the old value
3) Need to call findCertificateInStore() when finding the selected TLS
   certificate in Schannel code. Without that "sha1:XXXX" URIs don't
   work

Also minor optimization of string operations.

License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.

diff --git a/Swift/QtUI/CAPICertificateSelector.cpp b/Swift/QtUI/CAPICertificateSelector.cpp
index e7948ef..0d4768c 100644
--- a/Swift/QtUI/CAPICertificateSelector.cpp
+++ b/Swift/QtUI/CAPICertificateSelector.cpp
@@ -30,7 +30,10 @@ namespace Swift {
 static std::string getCertUri(PCCERT_CONTEXT cert, const char * cert_store_name) {
 	DWORD cbHash = SHA1_HASH_LEN;
 	BYTE aHash[SHA1_HASH_LEN];
-	std::string ret = std::string("certstore:") + cert_store_name + ":" + "sha1:";
+	std::string ret("certstore:");
+
+	ret += cert_store_name;
+	ret += ":sha1:";
 
 	if (CertGetCertificateContextProperty(cert,
 		 CERT_HASH_PROP_ID,
@@ -39,7 +42,7 @@ static std::string getCertUri(PCCERT_CONTEXT cert, const char * cert_store_name)
 		return "";
 	}
 
-	ByteArray byteArray = createByteArray((char *)(&aHash[0]));
+	ByteArray byteArray = createByteArray((char *)(&aHash[0]), cbHash);
 	ret += Hexify::hexify(byteArray);
 
 	return ret;
diff --git a/Swiften/TLS/CAPICertificate.cpp b/Swiften/TLS/CAPICertificate.cpp
index a6725c9..0dc3009 100644
--- a/Swiften/TLS/CAPICertificate.cpp
+++ b/Swiften/TLS/CAPICertificate.cpp
@@ -38,7 +38,7 @@ const std::string& CAPICertificate::getCertName() const {
 	return certName_;
 }
 
-static PCCERT_CONTEXT findCertificateInStore (HCERTSTORE certStoreHandle, const std::string &certName) {
+PCCERT_CONTEXT findCertificateInStore (HCERTSTORE certStoreHandle, const std::string &certName) {
 	PCCERT_CONTEXT pCertContext = NULL;
 
 	if (!boost::iequals(certName.substr(0, 5), "sha1:")) {
@@ -113,7 +113,7 @@ void CAPICertificate::setUri (const std::string& capiUri) {
 	}
 
 	if (certStoreHandle_ == NULL) {
-		certStoreHandle_ = CertOpenSystemStore(0, certStore_.c_str());
+		certStoreHandle_ = CertOpenSystemStore(0, new_certStore_name.c_str());
 		if (!certStoreHandle_) {
 			return;
 		}
diff --git a/Swiften/TLS/CAPICertificate.h b/Swiften/TLS/CAPICertificate.h
index d9e2704..4204a6b 100644
--- a/Swiften/TLS/CAPICertificate.h
+++ b/Swiften/TLS/CAPICertificate.h
@@ -39,4 +39,7 @@ namespace Swift {
 			std::string certStore_;
 			std::string certName_;
 	};
+
+PCCERT_CONTEXT findCertificateInStore (HCERTSTORE certStoreHandle, const std::string &certName);
+
 }
diff --git a/Swiften/TLS/Schannel/SchannelContext.cpp b/Swiften/TLS/Schannel/SchannelContext.cpp
index ddbebcb..b2fea65 100644
--- a/Swiften/TLS/Schannel/SchannelContext.cpp
+++ b/Swiften/TLS/Schannel/SchannelContext.cpp
@@ -69,15 +69,7 @@ void SchannelContext::connect()
 			}
 		}
 
-		// Find client certificate. Note that this sample just searches for a 
-		// certificate that contains the user name somewhere in the subject name.
-		pCertContext = CertFindCertificateInStore( m_my_cert_store,
-			X509_ASN_ENCODING,
-			0,				// dwFindFlags
-			CERT_FIND_SUBJECT_STR_A,
-			m_cert_name.c_str(),		// *pvFindPara
-			NULL );				// pPrevCertContext
-
+		pCertContext = findCertificateInStore( m_my_cert_store, m_cert_name );
 		if (pCertContext == NULL)
 		{
 /////		printf("**** Error 0x%x returned by CertFindCertificateInStore\n", GetLastError());
@@ -94,7 +86,6 @@ void SchannelContext::connect()
 
 /////SSL3?
 	sc.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT | SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT;
-/////Check SCH_CRED_REVOCATION_CHECK_CHAIN
 	sc.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION | SCH_CRED_REVOCATION_CHECK_CHAIN;
 
 	if (pCertContext)
-- 
cgit v0.10.2-6-g49f6