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 bb923431f94a9c8d463302ac29f0ed035617a729..206547313cac898555e2890b2458377e22d973c2 100644 |
--- a/net/socket/ssl_client_socket_nss.cc |
+++ b/net/socket/ssl_client_socket_nss.cc |
@@ -570,11 +570,13 @@ class SSLClientSocketNSS::Core : public base::RefCountedThreadSafe<Core> { |
void* arg, |
PRBool* can_false_start); |
- // Called by NSS once the handshake has completed. |
+ // Called by NSS each time a handshake completely finishes. |
// |arg| contains a pointer to the current SSLClientSocketNSS::Core. |
static void HandshakeCallback(PRFileDesc* socket, void* arg); |
- // Called once the handshake has succeeded. |
+ // Called once for each successful handshake. If the initial handshake false |
+ // starts, it is called when it false starts and not when it completely |
+ // finishes. |
void HandshakeSucceeded(); |
// Handles an NSS error generated while handshaking or performing IO. |
@@ -637,6 +639,9 @@ class SSLClientSocketNSS::Core : public base::RefCountedThreadSafe<Core> { |
// Record TLS extension used for protocol negotiation (NPN or ALPN). |
void UpdateExtensionUsed(); |
+ // Returns true if renegotiations are allowed. |
+ bool IsRenegotiationAllowed() const; |
+ |
//////////////////////////////////////////////////////////////////////////// |
// Methods that are ONLY called on the network task runner: |
//////////////////////////////////////////////////////////////////////////// |
@@ -741,7 +746,8 @@ class SSLClientSocketNSS::Core : public base::RefCountedThreadSafe<Core> { |
bool channel_id_needed_; |
// True if the handshake state machine was interrupted for client auth. |
bool client_auth_cert_needed_; |
- // True if NSS has False Started. |
+ // True if NSS has False Started in the initial handshake, but the initial |
+ // handshake has not yet completely finished.. |
bool false_started_; |
// True if NSS has called HandshakeCallback. |
bool handshake_callback_called_; |
@@ -1450,6 +1456,14 @@ int SSLClientSocketNSS::Core::DoHandshake() { |
false_started_ = true; |
HandshakeSucceeded(); |
} |
+ |
+ if (IsRenegotiationAllowed()) { |
+ // For compatibility, do not enforce RFC 5746 support. Per section 4.1, |
+ // enforcement falls largely on the server. |
+ SECStatus rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, |
+ SSL_RENEGOTIATE_TRANSITIONAL); |
+ DCHECK_EQ(SECSuccess, rv); |
+ } |
} else { |
PRErrorCode prerr = PR_GetError(); |
net_error = HandleNSSError(prerr); |
@@ -2121,6 +2135,20 @@ void SSLClientSocketNSS::Core::UpdateExtensionUsed() { |
} |
} |
+bool SSLClientSocketNSS::Core::IsRenegotiationAllowed() const { |
+ DCHECK(OnNSSTaskRunner()); |
+ |
+ if (nss_handshake_state_.next_proto_status == kNextProtoUnsupported) |
+ return ssl_config_.renego_allowed_default; |
+ |
+ NextProto next_proto = NextProtoFromString(nss_handshake_state_.next_proto); |
+ for (NextProto allowed : ssl_config_.renego_allowed_for_protos) { |
+ if (next_proto == allowed) |
+ return true; |
+ } |
+ return false; |
+} |
+ |
void SSLClientSocketNSS::Core::RecordChannelIDSupportOnNSSTaskRunner() { |
DCHECK(OnNSSTaskRunner()); |
if (nss_handshake_state_.resumed_handshake) |
@@ -2792,13 +2820,9 @@ int SSLClientSocketNSS::InitializeSSLOptions() { |
if (rv != SECSuccess) |
LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START"); |
- // We allow servers to request renegotiation. Since we're a client, |
- // prohibiting this is rather a waste of time. Only servers are in a |
- // position to prevent renegotiation attacks. |
- // http://extendedsubset.com/?p=8 |
- |
- rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, |
- SSL_RENEGOTIATE_TRANSITIONAL); |
+ // By default, renegotiations are rejected. After the initial handshake |
+ // completes, some application protocols may re-enable it. |
+ rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_NEVER); |
if (rv != SECSuccess) { |
LogFailedNSSFunction( |
net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION"); |