summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Cooper <adam.cooper@mongodb.com>2020-07-02 16:06:32 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-07-14 21:30:49 +0000
commitc02d19aebdba13451d576f56885e3358dad90e48 (patch)
tree6fd3d3ca3c71455e608b9a280ad30df8e38bef84
parentd3430cddfc340f76ac71a58587a1a14c6c506b05 (diff)
downloadmongo-c02d19aebdba13451d576f56885e3358dad90e48.tar.gz
SERVER-48774 setting cipher list does not work for TLSv1.3 only (if TLS1_0, TLS1_1, TLS1_2 are disabled)
-rw-r--r--jstests/ssl/openssl_ciphersuites.js58
-rw-r--r--src/mongo/util/net/ssl_manager_openssl.cpp22
-rw-r--r--src/mongo/util/net/ssl_options.h11
-rw-r--r--src/mongo/util/net/ssl_parameters.idl5
4 files changed, 91 insertions, 5 deletions
diff --git a/jstests/ssl/openssl_ciphersuites.js b/jstests/ssl/openssl_ciphersuites.js
new file mode 100644
index 00000000000..770a8fb8c54
--- /dev/null
+++ b/jstests/ssl/openssl_ciphersuites.js
@@ -0,0 +1,58 @@
+// Test setParameter sslCipherSuitesConfig for TLS 1.3
+// sslCipherSuitesConfig allows the user to set the list of cipher suites for just TLS 1.3
+
+(function() {
+"use strict";
+load("jstests/ssl/libs/ssl_helpers.js");
+
+// Short circuits for system configurations that do not support this setParameter, (i.e. OpenSSL
+// that don't support TLS 1.3)
+if (determineSSLProvider() !== "openssl") {
+ jsTestLog("SSL provider is not OpenSSL; skipping test.");
+ return;
+} else if (detectDefaultTLSProtocol() !== "TLS1_3") {
+ jsTestLog("Platform does not support TLS 1.3; skipping test.");
+ return;
+}
+
+const baseParams = {
+ tlsMode: "requireTLS",
+ tlsCertificateKeyFile: "jstests/libs/server.pem",
+ tlsCAFile: "jstests/ssl/x509/root-and-trusted-ca.pem",
+ waitForConnect: false,
+};
+
+function testConn() {
+ const mongo = runMongoProgram('mongo',
+ '--host',
+ 'localhost',
+ '--port',
+ mongod.port,
+ '--tls',
+ '--tlsCAFile',
+ 'jstests/libs/ca.pem',
+ '--tlsCertificateKeyFile',
+ 'jstests/libs/trusted-client.pem',
+ '--eval',
+ ';');
+ return mongo === 0;
+}
+
+// test a successful connection when setting cipher suites
+jsTestLog("Testing for successful connection with valid cipher suite config");
+let mongod = MongoRunner.runMongod(
+ Object.merge(baseParams, {setParameter: {opensslCipherSuiteConfig: "TLS_AES_256_GCM_SHA384"}}));
+assert.soon(testConn, "Client could not connect to server with valid ciphersuite config.");
+MongoRunner.stopMongod(mongod);
+
+// test an unsuccessful connection when mandating a cipher suite which OpenSSL disables by default
+jsTestLog(
+ "Testing for unsuccessful connection with cipher suite config which OpenSSL disables by default.");
+mongod = MongoRunner.runMongod(Object.merge(
+ baseParams, {setParameter: {opensslCipherSuiteConfig: "TLS_AES_128_CCM_8_SHA256"}}));
+sleep(30000);
+
+assert.eq(
+ false, testConn(), "Client successfully connected to server with invalid ciphersuite config.");
+MongoRunner.stopMongod(mongod);
+})(); \ No newline at end of file
diff --git a/src/mongo/util/net/ssl_manager_openssl.cpp b/src/mongo/util/net/ssl_manager_openssl.cpp
index a1b93c0dd17..00a30700712 100644
--- a/src/mongo/util/net/ssl_manager_openssl.cpp
+++ b/src/mongo/util/net/ssl_manager_openssl.cpp
@@ -51,6 +51,7 @@
#include "mongo/logv2/log.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/transport/session.h"
+#include "mongo/util/assert_util.h"
#include "mongo/util/concurrency/mutex.h"
#include "mongo/util/debug_util.h"
#include "mongo/util/exit.h"
@@ -86,6 +87,15 @@
#include <openssl/ec.h>
#endif
+#if OPENSSL_VERSION_NUMBER < 0x1010100FL
+int SSL_CTX_set_ciphersuites(SSL_CTX*, const char*) {
+ uasserted(
+ 4877400,
+ "Setting OpenSSL cipher suites is not allowed for OpenSSL versions older than 1.1.1.");
+ return 0;
+}
+#endif
+
namespace mongo {
namespace {
@@ -1883,6 +1893,18 @@ Status SSLManagerOpenSSL::initSSLContext(SSL_CTX* context,
<< "\": " << getSSLErrorMessage(ERR_get_error()));
}
+ if (!params.sslCipherSuiteConfig.empty()) {
+ // OpenSSL versions older than version 1.1.1 are not allowed to configure their cipher
+ // suites using the sslCipherSuiteConfig flag.
+ if (0 == ::SSL_CTX_set_ciphersuites(context, params.sslCipherSuiteConfig.c_str())) {
+ return Status(ErrorCodes::InvalidSSLConfiguration,
+ str::stream()
+ << "Can not set supported cipher suites with config string \""
+ << params.sslCipherSuiteConfig
+ << "\": " << getSSLErrorMessage(ERR_get_error()));
+ }
+ }
+
// We use the address of the context as the session id context.
if (0 ==
::SSL_CTX_set_session_id_context(
diff --git a/src/mongo/util/net/ssl_options.h b/src/mongo/util/net/ssl_options.h
index 0052519c29b..aa7aff1451d 100644
--- a/src/mongo/util/net/ssl_options.h
+++ b/src/mongo/util/net/ssl_options.h
@@ -65,11 +65,12 @@ struct SSLParams {
std::string sslPEMKeyFile; // --tlsCertificateKeyFile
std::string sslPEMKeyPassword; // --tlsCertificateKeyFilePassword
std::string sslClusterFile; // --tlsInternalKeyFile
- std::string sslClusterPassword; // --tlsInternalKeyPassword
- std::string sslCAFile; // --tlsCAFile
- std::string sslClusterCAFile; // --tlsClusterCAFile
- std::string sslCRLFile; // --tlsCRLFile
- std::string sslCipherConfig; // --tlsCipherConfig
+ std::string sslClusterPassword; // --tlsInternalKeyPassword
+ std::string sslCAFile; // --tlsCAFile
+ std::string sslClusterCAFile; // --tlsClusterCAFile
+ std::string sslCRLFile; // --tlsCRLFile
+ std::string sslCipherConfig; // --tlsCipherConfig
+ std::string sslCipherSuiteConfig; // --tlsCipherSuiteConfig
boost::optional<TLSCATrusts> tlsCATrusts; // --setParameter tlsCATrusts
diff --git a/src/mongo/util/net/ssl_parameters.idl b/src/mongo/util/net/ssl_parameters.idl
index e920f358f08..1123f04f5a0 100644
--- a/src/mongo/util/net/ssl_parameters.idl
+++ b/src/mongo/util/net/ssl_parameters.idl
@@ -110,6 +110,11 @@ server_parameters:
validator:
callback: "validateOpensslCipherConfig"
+ opensslCipherSuiteConfig:
+ description: "Cipher configuration string for OpenSSL based connections that use TLS 1.3 or newer ONLY"
+ set_at: startup
+ cpp_varname: "sslGlobalParams.sslCipherSuiteConfig"
+
disableNonTLSConnectionLogging:
deprecated_name: "disableNonSSLConnectionLogging"
description: "Suppress logging of warnings when non-SSL connections are accepted in preferSSL mode"