summaryrefslogtreecommitdiffstats
path: root/net/socket
diff options
context:
space:
mode:
authorsergeyu <sergeyu@chromium.org>2015-06-16 13:43:04 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-16 20:44:40 +0000
commit0144249b934d0869a20a69931e6ec261c5cb27da (patch)
treed65e092a722c22ef42bc0fd0671c70acf1d9ea12 /net/socket
parent5e21faa01fbaa436ce253f2cdcf2b384b744d10a (diff)
downloadchromium_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.cc16
-rw-r--r--net/socket/ssl_client_socket_openssl.cc13
-rw-r--r--net/socket/ssl_client_socket_unittest.cc31
-rw-r--r--net/socket/ssl_server_socket_nss.cc3
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)) ==