diff options
-rw-r--r-- | Swiften/QA/TLSTest/CertificateErrorTest.cpp | 5 | ||||
-rw-r--r-- | Swiften/QA/TLSTest/SConscript | 9 | ||||
-rw-r--r-- | Swiften/TLS/Schannel/SchannelContext.cpp | 13 |
3 files changed, 22 insertions, 5 deletions
diff --git a/Swiften/QA/TLSTest/CertificateErrorTest.cpp b/Swiften/QA/TLSTest/CertificateErrorTest.cpp index 3b33e8e..1d87994 100644 --- a/Swiften/QA/TLSTest/CertificateErrorTest.cpp +++ b/Swiften/QA/TLSTest/CertificateErrorTest.cpp @@ -97,61 +97,66 @@ class CertificateErrorTest : public CppUnit::TestFixture { void connectToServer(boost::shared_ptr<TLSConnection> connection, const std::string& hostname, int port) { connection->onConnectFinished.connect(boost::bind(&CertificateErrorTest::handleConnectFinished, this, _1)); HostAddress address = resolveName(hostname); connection->connect(HostAddressPort(address, port)); while (!connectFinished_) { eventLoop_->processEvents(); } } void testTLS_O_MaticTrusted() { boost::shared_ptr<TLSConnection> connection = boost::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); TLSContext* context = connection->getTLSContext(); connectToServer(connection, "test1.tls-o-matic.com", 443); CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError_); CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::ref(), context->getPeerCertificateVerificationError()); } void testTLS_O_MaticCertificateFromTheFuture() { boost::shared_ptr<TLSConnection> connection = boost::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); TLSContext* context = connection->getTLSContext(); connectToServer(connection, "test5.tls-o-matic.com", 405); CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError_); CPPUNIT_ASSERT(context->getPeerCertificateVerificationError()); +#if defined(HAVE_SCHANNEL) + // Windows SChannel API does not differentiate between expired and not yet valid. + CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::Expired, context->getPeerCertificateVerificationError()->getType()); +#else CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::NotYetValid, context->getPeerCertificateVerificationError()->getType()); +#endif } void testTLS_O_MaticCertificateFromThePast() { boost::shared_ptr<TLSConnection> connection = boost::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); TLSContext* context = connection->getTLSContext(); connectToServer(connection, "test6.tls-o-matic.com", 406); CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError_); CPPUNIT_ASSERT(context->getPeerCertificateVerificationError()); CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::Expired, context->getPeerCertificateVerificationError()->getType()); } void testTLS_O_MaticCertificateFromUnknownCA() { boost::shared_ptr<TLSConnection> connection = boost::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); TLSContext* context = connection->getTLSContext(); connectToServer(connection, "test7.tls-o-matic.com", 407); CPPUNIT_ASSERT_EQUAL(false, connectFinishedWithError_); CPPUNIT_ASSERT(context->getPeerCertificateVerificationError()); CPPUNIT_ASSERT_EQUAL(CertificateVerificationError::Untrusted, context->getPeerCertificateVerificationError()->getType()); } // test14.tls-o-matic.com:414 void testTLS_O_MaticCertificateWrongPurpose() { boost::shared_ptr<TLSConnection> connection = boost::dynamic_pointer_cast<TLSConnection>(tlsConnectionFactory_->createConnection()); TLSContext* context = connection->getTLSContext(); connectToServer(connection, "test14.tls-o-matic.com", 414); diff --git a/Swiften/QA/TLSTest/SConscript b/Swiften/QA/TLSTest/SConscript index c597ab1..0ac50e6 100644 --- a/Swiften/QA/TLSTest/SConscript +++ b/Swiften/QA/TLSTest/SConscript @@ -1,17 +1,24 @@ import os Import("env") if env["TEST"] : myenv = env.Clone() myenv.MergeFlags(myenv["CHECKER_FLAGS"]) myenv.MergeFlags(myenv["SWIFTOOLS_FLAGS"]) myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) myenv.MergeFlags(myenv["SWIFTEN_DEP_FLAGS"]) myenv.MergeFlags(myenv["CPPUNIT_FLAGS"]) + if myenv.get("HAVE_OPENSSL", 0) : + myenv.Append(CPPDEFINES = "HAVE_OPENSSL") + elif myenv.get("HAVE_SCHANNEL", 0) : + myenv.Append(CPPDEFINES = "HAVE_SCHANNEL") + elif myenv.get("HAVE_SECURETRANSPORT", 0) : + myenv.Append(CPPDEFINES = "HAVE_SECURETRANSPORT") + tester = myenv.Program("TLSTest", [ "CertificateTest.cpp", "CertificateErrorTest.cpp" ]) - myenv.Test(tester, "system") + myenv.Test(tester, "system")
\ No newline at end of file diff --git a/Swiften/TLS/Schannel/SchannelContext.cpp b/Swiften/TLS/Schannel/SchannelContext.cpp index 70ff7dd..62aa137 100644 --- a/Swiften/TLS/Schannel/SchannelContext.cpp +++ b/Swiften/TLS/Schannel/SchannelContext.cpp @@ -1,49 +1,51 @@ /* * Copyright (c) 2011 Soren Dreijer * Licensed under the simplified BSD license. * See Documentation/Licenses/BSD-simplified.txt for more information. */ /* - * Copyright (c) 2012-2015 Isode Limited. + * Copyright (c) 2012-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ +#include <Swiften/TLS/Schannel/SchannelContext.h> + #include <boost/bind.hpp> -#include <Swiften/TLS/Schannel/SchannelContext.h> -#include <Swiften/TLS/Schannel/SchannelCertificate.h> -#include <Swiften/TLS/CAPICertificate.h> #include <WinHTTP.h> /* For SECURITY_FLAG_IGNORE_CERT_CN_INVALID */ +#include <Swiften/TLS/CAPICertificate.h> +#include <Swiften/TLS/Schannel/SchannelCertificate.h> + namespace Swift { //------------------------------------------------------------------------ SchannelContext::SchannelContext(bool tls1_0Workaround) : state_(Start), secContext_(0), myCertStore_(NULL), certStoreName_("MY"), certName_(), smartCardReader_(), checkCertificateRevocation_(true), tls1_0Workaround_(tls1_0Workaround), disconnectOnCardRemoval_(true) { contextFlags_ = ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_EXTENDED_ERROR | ISC_REQ_INTEGRITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_USE_SUPPLIED_CREDS | ISC_REQ_STREAM; ZeroMemory(&streamSizes_, sizeof(streamSizes_)); } //------------------------------------------------------------------------ SchannelContext::~SchannelContext() { if (myCertStore_) CertCloseStore(myCertStore_, 0); } //------------------------------------------------------------------------ void SchannelContext::determineStreamSizes() { QueryContextAttributes(contextHandle_, SECPKG_ATTR_STREAM_SIZES, &streamSizes_); } //------------------------------------------------------------------------ @@ -365,60 +367,63 @@ void SchannelContext::continueHandshake(const SafeByteArray& data) { //------------------------------------------------------------------------ void SchannelContext::handleCertError(SECURITY_STATUS status) { if (status == SEC_E_UNTRUSTED_ROOT || status == CERT_E_UNTRUSTEDROOT || status == CRYPT_E_ISSUER_SERIALNUMBER || status == CRYPT_E_SIGNER_NOT_FOUND || status == CRYPT_E_NO_TRUSTED_SIGNER) { verificationError_ = CertificateVerificationError::Untrusted; } else if (status == SEC_E_CERT_EXPIRED || status == CERT_E_EXPIRED) { verificationError_ = CertificateVerificationError::Expired; } else if (status == CRYPT_E_SELF_SIGNED) { verificationError_ = CertificateVerificationError::SelfSigned; } else if (status == CRYPT_E_HASH_VALUE || status == TRUST_E_CERT_SIGNATURE) { verificationError_ = CertificateVerificationError::InvalidSignature; } else if (status == CRYPT_E_REVOKED) { verificationError_ = CertificateVerificationError::Revoked; } else if (status == CRYPT_E_NO_REVOCATION_CHECK || status == CRYPT_E_REVOCATION_OFFLINE) { verificationError_ = CertificateVerificationError::RevocationCheckFailed; } + else if (status == CERT_E_WRONG_USAGE) { + verificationError_ = CertificateVerificationError::InvalidPurpose; + } else { verificationError_ = CertificateVerificationError::UnknownError; } } //------------------------------------------------------------------------ void SchannelContext::sendDataOnNetwork(const void* pData, size_t dataSize) { if (dataSize > 0 && pData) { SafeByteArray byteArray(dataSize); memcpy(&byteArray[0], pData, dataSize); onDataForNetwork(byteArray); } } //------------------------------------------------------------------------ void SchannelContext::forwardDataToApplication(const void* pData, size_t dataSize) { SafeByteArray byteArray(dataSize); memcpy(&byteArray[0], pData, dataSize); onDataForApplication(byteArray); } //------------------------------------------------------------------------ void SchannelContext::handleDataFromApplication(const SafeByteArray& data) { // Don't attempt to send data until we're fully connected if (state_ == Connecting) { |