summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swiften/Network/BOSHConnection.h2
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.cpp233
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.h11
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp6
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContextFactory.h2
-rw-r--r--Swiften/TLS/TLSContext.h2
-rw-r--r--Swiften/TLS/TLSOptions.h43
7 files changed, 286 insertions, 13 deletions
diff --git a/Swiften/Network/BOSHConnection.h b/Swiften/Network/BOSHConnection.h
index c492ac4..f0a946a 100644
--- a/Swiften/Network/BOSHConnection.h
+++ b/Swiften/Network/BOSHConnection.h
@@ -25,19 +25,19 @@
#include <Swiften/Session/SessionStream.h>
#include <Swiften/TLS/TLSError.h>
class BOSHConnectionTest;
namespace Swift {
class XMLParserFactory;
class TLSContextFactory;
class TLSLayer;
- struct TLSOptions;
+ class TLSOptions;
class HighLayer;
class SWIFTEN_API BOSHError : public SessionStream::SessionStreamError {
public:
enum Type {
BadRequest, HostGone, HostUnknown, ImproperAddressing,
InternalServerError, ItemNotFound, OtherRequest, PolicyViolation,
RemoteConnectionFailed, RemoteStreamError, SeeOtherURI, SystemShutdown, UndefinedCondition,
NoError};
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
index 5692e74..e585766 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
@@ -36,18 +36,26 @@
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
#pragma clang diagnostic ignored "-Wcast-align"
#pragma clang diagnostic ignored "-Wsign-conversion"
namespace Swift {
static const int MAX_FINISHED_SIZE = 4096;
static const int SSL_READ_BUFFERSIZE = 8192;
+#define SSL_DEFAULT_VERIFY_DEPTH 5
+
+// Callback function declarations for certificate verification
+extern "C" {
+ static int certVerifyCallback(X509_STORE_CTX *store_ctx, void*);
+ static int verifyCallback(int preverify_ok, X509_STORE_CTX *ctx);
+}
+
static void freeX509Stack(STACK_OF(X509)* stack) {
sk_X509_free(stack);
}
namespace {
class OpenSSLInitializerFinalizer {
public:
OpenSSLInitializerFinalizer() {
SSL_load_error_strings();
@@ -84,19 +92,19 @@ namespace {
auto bio = std::shared_ptr<BIO>(BIO_new(BIO_s_mem()), BIO_free);
ERR_print_errors(bio.get());
std::string errorString;
errorString.resize(BIO_pending(bio.get()));
BIO_read(bio.get(), (void*)errorString.data(), errorString.size());
return errorString;
}
}
-OpenSSLContext::OpenSSLContext(Mode mode) : mode_(mode), state_(State::Start) {
+OpenSSLContext::OpenSSLContext(const TLSOptions& options, Mode mode) : mode_(mode), state_(State::Start) {
ensureLibraryInitialized();
context_ = createSSL_CTX(mode_);
SSL_CTX_set_options(context_.get(), SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
if (mode_ == Mode::Server) {
#if OPENSSL_VERSION_NUMBER < 0x1010
// Automatically select highest preference curve used for ECDH temporary keys used during
// key exchange if possible.
// Since version 1.1.0, this option is always enabled.
@@ -112,21 +120,21 @@ OpenSSLContext::OpenSSLContext(Mode mode) : mode_(mode), state_(State::Start) {
// 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_.get());
HCERTSTORE systemStore = CertOpenSystemStore(0, "ROOT");
if (systemStore) {
- PCCERT_CONTEXT certContext = NULL;
+ PCCERT_CONTEXT certContext = nullptr;
while (true) {
- certContext = CertFindCertificateInStore(systemStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, certContext);
+ certContext = CertFindCertificateInStore(systemStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, nullptr, certContext);
if (!certContext) {
break;
}
OpenSSLCertificate cert(createByteArray(certContext->pbCertEncoded, certContext->cbCertEncoded));
if (store && cert.getInternalX509()) {
X509_STORE_add_cert(store, cert.getInternalX509().get());
}
}
}
@@ -153,34 +161,251 @@ OpenSSLContext::OpenSSLContext(Mode mode) : mode_(mode), state_(State::Start) {
memcpy(&certData[0], certCSSMData.Data, certCSSMData.Length);
OpenSSLCertificate certificate(certData);
if (store && certificate.getInternalX509()) {
X509_STORE_add_cert(store, certificate.getInternalX509().get());
}
}
CFRelease(anchorCertificates);
}
#endif
+ configure(options);
}
OpenSSLContext::~OpenSSLContext() {
}
void OpenSSLContext::ensureLibraryInitialized() {
static OpenSSLInitializerFinalizer openSSLInit;
}
void OpenSSLContext::initAndSetBIOs() {
// Ownership of BIOs is transferred
readBIO_ = BIO_new(BIO_s_mem());
writeBIO_ = BIO_new(BIO_s_mem());
SSL_set_bio(handle_.get(), readBIO_, writeBIO_);
}
+// This callback is called by OpenSSL when a client certificate needs to be verified.
+// In turn, this calls the verification callback which the user
+// of this OpenSSLContext has configured (if any).
+static int certVerifyCallback(X509_STORE_CTX* store_ctx, void* arg)
+{
+ OpenSSLContext* context = static_cast<OpenSSLContext *>(arg);
+
+ // Need to stash store_ctx pointer for use within verification
+ context->setX509StoreContext(store_ctx);
+
+ int ret;
+
+ // This callback shouldn't have been set up if the context doesn't
+ // have a verifyCertCallback set, but it doesn't hurt to double check
+ std::function<int (const TLSContext *)> cb = context->getVerifyCertCallback();
+ if (cb != nullptr) {
+ ret = cb(static_cast<const OpenSSLContext*>(context));
+ } else {
+ SWIFT_LOG(warning) << "certVerifyCallback called but context.verifyCertCallback is unset" << std::endl;
+ ret = 0;
+ }
+
+ context->setX509StoreContext(nullptr);
+ return ret;
+}
+
+// Convenience function to generate a text representation
+// of an X509 Name. This information is only used for logging.
+static std::string X509_NAME_to_text(X509_NAME* name)
+{
+ std::string nameString;
+
+ if (!name) {
+ return nameString;
+ }
+
+ std::unique_ptr<BIO, decltype(&BIO_free)> io(BIO_new(BIO_s_mem()), &BIO_free);
+ int r = X509_NAME_print_ex(io.get(), name, 0, XN_FLAG_RFC2253);
+ BIO_write(io.get(), "\0", 1);
+
+ if (r > 0) {
+ BUF_MEM* ptr = nullptr;
+ BIO_get_mem_ptr(io.get(), &ptr);
+ nameString = ptr->data;
+ }
+
+ return nameString;
+}
+
+// Check depth of certificate chain
+static int verifyCallback(int preverifyOk, X509_STORE_CTX* ctx)
+{
+ // Retrieve the pointer to the SSL of the connection currently treated
+ // and the application specific data stored into the SSL object.
+
+ int err = X509_STORE_CTX_get_error(ctx);
+ int depth = X509_STORE_CTX_get_error_depth(ctx);
+
+ SSL* ssl = static_cast<SSL*>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
+ SSL_CTX* sslctx = ssl ? SSL_get_SSL_CTX(ssl) : nullptr;
+ if (!sslctx) {
+ SWIFT_LOG(error) << "verifyCallback: internal error" << std::endl;
+ return preverifyOk;
+ }
+
+ if (SSL_CTX_get_verify_mode(sslctx) == SSL_VERIFY_NONE) {
+ SWIFT_LOG(info) << "verifyCallback: no verification required" << std::endl;
+ // No verification requested
+ return 1;
+ }
+
+ X509* errCert = X509_STORE_CTX_get_current_cert(ctx);
+ std::string subjectString;
+ if (errCert) {
+ X509_NAME* subjectName = X509_get_subject_name(errCert);
+ subjectString = X509_NAME_to_text(subjectName);
+ }
+
+ // Catch a too long certificate chain. The depth limit set using
+ // SSL_CTX_set_verify_depth() is by purpose set to "limit+1" so
+ // that whenever the "depth>verify_depth" condition is met, we
+ // have violated the limit and want to log this error condition.
+ // We must do it here, because the CHAIN_TOO_LONG error would not
+ // be found explicitly; only errors introduced by cutting off the
+ // additional certificates would be logged.
+ if (depth >= SSL_CTX_get_verify_depth(sslctx)) {
+ preverifyOk = 0;
+ err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+ X509_STORE_CTX_set_error(ctx, err);
+ }
+
+ if (!preverifyOk) {
+ std::string issuerString;
+ if (errCert) {
+ X509_NAME* issuerName = X509_get_issuer_name(errCert);
+ issuerString = X509_NAME_to_text(issuerName);
+ }
+ SWIFT_LOG(error) << "verifyCallback: verification error" <<
+ X509_verify_cert_error_string(err) << " depth: " <<
+ depth << " issuer: " << ((issuerString.length() > 0) ? issuerString : "<unknown>") << std::endl;
+ } else {
+ SWIFT_LOG(info) << "verifyCallback: SSL depth: " << depth << " Subject: " <<
+ ((subjectString.length() > 0) ? subjectString : "<>") << std::endl;
+ }
+ return preverifyOk;
+}
+
+bool OpenSSLContext::configure(const TLSOptions &options)
+{
+ if (options.cipherSuites) {
+ std::string cipherSuites = *(options.cipherSuites);
+ if (SSL_CTX_set_cipher_list(context_.get(), cipherSuites.c_str()) != 1 ) {
+ SWIFT_LOG(error) << "Failed to set cipher-suites" << std::endl;
+ return false;
+ }
+ }
+
+ if (options.context) {
+ const auto& contextId = *options.context;
+
+ if (SSL_CTX_set_session_id_context(context_.get(),
+ reinterpret_cast<const unsigned char *>(contextId.c_str()),
+ contextId.length()) != 1) {
+ SWIFT_LOG(error) << "Failed to set context-id" << std::endl;
+ return false;
+ }
+ }
+
+ if (options.sessionCacheTimeout) {
+ int scto = *options.sessionCacheTimeout;
+ if (scto <= 0) {
+ SWIFT_LOG(error) << "Invalid value for session-cache-timeout" << std::endl;
+ return false;
+ }
+ (void)SSL_CTX_set_timeout(context_.get(), scto);
+ if (SSL_CTX_get_timeout(context_.get()) != scto) {
+ SWIFT_LOG(error) << "Failed to set session-cache-timeout" << std::endl;
+ return false;
+ }
+ }
+
+ if (options.verifyCertificateCallback) {
+ verifyCertCallback = *options.verifyCertificateCallback;
+ } else {
+ verifyCertCallback = nullptr;
+ }
+
+ if (options.verifyMode) {
+ TLSOptions::VerifyMode verify_mode = *options.verifyMode;
+ int mode;
+ switch (verify_mode) {
+ case TLSOptions::VerifyMode::NONE:
+ mode = SSL_VERIFY_NONE;
+ break;
+ case TLSOptions::VerifyMode::REQUIRED:
+ mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE;
+ break;
+ case TLSOptions::VerifyMode::OPTIONAL:
+ mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
+ break;
+ }
+
+ // Set up default certificate chain verification depth - may be overridden below
+ SSL_CTX_set_verify_depth(context_.get(), SSL_DEFAULT_VERIFY_DEPTH + 1);
+
+ // Set callbacks up
+ SSL_CTX_set_verify(context_.get(), mode, verifyCallback);
+
+ // Only set up certificate verification callback if a user callback has
+ // been configured via the TLSOptions
+ if (verifyCertCallback != nullptr) {
+ SSL_CTX_set_cert_verify_callback(context_.get(), certVerifyCallback, this);
+ }
+ }
+
+ if (options.verifyDepth) {
+ int depth = *options.verifyDepth;
+ if (depth <= 0) {
+ SWIFT_LOG(error) << "Invalid value for verify-depth" << std::endl;
+ return false;
+ }
+
+ // Increase depth limit by one, so that verifyCallback() will log it
+ SSL_CTX_set_verify_depth(context_.get(), depth + 1);
+ }
+
+ auto updateOptionIfPresent = [this](boost::optional<bool> option, int flag) {
+ if (option) {
+ if (*option) {
+ SSL_CTX_set_options(context_.get(), flag);
+ }
+ else {
+ SSL_CTX_clear_options(context_.get(), flag);
+ }
+ }
+ };
+ updateOptionIfPresent(options.workaroundMicrosoftSessID, SSL_OP_MICROSOFT_SESS_ID_BUG);
+ updateOptionIfPresent(options.workaroundNetscapeChallenge, SSL_OP_NETSCAPE_CHALLENGE_BUG);
+ updateOptionIfPresent(options.workaroundNetscapeReuseCipherChange, SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
+ updateOptionIfPresent(options.workaroundSSLRef2ReuseCertType, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG);
+ updateOptionIfPresent(options.workaroundMicrosoftBigSSLv3Buffer, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER);
+ updateOptionIfPresent(options.workaroundSSLeay080ClientDH, SSL_OP_SSLEAY_080_CLIENT_DH_BUG);
+ updateOptionIfPresent(options.workaroundTLSD5, SSL_OP_TLS_D5_BUG);
+ updateOptionIfPresent(options.workaroundTLSBlockPadding, SSL_OP_TLS_BLOCK_PADDING_BUG);
+ updateOptionIfPresent(options.workaroundDontInsertEmptyFragments, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
+ updateOptionIfPresent(options.workaroundAll, SSL_OP_ALL);
+ updateOptionIfPresent(options.suppressSSLv2, SSL_OP_NO_SSLv2);
+ updateOptionIfPresent(options.suppressSSLv3, SSL_OP_NO_SSLv3);
+ updateOptionIfPresent(options.suppressTLSv1, SSL_OP_NO_TLSv1);
+ updateOptionIfPresent(options.disableTLSRollBackBug, SSL_OP_TLS_ROLLBACK_BUG);
+ updateOptionIfPresent(options.singleDHUse, SSL_OP_SINGLE_DH_USE);
+
+ return true;
+}
+
+
void OpenSSLContext::accept() {
assert(mode_ == Mode::Server);
handle_ = std::unique_ptr<SSL>(SSL_new(context_.get()));
if (!handle_) {
state_ = State::Error;
onError(std::make_shared<TLSError>(TLSError::AcceptFailed, openSSLInternalErrorToString()));
return;
}
@@ -480,19 +705,19 @@ bool OpenSSLContext::setClientCertificate(CertificateWithKey::ref certificate) {
}
return true;
}
bool OpenSSLContext::setDiffieHellmanParameters(const ByteArray& parametersInOpenSslDer) {
auto bio = std::unique_ptr<BIO, decltype(&BIO_free)>(BIO_new(BIO_s_mem()), BIO_free);
if (bio) {
BIO_write(bio.get(), vecptr(parametersInOpenSslDer), parametersInOpenSslDer.size());
auto result = 0L;
- if (auto dhparams = d2i_DHparams_bio(bio.get(), NULL)) {
+ if (auto dhparams = d2i_DHparams_bio(bio.get(), nullptr)) {
if (handle_) {
result = SSL_set_tmp_dh(handle_.get(), dhparams);
}
else {
result = SSL_CTX_set_tmp_dh(context_.get(), dhparams);
}
DH_free(dhparams);
}
return result == 1;
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.h b/Swiften/TLS/OpenSSL/OpenSSLContext.h
index c18a6f4..885b1fe 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.h
@@ -10,18 +10,19 @@
#include <boost/noncopyable.hpp>
#include <boost/signals2.hpp>
#include <openssl/ssl.h>
#include <Swiften/Base/ByteArray.h>
#include <Swiften/TLS/CertificateWithKey.h>
#include <Swiften/TLS/TLSContext.h>
+#include <Swiften/TLS/TLSOptions.h>
namespace std {
template<>
class default_delete<SSL_CTX> {
public:
void operator()(SSL_CTX *ptr) {
SSL_CTX_free(ptr);
}
};
@@ -32,19 +33,19 @@ namespace std {
void operator()(SSL *ptr) {
SSL_free(ptr);
}
};
}
namespace Swift {
class OpenSSLContext : public TLSContext, boost::noncopyable {
public:
- OpenSSLContext(Mode mode);
+ OpenSSLContext(const TLSOptions& options, Mode mode);
virtual ~OpenSSLContext() override final;
void accept() override final;
void connect() override final;
void connect(const std::string& requestHostname) override final;
bool setCertificateChain(std::vector<std::unique_ptr<Certificate>>&& certificateChain) override final;
bool setPrivateKey(const PrivateKey::ref& privateKey) override final;
bool setClientCertificate(CertificateWithKey::ref cert) override final;
@@ -54,19 +55,23 @@ namespace Swift {
void handleDataFromNetwork(const SafeByteArray&) override final;
void handleDataFromApplication(const SafeByteArray&) override final;
std::vector<Certificate::ref> getPeerCertificateChain() const override final;
std::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const override final;
virtual ByteArray getFinishMessage() const override final;
virtual ByteArray getPeerFinishMessage() const override final;
+ void setX509StoreContext(X509_STORE_CTX *ptr) { x509_store_ctx = ptr; }
+ std::function<int (const TLSContext *)> getVerifyCertCallback() { return verifyCertCallback; }
+
private:
+ bool configure(const TLSOptions& options);
static void ensureLibraryInitialized();
static int handleServerNameCallback(SSL *ssl, int *ad, void *arg);
static CertificateVerificationError::Type getVerificationErrorTypeForResult(int);
void initAndSetBIOs();
void doAccept();
void doConnect();
void sendPendingDataToNetwork();
void sendPendingDataToApplication();
@@ -75,11 +80,13 @@ namespace Swift {
enum class State { Start, Accepting, Connecting, Connected, Error };
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;
- };
+ X509_STORE_CTX *x509_store_ctx = nullptr;
+ std::function<int (const TLSContext *)> verifyCertCallback = nullptr;
+ };
}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp
index a9ba5ab..12445fd 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2010-2018 Isode Limited.
+ * Copyright (c) 2010-2019 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swiften/TLS/OpenSSL/OpenSSLContextFactory.h>
#include <openssl/bio.h>
#include <openssl/dh.h>
#include <openssl/pem.h>
@@ -15,20 +15,20 @@
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
namespace Swift {
bool OpenSSLContextFactory::canCreate() const {
return true;
}
-std::unique_ptr<TLSContext> OpenSSLContextFactory::createTLSContext(const TLSOptions&, TLSContext::Mode mode) {
- return std::unique_ptr<TLSContext>(new OpenSSLContext(mode));
+std::unique_ptr<TLSContext> OpenSSLContextFactory::createTLSContext(const TLSOptions& options, TLSContext::Mode mode) {
+ return std::make_unique<OpenSSLContext>(options, mode);
}
ByteArray OpenSSLContextFactory::convertDHParametersFromPEMToDER(const std::string& dhParametersInPEM) {
ByteArray dhParametersInDER;
auto bio = std::unique_ptr<BIO, decltype(&BIO_free)>(BIO_new(BIO_s_mem()), BIO_free);
if (bio) {
BIO_write(bio.get(), dhParametersInPEM.data(), dhParametersInPEM.size());
if (auto params = PEM_read_bio_DHparams(bio.get(), nullptr, nullptr, nullptr)) {
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h
index 95a2b0c..834e479 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2010-2018 Isode Limited.
+ * Copyright (c) 2010-2019 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
#include <memory>
#include <Swiften/TLS/TLSContextFactory.h>
diff --git a/Swiften/TLS/TLSContext.h b/Swiften/TLS/TLSContext.h
index 003069f..85776d8 100644
--- a/Swiften/TLS/TLSContext.h
+++ b/Swiften/TLS/TLSContext.h
@@ -44,19 +44,19 @@ namespace Swift {
virtual void handleDataFromApplication(const SafeByteArray&) = 0;
Certificate::ref getPeerCertificate() const;
virtual std::vector<Certificate::ref> getPeerCertificateChain() const = 0;
virtual CertificateVerificationError::ref getPeerCertificateVerificationError() const = 0;
virtual ByteArray getFinishMessage() const = 0;
virtual ByteArray getPeerFinishMessage() const;
- public:
+ public:
enum class Mode {
Client,
Server
};
public:
boost::signals2::signal<void (const SafeByteArray&)> onDataForNetwork;
boost::signals2::signal<void (const SafeByteArray&)> onDataForApplication;
boost::signals2::signal<void (std::shared_ptr<TLSError>)> onError;
diff --git a/Swiften/TLS/TLSOptions.h b/Swiften/TLS/TLSOptions.h
index dd7e920..7a38aa2 100644
--- a/Swiften/TLS/TLSOptions.h
+++ b/Swiften/TLS/TLSOptions.h
@@ -1,25 +1,66 @@
/*
* Copyright (c) 2015 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
namespace Swift {
+ class TLSContext;
- struct TLSOptions {
+ class TLSOptions {
+ public:
TLSOptions() : schannelTLS1_0Workaround(false) {
}
/**
* A bug in the Windows SChannel TLS stack, combined with
* overly-restrictive server stacks means it's sometimes necessary to
* not use TLS>1.0. This option has no effect unless compiled on
* Windows against SChannel (OpenSSL users are unaffected).
*/
bool schannelTLS1_0Workaround;
+ /**
+ * OpenSSL configuration flags
+ */
+ boost::optional<bool> workaroundMicrosoftSessID;
+ boost::optional<bool> workaroundNetscapeChallenge;
+ boost::optional<bool> workaroundNetscapeReuseCipherChange;
+ boost::optional<bool> workaroundSSLRef2ReuseCertType;
+ boost::optional<bool> workaroundMicrosoftBigSSLv3Buffer;
+ boost::optional<bool> workaroundSSLeay080ClientDH;
+ boost::optional<bool> workaroundTLSD5;
+ boost::optional<bool> workaroundTLSBlockPadding;
+ boost::optional<bool> workaroundDontInsertEmptyFragments;
+ boost::optional<bool> workaroundAll;
+ boost::optional<bool> suppressSSLv2;
+ boost::optional<bool> suppressSSLv3;
+ boost::optional<bool> suppressTLSv1;
+ boost::optional<bool> disableTLSRollBackBug;
+ boost::optional<bool> singleDHUse;
+
+ /**
+ * Other OpenSSL configuration items
+ */
+ boost::optional<std::string> cipherSuites;
+ boost::optional<std::string> context;
+ boost::optional<int> sessionCacheTimeout;
+ boost::optional<int> verifyDepth;
+
+ enum class VerifyMode {
+ NONE,
+ REQUIRED,
+ OPTIONAL
+ } ;
+ boost::optional<VerifyMode> verifyMode;
+
+ /**
+ * Callback for certificate verification
+ */
+
+ boost::optional<std::function<int(const TLSContext *)>> verifyCertificateCallback;
};
}