diff options
Diffstat (limited to 'Swiften/TLS/CAPICertificate.cpp')
| -rw-r--r-- | Swiften/TLS/CAPICertificate.cpp | 278 | 
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();  }  } | 
 Swift
 Swift