Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: net/http/http_network_transaction.cc

Issue 1585041: SSL fixes for sites with buggy DEFLATE support. (Closed)
Patch Set: ... Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_network_transaction.h" 5 #include "net/http/http_network_transaction.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/field_trial.h" 8 #include "base/field_trial.h"
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/histogram.h" 10 #include "base/histogram.h"
11 #include "base/scoped_ptr.h" 11 #include "base/scoped_ptr.h"
12 #include "base/stats_counters.h" 12 #include "base/stats_counters.h"
13 #include "base/stl_util-inl.h"
13 #include "base/string_util.h" 14 #include "base/string_util.h"
14 #include "base/trace_event.h" 15 #include "base/trace_event.h"
15 #include "build/build_config.h" 16 #include "build/build_config.h"
16 #include "net/base/connection_type_histograms.h" 17 #include "net/base/connection_type_histograms.h"
17 #include "net/base/io_buffer.h" 18 #include "net/base/io_buffer.h"
18 #include "net/base/load_flags.h" 19 #include "net/base/load_flags.h"
19 #include "net/base/net_errors.h" 20 #include "net/base/net_errors.h"
20 #include "net/base/net_util.h" 21 #include "net/base/net_util.h"
21 #include "net/base/ssl_cert_request_info.h" 22 #include "net/base/ssl_cert_request_info.h"
22 #include "net/base/upload_data_stream.h" 23 #include "net/base/upload_data_stream.h"
(...skipping 18 matching lines...) Expand all
41 42
42 using base::Time; 43 using base::Time;
43 44
44 namespace net { 45 namespace net {
45 46
46 namespace { 47 namespace {
47 48
48 const std::string* g_next_protos = NULL; 49 const std::string* g_next_protos = NULL;
49 bool g_use_alternate_protocols = false; 50 bool g_use_alternate_protocols = false;
50 51
52 // A set of host:port strings. These are servers which we have needed to back
53 // off to SSLv3 for.
54 std::set<std::string>* g_tls_intolerant_servers = NULL;
55
51 void BuildRequestHeaders(const HttpRequestInfo* request_info, 56 void BuildRequestHeaders(const HttpRequestInfo* request_info,
52 const HttpRequestHeaders& authorization_headers, 57 const HttpRequestHeaders& authorization_headers,
53 const UploadDataStream* upload_data_stream, 58 const UploadDataStream* upload_data_stream,
54 bool using_proxy, 59 bool using_proxy,
55 HttpRequestHeaders* request_headers) { 60 HttpRequestHeaders* request_headers) {
56 const std::string path = using_proxy ? 61 const std::string path = using_proxy ?
57 HttpUtil::SpecForRequest(request_info->url) : 62 HttpUtil::SpecForRequest(request_info->url) :
58 HttpUtil::PathForRequest(request_info->url); 63 HttpUtil::PathForRequest(request_info->url);
59 request_headers->SetRequestLine( 64 request_headers->SetRequestLine(
60 request_info->method, path, "1.1"); 65 request_info->method, path, "1.1");
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 alternate_protocol_mode_( 243 alternate_protocol_mode_(
239 g_use_alternate_protocols ? kUnspecified : 244 g_use_alternate_protocols ? kUnspecified :
240 kDoNotUseAlternateProtocol), 245 kDoNotUseAlternateProtocol),
241 embedded_identity_used_(false), 246 embedded_identity_used_(false),
242 default_credentials_used_(false), 247 default_credentials_used_(false),
243 read_buf_len_(0), 248 read_buf_len_(0),
244 next_state_(STATE_NONE) { 249 next_state_(STATE_NONE) {
245 session->ssl_config_service()->GetSSLConfig(&ssl_config_); 250 session->ssl_config_service()->GetSSLConfig(&ssl_config_);
246 if (g_next_protos) 251 if (g_next_protos)
247 ssl_config_.next_protos = *g_next_protos; 252 ssl_config_.next_protos = *g_next_protos;
253 if (!g_tls_intolerant_servers)
254 g_tls_intolerant_servers = new std::set<std::string>;
248 } 255 }
249 256
250 // static 257 // static
251 void HttpNetworkTransaction::SetUseAlternateProtocols(bool value) { 258 void HttpNetworkTransaction::SetUseAlternateProtocols(bool value) {
252 g_use_alternate_protocols = value; 259 g_use_alternate_protocols = value;
253 } 260 }
254 261
255 // static 262 // static
256 void HttpNetworkTransaction::SetNextProtos(const std::string& next_protos) { 263 void HttpNetworkTransaction::SetNextProtos(const std::string& next_protos) {
257 delete g_next_protos; 264 delete g_next_protos;
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 establishing_tunnel_ = true; 845 establishing_tunnel_ = true;
839 } 846 }
840 } 847 }
841 848
842 return OK; 849 return OK;
843 } 850 }
844 851
845 int HttpNetworkTransaction::DoSSLConnect() { 852 int HttpNetworkTransaction::DoSSLConnect() {
846 next_state_ = STATE_SSL_CONNECT_COMPLETE; 853 next_state_ = STATE_SSL_CONNECT_COMPLETE;
847 854
855 if (ContainsKey(*g_tls_intolerant_servers, GetHostAndPort(request_->url))) {
856 LOG(WARNING) << "Falling back to SSLv3 because host is TLS intolerant: "
857 << GetHostAndPort(request_->url);
858 ssl_config_.tls1_enabled = false;
859 }
860
848 if (request_->load_flags & LOAD_VERIFY_EV_CERT) 861 if (request_->load_flags & LOAD_VERIFY_EV_CERT)
849 ssl_config_.verify_ev_cert = true; 862 ssl_config_.verify_ev_cert = true;
850 863
851 ssl_connect_start_time_ = base::TimeTicks::Now(); 864 ssl_connect_start_time_ = base::TimeTicks::Now();
852 865
853 // Add a SSL socket on top of our existing transport socket. 866 // Add a SSL socket on top of our existing transport socket.
854 ClientSocket* s = connection_->release_socket(); 867 ClientSocket* s = connection_->release_socket();
855 s = session_->socket_factory()->CreateSSLClientSocket( 868 s = session_->socket_factory()->CreateSSLClientSocket(
856 s, request_->url.HostNoBrackets(), ssl_config_); 869 s, request_->url.HostNoBrackets(), ssl_config_);
857 connection_->set_socket(s); 870 connection_->set_socket(s);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 // We don't handle a certificate error during SSL renegotiation, so we 1028 // We don't handle a certificate error during SSL renegotiation, so we
1016 // have to return an error that's not in the certificate error range 1029 // have to return an error that's not in the certificate error range
1017 // (-2xx). 1030 // (-2xx).
1018 LOG(ERROR) << "Got a server certificate with error " << result 1031 LOG(ERROR) << "Got a server certificate with error " << result
1019 << " during SSL renegotiation"; 1032 << " during SSL renegotiation";
1020 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION; 1033 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION;
1021 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 1034 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
1022 result = HandleCertificateRequest(result); 1035 result = HandleCertificateRequest(result);
1023 if (result == OK) 1036 if (result == OK)
1024 return result; 1037 return result;
1038 } else if (result == ERR_SSL_DECOMPRESSION_FAILURE_ALERT &&
1039 ssl_config_.tls1_enabled) {
1040 // Some buggy servers select DEFLATE compression when offered and then
1041 // fail to ever decompress anything. They will send a fatal alert telling
1042 // us this. Normally we would pick this up during the handshake because
1043 // our Finished message is compressed and we'll never get the server's
1044 // Finished if it fails to process ours.
1045 //
1046 // However, with False Start, we'll believe that the handshake is
1047 // complete as soon as we've /sent/ our Finished message. In this case,
1048 // we only find out that the server is buggy here, when we try to read
1049 // the initial reply.
1050 g_tls_intolerant_servers->insert(GetHostAndPort(request_->url));
1051 ResetConnectionAndRequestForResend();
1052 return OK;
1025 } 1053 }
1026 } 1054 }
1027 1055
1028 if (result < 0 && result != ERR_CONNECTION_CLOSED) 1056 if (result < 0 && result != ERR_CONNECTION_CLOSED)
1029 return HandleIOError(result); 1057 return HandleIOError(result);
1030 1058
1031 if (result == ERR_CONNECTION_CLOSED && ShouldResendRequest(result)) { 1059 if (result == ERR_CONNECTION_CLOSED && ShouldResendRequest(result)) {
1032 ResetConnectionAndRequestForResend(); 1060 ResetConnectionAndRequestForResend();
1033 return OK; 1061 return OK;
1034 } 1062 }
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { 1543 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
1516 if (ssl_config_.send_client_cert && 1544 if (ssl_config_.send_client_cert &&
1517 (error == ERR_SSL_PROTOCOL_ERROR || 1545 (error == ERR_SSL_PROTOCOL_ERROR ||
1518 error == ERR_BAD_SSL_CLIENT_AUTH_CERT)) { 1546 error == ERR_BAD_SSL_CLIENT_AUTH_CERT)) {
1519 session_->ssl_client_auth_cache()->Remove(GetHostAndPort(request_->url)); 1547 session_->ssl_client_auth_cache()->Remove(GetHostAndPort(request_->url));
1520 } 1548 }
1521 1549
1522 switch (error) { 1550 switch (error) {
1523 case ERR_SSL_PROTOCOL_ERROR: 1551 case ERR_SSL_PROTOCOL_ERROR:
1524 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH: 1552 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
1553 case ERR_SSL_DECOMPRESSION_FAILURE_ALERT:
1525 if (ssl_config_.tls1_enabled) { 1554 if (ssl_config_.tls1_enabled) {
1526 // This could be a TLS-intolerant server or an SSL 3.0 server that 1555 // This could be a TLS-intolerant server or an SSL 3.0 server that
1527 // chose a TLS-only cipher suite. Turn off TLS 1.0 and retry. 1556 // chose a TLS-only cipher suite. Turn off TLS 1.0 and retry.
1528 ssl_config_.tls1_enabled = false; 1557 g_tls_intolerant_servers->insert(GetHostAndPort(request_->url));
1529 connection_->socket()->Disconnect(); 1558 ResetConnectionAndRequestForResend();
1530 connection_->Reset();
1531 next_state_ = STATE_INIT_CONNECTION;
1532 error = OK; 1559 error = OK;
1533 } 1560 }
1534 break; 1561 break;
1535 } 1562 }
1536 return error; 1563 return error;
1537 } 1564 }
1538 1565
1539 // This method determines whether it is safe to resend the request after an 1566 // This method determines whether it is safe to resend the request after an
1540 // IO error. It can only be called in response to request header or body 1567 // IO error. It can only be called in response to request header or body
1541 // write errors or response header read errors. It should not be used in 1568 // write errors or response header read errors. It should not be used in
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 http_host_port_pair); 1999 http_host_port_pair);
1973 2000
1974 alternate_protocol_mode_ = kDoNotUseAlternateProtocol; 2001 alternate_protocol_mode_ = kDoNotUseAlternateProtocol;
1975 if (connection_->socket()) 2002 if (connection_->socket())
1976 connection_->socket()->Disconnect(); 2003 connection_->socket()->Disconnect();
1977 connection_->Reset(); 2004 connection_->Reset();
1978 next_state_ = STATE_INIT_CONNECTION; 2005 next_state_ = STATE_INIT_CONNECTION;
1979 } 2006 }
1980 2007
1981 } // namespace net 2008 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698