diff options
author | sergeyu <sergeyu@chromium.org> | 2015-06-16 13:43:04 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-16 20:44:40 +0000 |
commit | 0144249b934d0869a20a69931e6ec261c5cb27da (patch) | |
tree | d65e092a722c22ef42bc0fd0671c70acf1d9ea12 /net/socket | |
parent | 5e21faa01fbaa436ce253f2cdcf2b384b744d10a (diff) | |
download | chromium_src-0144249b934d0869a20a69931e6ec261c5cb27da.zip chromium_src-0144249b934d0869a20a69931e6ec261c5cb27da.tar.gz chromium_src-0144249b934d0869a20a69931e6ec261c5cb27da.tar.bz2 |
Require ECDHE cipher in remoting client.
Also added support for enable_ecdhe flag in SSLClientSocketOpenSSL and
SSLClientSocketNSS. It's not really needed with NSS as the client
is only compiled with BoringSSL, but added it anyway for consistency.
BUG=481163
Review URL: https://codereview.chromium.org/1191623002
Cr-Commit-Position: refs/heads/master@{#334684}
Diffstat (limited to 'net/socket')
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 16 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_openssl.cc | 13 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_unittest.cc | 31 | ||||
-rw-r--r-- | net/socket/ssl_server_socket_nss.cc | 3 |
4 files changed, 54 insertions, 9 deletions
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index a1abc62..3633c17 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -2761,6 +2761,22 @@ int SSLClientSocketNSS::InitializeSSLOptions() { return ERR_NO_SSL_VERSIONS_ENABLED; } + if (ssl_config_.require_ecdhe) { + const PRUint16* const ssl_ciphers = SSL_GetImplementedCiphers(); + const PRUint16 num_ciphers = SSL_GetNumImplementedCiphers(); + + // Iterate over the cipher suites and disable those that don't use ECDHE. + for (unsigned i = 0; i < num_ciphers; i++) { + SSLCipherSuiteInfo info; + if (SSL_GetCipherSuiteInfo(ssl_ciphers[i], &info, sizeof(info)) == + SECSuccess) { + if (strcmp(info.keaTypeName, "ECDHE") != 0) { + SSL_CipherPrefSet(nss_fd_, ssl_ciphers[i], PR_FALSE); + } + } + } + } + if (ssl_config_.version_fallback) { rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALLBACK_SCSV, PR_TRUE); if (rv != SECSuccess) { diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc index ba47b97..4efaf7e 100644 --- a/net/socket/ssl_client_socket_openssl.cc +++ b/net/socket/ssl_client_socket_openssl.cc @@ -765,18 +765,17 @@ int SSLClientSocketOpenSSL::Init() { // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256 // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384 // as the handshake hash. - std::string command( - "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK"); + std::string command("DEFAULT:!SHA256:!SHA384:!AESGCM+AES256:!aPSK"); // Walk through all the installed ciphers, seeing if any need to be // appended to the cipher removal |command|. for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) { const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i); const uint16 id = static_cast<uint16>(SSL_CIPHER_get_id(cipher)); - // Remove any ciphers with a strength of less than 80 bits. Note the NSS - // implementation uses "effective" bits here but OpenSSL does not provide - // this detail. This only impacts Triple DES: reports 112 vs. 168 bits, - // both of which are greater than 80 anyway. - bool disable = SSL_CIPHER_get_bits(cipher, NULL) < 80; + bool disable = false; + if (ssl_config_.require_ecdhe) { + base::StringPiece kx_name(SSL_CIPHER_get_kx_name(cipher)); + disable = kx_name != "ECDHE_RSA" && kx_name != "ECDHE_ECDSA"; + } if (!disable) { disable = std::find(ssl_config_.disabled_cipher_suites.begin(), ssl_config_.disabled_cipher_suites.end(), id) != diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index 62b52df..c93473f 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc @@ -3105,6 +3105,37 @@ TEST_F(SSLClientSocketTest, DeprecatedShardSessionCache) { EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type); } +TEST_F(SSLClientSocketTest, RequireECDHE) { + // Run test server without ECDHE. + SpawnedTestServer::SSLOptions ssl_options; + ssl_options.key_exchanges = SpawnedTestServer::SSLOptions::KEY_EXCHANGE_RSA; + SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, ssl_options, + base::FilePath()); + ASSERT_TRUE(test_server.Start()); + + AddressList addr; + ASSERT_TRUE(test_server.GetAddressList(&addr)); + + TestCompletionCallback callback; + TestNetLog log; + scoped_ptr<StreamSocket> transport( + new TCPClientSocket(addr, &log, NetLog::Source())); + int rv = transport->Connect(callback.callback()); + rv = callback.GetResult(rv); + EXPECT_EQ(OK, rv); + + SSLConfig config; + config.require_ecdhe = true; + + scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( + transport.Pass(), test_server.host_port_pair(), config)); + + rv = sock->Connect(callback.callback()); + rv = callback.GetResult(rv); + + EXPECT_EQ(ERR_SSL_VERSION_OR_CIPHER_MISMATCH, rv); +} + TEST_F(SSLClientSocketFalseStartTest, FalseStartEnabled) { if (!SupportsAESGCM()) { LOG(WARNING) << "Skipping test because AES-GCM is not supported."; diff --git a/net/socket/ssl_server_socket_nss.cc b/net/socket/ssl_server_socket_nss.cc index 4483c91..c48c04c 100644 --- a/net/socket/ssl_server_socket_nss.cc +++ b/net/socket/ssl_server_socket_nss.cc @@ -357,8 +357,7 @@ int SSLServerSocketNSS::InitializeSSLOptions() { const PRUint16* const ssl_ciphers = SSL_GetImplementedCiphers(); const PRUint16 num_ciphers = SSL_GetNumImplementedCiphers(); - // Require forward security by iterating over the cipher suites and - // disabling all those that don't use ECDHE. + // Iterate over the cipher suites and disable those that don't use ECDHE. for (unsigned i = 0; i < num_ciphers; i++) { SSLCipherSuiteInfo info; if (SSL_GetCipherSuiteInfo(ssl_ciphers[i], &info, sizeof(info)) == |