diff options
| -rw-r--r-- | Swiften/Network/BOSHConnection.h | 2 | ||||
| -rw-r--r-- | Swiften/TLS/OpenSSL/OpenSSLContext.cpp | 233 | ||||
| -rw-r--r-- | Swiften/TLS/OpenSSL/OpenSSLContext.h | 11 | ||||
| -rw-r--r-- | Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp | 6 | ||||
| -rw-r--r-- | Swiften/TLS/OpenSSL/OpenSSLContextFactory.h | 2 | ||||
| -rw-r--r-- | Swiften/TLS/TLSContext.h | 2 | ||||
| -rw-r--r-- | Swiften/TLS/TLSOptions.h | 43 |
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 | |||
| @@ -31,7 +31,7 @@ namespace Swift { | |||
| 31 | class XMLParserFactory; | 31 | class XMLParserFactory; |
| 32 | class TLSContextFactory; | 32 | class TLSContextFactory; |
| 33 | class TLSLayer; | 33 | class TLSLayer; |
| 34 | struct TLSOptions; | 34 | class TLSOptions; |
| 35 | class HighLayer; | 35 | class HighLayer; |
| 36 | 36 | ||
| 37 | class SWIFTEN_API BOSHError : public SessionStream::SessionStreamError { | 37 | class SWIFTEN_API BOSHError : public SessionStream::SessionStreamError { |
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 | |||
| @@ -42,6 +42,14 @@ namespace Swift { | |||
| 42 | static const int MAX_FINISHED_SIZE = 4096; | 42 | static const int MAX_FINISHED_SIZE = 4096; |
| 43 | static const int SSL_READ_BUFFERSIZE = 8192; | 43 | static const int SSL_READ_BUFFERSIZE = 8192; |
| 44 | 44 | ||
| 45 | #define SSL_DEFAULT_VERIFY_DEPTH 5 | ||
| 46 | |||
| 47 | // Callback function declarations for certificate verification | ||
| 48 | extern "C" { | ||
| 49 | static int certVerifyCallback(X509_STORE_CTX *store_ctx, void*); | ||
| 50 | static int verifyCallback(int preverify_ok, X509_STORE_CTX *ctx); | ||
| 51 | } | ||
| 52 | |||
| 45 | static void freeX509Stack(STACK_OF(X509)* stack) { | 53 | static void freeX509Stack(STACK_OF(X509)* stack) { |
| 46 | sk_X509_free(stack); | 54 | sk_X509_free(stack); |
| 47 | } | 55 | } |
| @@ -90,7 +98,7 @@ namespace { | |||
| 90 | } | 98 | } |
| 91 | } | 99 | } |
| 92 | 100 | ||
| 93 | OpenSSLContext::OpenSSLContext(Mode mode) : mode_(mode), state_(State::Start) { | 101 | OpenSSLContext::OpenSSLContext(const TLSOptions& options, Mode mode) : mode_(mode), state_(State::Start) { |
| 94 | ensureLibraryInitialized(); | 102 | ensureLibraryInitialized(); |
| 95 | context_ = createSSL_CTX(mode_); | 103 | context_ = createSSL_CTX(mode_); |
| 96 | SSL_CTX_set_options(context_.get(), SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); | 104 | SSL_CTX_set_options(context_.get(), SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); |
| @@ -118,9 +126,9 @@ OpenSSLContext::OpenSSLContext(Mode mode) : mode_(mode), state_(State::Start) { | |||
| 118 | X509_STORE* store = SSL_CTX_get_cert_store(context_.get()); | 126 | X509_STORE* store = SSL_CTX_get_cert_store(context_.get()); |
| 119 | HCERTSTORE systemStore = CertOpenSystemStore(0, "ROOT"); | 127 | HCERTSTORE systemStore = CertOpenSystemStore(0, "ROOT"); |
| 120 | if (systemStore) { | 128 | if (systemStore) { |
| 121 | PCCERT_CONTEXT certContext = NULL; | 129 | PCCERT_CONTEXT certContext = nullptr; |
| 122 | while (true) { | 130 | while (true) { |
| 123 | certContext = CertFindCertificateInStore(systemStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, certContext); | 131 | certContext = CertFindCertificateInStore(systemStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, nullptr, certContext); |
| 124 | if (!certContext) { | 132 | if (!certContext) { |
| 125 | break; | 133 | break; |
| 126 | } | 134 | } |
| @@ -159,6 +167,7 @@ OpenSSLContext::OpenSSLContext(Mode mode) : mode_(mode), state_(State::Start) { | |||
| 159 | CFRelease(anchorCertificates); | 167 | CFRelease(anchorCertificates); |
| 160 | } | 168 | } |
| 161 | #endif | 169 | #endif |
| 170 | configure(options); | ||
| 162 | } | 171 | } |
| 163 | 172 | ||
| 164 | OpenSSLContext::~OpenSSLContext() { | 173 | OpenSSLContext::~OpenSSLContext() { |
| @@ -175,6 +184,222 @@ void OpenSSLContext::initAndSetBIOs() { | |||
| 175 | SSL_set_bio(handle_.get(), readBIO_, writeBIO_); | 184 | SSL_set_bio(handle_.get(), readBIO_, writeBIO_); |
| 176 | } | 185 | } |
| 177 | 186 | ||
| 187 | // This callback is called by OpenSSL when a client certificate needs to be verified. | ||
| 188 | // In turn, this calls the verification callback which the user | ||
| 189 | // of this OpenSSLContext has configured (if any). | ||
| 190 | static int certVerifyCallback(X509_STORE_CTX* store_ctx, void* arg) | ||
| 191 | { | ||
| 192 | OpenSSLContext* context = static_cast<OpenSSLContext *>(arg); | ||
| 193 | |||
| 194 | // Need to stash store_ctx pointer for use within verification | ||
| 195 | context->setX509StoreContext(store_ctx); | ||
| 196 | |||
| 197 | int ret; | ||
| 198 | |||
| 199 | // This callback shouldn't have been set up if the context doesn't | ||
| 200 | // have a verifyCertCallback set, but it doesn't hurt to double check | ||
| 201 | std::function<int (const TLSContext *)> cb = context->getVerifyCertCallback(); | ||
| 202 | if (cb != nullptr) { | ||
| 203 | ret = cb(static_cast<const OpenSSLContext*>(context)); | ||
| 204 | } else { | ||
| 205 | SWIFT_LOG(warning) << "certVerifyCallback called but context.verifyCertCallback is unset" << std::endl; | ||
| 206 | ret = 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | context->setX509StoreContext(nullptr); | ||
| 210 | return ret; | ||
| 211 | } | ||
| 212 | |||
| 213 | // Convenience function to generate a text representation | ||
| 214 | // of an X509 Name. This information is only used for logging. | ||
| 215 | static std::string X509_NAME_to_text(X509_NAME* name) | ||
| 216 | { | ||
| 217 | std::string nameString; | ||
| 218 | |||
| 219 | if (!name) { | ||
| 220 | return nameString; | ||
| 221 | } | ||
| 222 | |||
| 223 | std::unique_ptr<BIO, decltype(&BIO_free)> io(BIO_new(BIO_s_mem()), &BIO_free); | ||
| 224 | int r = X509_NAME_print_ex(io.get(), name, 0, XN_FLAG_RFC2253); | ||
| 225 | BIO_write(io.get(), "\0", 1); | ||
| 226 | |||
| 227 | if (r > 0) { | ||
| 228 | BUF_MEM* ptr = nullptr; | ||
| 229 | BIO_get_mem_ptr(io.get(), &ptr); | ||
| 230 | nameString = ptr->data; | ||
| 231 | } | ||
| 232 | |||
| 233 | return nameString; | ||
| 234 | } | ||
| 235 | |||
| 236 | // Check depth of certificate chain | ||
| 237 | static int verifyCallback(int preverifyOk, X509_STORE_CTX* ctx) | ||
| 238 | { | ||
| 239 | // Retrieve the pointer to the SSL of the connection currently treated | ||
| 240 | // and the application specific data stored into the SSL object. | ||
| 241 | |||
| 242 | int err = X509_STORE_CTX_get_error(ctx); | ||
| 243 | int depth = X509_STORE_CTX_get_error_depth(ctx); | ||
| 244 | |||
| 245 | SSL* ssl = static_cast<SSL*>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx())); | ||
| 246 | SSL_CTX* sslctx = ssl ? SSL_get_SSL_CTX(ssl) : nullptr; | ||
| 247 | if (!sslctx) { | ||
| 248 | SWIFT_LOG(error) << "verifyCallback: internal error" << std::endl; | ||
| 249 | return preverifyOk; | ||
| 250 | } | ||
| 251 | |||
| 252 | if (SSL_CTX_get_verify_mode(sslctx) == SSL_VERIFY_NONE) { | ||
| 253 | SWIFT_LOG(info) << "verifyCallback: no verification required" << std::endl; | ||
| 254 | // No verification requested | ||
| 255 | return 1; | ||
| 256 | } | ||
| 257 | |||
| 258 | X509* errCert = X509_STORE_CTX_get_current_cert(ctx); | ||
| 259 | std::string subjectString; | ||
| 260 | if (errCert) { | ||
| 261 | X509_NAME* subjectName = X509_get_subject_name(errCert); | ||
| 262 | subjectString = X509_NAME_to_text(subjectName); | ||
| 263 | } | ||
| 264 | |||
| 265 | // Catch a too long certificate chain. The depth limit set using | ||
| 266 | // SSL_CTX_set_verify_depth() is by purpose set to "limit+1" so | ||
| 267 | // that whenever the "depth>verify_depth" condition is met, we | ||
| 268 | // have violated the limit and want to log this error condition. | ||
| 269 | // We must do it here, because the CHAIN_TOO_LONG error would not | ||
| 270 | // be found explicitly; only errors introduced by cutting off the | ||
| 271 | // additional certificates would be logged. | ||
| 272 | if (depth >= SSL_CTX_get_verify_depth(sslctx)) { | ||
| 273 | preverifyOk = 0; | ||
| 274 | err = X509_V_ERR_CERT_CHAIN_TOO_LONG; | ||
| 275 | X509_STORE_CTX_set_error(ctx, err); | ||
| 276 | } | ||
| 277 | |||
| 278 | if (!preverifyOk) { | ||
| 279 | std::string issuerString; | ||
| 280 | if (errCert) { | ||
| 281 | X509_NAME* issuerName = X509_get_issuer_name(errCert); | ||
| 282 | issuerString = X509_NAME_to_text(issuerName); | ||
| 283 | } | ||
| 284 | SWIFT_LOG(error) << "verifyCallback: verification error" << | ||
| 285 | X509_verify_cert_error_string(err) << " depth: " << | ||
| 286 | depth << " issuer: " << ((issuerString.length() > 0) ? issuerString : "<unknown>") << std::endl; | ||
| 287 | } else { | ||
| 288 | SWIFT_LOG(info) << "verifyCallback: SSL depth: " << depth << " Subject: " << | ||
| 289 | ((subjectString.length() > 0) ? subjectString : "<>") << std::endl; | ||
| 290 | } | ||
| 291 | return preverifyOk; | ||
| 292 | } | ||
| 293 | |||
| 294 | bool OpenSSLContext::configure(const TLSOptions &options) | ||
| 295 | { | ||
| 296 | if (options.cipherSuites) { | ||
| 297 | std::string cipherSuites = *(options.cipherSuites); | ||
| 298 | if (SSL_CTX_set_cipher_list(context_.get(), cipherSuites.c_str()) != 1 ) { | ||
| 299 | SWIFT_LOG(error) << "Failed to set cipher-suites" << std::endl; | ||
| 300 | return false; | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | if (options.context) { | ||
| 305 | const auto& contextId = *options.context; | ||
| 306 | |||
| 307 | if (SSL_CTX_set_session_id_context(context_.get(), | ||
| 308 | reinterpret_cast<const unsigned char *>(contextId.c_str()), | ||
| 309 | contextId.length()) != 1) { | ||
| 310 | SWIFT_LOG(error) << "Failed to set context-id" << std::endl; | ||
| 311 | return false; | ||
| 312 | } | ||
| 313 | } | ||
| 314 | |||
| 315 | if (options.sessionCacheTimeout) { | ||
| 316 | int scto = *options.sessionCacheTimeout; | ||
| 317 | if (scto <= 0) { | ||
| 318 | SWIFT_LOG(error) << "Invalid value for session-cache-timeout" << std::endl; | ||
| 319 | return false; | ||
| 320 | } | ||
| 321 | (void)SSL_CTX_set_timeout(context_.get(), scto); | ||
| 322 | if (SSL_CTX_get_timeout(context_.get()) != scto) { | ||
| 323 | SWIFT_LOG(error) << "Failed to set session-cache-timeout" << std::endl; | ||
| 324 | return false; | ||
| 325 | } | ||
| 326 | } | ||
| 327 | |||
| 328 | if (options.verifyCertificateCallback) { | ||
| 329 | verifyCertCallback = *options.verifyCertificateCallback; | ||
| 330 | } else { | ||
| 331 | verifyCertCallback = nullptr; | ||
| 332 | } | ||
| 333 | |||
| 334 | if (options.verifyMode) { | ||
| 335 | TLSOptions::VerifyMode verify_mode = *options.verifyMode; | ||
| 336 | int mode; | ||
| 337 | switch (verify_mode) { | ||
| 338 | case TLSOptions::VerifyMode::NONE: | ||
| 339 | mode = SSL_VERIFY_NONE; | ||
| 340 | break; | ||
| 341 | case TLSOptions::VerifyMode::REQUIRED: | ||
| 342 | mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE; | ||
| 343 | break; | ||
| 344 | case TLSOptions::VerifyMode::OPTIONAL: | ||
| 345 | mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; | ||
| 346 | break; | ||
| 347 | } | ||
| 348 | |||
| 349 | // Set up default certificate chain verification depth - may be overridden below | ||
| 350 | SSL_CTX_set_verify_depth(context_.get(), SSL_DEFAULT_VERIFY_DEPTH + 1); | ||
| 351 | |||
| 352 | // Set callbacks up | ||
| 353 | SSL_CTX_set_verify(context_.get(), mode, verifyCallback); | ||
| 354 | |||
| 355 | // Only set up certificate verification callback if a user callback has | ||
| 356 | // been configured via the TLSOptions | ||
| 357 | if (verifyCertCallback != nullptr) { | ||
| 358 | SSL_CTX_set_cert_verify_callback(context_.get(), certVerifyCallback, this); | ||
| 359 | } | ||
| 360 | } | ||
| 361 | |||
| 362 | if (options.verifyDepth) { | ||
| 363 | int depth = *options.verifyDepth; | ||
| 364 | if (depth <= 0) { | ||
| 365 | SWIFT_LOG(error) << "Invalid value for verify-depth" << std::endl; | ||
| 366 | return false; | ||
| 367 | } | ||
| 368 | |||
| 369 | // Increase depth limit by one, so that verifyCallback() will log it | ||
| 370 | SSL_CTX_set_verify_depth(context_.get(), depth + 1); | ||
| 371 | } | ||
| 372 | |||
| 373 | auto updateOptionIfPresent = [this](boost::optional<bool> option, int flag) { | ||
| 374 | if (option) { | ||
| 375 | if (*option) { | ||
| 376 | SSL_CTX_set_options(context_.get(), flag); | ||
| 377 | } | ||
| 378 | else { | ||
| 379 | SSL_CTX_clear_options(context_.get(), flag); | ||
| 380 | } | ||
| 381 | } | ||
| 382 | }; | ||
| 383 | updateOptionIfPresent(options.workaroundMicrosoftSessID, SSL_OP_MICROSOFT_SESS_ID_BUG); | ||
| 384 | updateOptionIfPresent(options.workaroundNetscapeChallenge, SSL_OP_NETSCAPE_CHALLENGE_BUG); | ||
| 385 | updateOptionIfPresent(options.workaroundNetscapeReuseCipherChange, SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG); | ||
| 386 | updateOptionIfPresent(options.workaroundSSLRef2ReuseCertType, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG); | ||
| 387 | updateOptionIfPresent(options.workaroundMicrosoftBigSSLv3Buffer, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); | ||
| 388 | updateOptionIfPresent(options.workaroundSSLeay080ClientDH, SSL_OP_SSLEAY_080_CLIENT_DH_BUG); | ||
| 389 | updateOptionIfPresent(options.workaroundTLSD5, SSL_OP_TLS_D5_BUG); | ||
| 390 | updateOptionIfPresent(options.workaroundTLSBlockPadding, SSL_OP_TLS_BLOCK_PADDING_BUG); | ||
| 391 | updateOptionIfPresent(options.workaroundDontInsertEmptyFragments, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); | ||
| 392 | updateOptionIfPresent(options.workaroundAll, SSL_OP_ALL); | ||
| 393 | updateOptionIfPresent(options.suppressSSLv2, SSL_OP_NO_SSLv2); | ||
| 394 | updateOptionIfPresent(options.suppressSSLv3, SSL_OP_NO_SSLv3); | ||
| 395 | updateOptionIfPresent(options.suppressTLSv1, SSL_OP_NO_TLSv1); | ||
| 396 | updateOptionIfPresent(options.disableTLSRollBackBug, SSL_OP_TLS_ROLLBACK_BUG); | ||
| 397 | updateOptionIfPresent(options.singleDHUse, SSL_OP_SINGLE_DH_USE); | ||
| 398 | |||
| 399 | return true; | ||
| 400 | } | ||
| 401 | |||
| 402 | |||
| 178 | void OpenSSLContext::accept() { | 403 | void OpenSSLContext::accept() { |
| 179 | assert(mode_ == Mode::Server); | 404 | assert(mode_ == Mode::Server); |
| 180 | handle_ = std::unique_ptr<SSL>(SSL_new(context_.get())); | 405 | handle_ = std::unique_ptr<SSL>(SSL_new(context_.get())); |
| @@ -486,7 +711,7 @@ bool OpenSSLContext::setDiffieHellmanParameters(const ByteArray& parametersInOpe | |||
| 486 | if (bio) { | 711 | if (bio) { |
| 487 | BIO_write(bio.get(), vecptr(parametersInOpenSslDer), parametersInOpenSslDer.size()); | 712 | BIO_write(bio.get(), vecptr(parametersInOpenSslDer), parametersInOpenSslDer.size()); |
| 488 | auto result = 0L; | 713 | auto result = 0L; |
| 489 | if (auto dhparams = d2i_DHparams_bio(bio.get(), NULL)) { | 714 | if (auto dhparams = d2i_DHparams_bio(bio.get(), nullptr)) { |
| 490 | if (handle_) { | 715 | if (handle_) { |
| 491 | result = SSL_set_tmp_dh(handle_.get(), dhparams); | 716 | result = SSL_set_tmp_dh(handle_.get(), dhparams); |
| 492 | } | 717 | } |
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 | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <Swiften/Base/ByteArray.h> | 16 | #include <Swiften/Base/ByteArray.h> |
| 17 | #include <Swiften/TLS/CertificateWithKey.h> | 17 | #include <Swiften/TLS/CertificateWithKey.h> |
| 18 | #include <Swiften/TLS/TLSContext.h> | 18 | #include <Swiften/TLS/TLSContext.h> |
| 19 | #include <Swiften/TLS/TLSOptions.h> | ||
| 19 | 20 | ||
| 20 | namespace std { | 21 | namespace std { |
| 21 | template<> | 22 | template<> |
| @@ -38,7 +39,7 @@ namespace std { | |||
| 38 | namespace Swift { | 39 | namespace Swift { |
| 39 | class OpenSSLContext : public TLSContext, boost::noncopyable { | 40 | class OpenSSLContext : public TLSContext, boost::noncopyable { |
| 40 | public: | 41 | public: |
| 41 | OpenSSLContext(Mode mode); | 42 | OpenSSLContext(const TLSOptions& options, Mode mode); |
| 42 | virtual ~OpenSSLContext() override final; | 43 | virtual ~OpenSSLContext() override final; |
| 43 | 44 | ||
| 44 | void accept() override final; | 45 | void accept() override final; |
| @@ -60,7 +61,11 @@ namespace Swift { | |||
| 60 | virtual ByteArray getFinishMessage() const override final; | 61 | virtual ByteArray getFinishMessage() const override final; |
| 61 | virtual ByteArray getPeerFinishMessage() const override final; | 62 | virtual ByteArray getPeerFinishMessage() const override final; |
| 62 | 63 | ||
| 64 | void setX509StoreContext(X509_STORE_CTX *ptr) { x509_store_ctx = ptr; } | ||
| 65 | std::function<int (const TLSContext *)> getVerifyCertCallback() { return verifyCertCallback; } | ||
| 66 | |||
| 63 | private: | 67 | private: |
| 68 | bool configure(const TLSOptions& options); | ||
| 64 | static void ensureLibraryInitialized(); | 69 | static void ensureLibraryInitialized(); |
| 65 | static int handleServerNameCallback(SSL *ssl, int *ad, void *arg); | 70 | static int handleServerNameCallback(SSL *ssl, int *ad, void *arg); |
| 66 | static CertificateVerificationError::Type getVerificationErrorTypeForResult(int); | 71 | static CertificateVerificationError::Type getVerificationErrorTypeForResult(int); |
| @@ -81,5 +86,7 @@ namespace Swift { | |||
| 81 | BIO* readBIO_ = nullptr; | 86 | BIO* readBIO_ = nullptr; |
| 82 | BIO* writeBIO_ = nullptr; | 87 | BIO* writeBIO_ = nullptr; |
| 83 | bool abortTLSHandshake_ = false; | 88 | bool abortTLSHandshake_ = false; |
| 84 | }; | 89 | X509_STORE_CTX *x509_store_ctx = nullptr; |
| 90 | std::function<int (const TLSContext *)> verifyCertCallback = nullptr; | ||
| 91 | }; | ||
| 85 | } | 92 | } |
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,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2010-2018 Isode Limited. | 2 | * Copyright (c) 2010-2019 Isode Limited. |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
| @@ -21,8 +21,8 @@ bool OpenSSLContextFactory::canCreate() const { | |||
| 21 | return true; | 21 | return true; |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | std::unique_ptr<TLSContext> OpenSSLContextFactory::createTLSContext(const TLSOptions&, TLSContext::Mode mode) { | 24 | std::unique_ptr<TLSContext> OpenSSLContextFactory::createTLSContext(const TLSOptions& options, TLSContext::Mode mode) { |
| 25 | return std::unique_ptr<TLSContext>(new OpenSSLContext(mode)); | 25 | return std::make_unique<OpenSSLContext>(options, mode); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | ByteArray OpenSSLContextFactory::convertDHParametersFromPEMToDER(const std::string& dhParametersInPEM) { | 28 | ByteArray OpenSSLContextFactory::convertDHParametersFromPEMToDER(const std::string& dhParametersInPEM) { |
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,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2010-2018 Isode Limited. | 2 | * Copyright (c) 2010-2019 Isode Limited. |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
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 | |||
| @@ -50,7 +50,7 @@ namespace Swift { | |||
| 50 | virtual ByteArray getFinishMessage() const = 0; | 50 | virtual ByteArray getFinishMessage() const = 0; |
| 51 | virtual ByteArray getPeerFinishMessage() const; | 51 | virtual ByteArray getPeerFinishMessage() const; |
| 52 | 52 | ||
| 53 | public: | 53 | public: |
| 54 | enum class Mode { | 54 | enum class Mode { |
| 55 | Client, | 55 | Client, |
| 56 | Server | 56 | Server |
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 | |||
| @@ -7,8 +7,10 @@ | |||
| 7 | #pragma once | 7 | #pragma once |
| 8 | 8 | ||
| 9 | namespace Swift { | 9 | namespace Swift { |
| 10 | class TLSContext; | ||
| 10 | 11 | ||
| 11 | struct TLSOptions { | 12 | class TLSOptions { |
| 13 | public: | ||
| 12 | TLSOptions() : schannelTLS1_0Workaround(false) { | 14 | TLSOptions() : schannelTLS1_0Workaround(false) { |
| 13 | 15 | ||
| 14 | } | 16 | } |
| @@ -21,5 +23,44 @@ namespace Swift { | |||
| 21 | */ | 23 | */ |
| 22 | bool schannelTLS1_0Workaround; | 24 | bool schannelTLS1_0Workaround; |
| 23 | 25 | ||
| 26 | /** | ||
| 27 | * OpenSSL configuration flags | ||
| 28 | */ | ||
| 29 | boost::optional<bool> workaroundMicrosoftSessID; | ||
| 30 | boost::optional<bool> workaroundNetscapeChallenge; | ||
| 31 | boost::optional<bool> workaroundNetscapeReuseCipherChange; | ||
| 32 | boost::optional<bool> workaroundSSLRef2ReuseCertType; | ||
| 33 | boost::optional<bool> workaroundMicrosoftBigSSLv3Buffer; | ||
| 34 | boost::optional<bool> workaroundSSLeay080ClientDH; | ||
| 35 | boost::optional<bool> workaroundTLSD5; | ||
| 36 | boost::optional<bool> workaroundTLSBlockPadding; | ||
| 37 | boost::optional<bool> workaroundDontInsertEmptyFragments; | ||
| 38 | boost::optional<bool> workaroundAll; | ||
| 39 | boost::optional<bool> suppressSSLv2; | ||
| 40 | boost::optional<bool> suppressSSLv3; | ||
| 41 | boost::optional<bool> suppressTLSv1; | ||
| 42 | boost::optional<bool> disableTLSRollBackBug; | ||
| 43 | boost::optional<bool> singleDHUse; | ||
| 44 | |||
| 45 | /** | ||
| 46 | * Other OpenSSL configuration items | ||
| 47 | */ | ||
| 48 | boost::optional<std::string> cipherSuites; | ||
| 49 | boost::optional<std::string> context; | ||
| 50 | boost::optional<int> sessionCacheTimeout; | ||
| 51 | boost::optional<int> verifyDepth; | ||
| 52 | |||
| 53 | enum class VerifyMode { | ||
| 54 | NONE, | ||
| 55 | REQUIRED, | ||
| 56 | OPTIONAL | ||
| 57 | } ; | ||
| 58 | boost::optional<VerifyMode> verifyMode; | ||
| 59 | |||
| 60 | /** | ||
| 61 | * Callback for certificate verification | ||
| 62 | */ | ||
| 63 | |||
| 64 | boost::optional<std::function<int(const TLSContext *)>> verifyCertificateCallback; | ||
| 24 | }; | 65 | }; |
| 25 | } | 66 | } |
Swift