summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2012-05-04 21:39:30 (GMT)
committerRemko Tronçon <git@el-tramo.be>2012-05-11 19:29:38 (GMT)
commit0f91f88ac69644fb7e7bdbf601b7e098194490fa (patch)
treee66ca4acbf869c82bba607ca9c394a47615c6e6e /Swiften
parent15ed4a079a8bbe3cc9ee2ca47233be7b890464ec (diff)
downloadswift-contrib-0f91f88ac69644fb7e7bdbf601b7e098194490fa.zip
swift-contrib-0f91f88ac69644fb7e7bdbf601b7e098194490fa.tar.bz2
Showing stream encryption status in the roster header. Provide native certificate viewers on click.
Native viewers for Windows and Mac OS X are implemented. Added TODOs to OpenSSL based TLS interface related to CRL and OCSP. Resolves: #167 License: This patch is BSD-licensed, see http://www.opensource.org/licenses/bsd-license.php
Diffstat (limited to 'Swiften')
-rw-r--r--Swiften/Client/ClientSession.h4
-rw-r--r--Swiften/Client/ClientSessionStanzaChannel.cpp7
-rw-r--r--Swiften/Client/ClientSessionStanzaChannel.h1
-rw-r--r--Swiften/Client/CoreClient.cpp4
-rw-r--r--Swiften/Client/CoreClient.h5
-rw-r--r--Swiften/Client/DummyStanzaChannel.h4
-rw-r--r--Swiften/Client/StanzaChannel.h2
-rw-r--r--Swiften/Client/UnitTest/ClientSessionTest.cpp4
-rw-r--r--Swiften/Component/ComponentSessionStanzaChannel.h5
-rw-r--r--Swiften/Component/UnitTest/ComponentSessionTest.cpp4
-rw-r--r--Swiften/Session/BOSHSessionStream.cpp4
-rw-r--r--Swiften/Session/BOSHSessionStream.h1
-rw-r--r--Swiften/Session/BasicSessionStream.cpp4
-rw-r--r--Swiften/Session/BasicSessionStream.h2
-rw-r--r--Swiften/Session/SessionStream.h1
-rw-r--r--Swiften/StreamStack/TLSLayer.cpp4
-rw-r--r--Swiften/StreamStack/TLSLayer.h1
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.cpp18
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.h1
-rw-r--r--Swiften/TLS/Schannel/SchannelContext.cpp29
-rw-r--r--Swiften/TLS/Schannel/SchannelContext.h1
-rw-r--r--Swiften/TLS/TLSContext.h1
22 files changed, 107 insertions, 0 deletions
diff --git a/Swiften/Client/ClientSession.h b/Swiften/Client/ClientSession.h
index 2205c8d..b67b23d 100644
--- a/Swiften/Client/ClientSession.h
+++ b/Swiften/Client/ClientSession.h
@@ -98,6 +98,10 @@ namespace Swift {
return rosterVersioningSupported;
}
+ std::vector<Certificate::ref> getPeerCertificateChain() const {
+ return stream->getPeerCertificateChain();
+ }
+
const JID& getLocalJID() const {
return localJID;
}
diff --git a/Swiften/Client/ClientSessionStanzaChannel.cpp b/Swiften/Client/ClientSessionStanzaChannel.cpp
index 5dc0a42..8d85953 100644
--- a/Swiften/Client/ClientSessionStanzaChannel.cpp
+++ b/Swiften/Client/ClientSessionStanzaChannel.cpp
@@ -82,6 +82,13 @@ bool ClientSessionStanzaChannel::getStreamManagementEnabled() const {
return false;
}
+std::vector<Certificate::ref> ClientSessionStanzaChannel::getPeerCertificateChain() const {
+ if (session) {
+ return session->getPeerCertificateChain();
+ }
+ return std::vector<Certificate::ref>();
+}
+
void ClientSessionStanzaChannel::handleStanzaAcked(boost::shared_ptr<Stanza> stanza) {
onStanzaAcked(stanza);
}
diff --git a/Swiften/Client/ClientSessionStanzaChannel.h b/Swiften/Client/ClientSessionStanzaChannel.h
index 47fb50e..2743a16 100644
--- a/Swiften/Client/ClientSessionStanzaChannel.h
+++ b/Swiften/Client/ClientSessionStanzaChannel.h
@@ -27,6 +27,7 @@ namespace Swift {
void sendMessage(boost::shared_ptr<Message> message);
void sendPresence(boost::shared_ptr<Presence> presence);
bool getStreamManagementEnabled() const;
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const;
bool isAvailable() const {
return session && session->getState() == ClientSession::Initialized;
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index 8a922ba..36e27eb 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -360,6 +360,10 @@ bool CoreClient::getStreamManagementEnabled() const {
return stanzaChannel_->getStreamManagementEnabled();
}
+bool CoreClient::isStreamEncrypted() const {
+ return sessionStream_->isTLSEncrypted();
+}
+
StanzaChannel* CoreClient::getStanzaChannel() const {
return stanzaChannel_;
}
diff --git a/Swiften/Client/CoreClient.h b/Swiften/Client/CoreClient.h
index cafc634..985bf7f 100644
--- a/Swiften/Client/CoreClient.h
+++ b/Swiften/Client/CoreClient.h
@@ -127,6 +127,11 @@ namespace Swift {
*/
bool getStreamManagementEnabled() const;
+ /**
+ * Checks whether stream encryption (TLS) is currently active.
+ */
+ bool isStreamEncrypted() const;
+
StanzaChannel* getStanzaChannel() const;
/**
diff --git a/Swiften/Client/DummyStanzaChannel.h b/Swiften/Client/DummyStanzaChannel.h
index c2f3919..5cdedba 100644
--- a/Swiften/Client/DummyStanzaChannel.h
+++ b/Swiften/Client/DummyStanzaChannel.h
@@ -79,6 +79,10 @@ namespace Swift {
return boost::dynamic_pointer_cast<T>(sentStanzas[index]);
}
+ std::vector<Certificate::ref> getPeerCertificateChain() const {
+ return std::vector<Certificate::ref>();
+ }
+
std::vector<boost::shared_ptr<Stanza> > sentStanzas;
bool available_;
};
diff --git a/Swiften/Client/StanzaChannel.h b/Swiften/Client/StanzaChannel.h
index f1d76e0..5e85d3c 100644
--- a/Swiften/Client/StanzaChannel.h
+++ b/Swiften/Client/StanzaChannel.h
@@ -12,6 +12,7 @@
#include <Swiften/Queries/IQChannel.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/Presence.h>
+#include <Swiften/TLS/Certificate.h>
namespace Swift {
class StanzaChannel : public IQChannel {
@@ -20,6 +21,7 @@ namespace Swift {
virtual void sendPresence(boost::shared_ptr<Presence>) = 0;
virtual bool isAvailable() const = 0;
virtual bool getStreamManagementEnabled() const = 0;
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const = 0;
boost::signal<void (bool /* isAvailable */)> onAvailableChanged;
boost::signal<void (boost::shared_ptr<Message>)> onMessageReceived;
diff --git a/Swiften/Client/UnitTest/ClientSessionTest.cpp b/Swiften/Client/UnitTest/ClientSessionTest.cpp
index 6793643..d1ca70a 100644
--- a/Swiften/Client/UnitTest/ClientSessionTest.cpp
+++ b/Swiften/Client/UnitTest/ClientSessionTest.cpp
@@ -399,6 +399,10 @@ class ClientSessionTest : public CppUnit::TestFixture {
return Certificate::ref(new SimpleCertificate());
}
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const {
+ return std::vector<Certificate::ref>();
+ }
+
virtual boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const {
return boost::shared_ptr<CertificateVerificationError>();
}
diff --git a/Swiften/Component/ComponentSessionStanzaChannel.h b/Swiften/Component/ComponentSessionStanzaChannel.h
index 45f90b5..4e133b8 100644
--- a/Swiften/Component/ComponentSessionStanzaChannel.h
+++ b/Swiften/Component/ComponentSessionStanzaChannel.h
@@ -31,6 +31,11 @@ namespace Swift {
return false;
}
+ std::vector<Certificate::ref> getPeerCertificateChain() const {
+ // TODO: actually implement this method
+ return std::vector<Certificate::ref>();
+ }
+
bool isAvailable() const {
return session && session->getState() == ComponentSession::Initialized;
}
diff --git a/Swiften/Component/UnitTest/ComponentSessionTest.cpp b/Swiften/Component/UnitTest/ComponentSessionTest.cpp
index da9ca7d..238d0b0 100644
--- a/Swiften/Component/UnitTest/ComponentSessionTest.cpp
+++ b/Swiften/Component/UnitTest/ComponentSessionTest.cpp
@@ -138,6 +138,10 @@ class ComponentSessionTest : public CppUnit::TestFixture {
return Certificate::ref();
}
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const {
+ return std::vector<Certificate::ref>();
+ }
+
virtual boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const {
return boost::shared_ptr<CertificateVerificationError>();
}
diff --git a/Swiften/Session/BOSHSessionStream.cpp b/Swiften/Session/BOSHSessionStream.cpp
index 237a394..6f15b84 100644
--- a/Swiften/Session/BOSHSessionStream.cpp
+++ b/Swiften/Session/BOSHSessionStream.cpp
@@ -129,6 +129,10 @@ Certificate::ref BOSHSessionStream::getPeerCertificate() const {
return Certificate::ref();
}
+std::vector<Certificate::ref> BOSHSessionStream::getPeerCertificateChain() const {
+ return std::vector<Certificate::ref>();
+}
+
boost::shared_ptr<CertificateVerificationError> BOSHSessionStream::getPeerCertificateVerificationError() const {
return boost::shared_ptr<CertificateVerificationError>();
}
diff --git a/Swiften/Session/BOSHSessionStream.h b/Swiften/Session/BOSHSessionStream.h
index 497d391..99851b5 100644
--- a/Swiften/Session/BOSHSessionStream.h
+++ b/Swiften/Session/BOSHSessionStream.h
@@ -61,6 +61,7 @@ namespace Swift {
virtual void addTLSEncryption();
virtual bool isTLSEncrypted();
virtual Certificate::ref getPeerCertificate() const;
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const;
virtual boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const;
virtual ByteArray getTLSFinishMessage() const;
diff --git a/Swiften/Session/BasicSessionStream.cpp b/Swiften/Session/BasicSessionStream.cpp
index b49ffc9..cbe85ab 100644
--- a/Swiften/Session/BasicSessionStream.cpp
+++ b/Swiften/Session/BasicSessionStream.cpp
@@ -129,6 +129,10 @@ Certificate::ref BasicSessionStream::getPeerCertificate() const {
return tlsLayer->getPeerCertificate();
}
+std::vector<Certificate::ref> BasicSessionStream::getPeerCertificateChain() const {
+ return tlsLayer->getPeerCertificateChain();
+}
+
boost::shared_ptr<CertificateVerificationError> BasicSessionStream::getPeerCertificateVerificationError() const {
return tlsLayer->getPeerCertificateVerificationError();
}
diff --git a/Swiften/Session/BasicSessionStream.h b/Swiften/Session/BasicSessionStream.h
index e1f32f4..084a191 100644
--- a/Swiften/Session/BasicSessionStream.h
+++ b/Swiften/Session/BasicSessionStream.h
@@ -55,6 +55,8 @@ namespace Swift {
virtual void addTLSEncryption();
virtual bool isTLSEncrypted();
virtual Certificate::ref getPeerCertificate() const;
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const;
+
virtual boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const;
virtual ByteArray getTLSFinishMessage() const;
diff --git a/Swiften/Session/SessionStream.h b/Swiften/Session/SessionStream.h
index 32cb6b6..4735d5f 100644
--- a/Swiften/Session/SessionStream.h
+++ b/Swiften/Session/SessionStream.h
@@ -67,6 +67,7 @@ namespace Swift {
}
virtual Certificate::ref getPeerCertificate() const = 0;
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const = 0;
virtual boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const = 0;
virtual ByteArray getTLSFinishMessage() const = 0;
diff --git a/Swiften/StreamStack/TLSLayer.cpp b/Swiften/StreamStack/TLSLayer.cpp
index 6d416bc..86221ea 100644
--- a/Swiften/StreamStack/TLSLayer.cpp
+++ b/Swiften/StreamStack/TLSLayer.cpp
@@ -45,6 +45,10 @@ Certificate::ref TLSLayer::getPeerCertificate() const {
return context->getPeerCertificate();
}
+std::vector<Certificate::ref> TLSLayer::getPeerCertificateChain() const {
+ return context->getPeerCertificateChain();
+}
+
boost::shared_ptr<CertificateVerificationError> TLSLayer::getPeerCertificateVerificationError() const {
return context->getPeerCertificateVerificationError();
}
diff --git a/Swiften/StreamStack/TLSLayer.h b/Swiften/StreamStack/TLSLayer.h
index ce0c89b..24978e0 100644
--- a/Swiften/StreamStack/TLSLayer.h
+++ b/Swiften/StreamStack/TLSLayer.h
@@ -26,6 +26,7 @@ namespace Swift {
bool setClientCertificate(CertificateWithKey::ref cert);
Certificate::ref getPeerCertificate() const;
+ std::vector<Certificate::ref> getPeerCertificateChain() const;
boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const;
void writeData(const SafeByteArray& data);
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
index 8c03052..58a8d05 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
@@ -39,6 +39,12 @@ OpenSSLContext::OpenSSLContext() : state_(Start), context_(0), handle_(0), readB
ensureLibraryInitialized();
context_ = SSL_CTX_new(TLSv1_client_method());
+ // 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)
X509_STORE* store = SSL_CTX_get_cert_store(context_);
@@ -236,6 +242,18 @@ Certificate::ref OpenSSLContext::getPeerCertificate() const {
}
}
+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;
+}
+
boost::shared_ptr<CertificateVerificationError> OpenSSLContext::getPeerCertificateVerificationError() const {
int verifyResult = SSL_get_verify_result(handle_);
if (verifyResult != X509_V_OK) {
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.h b/Swiften/TLS/OpenSSL/OpenSSLContext.h
index d8d0d2f..cee4f79 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.h
@@ -28,6 +28,7 @@ namespace Swift {
void handleDataFromApplication(const SafeByteArray&);
Certificate::ref getPeerCertificate() const;
+ std::vector<Certificate::ref> getPeerCertificateChain() const;
boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const;
virtual ByteArray getFinishMessage() const;
diff --git a/Swiften/TLS/Schannel/SchannelContext.cpp b/Swiften/TLS/Schannel/SchannelContext.cpp
index 641568d..997d760 100644
--- a/Swiften/TLS/Schannel/SchannelContext.cpp
+++ b/Swiften/TLS/Schannel/SchannelContext.cpp
@@ -633,6 +633,35 @@ 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());
+
+ 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;
+}
+
+//------------------------------------------------------------------------
+
CertificateVerificationError::ref SchannelContext::getPeerCertificateVerificationError() const {
return m_verificationError ? boost::make_shared<CertificateVerificationError>(*m_verificationError) : CertificateVerificationError::ref();
}
diff --git a/Swiften/TLS/Schannel/SchannelContext.h b/Swiften/TLS/Schannel/SchannelContext.h
index 587d0e7..2d65a8a 100644
--- a/Swiften/TLS/Schannel/SchannelContext.h
+++ b/Swiften/TLS/Schannel/SchannelContext.h
@@ -51,6 +51,7 @@ 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;
virtual ByteArray getFinishMessage() const;
diff --git a/Swiften/TLS/TLSContext.h b/Swiften/TLS/TLSContext.h
index 5640fe1..388f8ee 100644
--- a/Swiften/TLS/TLSContext.h
+++ b/Swiften/TLS/TLSContext.h
@@ -29,6 +29,7 @@ namespace Swift {
virtual void handleDataFromApplication(const SafeByteArray&) = 0;
virtual Certificate::ref getPeerCertificate() const = 0;
+ virtual std::vector<Certificate::ref> getPeerCertificateChain() const = 0;
virtual CertificateVerificationError::ref getPeerCertificateVerificationError() const = 0;
virtual ByteArray getFinishMessage() const = 0;