Changeset - 5c5cd0e346d3
[Not reviewed]
Merge
0 7 2
Jan Kaluza - 10 years ago 2015-12-01 08:48:28
jkaluza@redhat.com
Merge branch 'master' of github.com:hanzz/libtransport
5 files changed with 573 insertions and 1 deletions:
0 comments (0 inline, 0 general)
include/Swiften/TLS/SecureTransport/SecureTransportServerContext.h
Show inline comments
 
new file 100644
 
/*
 
 * Copyright (c) 2015 Isode Limited.
 
 * All rights reserved.
 
 * See the COPYING file for more information.
 
 */
 

	
 
#pragma once
 

	
 
#include <Security/SecureTransport.h>
 
#include <Swiften/TLS/TLSError.h>
 
#include "Swiften/TLS/TLSServerContext.h"
 

	
 
namespace Swift {
 

	
 
class SecureTransportServerContext : public TLSServerContext {
 
	public:
 
		SecureTransportServerContext(bool checkCertificateRevocation);
 
		virtual ~SecureTransportServerContext();
 

	
 
		virtual void connect();
 

	
 
		virtual bool setClientCertificate(CertificateWithKey::ref cert);
 

	
 
		virtual void handleDataFromNetwork(const SafeByteArray&);
 
		virtual void handleDataFromApplication(const SafeByteArray&);
 

	
 
		virtual std::vector<Certificate::ref> getPeerCertificateChain() const;
 
		virtual CertificateVerificationError::ref getPeerCertificateVerificationError() const;
 

	
 
		virtual ByteArray getFinishMessage() const;
 
	
 
	private:
 
		static OSStatus SSLSocketReadCallback(SSLConnectionRef connection, void *data, size_t *dataLength); 
 
		static OSStatus SSLSocketWriteCallback(SSLConnectionRef connection, const void *data, size_t *dataLength);
 

	
 
	private:
 
		enum State { None, Handshake, HandshakeDone, Error};
 
		static std::string stateToString(State state);
 
		void setState(State newState);
 

	
 
		static boost::shared_ptr<TLSError> nativeToTLSError(OSStatus error);
 
		boost::shared_ptr<CertificateVerificationError> CSSMErrorToVerificationError(OSStatus resultCode);
 

	
 
		void processHandshake();
 
		void verifyServerCertificate();
 

	
 
		void fatalError(boost::shared_ptr<TLSError> error, boost::shared_ptr<CertificateVerificationError> certificateError);
 

	
 
	private:
 
		boost::shared_ptr<SSLContext> sslContext_;
 
		SafeByteArray readingBuffer_;
 
		State state_;
 
		CertificateVerificationError::ref verificationError_;
 
		CertificateWithKey::ref clientCertificate_;
 
		bool checkCertificateRevocation_;
 
};
 

	
 
}
include/Swiften/TLS/SecureTransport/SecureTransportServerContext.mm
Show inline comments
 
new file 100644
 
/*
 
 * Copyright (c) 2015 Isode Limited.
 
 * All rights reserved.
 
 * See the COPYING file for more information.
 
 */
 

	
 
#include <Swiften/TLS/SecureTransport/SecureTransportServerContext.h>
 

	
 
#include <boost/type_traits.hpp>
 
#include <boost/numeric/conversion/cast.hpp>
 

	
 
#include <Swiften/Base/Algorithm.h>
 
#include <Swiften/Base/Log.h>
 
#include <Swiften/TLS/SecureTransport/SecureTransportCertificate.h>
 
#include <Swiften/TLS/PKCS12Certificate.h>
 
#include <Swiften/TLS/CertificateWithKey.h>
 

	
 
#include <Cocoa/Cocoa.h>
 

	
 
#import <Security/SecCertificate.h>
 
#import <Security/SecImportExport.h>
 

	
 
namespace {
 
	typedef boost::remove_pointer<CFArrayRef>::type CFArray;
 
	typedef boost::remove_pointer<SecTrustRef>::type SecTrust;
 
}
 

	
 
template <typename T, typename S>
 
T bridge_cast(S source) {
 
#pragma clang diagnostic push
 
#pragma clang diagnostic ignored "-Wold-style-cast"
 
	return (__bridge T)(source);
 
#pragma clang diagnostic pop
 
}
 

	
 
namespace Swift {
 

	
 
namespace {
 

	
 
	
 
CFArrayRef CreateClientCertificateChainAsCFArrayRef(CertificateWithKey::ref key) {
 
	boost::shared_ptr<PKCS12Certificate> pkcs12 = boost::dynamic_pointer_cast<PKCS12Certificate>(key);
 
	if (!key) {
 
		return NULL;
 
	}
 

	
 
	SafeByteArray safePassword = pkcs12->getPassword();
 
	CFIndex passwordSize = 0;
 
	try {
 
		passwordSize = boost::numeric_cast<CFIndex>(safePassword.size());
 
	} catch (...) {
 
		return NULL;
 
	}
 

	
 
	CFMutableArrayRef certChain = CFArrayCreateMutable(NULL, 0, 0);
 

	
 
	OSStatus securityError = errSecSuccess;
 
	CFStringRef password = CFStringCreateWithBytes(kCFAllocatorDefault, safePassword.data(), passwordSize, kCFStringEncodingUTF8, false);
 
	const void* keys[] = { kSecImportExportPassphrase };
 
	const void* values[] = { password };
 

	
 
	CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
 

	
 
	CFArrayRef items = NULL;
 
	CFDataRef pkcs12Data = bridge_cast<CFDataRef>([NSData dataWithBytes: static_cast<const void *>(pkcs12->getData().data()) length:pkcs12->getData().size()]);
 
	securityError = SecPKCS12Import(pkcs12Data, options, &items);
 
	CFRelease(options);
 
	NSArray* nsItems = bridge_cast<NSArray*>(items);
 

	
 
	switch(securityError) {
 
		case errSecSuccess:
 
			break;
 
		case errSecAuthFailed:
 
			// Password did not work for decoding the certificate.
 
			SWIFT_LOG(warning) << "Invalid password." << std::endl;
 
			break;
 
		case errSecDecode:
 
			// Other decoding error.
 
			SWIFT_LOG(warning) << "PKCS12 decoding error." << std::endl;
 
			break;
 
		default:
 
			SWIFT_LOG(warning) << "Unknown error." << std::endl;
 
	}
 
	
 
	if (securityError != errSecSuccess) {
 
		if (items) {
 
			CFRelease(items);
 
			items = NULL;
 
		}
 
		CFRelease(certChain);
 
		certChain = NULL;
 
	}
 

	
 
	if (certChain) {
 
		CFArrayAppendValue(certChain, nsItems[0][@"identity"]);
 

	
 
		for (CFIndex index = 0; index < CFArrayGetCount(bridge_cast<CFArrayRef>(nsItems[0][@"chain"])); index++) {
 
			CFArrayAppendValue(certChain, CFArrayGetValueAtIndex(bridge_cast<CFArrayRef>(nsItems[0][@"chain"]), index));
 
		}
 
	}
 
	return certChain;
 
}
 

	
 
}
 

	
 
SecureTransportContext::SecureTransportServerContext(bool checkCertificateRevocation) : state_(None), checkCertificateRevocation_(checkCertificateRevocation) {
 
	sslContext_ = boost::shared_ptr<SSLContext>(SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), CFRelease);
 

	
 
	OSStatus error = noErr;
 
	// set IO callbacks
 
	error = SSLSetIOFuncs(sslContext_.get(), &SecureTransportContext::SSLSocketReadCallback, &SecureTransportContext::SSLSocketWriteCallback);
 
	if (error != noErr) {
 
		SWIFT_LOG(error) << "Unable to set IO functions to SSL context." << std::endl;
 
		sslContext_.reset();
 
	}
 

	
 
	error = SSLSetConnection(sslContext_.get(), this);
 
	if (error != noErr) {
 
		SWIFT_LOG(error) << "Unable to set connection to SSL context." << std::endl;
 
		sslContext_.reset();
 
	}
 

	
 

	
 
	error = SSLSetSessionOption(sslContext_.get(), kSSLSessionOptionBreakOnServerAuth, true);
 
	if (error != noErr) {
 
		SWIFT_LOG(error) << "Unable to set kSSLSessionOptionBreakOnServerAuth on session." << std::endl;
 
		sslContext_.reset();
 
	}
 
}
 

	
 
SecureTransportServerContext::~SecureTransportServerContext() {
 
	if (sslContext_) {
 
		SSLClose(sslContext_.get());
 
	}
 
}
 

	
 
std::string SecureTransportContext::stateToString(State state) {
 
	std::string returnValue;
 
	switch(state) {
 
		case Handshake:
 
			returnValue = "Handshake";
 
			break;
 
		case HandshakeDone:
 
			returnValue = "HandshakeDone";
 
			break;
 
		case None:
 
			returnValue = "None";
 
			break;
 
		case Error:
 
			returnValue = "Error";
 
			break;
 
	}
 
	return returnValue;
 
}
 

	
 
void SecureTransportServerContext::setState(State newState) {
 
	SWIFT_LOG(debug) << "Switch state from " << stateToString(state_) << " to " << stateToString(newState) << "." << std::endl;
 
	state_ = newState;
 
}
 

	
 
void SecureTransportServerContext::connect() {
 
	SWIFT_LOG_ASSERT(state_ == None, error) << "current state '" << stateToString(state_) << " invalid." << std::endl;
 
	if (clientCertificate_) {
 
		CFArrayRef certs = CreateClientCertificateChainAsCFArrayRef(clientCertificate_);
 
		if (certs) {
 
			boost::shared_ptr<CFArray> certRefs(certs, CFRelease);
 
			OSStatus result = SSLSetCertificate(sslContext_.get(), certRefs.get());
 
			if (result != noErr) {
 
				SWIFT_LOG(error) << "SSLSetCertificate failed with error " << result << "." << std::endl;
 
			}
 
		}
 
	}
 
	processHandshake();
 
}
 

	
 
void SecureTransportServerContext::processHandshake() {
 
	SWIFT_LOG_ASSERT(state_ == None || state_ == Handshake, error) << "current state '" << stateToString(state_) << " invalid." << std::endl;
 
	OSStatus error = SSLHandshake(sslContext_.get());
 
	if (error == errSSLWouldBlock) {
 
		setState(Handshake);
 
	}
 
	else if (error == noErr) {
 
		SWIFT_LOG(debug) << "TLS handshake successful." << std::endl;
 
		setState(HandshakeDone);
 
		onConnected();
 
	}
 
	else if (error == errSSLPeerAuthCompleted) {
 
		SWIFT_LOG(debug) << "Received server certificate. Start verification." << std::endl;
 
		setState(Handshake);
 
		verifyServerCertificate();
 
	}
 
	else {
 
		SWIFT_LOG(debug) << "Error returned from SSLHandshake call is " << error << "." << std::endl;
 
		fatalError(nativeToTLSError(error), boost::make_shared<CertificateVerificationError>());
 
	}
 
}
 

	
 

	
 
#pragma clang diagnostic push
 
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
 

	
 
void SecureTransportServerContext::verifyServerCertificate() {
 
	SecTrustRef trust = NULL;
 
	OSStatus error = SSLCopyPeerTrust(sslContext_.get(), &trust);
 
	if (error != noErr) {
 
		fatalError(boost::make_shared<TLSError>(), boost::make_shared<CertificateVerificationError>());
 
		return;
 
	}
 
	boost::shared_ptr<SecTrust> trustRef = boost::shared_ptr<SecTrust>(trust, CFRelease);
 

	
 
	if (checkCertificateRevocation_) {
 
		error = SecTrustSetOptions(trust, kSecTrustOptionRequireRevPerCert | kSecTrustOptionFetchIssuerFromNet);
 
		if (error != noErr) {
 
			fatalError(boost::make_shared<TLSError>(), boost::make_shared<CertificateVerificationError>());
 
			return;
 
		}
 
	}
 

	
 
	SecTrustResultType trustResult;
 
	error = SecTrustEvaluate(trust, &trustResult);
 
	if (error != errSecSuccess) {
 
		fatalError(boost::make_shared<TLSError>(), boost::make_shared<CertificateVerificationError>());
 
		return;
 
	}
 

	
 
	OSStatus cssmResult = 0;
 
	switch(trustResult) {
 
		case kSecTrustResultUnspecified:
 
			SWIFT_LOG(warning) << "Successful implicit validation. Result unspecified." << std::endl;
 
			break;
 
		case kSecTrustResultProceed:
 
			SWIFT_LOG(warning) << "Validation resulted in explicitly trusted." << std::endl;
 
			break;
 
		case kSecTrustResultRecoverableTrustFailure:
 
			SWIFT_LOG(warning) << "recoverable trust failure" << std::endl;
 
			error = SecTrustGetCssmResultCode(trust, &cssmResult);
 
			if (error == errSecSuccess) {
 
				verificationError_ = CSSMErrorToVerificationError(cssmResult);
 
				if (cssmResult == CSSMERR_TP_VERIFY_ACTION_FAILED || cssmResult == CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK ) {
 
					// Find out the reason why the verification failed.
 
					CFArrayRef certChain;
 
					CSSM_TP_APPLE_EVIDENCE_INFO* statusChain;
 
					error = SecTrustGetResult(trustRef.get(), &trustResult, &certChain, &statusChain);
 
					if (error == errSecSuccess) {
 
						boost::shared_ptr<CFArray> certChainRef = boost::shared_ptr<CFArray>(certChain, CFRelease);
 
						for (CFIndex index = 0; index < CFArrayGetCount(certChainRef.get()); index++) {
 
							for (CFIndex n = 0; n < statusChain[index].NumStatusCodes; n++) {
 
								// Even though Secure Transport reported CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK on the whole certificate
 
								// chain, the actual cause can be that a revocation check for a specific cert returned CSSMERR_TP_CERT_REVOKED.
 
								if (!verificationError_ || verificationError_->getType() == CertificateVerificationError::RevocationCheckFailed) {
 
									verificationError_ = CSSMErrorToVerificationError(statusChain[index].StatusCodes[n]);
 
								}
 
							}
 
						}
 
					}
 
					else {
 

	
 
					}
 
				}
 
			}
 
			else {
 
				verificationError_ = boost::make_shared<CertificateVerificationError>(CertificateVerificationError::UnknownError);
 
			}
 
			break;
 
		case kSecTrustResultOtherError:
 
			verificationError_ = boost::make_shared<CertificateVerificationError>(CertificateVerificationError::UnknownError);
 
			break;
 
		default:
 
			SWIFT_LOG(warning) << "Unhandled trust result " << trustResult << "." << std::endl;
 
			break;
 
	}
 
	
 
	if (verificationError_) {
 
		setState(Error);
 
		SSLClose(sslContext_.get());
 
		sslContext_.reset();
 
		onError(boost::make_shared<TLSError>());
 
	}
 
	else {
 
		// proceed with handshake
 
		processHandshake();
 
	}
 
}
 

	
 
#pragma clang diagnostic pop
 

	
 
bool SecureTransportServerContext::setClientCertificate(CertificateWithKey::ref cert) {
 
	CFArrayRef nativeClientChain = CreateClientCertificateChainAsCFArrayRef(cert);
 
	if (nativeClientChain) {
 
		clientCertificate_ = cert;
 
		CFRelease(nativeClientChain);
 
		return true;
 
	}
 
	else {
 
		return false;
 
	}
 
}
 

	
 
void SecureTransportServerContext::handleDataFromNetwork(const SafeByteArray& data) {
 
	SWIFT_LOG(debug) << std::endl;
 
	SWIFT_LOG_ASSERT(state_ == HandshakeDone || state_ == Handshake, error) << "current state '" << stateToString(state_) << " invalid." << std::endl;
 

	
 
	append(readingBuffer_, data);
 

	
 
	size_t bytesRead = 0;
 
	OSStatus error = noErr;
 
	SafeByteArray applicationData;
 

	
 
	switch(state_) {
 
		case None:
 
			assert(false && "Invalid state 'None'.");
 
			break;
 
		case Handshake:
 
			processHandshake();
 
			break;
 
		case HandshakeDone:
 
			while (error == noErr) {
 
				applicationData.resize(readingBuffer_.size());
 
				error = SSLRead(sslContext_.get(), applicationData.data(), applicationData.size(), &bytesRead);
 
				if (error == noErr) {
 
					// Read successful.
 
				}
 
				else if (error == errSSLWouldBlock) {
 
					// Secure Transport does not want more data.
 
					break;
 
				}
 
				else {
 
					SWIFT_LOG(error) << "SSLRead failed with error " << error << ", read bytes: " << bytesRead << "." << std::endl;
 
					fatalError(boost::make_shared<TLSError>(), boost::make_shared<CertificateVerificationError>());
 
					return;
 
				}
 

	
 
				if (bytesRead > 0) {
 
					applicationData.resize(bytesRead);
 
					onDataForApplication(applicationData);
 
				}
 
				else {
 
					break;	
 
				}
 
			}
 
			break;
 
		case Error:
 
			SWIFT_LOG(debug) << "Igoring received data in error state." << std::endl;
 
			break;
 
	}
 
}
 

	
 

	
 
void SecureTransportServerContext::handleDataFromApplication(const SafeByteArray& data) {
 
	size_t processedBytes = 0;
 
	OSStatus error = SSLWrite(sslContext_.get(), data.data(), data.size(), &processedBytes);
 
	switch(error) {
 
		case errSSLWouldBlock:
 
			SWIFT_LOG(warning) << "Unexpected because the write callback does not block." << std::endl;
 
			return;
 
		case errSSLClosedGraceful:
 
		case noErr:
 
			return;
 
		default:
 
			SWIFT_LOG(warning) << "SSLWrite returned error code: " << error << ", processed bytes: " << processedBytes << std::endl;
 
			fatalError(boost::make_shared<TLSError>(), boost::shared_ptr<CertificateVerificationError>());
 
	}
 
}
 

	
 
std::vector<Certificate::ref> SecureTransportServerContext::getPeerCertificateChain() const {
 
	std::vector<Certificate::ref> peerCertificateChain;
 

	
 
	if (sslContext_) {
 
			typedef boost::remove_pointer<SecTrustRef>::type SecTrust;
 
			boost::shared_ptr<SecTrust> securityTrust;
 

	
 
			SecTrustRef secTrust = NULL;;
 
			OSStatus error = SSLCopyPeerTrust(sslContext_.get(), &secTrust);
 
			if (error == noErr) {
 
				securityTrust = boost::shared_ptr<SecTrust>(secTrust, CFRelease);
 

	
 
				CFIndex chainSize = SecTrustGetCertificateCount(securityTrust.get());
 
				for (CFIndex n = 0; n < chainSize; n++) {
 
					SecCertificateRef certificate = SecTrustGetCertificateAtIndex(securityTrust.get(), n);
 
					if (certificate) {
 
						peerCertificateChain.push_back(boost::make_shared<SecureTransportCertificate>(certificate));
 
					}
 
				}
 
			}
 
			else {
 
				SWIFT_LOG(warning) << "Failed to obtain peer trust structure; error = " << error << "." << std::endl;
 
			}
 
	}
 

	
 
	return peerCertificateChain;
 
}
 

	
 
CertificateVerificationError::ref SecureTransportServerContext::getPeerCertificateVerificationError() const {
 
	return verificationError_;
 
}
 

	
 
ByteArray SecureTransportServerContext::getFinishMessage() const {
 
	SWIFT_LOG(warning) << "Access to TLS handshake finish message is not part of OS X Secure Transport APIs." << std::endl;
 
	return ByteArray();
 
}
 

	
 
/**
 
 *	This I/O callback simulates an asynchronous read to the read buffer of the context. If it is empty, it returns errSSLWouldBlock; else
 
 *  the data within the buffer is returned.
 
 */
 
OSStatus SecureTransportServerContext::SSLSocketReadCallback(SSLConnectionRef connection, void *data, size_t *dataLength) {
 
	SecureTransportContext* context = const_cast<SecureTransportContext*>(static_cast<const SecureTransportContext*>(connection));
 
	OSStatus retValue = noErr;
 

	
 
	if (context->readingBuffer_.size() < *dataLength) {
 
		// Would block because Secure Transport is trying to read more data than there currently is available in the buffer.
 
		*dataLength = 0;
 
		retValue = errSSLWouldBlock;
 
	}
 
	else {
 
		size_t bufferLen = *dataLength;
 
		size_t copyToBuffer = bufferLen < context->readingBuffer_.size() ? bufferLen : context->readingBuffer_.size();
 

	
 
		memcpy(data, context->readingBuffer_.data(), copyToBuffer);
 
			
 
		context->readingBuffer_ = SafeByteArray(context->readingBuffer_.data() + copyToBuffer, context->readingBuffer_.data() + context->readingBuffer_.size());
 
		*dataLength = copyToBuffer;
 
	}
 
	return retValue;
 
}
 

	
 
OSStatus SecureTransportServerContext::SSLSocketWriteCallback(SSLConnectionRef connection, const void *data, size_t *dataLength) {
 
	SecureTransportContext* context = const_cast<SecureTransportContext*>(static_cast<const SecureTransportContext*>(connection));
 
	OSStatus retValue = noErr;
 
	
 
	SafeByteArray safeData;
 
	safeData.resize(*dataLength);
 
	memcpy(safeData.data(), data, safeData.size());
 
	
 
	context->onDataForNetwork(safeData);
 
	return retValue;
 
}
 

	
 
boost::shared_ptr<TLSError> SecureTransportServerContext::nativeToTLSError(OSStatus /* error */) {
 
	boost::shared_ptr<TLSError> swiftenError;
 
	swiftenError = boost::make_shared<TLSError>();
 
	return swiftenError;
 
}
 

	
 
boost::shared_ptr<CertificateVerificationError> SecureTransportServerContext::CSSMErrorToVerificationError(OSStatus resultCode) {
 
	boost::shared_ptr<CertificateVerificationError> error;
 
	switch(resultCode) {
 
		case CSSMERR_TP_NOT_TRUSTED:
 
			SWIFT_LOG(debug) << "CSSM result code: CSSMERR_TP_NOT_TRUSTED" << std::endl;
 
			error = boost::make_shared<CertificateVerificationError>(CertificateVerificationError::Untrusted);
 
			break;
 
		case CSSMERR_TP_CERT_NOT_VALID_YET:
 
			SWIFT_LOG(debug) << "CSSM result code: CSSMERR_TP_CERT_NOT_VALID_YET" << std::endl;
 
			error = boost::make_shared<CertificateVerificationError>(CertificateVerificationError::NotYetValid);
 
			break;
 
		case CSSMERR_TP_CERT_EXPIRED:
 
			SWIFT_LOG(debug) << "CSSM result code: CSSMERR_TP_CERT_EXPIRED" << std::endl;
 
			error = boost::make_shared<CertificateVerificationError>(CertificateVerificationError::Expired);
 
			break;
 
		case CSSMERR_TP_CERT_REVOKED:
 
			SWIFT_LOG(debug) << "CSSM result code: CSSMERR_TP_CERT_REVOKED" << std::endl;
 
			error = boost::make_shared<CertificateVerificationError>(CertificateVerificationError::Revoked);
 
			break;
 
		case CSSMERR_TP_VERIFY_ACTION_FAILED:
 
			SWIFT_LOG(debug) << "CSSM result code: CSSMERR_TP_VERIFY_ACTION_FAILED" << std::endl;
 
			break;
 
		case CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK:
 
			SWIFT_LOG(debug) << "CSSM result code: CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK" << std::endl;
 
			if (checkCertificateRevocation_) {
 
				error = boost::make_shared<CertificateVerificationError>(CertificateVerificationError::RevocationCheckFailed);
 
			}
 
			break;
 
		case CSSMERR_APPLETP_OCSP_UNAVAILABLE:
 
			SWIFT_LOG(debug) << "CSSM result code: CSSMERR_APPLETP_OCSP_UNAVAILABLE" << std::endl;
 
			if (checkCertificateRevocation_) {
 
				error = boost::make_shared<CertificateVerificationError>(CertificateVerificationError::RevocationCheckFailed);
 
			}
 
			break;
 
		case CSSMERR_APPLETP_SSL_BAD_EXT_KEY_USE:
 
			SWIFT_LOG(debug) << "CSSM result code: CSSMERR_APPLETP_SSL_BAD_EXT_KEY_USE" << std::endl;
 
			error = boost::make_shared<CertificateVerificationError>(CertificateVerificationError::InvalidPurpose);
 
			break;
 
		default:
 
			SWIFT_LOG(warning) << "unhandled CSSM error: " << resultCode << ", CSSM_TP_BASE_TP_ERROR: " << CSSM_TP_BASE_TP_ERROR << std::endl;
 
			error = boost::make_shared<CertificateVerificationError>(CertificateVerificationError::UnknownError);
 
			break;
 
	}
 
	return error;
 
}
 

	
 
void SecureTransportServerContext::fatalError(boost::shared_ptr<TLSError> error, boost::shared_ptr<CertificateVerificationError> certificateError) {
 
	setState(Error);
 
	if (sslContext_) {
 
		SSLClose(sslContext_.get());
 
	}
 
	verificationError_ = certificateError;
 
	onError(error);
 
}
 

	
 
}
spectrum/src/frontends/xmpp/XMPPFrontend.cpp
Show inline comments
 
@@ -28,24 +28,27 @@
 
#include "transport/StorageBackend.h"
 
#include "transport/Factory.h"
 
#include "transport/UserRegistry.h"
 
#include "transport/Logging.h"
 
#include "transport/Config.h"
 
#include "transport/Transport.h"
 
#include "discoitemsresponder.h"
 
#include "storageparser.h"
 
#ifdef _WIN32
 
#include <Swiften/TLS/CAPICertificate.h>
 
#include "Swiften/TLS/Schannel/SchannelServerContext.h"
 
#include "Swiften/TLS/Schannel/SchannelServerContextFactory.h"
 
#elif defined(__APPLE__) && HAVE_SWIFTEN_3
 
#include <Swiften/TLS/SecureTransport/SecureTransportCertificate.h>
 
#include <Swiften/TLS/SecureTransport/SecureTransportServerContext.h>
 
#else
 
#include "Swiften/TLS/PKCS12Certificate.h"
 
#include "Swiften/TLS/CertificateWithKey.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLServerContext.h"
 
#include "Swiften/TLS/OpenSSL/OpenSSLServerContextFactory.h"
 
#endif
 
#include "Swiften/Parser/PayloadParsers/AttentionParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/AttentionSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/XHTMLIMParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
 
#include "Swiften/Parser/PayloadParsers/StatsParser.h"
 
#include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h"
 
@@ -78,30 +81,32 @@ void XMPPFrontend::init(Component *transport, Swift::EventLoop *loop, Swift::Net
 
	m_server = NULL;
 
	m_rawXML = false;
 
	m_config = transport->getConfig();
 
	m_jid = Swift::JID(CONFIG_STRING(m_config, "service.jid"));
 

	
 
	m_config->onBackendConfigUpdated.connect(boost::bind(&XMPPFrontend::handleBackendConfigChanged, this));
 

	
 
	if (CONFIG_BOOL(m_config, "service.server_mode")) {
 
		LOG4CXX_INFO(logger, "Creating component in server mode on port " << CONFIG_INT(m_config, "service.port"));
 
		m_server = new Swift::Server(loop, factories, userRegistry, m_jid, CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
 
		if (!CONFIG_STRING(m_config, "service.cert").empty()) {
 
#ifndef _WIN32
 
#ifndef __APPLE__
 
//TODO: fix
 
			LOG4CXX_INFO(logger, "Using PKCS#12 certificate " << CONFIG_STRING(m_config, "service.cert"));
 
			LOG4CXX_INFO(logger, "SSLv23_server_method used.");
 
			TLSServerContextFactory *f = new OpenSSLServerContextFactory();
 
			CertificateWithKey::ref certificate = boost::make_shared<PKCS12Certificate>(CONFIG_STRING(m_config, "service.cert"), createSafeByteArray(CONFIG_STRING(m_config, "service.cert_password")));
 
			m_server->addTLSEncryption(f, certificate);
 
#endif
 
#endif
 
			
 
		}
 
		else {
 
			LOG4CXX_WARN(logger, "No PKCS#12 certificate used. TLS is disabled.");
 
		}
 
// 		m_server->start();
 
		m_stanzaChannel = m_server->getStanzaChannel();
 
		m_iqRouter = m_server->getIQRouter();
 

	
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
 
		m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
spectrum/src/frontends/xmpp/XMPPFrontend.h
Show inline comments
 
@@ -14,24 +14,26 @@
 
 * GNU General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
 
 */
 

	
 
#pragma once
 

	
 
#include "transport/Frontend.h"
 

	
 
#include <vector>
 
#include <Swiften/Version.h>
 
#define HAVE_SWIFTEN_3  (SWIFTEN_VERSION >= 0x030000)
 
#include "Swiften/Server/Server.h"
 
#include "Swiften/Disco/GetDiscoInfoRequest.h"
 
#include "Swiften/Disco/EntityCapsManager.h"
 
#include "Swiften/Disco/CapsManager.h"
 
#include "Swiften/Disco/CapsMemoryStorage.h"
 
#include "Swiften/Network/BoostTimerFactory.h"
 
#include "Swiften/Network/BoostIOServiceThread.h"
 
#include "Swiften/Server/UserRegistry.h"
 
#include "Swiften/Base/SafeByteArray.h"
 
#include "Swiften/Queries/IQHandler.h"
 
#include "Swiften/Component/ComponentError.h"
 
#include "Swiften/Component/Component.h"
src/CMakeLists.txt
Show inline comments
 
cmake_minimum_required(VERSION 2.6)
 
FILE(GLOB SRC *.cpp *.h)
 
FILE(GLOB_RECURSE SWIFTEN_SRC ../include/Swiften/*.cpp)
 

	
 
# Build without openssl on msvc
 
if (NOT MSVC)
 
	string(REGEX REPLACE "[^;]+;?/Schannel/[^;]+;?" "" SWIFTEN_SRC "${SWIFTEN_SRC}") 
 
if (APPLE)
 
	string(REGEX REPLACE "[^;]+;?/Schannel/[^;]+;?" "" SWIFTEN_SRC "${SWIFTEN_SRC}")
 
	string(REGEX REPLACE "[^;]+;?/OpenSSL/[^;]+;?" "" SWIFTEN_SRC "${SWIFTEN_SRC}")
 
else()
 
	string(REGEX REPLACE "[^;]+;?/Schannel/[^;]+;?" "" SWIFTEN_SRC "${SWIFTEN_SRC}")
 
	string(REGEX REPLACE "[^;]+;?/SecureTransport/[^;]+;?" "" SWIFTEN_SRC "${SWIFTEN_SRC}") 
 
endif()
 
else()
 
	string(REGEX REPLACE "[^;]+;?/OpenSSL/[^;]+;?" "" SWIFTEN_SRC "${SWIFTEN_SRC}") 
 
	string(REGEX REPLACE "[^;]+;?/SecureTransport/[^;]+;?" "" SWIFTEN_SRC "${SWIFTEN_SRC}")
 
endif()
 

	
 
FILE(GLOB HEADERS ../include/transport/*.h)
 
include_directories(../spectrum/src/frontends/xmpp/)
 

	
 
if (CPPUNIT_FOUND)
 
	FILE(GLOB SRC_TEST tests/*.cpp)
 
	FILE(GLOB SRC_TEST_FRONTEND ../spectrum/src/frontends/xmpp/*.cpp)
 

	
 
	ADD_EXECUTABLE(libtransport_test ${SRC_TEST} ${SRC_TEST_FRONTEND})
 
	set_target_properties(libtransport_test PROPERTIES COMPILE_DEFINITIONS LIBTRANSPORT_TEST=1)
 
	
0 comments (0 inline, 0 general)