summaryrefslogtreecommitdiffstats
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 /Swiften/TLS/CAPICertificate.cpp
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 'Swiften/TLS/CAPICertificate.cpp')
-rw-r--r--Swiften/TLS/CAPICertificate.cpp278
1 files changed, 122 insertions, 156 deletions
diff --git a/Swiften/TLS/CAPICertificate.cpp b/Swiften/TLS/CAPICertificate.cpp
index b33ebcf..0083b6f 100644
--- a/Swiften/TLS/CAPICertificate.cpp
+++ b/Swiften/TLS/CAPICertificate.cpp
@@ -3,31 +3,35 @@
* Licensed under the simplified BSD license.
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+
#pragma once
#include <Swiften/Network/TimerFactory.h>
#include <Swiften/TLS/CAPICertificate.h>
#include <Swiften/StringCodecs/Hexify.h>
+#include <Swiften/Base/Log.h>
#include <boost/bind.hpp>
#include <boost/algorithm/string/predicate.hpp>
// Size of the SHA1 hash
-#define SHA1_HASH_LEN 20
+#define SHA1_HASH_LEN 20
namespace Swift {
-CAPICertificate::CAPICertificate(const std::string& capiUri, TimerFactory* timerFactory)
- : valid_(false),
- uri_(capiUri),
- certStoreHandle_(0),
- scardContext_(0),
- cardHandle_(0),
- certStore_(),
- certName_(),
- smartCardReaderName_(),
- timerFactory_(timerFactory) {
+CAPICertificate::CAPICertificate(const std::string& capiUri, TimerFactory* timerFactory) :
+ valid_(false),
+ uri_(capiUri),
+ certStoreHandle_(0),
+ scardContext_(0),
+ cardHandle_(0),
+ certStore_(),
+ certName_(),
+ smartCardReaderName_(),
+ timerFactory_(timerFactory),
+ lastPollingResult_(true) {
+ assert(timerFactory_);
setUri(capiUri);
}
@@ -69,19 +73,11 @@ const std::string& CAPICertificate::getSmartCardReaderName() const {
}
PCCERT_CONTEXT findCertificateInStore (HCERTSTORE certStoreHandle, const std::string &certName) {
- PCCERT_CONTEXT pCertContext = NULL;
-
if (!boost::iequals(certName.substr(0, 5), "sha1:")) {
// Find client certificate. Note that this sample just searches for a
// certificate that contains the user name somewhere in the subject name.
- pCertContext = CertFindCertificateInStore(certStoreHandle,
- X509_ASN_ENCODING,
- 0, // dwFindFlags
- CERT_FIND_SUBJECT_STR_A,
- certName.c_str(), // *pvFindPara
- NULL ); // pPrevCertContext
- return pCertContext;
+ return CertFindCertificateInStore(certStoreHandle, X509_ASN_ENCODING, /*dwFindFlags*/ 0, CERT_FIND_SUBJECT_STR_A, /* *pvFindPara*/certName.c_str(), /*pPrevCertContext*/ NULL);
}
@@ -97,19 +93,12 @@ PCCERT_CONTEXT findCertificateInStore (HCERTSTORE certStoreHandle, const std::st
// Find client certificate. Note that this sample just searches for a
// certificate that contains the user name somewhere in the subject name.
- pCertContext = CertFindCertificateInStore(certStoreHandle,
- X509_ASN_ENCODING,
- 0, // dwFindFlags
- CERT_FIND_HASH,
- &HashBlob,
- NULL ); // pPrevCertContext
-
- return pCertContext;
+ return CertFindCertificateInStore(certStoreHandle, X509_ASN_ENCODING, /* dwFindFlags */ 0, CERT_FIND_HASH, &HashBlob, /* pPrevCertContext */ NULL);
+
}
void CAPICertificate::setUri (const std::string& capiUri) {
-
valid_ = false;
/* Syntax: "certstore:" <cert_store> ":" <hash> ":" <hash_of_cert> */
@@ -119,41 +108,39 @@ void CAPICertificate::setUri (const std::string& capiUri) {
}
/* Substring of subject: uses "storename" */
- std::string capi_identity = capiUri.substr(10);
- std::string new_certStore_name;
- size_t pos = capi_identity.find_first_of (':');
+ std::string capiIdentity = capiUri.substr(10);
+ std::string newCertStoreName;
+ size_t pos = capiIdentity.find_first_of (':');
if (pos == std::string::npos) {
/* Using the default certificate store */
- new_certStore_name = "MY";
- certName_ = capi_identity;
+ newCertStoreName = "MY";
+ certName_ = capiIdentity;
}
else {
- new_certStore_name = capi_identity.substr(0, pos);
- certName_ = capi_identity.substr(pos + 1);
+ newCertStoreName = capiIdentity.substr(0, pos);
+ certName_ = capiIdentity.substr(pos + 1);
}
- PCCERT_CONTEXT pCertContext = NULL;
-
if (certStoreHandle_ != NULL) {
- if (new_certStore_name != certStore_) {
+ if (newCertStoreName != certStore_) {
CertCloseStore(certStoreHandle_, 0);
certStoreHandle_ = NULL;
}
}
if (certStoreHandle_ == NULL) {
- certStoreHandle_ = CertOpenSystemStore(0, new_certStore_name.c_str());
+ certStoreHandle_ = CertOpenSystemStore(0, newCertStoreName.c_str());
if (!certStoreHandle_) {
return;
}
}
- certStore_ = new_certStore_name;
+ certStore_ = newCertStoreName;
- pCertContext = findCertificateInStore (certStoreHandle_, certName_);
+ PCCERT_CONTEXT certContext = findCertificateInStore (certStoreHandle_, certName_);
- if (!pCertContext) {
+ if (!certContext) {
return;
}
@@ -165,61 +152,50 @@ void CAPICertificate::setUri (const std::string& capiUri) {
HCRYPTPROV hprov;
HCRYPTKEY key;
- if (!CertGetCertificateContextProperty(pCertContext,
+ if (!CertGetCertificateContextProperty(certContext,
CERT_KEY_PROV_INFO_PROP_ID,
NULL,
&len)) {
- CertFreeCertificateContext(pCertContext);
+ CertFreeCertificateContext(certContext);
return;
}
pinfo = static_cast<CRYPT_KEY_PROV_INFO *>(malloc(len));
if (!pinfo) {
- CertFreeCertificateContext(pCertContext);
+ CertFreeCertificateContext(certContext);
return;
}
- if (!CertGetCertificateContextProperty(pCertContext,
- CERT_KEY_PROV_INFO_PROP_ID,
- pinfo,
- &len)) {
- CertFreeCertificateContext(pCertContext);
+ if (!CertGetCertificateContextProperty(certContext, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len)) {
+ CertFreeCertificateContext(certContext);
free(pinfo);
return;
}
- CertFreeCertificateContext(pCertContext);
+ CertFreeCertificateContext(certContext);
// Now verify if we have access to the private key
- if (!CryptAcquireContextW(&hprov,
- pinfo->pwszContainerName,
- pinfo->pwszProvName,
- pinfo->dwProvType,
- 0)) {
+ if (!CryptAcquireContextW(&hprov, pinfo->pwszContainerName, pinfo->pwszProvName, pinfo->dwProvType, 0)) {
free(pinfo);
return;
}
- char smartcard_reader[1024];
- DWORD buflen;
-
- buflen = sizeof(smartcard_reader);
- if (!CryptGetProvParam(hprov, PP_SMARTCARD_READER, (BYTE *)&smartcard_reader, &buflen, 0)) {
- DWORD error;
-
- error = GetLastError();
+ char smartCardReader[1024];
+ DWORD bufferLength = sizeof(smartCardReader);
+ if (!CryptGetProvParam(hprov, PP_SMARTCARD_READER, (BYTE *)&smartCardReader, &bufferLength, 0)) {
+ DWORD error = GetLastError();
smartCardReaderName_ = "";
- } else {
- LONG lRet;
-
- smartCardReaderName_ = smartcard_reader;
+ }
+ else {
+ smartCardReaderName_ = smartCardReader;
- lRet = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &scardContext_);
- if (SCARD_S_SUCCESS == lRet) {
+ LONG result = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &scardContext_);
+ if (SCARD_S_SUCCESS == result) {
// Initiate monitoring for smartcard ejection
- smartCardTimer_ = timerFactory_->createTimer(SMARTCARD_EJECTION_CHECK_FREQ);
- } else {
+ smartCardTimer_ = timerFactory_->createTimer(SMARTCARD_EJECTION_CHECK_FREQUENCY_MILLISECONDS);
+ }
+ else {
///Need to handle an error here
}
}
@@ -242,125 +218,115 @@ void CAPICertificate::setUri (const std::string& capiUri) {
valid_ = true;
}
-static void smartcard_check_status (SCARDCONTEXT hContext,
- const char * pReader,
- SCARDHANDLE hCardHandle, // Can be 0 on the first call
- SCARDHANDLE * newCardHandle, // The handle returned
- DWORD * pdwState) {
- LONG lReturn;
- DWORD dwAP;
- char szReader[200];
- DWORD cch = sizeof(szReader);
- BYTE bAttr[32];
- DWORD cByte = 32;
-
+static void smartcard_check_status (SCARDCONTEXT hContext,
+ const char* pReader,
+ SCARDHANDLE hCardHandle, /* Can be 0 on the first call */
+ SCARDHANDLE* newCardHandle, /* The handle returned */
+ DWORD* pdwState) {
if (hCardHandle == 0) {
- lReturn = SCardConnect(hContext,
- pReader,
- SCARD_SHARE_SHARED,
- SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
- &hCardHandle,
- &dwAP);
- if ( SCARD_S_SUCCESS != lReturn ) {
+ DWORD dwAP;
+ LONG result = SCardConnect(hContext, pReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCardHandle, &dwAP);
+ if (SCARD_S_SUCCESS != result) {
hCardHandle = 0;
- if (SCARD_E_NO_SMARTCARD == lReturn || SCARD_W_REMOVED_CARD == lReturn) {
+ if (SCARD_E_NO_SMARTCARD == result || SCARD_W_REMOVED_CARD == result) {
*pdwState = SCARD_ABSENT;
- } else {
+ }
+ else {
*pdwState = SCARD_UNKNOWN;
}
- goto done;
+
+ if (newCardHandle == NULL) {
+ (void) SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
+ hCardHandle = 0;
+ }
+ else {
+ *newCardHandle = hCardHandle;
+ }
}
}
- lReturn = SCardStatus(hCardHandle,
- szReader, // Unfortunately we can't use NULL here
- &cch,
- pdwState,
- NULL,
- (LPBYTE)&bAttr,
- &cByte);
+ char szReader[200];
+ DWORD cch = sizeof(szReader);
+ BYTE bAttr[32];
+ DWORD cByte = 32;
+ LONG result = SCardStatus(hCardHandle, /* Unfortunately we can't use NULL here */ szReader, &cch, pdwState, NULL, (LPBYTE)&bAttr, &cByte);
- if ( SCARD_S_SUCCESS != lReturn ) {
- if (SCARD_E_NO_SMARTCARD == lReturn || SCARD_W_REMOVED_CARD == lReturn) {
+ if (SCARD_S_SUCCESS != result) {
+ if (SCARD_E_NO_SMARTCARD == result || SCARD_W_REMOVED_CARD == result) {
*pdwState = SCARD_ABSENT;
- } else {
+ }
+ else {
*pdwState = SCARD_UNKNOWN;
}
}
-done:
if (newCardHandle == NULL) {
(void) SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
hCardHandle = 0;
- } else {
+ }
+ else {
*newCardHandle = hCardHandle;
}
}
bool CAPICertificate::checkIfSmartCardPresent () {
-
- DWORD dwState;
-
if (!smartCardReaderName_.empty()) {
- smartcard_check_status (scardContext_,
- smartCardReaderName_.c_str(),
- cardHandle_,
- &cardHandle_,
- &dwState);
-////DEBUG
- switch ( dwState ) {
- case SCARD_ABSENT:
- printf("Card absent.\n");
- break;
- case SCARD_PRESENT:
- printf("Card present.\n");
- break;
- case SCARD_SWALLOWED:
- printf("Card swallowed.\n");
- break;
- case SCARD_POWERED:
- printf("Card has power.\n");
- break;
- case SCARD_NEGOTIABLE:
- printf("Card reset and waiting PTS negotiation.\n");
- break;
- case SCARD_SPECIFIC:
- printf("Card has specific communication protocols set.\n");
- break;
- default:
- printf("Unknown or unexpected card state.\n");
- break;
+ DWORD dwState;
+ smartcard_check_status(scardContext_, smartCardReaderName_.c_str(), cardHandle_, &cardHandle_, &dwState);
+
+ switch (dwState) {
+ case SCARD_ABSENT:
+ SWIFT_LOG("DEBUG") << "Card absent." << std::endl;
+ break;
+ case SCARD_PRESENT:
+ SWIFT_LOG("DEBUG") << "Card present." << std::endl;
+ break;
+ case SCARD_SWALLOWED:
+ SWIFT_LOG("DEBUG") << "Card swallowed." << std::endl;
+ break;
+ case SCARD_POWERED:
+ SWIFT_LOG("DEBUG") << "Card has power." << std::endl;
+ break;
+ case SCARD_NEGOTIABLE:
+ SWIFT_LOG("DEBUG") << "Card reset and waiting PTS negotiation." << std::endl;
+ break;
+ case SCARD_SPECIFIC:
+ SWIFT_LOG("DEBUG") << "Card has specific communication protocols set." << std::endl;
+ break;
+ default:
+ SWIFT_LOG("DEBUG") << "Unknown or unexpected card state." << std::endl;
+ break;
}
- switch ( dwState ) {
- case SCARD_ABSENT:
- return false;
+ switch (dwState) {
+ case SCARD_ABSENT:
+ return false;
- case SCARD_PRESENT:
- case SCARD_SWALLOWED:
- case SCARD_POWERED:
- case SCARD_NEGOTIABLE:
- case SCARD_SPECIFIC:
- return true;
+ case SCARD_PRESENT:
+ case SCARD_SWALLOWED:
+ case SCARD_POWERED:
+ case SCARD_NEGOTIABLE:
+ case SCARD_SPECIFIC:
+ return true;
- default:
- return false;
+ default:
+ return false;
}
- } else {
+ }
+ else {
return false;
}
}
void CAPICertificate::handleSmartCardTimerTick() {
-
- if (checkIfSmartCardPresent() == false) {
- smartCardTimer_->stop();
+ bool poll = checkIfSmartCardPresent();
+ if (lastPollingResult_ && !poll) {
onCertificateCardRemoved();
- } else {
- smartCardTimer_->start();
- }
+ }
+ lastPollingResult_ = poll;
+ smartCardTimer_->start();
}
}