summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/TLS/OpenSSL')
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.cpp38
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.h7
2 files changed, 43 insertions, 2 deletions
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
index f90b4a8..47e7175 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
@@ -92,6 +92,11 @@ OpenSSLContext::OpenSSLContext(Mode mode) : mode_(mode), state_(State::Start) {
context_ = createSSL_CTX(mode_);
SSL_CTX_set_options(context_.get(), SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
+ if (mode_ == Mode::Server) {
+ SSL_CTX_set_tlsext_servername_arg(context_.get(), this);
+ SSL_CTX_set_tlsext_servername_callback(context_.get(), OpenSSLContext::handleServerNameCallback);
+ }
+
// TODO: implement CRL checking
// TODO: download CRL (HTTP transport)
// TODO: cache CRL downloads for configurable time period
@@ -176,6 +181,10 @@ void OpenSSLContext::accept() {
}
void OpenSSLContext::connect() {
+ connect(std::string());
+}
+
+void OpenSSLContext::connect(const std::string& requestedServerName) {
assert(mode_ == Mode::Client);
handle_ = std::unique_ptr<SSL>(SSL_new(context_.get()));
if (!handle_) {
@@ -184,6 +193,12 @@ void OpenSSLContext::connect() {
return;
}
+ if (!requestedServerName.empty()) {
+ if (SSL_set_tlsext_host_name(handle_.get(), const_cast<char*>(requestedServerName.c_str())) != 1) {
+ SWIFT_LOG(error) << "Failed on SSL_set_tlsext_host_name()." << std::endl;
+ }
+ }
+
// Ownership of BIOs is transferred to the SSL_CTX instance in handle_.
initAndSetBIOs();
@@ -215,6 +230,7 @@ void OpenSSLContext::doAccept() {
SWIFT_LOG(warning) << openSSLInternalErrorToString() << std::endl;
state_ = State::Error;
onError(std::make_shared<TLSError>());
+ sendPendingDataToNetwork();
}
}
@@ -240,6 +256,24 @@ void OpenSSLContext::doConnect() {
}
}
+int OpenSSLContext::handleServerNameCallback(SSL* ssl, int*, void* arg) {
+ if (ssl == nullptr)
+ return SSL_TLSEXT_ERR_NOACK;
+
+ const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+ if (servername) {
+ auto serverNameString = std::string(servername);
+ auto context = reinterpret_cast<OpenSSLContext*>(arg);
+ context->onServerNameRequested(serverNameString);
+
+ if (context->abortTLSHandshake_) {
+ context->abortTLSHandshake_ = false;
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+ }
+ return SSL_TLSEXT_ERR_OK;
+}
+
void OpenSSLContext::sendPendingDataToNetwork() {
int size = BIO_pending(writeBIO_);
if (size > 0) {
@@ -385,6 +419,10 @@ bool OpenSSLContext::setPrivateKey(const PrivateKey::ref& privateKey) {
return true;
}
+void OpenSSLContext::setAbortTLSHandshake(bool abort) {
+ abortTLSHandshake_ = abort;
+}
+
bool OpenSSLContext::setClientCertificate(CertificateWithKey::ref certificate) {
std::shared_ptr<PKCS12Certificate> pkcs12Certificate = std::dynamic_pointer_cast<PKCS12Certificate>(certificate);
if (!pkcs12Certificate || pkcs12Certificate->isNull()) {
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.h b/Swiften/TLS/OpenSSL/OpenSSLContext.h
index 5f06811..4a94848 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.h
@@ -43,10 +43,12 @@ namespace Swift {
void accept() override final;
void connect() override final;
+ void connect(const std::string& requestHostname) override final;
bool setCertificateChain(const std::vector<Certificate::ref>& certificateChain) override final;
bool setPrivateKey(const PrivateKey::ref& privateKey) override final;
bool setClientCertificate(CertificateWithKey::ref cert) override final;
+ void setAbortTLSHandshake(bool abort) override final;
void handleDataFromNetwork(const SafeByteArray&) override final;
void handleDataFromApplication(const SafeByteArray&) override final;
@@ -58,7 +60,7 @@ namespace Swift {
private:
static void ensureLibraryInitialized();
-
+ static int handleServerNameCallback(SSL *ssl, int *ad, void *arg);
static CertificateVerificationError::Type getVerificationErrorTypeForResult(int);
void initAndSetBIOs();
@@ -70,11 +72,12 @@ namespace Swift {
private:
enum class State { Start, Accepting, Connecting, Connected, Error };
- Mode mode_;
+ const Mode mode_;
State state_;
std::unique_ptr<SSL_CTX> context_;
std::unique_ptr<SSL> handle_;
BIO* readBIO_ = nullptr;
BIO* writeBIO_ = nullptr;
+ bool abortTLSHandshake_ = false;
};
}