summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/TLS')
-rw-r--r--Swiften/TLS/BlindCertificateTrustChecker.h2
-rw-r--r--Swiften/TLS/CAPICertificate.h3
-rw-r--r--Swiften/TLS/Certificate.cpp8
-rw-r--r--Swiften/TLS/Certificate.h9
-rw-r--r--Swiften/TLS/CertificateFactory.h2
-rw-r--r--Swiften/TLS/CertificateTrustChecker.h13
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp7
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h6
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.cpp47
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.h2
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp4
-rw-r--r--Swiften/TLS/PKCS12Certificate.h3
-rw-r--r--Swiften/TLS/PlatformTLSFactories.h4
-rw-r--r--Swiften/TLS/Schannel/SchannelCertificateFactory.h4
-rw-r--r--Swiften/TLS/Schannel/SchannelContext.cpp25
-rw-r--r--Swiften/TLS/Schannel/SchannelContext.h2
-rw-r--r--Swiften/TLS/ServerIdentityVerifier.cpp20
-rw-r--r--Swiften/TLS/ServerIdentityVerifier.h8
-rw-r--r--Swiften/TLS/TLSContext.cpp5
-rw-r--r--Swiften/TLS/TLSContext.h3
-rw-r--r--Swiften/TLS/UnitTest/CertificateTest.cpp6
-rw-r--r--Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp40
22 files changed, 155 insertions, 68 deletions
diff --git a/Swiften/TLS/BlindCertificateTrustChecker.h b/Swiften/TLS/BlindCertificateTrustChecker.h
index 3177322..d91ec25 100644
--- a/Swiften/TLS/BlindCertificateTrustChecker.h
+++ b/Swiften/TLS/BlindCertificateTrustChecker.h
@@ -20,5 +20,5 @@ namespace Swift {
class BlindCertificateTrustChecker : public CertificateTrustChecker {
public:
- virtual bool isCertificateTrusted(Certificate::ref) {
+ virtual bool isCertificateTrusted(const std::vector<Certificate::ref>&) {
return true;
}
diff --git a/Swiften/TLS/CAPICertificate.h b/Swiften/TLS/CAPICertificate.h
index 5f24b7e..aebfb41 100644
--- a/Swiften/TLS/CAPICertificate.h
+++ b/Swiften/TLS/CAPICertificate.h
@@ -7,4 +7,5 @@
#pragma once
+#include <Swiften/Base/API.h>
#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Base/SafeByteArray.h>
@@ -22,5 +23,5 @@ namespace Swift {
class TimerFactory;
- class CAPICertificate : public Swift::CertificateWithKey {
+ class SWIFTEN_API CAPICertificate : public Swift::CertificateWithKey {
public:
CAPICertificate(const std::string& capiUri, TimerFactory* timerFactory);
diff --git a/Swiften/TLS/Certificate.cpp b/Swiften/TLS/Certificate.cpp
index a796463..ec268c8 100644
--- a/Swiften/TLS/Certificate.cpp
+++ b/Swiften/TLS/Certificate.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -9,5 +9,5 @@
#include <sstream>
-#include <Swiften/StringCodecs/SHA1.h>
+#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/StringCodecs/Hexify.h>
@@ -20,6 +20,6 @@ Certificate::~Certificate() {
}
-std::string Certificate::getSHA1Fingerprint() const {
- ByteArray hash = SHA1::getHash(toDER());
+std::string Certificate::getSHA1Fingerprint(Certificate::ref certificate, CryptoProvider* crypto) {
+ ByteArray hash = crypto->getSHA1Hash(certificate->toDER());
std::ostringstream s;
for (size_t i = 0; i < hash.size(); ++i) {
diff --git a/Swiften/TLS/Certificate.h b/Swiften/TLS/Certificate.h
index ec59a39..f558c12 100644
--- a/Swiften/TLS/Certificate.h
+++ b/Swiften/TLS/Certificate.h
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -10,8 +10,11 @@
#include <string>
+#include <Swiften/Base/API.h>
#include <Swiften/Base/ByteArray.h>
namespace Swift {
- class Certificate {
+ class CryptoProvider;
+
+ class SWIFTEN_API Certificate {
public:
typedef boost::shared_ptr<Certificate> ref;
@@ -32,5 +35,5 @@ namespace Swift {
virtual ByteArray toDER() const = 0;
- virtual std::string getSHA1Fingerprint() const;
+ static std::string getSHA1Fingerprint(Certificate::ref, CryptoProvider* crypto);
protected:
diff --git a/Swiften/TLS/CertificateFactory.h b/Swiften/TLS/CertificateFactory.h
index 3e94082..e8971c3 100644
--- a/Swiften/TLS/CertificateFactory.h
+++ b/Swiften/TLS/CertificateFactory.h
@@ -14,5 +14,5 @@ namespace Swift {
virtual ~CertificateFactory();
- virtual Certificate::ref createCertificateFromDER(const ByteArray& der) = 0;
+ virtual Certificate* createCertificateFromDER(const ByteArray& der) = 0;
};
}
diff --git a/Swiften/TLS/CertificateTrustChecker.h b/Swiften/TLS/CertificateTrustChecker.h
index 06c0c32..4ec0b39 100644
--- a/Swiften/TLS/CertificateTrustChecker.h
+++ b/Swiften/TLS/CertificateTrustChecker.h
@@ -8,6 +8,8 @@
#include <boost/shared_ptr.hpp>
-
#include <string>
+#include <vector>
+
+#include <Swiften/Base/API.h>
#include <Swiften/TLS/Certificate.h>
@@ -16,14 +18,17 @@ namespace Swift {
* A class to implement a check for certificate trust.
*/
- class CertificateTrustChecker {
+ class SWIFTEN_API CertificateTrustChecker {
public:
virtual ~CertificateTrustChecker();
/**
- * This method is called to find out whether a certificate is
+ * This method is called to find out whether a certificate (chain) is
* trusted. This usually happens when a certificate's validation
* fails, to check whether to proceed with the connection or not.
+ *
+ * certificateChain contains the chain of certificates. The first certificate
+ * is the subject certificate.
*/
- virtual bool isCertificateTrusted(Certificate::ref certificate) = 0;
+ virtual bool isCertificateTrusted(const std::vector<Certificate::ref>& certificateChain) = 0;
};
}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp b/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp
index 76b8bb9..d654787 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -14,4 +14,7 @@
#pragma GCC diagnostic ignored "-Wold-style-cast"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma clang diagnostic ignored "-Wcast-align"
+#pragma clang diagnostic ignored "-Wsign-conversion"
namespace Swift {
@@ -56,5 +59,5 @@ void OpenSSLCertificate::parse() {
ByteArray subjectNameData;
subjectNameData.resize(256);
- X509_NAME_oneline(X509_get_subject_name(cert.get()), reinterpret_cast<char*>(vecptr(subjectNameData)), subjectNameData.size());
+ X509_NAME_oneline(X509_get_subject_name(cert.get()), reinterpret_cast<char*>(vecptr(subjectNameData)), static_cast<unsigned int>(subjectNameData.size()));
this->subjectName = byteArrayToString(subjectNameData);
diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h b/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h
index 52f134c..98376ae 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2014 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -13,6 +13,6 @@ namespace Swift {
class OpenSSLCertificateFactory : public CertificateFactory {
public:
- virtual Certificate::ref createCertificateFromDER(const ByteArray& der) {
- return Certificate::ref(new OpenSSLCertificate(der));
+ virtual Certificate* createCertificateFromDER(const ByteArray& der) {
+ return new OpenSSLCertificate(der);
}
};
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
index 8c03052..54fb7bd 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -16,5 +16,5 @@
#include <boost/smart_ptr/make_shared.hpp>
-#if defined(SWIFTEN_PLATFORM_MACOSX) && OPENSSL_VERSION_NUMBER < 0x00908000
+#if defined(SWIFTEN_PLATFORM_MACOSX)
#include <Security/Security.h>
#endif
@@ -26,4 +26,8 @@
#pragma GCC diagnostic ignored "-Wold-style-cast"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma clang diagnostic ignored "-Wshorten-64-to-32"
+#pragma clang diagnostic ignored "-Wcast-align"
+#pragma clang diagnostic ignored "-Wsign-conversion"
namespace Swift {
@@ -32,5 +36,5 @@ static const int MAX_FINISHED_SIZE = 4096;
static const int SSL_READ_BUFFERSIZE = 8192;
-void freeX509Stack(STACK_OF(X509)* stack) {
+static void freeX509Stack(STACK_OF(X509)* stack) {
sk_X509_free(stack);
}
@@ -38,6 +42,13 @@ void freeX509Stack(STACK_OF(X509)* stack) {
OpenSSLContext::OpenSSLContext() : state_(Start), context_(0), handle_(0), readBIO_(0), writeBIO_(0) {
ensureLibraryInitialized();
- context_ = SSL_CTX_new(TLSv1_client_method());
+ context_ = SSL_CTX_new(SSLv23_client_method());
+ SSL_CTX_set_options(context_, SSL_OP_NO_SSLv2);
+ // TODO: implement CRL checking
+ // TODO: download CRL (HTTP transport)
+ // TODO: cache CRL downloads for configurable time period
+
+ // TODO: implement OCSP support
+ // TODO: handle OCSP stapling see https://www.rfc-editor.org/rfc/rfc4366.txt
// Load system certs
#if defined(SWIFTEN_PLATFORM_WINDOWS)
@@ -59,7 +70,11 @@ OpenSSLContext::OpenSSLContext() : state_(Start), context_(0), handle_(0), readB
#elif !defined(SWIFTEN_PLATFORM_MACOSX)
SSL_CTX_load_verify_locations(context_, NULL, "/etc/ssl/certs");
-#elif defined(SWIFTEN_PLATFORM_MACOSX) && OPENSSL_VERSION_NUMBER < 0x00908000
+#elif defined(SWIFTEN_PLATFORM_MACOSX)
// On Mac OS X 10.5 (OpenSSL < 0.9.8), OpenSSL does not automatically look in the system store.
- // We therefore add all certs from the system store ourselves.
+ // On Mac OS X 10.6 (OpenSSL >= 0.9.8), OpenSSL *does* look in the system store to determine trust.
+ // However, if there is a certificate error, it will always emit the "Invalid CA" error if we didn't add
+ // the certificates first. See
+ // http://opensource.apple.com/source/OpenSSL098/OpenSSL098-27/src/crypto/x509/x509_vfy_apple.c
+ // to understand why. We therefore add all certs from the system store ourselves.
X509_STORE* store = SSL_CTX_get_cert_store(context_);
CFArrayRef anchorCertificates;
@@ -206,5 +221,7 @@ bool OpenSSLContext::setClientCertificate(CertificateWithKey::ref certificate) {
EVP_PKEY* privateKeyPtr = 0;
STACK_OF(X509)* caCertsPtr = 0;
- int result = PKCS12_parse(pkcs12.get(), reinterpret_cast<const char*>(vecptr(pkcs12Certificate->getPassword())), &privateKeyPtr, &certPtr, &caCertsPtr);
+ SafeByteArray password(pkcs12Certificate->getPassword());
+ password.push_back(0);
+ int result = PKCS12_parse(pkcs12.get(), reinterpret_cast<const char*>(vecptr(password)), &privateKeyPtr, &certPtr, &caCertsPtr);
if (result != 1) {
return false;
@@ -227,12 +244,14 @@ bool OpenSSLContext::setClientCertificate(CertificateWithKey::ref certificate) {
}
-Certificate::ref OpenSSLContext::getPeerCertificate() const {
- boost::shared_ptr<X509> x509Cert(SSL_get_peer_certificate(handle_), X509_free);
- if (x509Cert) {
- return boost::make_shared<OpenSSLCertificate>(x509Cert);
- }
- else {
- return Certificate::ref();
+std::vector<Certificate::ref> OpenSSLContext::getPeerCertificateChain() const {
+ std::vector<Certificate::ref> result;
+ STACK_OF(X509)* chain = SSL_get_peer_cert_chain(handle_);
+ for (int i = 0; i < sk_X509_num(chain); ++i) {
+ boost::shared_ptr<X509> x509Cert(X509_dup(sk_X509_value(chain, i)), X509_free);
+
+ Certificate::ref cert = boost::make_shared<OpenSSLCertificate>(x509Cert);
+ result.push_back(cert);
}
+ return result;
}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.h b/Swiften/TLS/OpenSSL/OpenSSLContext.h
index d8d0d2f..d4327ca 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.h
@@ -28,5 +28,5 @@ namespace Swift {
void handleDataFromApplication(const SafeByteArray&);
- Certificate::ref getPeerCertificate() const;
+ std::vector<Certificate::ref> getPeerCertificateChain() const;
boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const;
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp
index 6cd3c83..671cba7 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp
@@ -19,8 +19,10 @@ TLSContext* OpenSSLContextFactory::createTLSContext() {
}
-void OpenSSLContextFactory::setCheckCertificateRevocation(bool) {
+void OpenSSLContextFactory::setCheckCertificateRevocation(bool check) {
+ if (check) {
assert(false);
SWIFT_LOG(warning) << "CRL Checking not supported for OpenSSL" << std::endl;
}
+}
diff --git a/Swiften/TLS/PKCS12Certificate.h b/Swiften/TLS/PKCS12Certificate.h
index 2f70456..2d4c2e5 100644
--- a/Swiften/TLS/PKCS12Certificate.h
+++ b/Swiften/TLS/PKCS12Certificate.h
@@ -9,4 +9,5 @@
#include <Swiften/Base/SafeByteArray.h>
#include <Swiften/TLS/CertificateWithKey.h>
+#include <boost/filesystem/path.hpp>
namespace Swift {
@@ -15,5 +16,5 @@ namespace Swift {
PKCS12Certificate() {}
- PKCS12Certificate(const std::string& filename, const SafeByteArray& password) : password_(password) {
+ PKCS12Certificate(const boost::filesystem::path& filename, const SafeByteArray& password) : password_(password) {
readByteArrayFromFile(data_, filename);
}
diff --git a/Swiften/TLS/PlatformTLSFactories.h b/Swiften/TLS/PlatformTLSFactories.h
index 605db31..850d6f9 100644
--- a/Swiften/TLS/PlatformTLSFactories.h
+++ b/Swiften/TLS/PlatformTLSFactories.h
@@ -7,9 +7,11 @@
#pragma once
+#include <Swiften/Base/API.h>
+
namespace Swift {
class TLSContextFactory;
class CertificateFactory;
- class PlatformTLSFactories {
+ class SWIFTEN_API PlatformTLSFactories {
public:
PlatformTLSFactories();
diff --git a/Swiften/TLS/Schannel/SchannelCertificateFactory.h b/Swiften/TLS/Schannel/SchannelCertificateFactory.h
index d09bb54..5a2b208 100644
--- a/Swiften/TLS/Schannel/SchannelCertificateFactory.h
+++ b/Swiften/TLS/Schannel/SchannelCertificateFactory.h
@@ -13,6 +13,6 @@ namespace Swift {
class SchannelCertificateFactory : public CertificateFactory {
public:
- virtual Certificate::ref createCertificateFromDER(const ByteArray& der) {
- return Certificate::ref(new SchannelCertificate(der));
+ virtual Certificate* createCertificateFromDER(const ByteArray& der) {
+ return new SchannelCertificate(der);
}
};
diff --git a/Swiften/TLS/Schannel/SchannelContext.cpp b/Swiften/TLS/Schannel/SchannelContext.cpp
index 641568d..b4b2843 100644
--- a/Swiften/TLS/Schannel/SchannelContext.cpp
+++ b/Swiften/TLS/Schannel/SchannelContext.cpp
@@ -626,8 +626,29 @@ void SchannelContext::handleCertificateCardRemoved() {
//------------------------------------------------------------------------
-Certificate::ref SchannelContext::getPeerCertificate() const {
+std::vector<Certificate::ref> SchannelContext::getPeerCertificateChain() const {
+ std::vector<Certificate::ref> certificateChain;
ScopedCertContext pServerCert;
+ ScopedCertContext pIssuerCert;
+ ScopedCertContext pCurrentCert;
SECURITY_STATUS status = QueryContextAttributes(m_ctxtHandle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, pServerCert.Reset());
- return status == SEC_E_OK ? boost::make_shared<SchannelCertificate>(pServerCert) : SchannelCertificate::ref();
+
+ if (status != SEC_E_OK) {
+ return certificateChain;
+ }
+ certificateChain.push_back(boost::make_shared<SchannelCertificate>(pServerCert));
+
+ pCurrentCert = pServerCert;
+ while(pCurrentCert.GetPointer()) {
+ DWORD dwVerificationFlags = 0;
+ pIssuerCert = CertGetIssuerCertificateFromStore(pServerCert->hCertStore, pCurrentCert, NULL, &dwVerificationFlags );
+ if (!(*pIssuerCert.GetPointer())) {
+ break;
+ }
+ certificateChain.push_back(boost::make_shared<SchannelCertificate>(pIssuerCert));
+
+ pCurrentCert = pIssuerCert;
+ pIssuerCert = NULL;
+ }
+ return certificateChain;
}
diff --git a/Swiften/TLS/Schannel/SchannelContext.h b/Swiften/TLS/Schannel/SchannelContext.h
index 587d0e7..8603498 100644
--- a/Swiften/TLS/Schannel/SchannelContext.h
+++ b/Swiften/TLS/Schannel/SchannelContext.h
@@ -51,5 +51,5 @@ namespace Swift
virtual void handleDataFromApplication(const SafeByteArray& data);
- virtual Certificate::ref getPeerCertificate() const;
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const;
virtual CertificateVerificationError::ref getPeerCertificateVerificationError() const;
diff --git a/Swiften/TLS/ServerIdentityVerifier.cpp b/Swiften/TLS/ServerIdentityVerifier.cpp
index a908ad0..0608a03 100644
--- a/Swiften/TLS/ServerIdentityVerifier.cpp
+++ b/Swiften/TLS/ServerIdentityVerifier.cpp
@@ -10,11 +10,15 @@
#include <Swiften/Base/foreach.h>
-#include <Swiften/IDN/IDNA.h>
+#include <Swiften/IDN/IDNConverter.h>
namespace Swift {
-ServerIdentityVerifier::ServerIdentityVerifier(const JID& jid) {
+ServerIdentityVerifier::ServerIdentityVerifier(const JID& jid, IDNConverter* idnConverter) : domainValid(false) {
domain = jid.getDomain();
- encodedDomain = IDNA::getEncoded(domain);
+ boost::optional<std::string> domainResult = idnConverter->getIDNAEncoded(domain);
+ if (!!domainResult) {
+ encodedDomain = *domainResult;
+ domainValid = true;
+ }
}
@@ -22,4 +26,7 @@ bool ServerIdentityVerifier::certificateVerifies(Certificate::ref certificate) {
bool hasSAN = false;
+ if (certificate == NULL) {
+ return false;
+ }
// DNS names
std::vector<std::string> dnsNames = certificate->getDNSNames();
@@ -65,9 +72,12 @@ bool ServerIdentityVerifier::certificateVerifies(Certificate::ref certificate) {
bool ServerIdentityVerifier::matchesDomain(const std::string& s) const {
+ if (!domainValid) {
+ return false;
+ }
if (boost::starts_with(s, "*.")) {
std::string matchString(s.substr(2, s.npos));
std::string matchDomain = encodedDomain;
- int dotIndex = matchDomain.find('.');
- if (dotIndex >= 0) {
+ size_t dotIndex = matchDomain.find('.');
+ if (dotIndex != matchDomain.npos) {
matchDomain = matchDomain.substr(dotIndex + 1, matchDomain.npos);
}
diff --git a/Swiften/TLS/ServerIdentityVerifier.h b/Swiften/TLS/ServerIdentityVerifier.h
index b09abd9..ea08749 100644
--- a/Swiften/TLS/ServerIdentityVerifier.h
+++ b/Swiften/TLS/ServerIdentityVerifier.h
@@ -10,11 +10,14 @@
#include <string>
+#include <Swiften/Base/API.h>
#include <Swiften/JID/JID.h>
#include <Swiften/TLS/Certificate.h>
namespace Swift {
- class ServerIdentityVerifier {
+ class IDNConverter;
+
+ class SWIFTEN_API ServerIdentityVerifier {
public:
- ServerIdentityVerifier(const JID& jid);
+ ServerIdentityVerifier(const JID& jid, IDNConverter* idnConverter);
bool certificateVerifies(Certificate::ref);
@@ -27,4 +30,5 @@ namespace Swift {
std::string domain;
std::string encodedDomain;
+ bool domainValid;
};
}
diff --git a/Swiften/TLS/TLSContext.cpp b/Swiften/TLS/TLSContext.cpp
index 026ae70..d461d91 100644
--- a/Swiften/TLS/TLSContext.cpp
+++ b/Swiften/TLS/TLSContext.cpp
@@ -12,3 +12,8 @@ TLSContext::~TLSContext() {
}
+Certificate::ref TLSContext::getPeerCertificate() const {
+ std::vector<Certificate::ref> chain = getPeerCertificateChain();
+ return chain.empty() ? Certificate::ref() : chain[0];
+}
+
}
diff --git a/Swiften/TLS/TLSContext.h b/Swiften/TLS/TLSContext.h
index 5640fe1..5fee021 100644
--- a/Swiften/TLS/TLSContext.h
+++ b/Swiften/TLS/TLSContext.h
@@ -29,5 +29,6 @@ namespace Swift {
virtual void handleDataFromApplication(const SafeByteArray&) = 0;
- virtual Certificate::ref getPeerCertificate() const = 0;
+ Certificate::ref getPeerCertificate() const;
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const = 0;
virtual CertificateVerificationError::ref getPeerCertificateVerificationError() const = 0;
diff --git a/Swiften/TLS/UnitTest/CertificateTest.cpp b/Swiften/TLS/UnitTest/CertificateTest.cpp
index 5df5639..3352118 100644
--- a/Swiften/TLS/UnitTest/CertificateTest.cpp
+++ b/Swiften/TLS/UnitTest/CertificateTest.cpp
@@ -1,4 +1,4 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
@@ -13,4 +13,6 @@
#include <Swiften/TLS/Certificate.h>
#include <Swiften/TLS/SimpleCertificate.h>
+#include <Swiften/Crypto/CryptoProvider.h>
+#include <Swiften/Crypto/PlatformCryptoProvider.h>
using namespace Swift;
@@ -26,5 +28,5 @@ class CertificateTest : public CppUnit::TestFixture {
testling->setDER(createByteArray("abcdefg"));
- CPPUNIT_ASSERT_EQUAL(std::string("2f:b5:e1:34:19:fc:89:24:68:65:e7:a3:24:f4:76:ec:62:4e:87:40"), testling->getSHA1Fingerprint());
+ CPPUNIT_ASSERT_EQUAL(std::string("2f:b5:e1:34:19:fc:89:24:68:65:e7:a3:24:f4:76:ec:62:4e:87:40"), Certificate::getSHA1Fingerprint(testling, boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()).get()));
}
};
diff --git a/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp b/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp
index bd68c84..e974eb7 100644
--- a/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp
+++ b/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp
@@ -13,4 +13,6 @@
#include <Swiften/TLS/ServerIdentityVerifier.h>
#include <Swiften/TLS/SimpleCertificate.h>
+#include <Swiften/IDN/IDNConverter.h>
+#include <Swiften/IDN/PlatformIDNConverter.h>
using namespace Swift;
@@ -37,6 +39,10 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
public:
+ void setUp() {
+ idnConverter = boost::shared_ptr<IDNConverter>(PlatformIDNConverter::create());
+ }
+
void testCertificateVerifies_WithoutMatchingDNSName() {
- ServerIdentityVerifier testling(JID("foo@bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addDNSName("foo.com");
@@ -46,5 +52,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingDNSName() {
- ServerIdentityVerifier testling(JID("foo@bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addDNSName("bar.com");
@@ -54,5 +60,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithSecondMatchingDNSName() {
- ServerIdentityVerifier testling(JID("foo@bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addDNSName("foo.com");
@@ -63,5 +69,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingInternationalDNSName() {
- ServerIdentityVerifier testling(JID("foo@tron\xc3\xa7on.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@tron\xc3\xa7on.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addDNSName("xn--tronon-zua.com");
@@ -71,5 +77,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingDNSNameWithWildcard() {
- ServerIdentityVerifier testling(JID("foo@im.bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@im.bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addDNSName("*.bar.com");
@@ -79,5 +85,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingDNSNameWithWildcardMatchingNoComponents() {
- ServerIdentityVerifier testling(JID("foo@bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addDNSName("*.bar.com");
@@ -87,5 +93,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithDNSNameWithWildcardMatchingTwoComponents() {
- ServerIdentityVerifier testling(JID("foo@xmpp.im.bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@xmpp.im.bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addDNSName("*.bar.com");
@@ -95,5 +101,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingSRVNameWithoutService() {
- ServerIdentityVerifier testling(JID("foo@bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addSRVName("bar.com");
@@ -103,5 +109,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingSRVNameWithService() {
- ServerIdentityVerifier testling(JID("foo@bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addSRVName("_xmpp-client.bar.com");
@@ -111,5 +117,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingSRVNameWithServiceAndWildcard() {
- ServerIdentityVerifier testling(JID("foo@im.bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@im.bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addSRVName("_xmpp-client.*.bar.com");
@@ -119,5 +125,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingSRVNameWithDifferentService() {
- ServerIdentityVerifier testling(JID("foo@bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addSRVName("_xmpp-server.bar.com");
@@ -127,5 +133,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingXmppAddr() {
- ServerIdentityVerifier testling(JID("foo@bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addXMPPAddress("bar.com");
@@ -135,5 +141,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingXmppAddrWithWildcard() {
- ServerIdentityVerifier testling(JID("foo@im.bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@im.bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addXMPPAddress("*.bar.com");
@@ -143,5 +149,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingInternationalXmppAddr() {
- ServerIdentityVerifier testling(JID("foo@tron\xc3\xa7.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@tron\xc3\xa7.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addXMPPAddress("tron\xc3\xa7.com");
@@ -151,5 +157,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingCNWithoutSAN() {
- ServerIdentityVerifier testling(JID("foo@bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addCommonName("bar.com");
@@ -159,5 +165,5 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
void testCertificateVerifies_WithMatchingCNWithSAN() {
- ServerIdentityVerifier testling(JID("foo@bar.com/baz"));
+ ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get());
SimpleCertificate::ref certificate(new SimpleCertificate());
certificate->addSRVName("foo.com");
@@ -166,4 +172,6 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT(!testling.certificateVerifies(certificate));
}
+
+ boost::shared_ptr<IDNConverter> idnConverter;
};