Use SSL_get_cipher_by_value to disable cipher suites.
The old logic was rather messy due to OpenSSL being unable to look up ciphers
by ID. BoringSSL, however, has a perfectly reasonable function to look up
cipher suites by value. Clean up the logic to not rely on SSL_get_ciphers. This
fixes a bug where TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 was not blacklistable
by command-line; at the time the blacklist code ran,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 is not in the list.
BUG=542322
Review URL: https://codereview.chromium.org/1395393002
Cr-Commit-Position: refs/heads/master@{#353566}
diff --git a/net/socket/ssl_server_socket_openssl.cc b/net/socket/ssl_server_socket_openssl.cc
index 5a61eeb..e8cbf5b 100644
--- a/net/socket/ssl_server_socket_openssl.cc
+++ b/net/socket/ssl_server_socket_openssl.cc
@@ -681,38 +681,21 @@
SSL_set_mode(ssl_, mode.set_mask);
SSL_clear_mode(ssl_, mode.clear_mask);
- // Removing ciphers by ID from OpenSSL is a bit involved as we must use the
- // textual name with SSL_set_cipher_list because there is no public API to
- // directly remove a cipher by ID.
- STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl_);
- DCHECK(ciphers);
// See SSLConfig::disabled_cipher_suites for description of the suites
// 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:!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_t id = static_cast<uint16_t>(SSL_CIPHER_get_id(cipher));
- 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) != ssl_config_.disabled_cipher_suites.end();
- }
- if (disable) {
- const char* name = SSL_CIPHER_get_name(cipher);
- DVLOG(3) << "Found cipher to remove: '" << name << "', ID: " << id
- << " strength: " << SSL_CIPHER_get_bits(cipher, NULL);
+ if (ssl_config_.require_ecdhe)
+ command.append(":!kRSA:!kDHE");
+
+ // Remove any disabled ciphers.
+ for (uint16_t id : ssl_config_.disabled_cipher_suites) {
+ const SSL_CIPHER* cipher = SSL_get_cipher_by_value(id);
+ if (cipher) {
command.append(":!");
- command.append(name);
+ command.append(SSL_CIPHER_get_name(cipher));
}
}