summaryrefslogtreecommitdiffstats
path: root/Swift
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2012-03-23 16:00:24 (GMT)
committerKevin Smith <git@kismith.co.uk>2012-04-12 13:49:48 (GMT)
commit0bf6afc5c01b9eb3024a8cfd04bfd743890db4f6 (patch)
treeca480f6b8e27afa97ade97ca7a13b11502b21f31 /Swift
parentd5f885dd9aa65d18145a99826a1c30aeb62aca8e (diff)
downloadswift-contrib-0bf6afc5c01b9eb3024a8cfd04bfd743890db4f6.zip
swift-contrib-0bf6afc5c01b9eb3024a8cfd04bfd743890db4f6.tar.bz2
Tidy up of assorted Schannel/CAPI stuffs.
Makes Swift disconnect if a smartcard used for auth is removed. Fixes compilation. Changes code style in a few places.
Diffstat (limited to 'Swift')
-rw-r--r--Swift/Controllers/MainController.cpp2
-rw-r--r--Swift/QtUI/CAPICertificateSelector.cpp101
-rw-r--r--Swift/QtUI/SConscript1
3 files changed, 59 insertions, 45 deletions
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index b0a1778..28fdb2b 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -550,6 +550,8 @@ void MainController::handleDisconnected(const boost::optional<ClientError>& erro
case ClientError::InvalidCertificateSignatureError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid certificate signature"); break;
case ClientError::InvalidCAError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid Certificate Authority"); break;
case ClientError::InvalidServerIdentityError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate does not match the host identity"); break;
+ case ClientError::RevokedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has been revoked"); break;
+ case ClientError::RevocationCheckFailedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Unable to determine certificate revocation state"); break;
}
bool forceReconnectAfterCertificateTrust = false;
if (!certificateErrorMessage.empty()) {
diff --git a/Swift/QtUI/CAPICertificateSelector.cpp b/Swift/QtUI/CAPICertificateSelector.cpp
index 0d4768c..cc69956 100644
--- a/Swift/QtUI/CAPICertificateSelector.cpp
+++ b/Swift/QtUI/CAPICertificateSelector.cpp
@@ -6,94 +6,107 @@
#include <string>
-#include "CAPICertificateSelector.h"
+#include <Swift/QtUI/CAPICertificateSelector.h>
#define SECURITY_WIN32
#include <Windows.h>
#include <WinCrypt.h>
#include <cryptuiapi.h>
+
#include <Swiften/StringCodecs/Hexify.h>
#include <boost/algorithm/string.hpp>
+#include <Swift/Controllers/Intl.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swiften/Base/Log.h>
namespace Swift {
-#define cert_dlg_title L"TLS Client Certificate Selection"
-#define cert_dlg_prompt L"Select a certificate to use for authentication"
/////Hmm, maybe we should not exlude the "location" column
-#define exclude_columns CRYPTUI_SELECT_LOCATION_COLUMN \
- |CRYPTUI_SELECT_INTENDEDUSE_COLUMN
+#define exclude_columns CRYPTUI_SELECT_LOCATION_COLUMN | CRYPTUI_SELECT_INTENDEDUSE_COLUMN
-// Size of the SHA1 hash
-#define SHA1_HASH_LEN 20
+#define SHA1_HASH_LENGTH 20
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("certstore:");
+ DWORD cbHash = SHA1_HASH_LENGTH;
+ BYTE aHash[SHA1_HASH_LENGTH];
+ std::string result("certstore:");
- ret += cert_store_name;
- ret += ":sha1:";
+ result += cert_store_name;
+ result += ":sha1:";
- if (CertGetCertificateContextProperty(cert,
- CERT_HASH_PROP_ID,
- aHash,
- &cbHash) == FALSE ) {
+ if (CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, aHash, &cbHash) == FALSE ) {
return "";
}
ByteArray byteArray = createByteArray((char *)(&aHash[0]), cbHash);
- ret += Hexify::hexify(byteArray);
+ result += Hexify::hexify(byteArray);
- return ret;
+ return result;
}
std::string selectCAPICertificate() {
+ const char* certStoreName = "MY";
- const char * cert_store_name = "MY";
- PCCERT_CONTEXT cert;
- DWORD store_flags;
- HCERTSTORE hstore;
- HWND hwnd;
-
- store_flags = CERT_STORE_OPEN_EXISTING_FLAG |
- CERT_STORE_READONLY_FLAG |
- CERT_SYSTEM_STORE_CURRENT_USER;
+ DWORD storeFlags = CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER;
- hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, store_flags, cert_store_name);
+ HCERTSTORE hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, storeFlags, certStoreName);
if (!hstore) {
return "";
}
-
-////Does this handle need to be freed as well?
- hwnd = GetForegroundWindow();
+ HWND hwnd = GetForegroundWindow();
if (!hwnd) {
hwnd = GetActiveWindow();
}
+ std::string certificateDialogTitle = QT_TRANSLATE_NOOP("", "TLS Client Certificate Selection");
+ std::string certificateDialogPrompt = QT_TRANSLATE_NOOP("", "Select a certificate to use for authentication");
+
+ int titleLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogTitle.c_str(), -1, NULL, 0);
+ int promptLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogPrompt.c_str(), -1, NULL, 0);
+
+ wchar_t* titleChars = new wchar_t[titleLength];
+ wchar_t* promptChars = new wchar_t[promptLength];
+
+ //titleChars[titleLength] = '\0';
+ //promptChars[promptLength] = '\0';
+
+ titleLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogTitle.c_str(), -1, titleChars, titleLength);
+ promptLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogPrompt.c_str(), -1, promptChars, promptLength);
+
+ if (titleLength == 0 || promptLength == 0) {
+ int error = GetLastError();
+ switch (error) {
+ case ERROR_INSUFFICIENT_BUFFER: SWIFT_LOG("error") << "Insufficient buffer for rendering cert dialog" << std::endl;break;
+ case ERROR_INVALID_FLAGS: SWIFT_LOG("error") << "Invalid flags for rendering cert dialog" << std::endl;break;
+ case ERROR_INVALID_PARAMETER: SWIFT_LOG("error") << "Invalid parameter for rendering cert dialog" << std::endl;break;
+ case ERROR_NO_UNICODE_TRANSLATION: SWIFT_LOG("error") << "Invalid unicode for rendering cert dialog" << std::endl;break;
+ default: SWIFT_LOG("error") << "Unexpected multibyte conversion errorcode" << std::endl;
+
+ }
+ }
+
+
+
/* Call Windows dialog to select a suitable certificate */
- cert = CryptUIDlgSelectCertificateFromStore(hstore,
- hwnd,
- cert_dlg_title,
- cert_dlg_prompt,
- exclude_columns,
- 0,
- NULL);
+ PCCERT_CONTEXT cert = CryptUIDlgSelectCertificateFromStore(hstore, hwnd, titleChars, promptChars, exclude_columns, 0, NULL);
+
+ delete[] titleChars;
+ delete[] promptChars;
if (hstore) {
CertCloseStore(hstore, 0);
}
- if (cert) {
- std::string ret = getCertUri(cert, cert_store_name);
+ std::string result;
+ if (cert) {
+ result = getCertUri(cert, certStoreName);
CertFreeCertificateContext(cert);
-
- return ret;
- } else {
- return "";
}
+
+ return result;
}
bool isCAPIURI(std::string uri) {
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index 0622cc6..0971577 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -41,7 +41,6 @@ if myenv.get("HAVE_SNARL", False) :
myenv.Append(CPPDEFINES = ["HAVE_SNARL"])
if env["PLATFORM"] == "win32" :
myenv.Append(LIBS = ["cryptui"])
- myenv.Append(LIBS = ["Winscard"])
myenv.UseFlags(myenv["PLATFORM_FLAGS"])
myenv.Tool("qt4", toolpath = ["#/BuildTools/SCons/Tools"])