| Index: net/socket/ssl_client_socket_nss.cc
|
| diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
|
| index 4397ad65e82c5371d265e0014ffc89a1510f334d..16d09aaae4675bb0aac65f0dca7c44b8de50ddb0 100644
|
| --- a/net/socket/ssl_client_socket_nss.cc
|
| +++ b/net/socket/ssl_client_socket_nss.cc
|
| @@ -3473,6 +3473,40 @@ int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
|
| }
|
| #endif
|
|
|
| + // Persist the negotiated SSL version if it is newer than the minimum
|
| + // version. This is used to prevent SSLv3 fallback for domains known
|
| + // to support TLS.
|
| +
|
| + // Note: this is effective only for non-preloaded HSTS hosts.
|
| +
|
| + // TODO(thaidn): determine if the negotiated version is authenticated
|
| + // at this point. Chrome must not use it if it isn't; otherwise MITM
|
| + // attackers can perform a permanent DoS attack against users by setting
|
| + // the version to TLSv1.2 for non-TLSv1.2 servers.
|
| + if (transport_security_state_ &&
|
| + result == OK) {
|
| + bool sni_available =
|
| + ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1 ||
|
| + ssl_config_.version_fallback;
|
| + const std::string& host = host_and_port_.host();
|
| + TransportSecurityState::DomainState domain_state;
|
| +
|
| + if (transport_security_state_->GetDomainState(host, sni_available,
|
| + &domain_state)) {
|
| + // Update the minimum version of existing |domain_state| if necessary.
|
| + int ssl_version = SSLConnectionStatusToVersion(
|
| + core_->state().ssl_connection_status);
|
| + if (ssl_version > SSL_CONNECTION_VERSION_UNKNOWN &&
|
| + ssl_version < SSL_CONNECTION_VERSION_MAX &&
|
| + ssl_version > domain_state.ssl_version_min) {
|
| + domain_state.ssl_version_min =
|
| + static_cast<SSL_CONNECTION_VERSION>(ssl_version);
|
| + }
|
| + }
|
| + // Note: the default value of |domain_state.ssl_version_min| is SSLv3.
|
| + transport_security_state_->EnableHost(host, domain_state);
|
| + }
|
| +
|
| // Exit DoHandshakeLoop and return the result to the caller to Connect.
|
| DCHECK_EQ(STATE_NONE, next_handshake_state_);
|
| return result;
|
|
|