diff options
author | wtc@google.com <wtc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-08 17:28:23 +0000 |
---|---|---|
committer | wtc@google.com <wtc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-08 17:28:23 +0000 |
commit | c5949a3000ca3d6a7bd3a400ebd89206835a740a (patch) | |
tree | 19e5d48d1eab7fdeff3a9f443eead80bd17edb00 /net/http | |
parent | db8d02d65496004718bcd0416fcb35326eb08cd5 (diff) | |
download | chromium_src-c5949a3000ca3d6a7bd3a400ebd89206835a740a.zip chromium_src-c5949a3000ca3d6a7bd3a400ebd89206835a740a.tar.gz chromium_src-c5949a3000ca3d6a7bd3a400ebd89206835a740a.tar.bz2 |
Handle TLS-intolerant servers by retrying with TLS 1.0
turned off.
R=darin
BUG=3001
Review URL: http://codereview.chromium.org/5617
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3017 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r-- | net/http/http_network_transaction.cc | 33 | ||||
-rw-r--r-- | net/http/http_network_transaction.h | 7 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 3 |
3 files changed, 39 insertions, 4 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index c391dae..de3539317 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -58,6 +58,12 @@ HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session, read_buf_(NULL), read_buf_len_(0), next_state_(STATE_NONE) { +#if defined(OS_WIN) + // TODO(wtc): Use SSL settings (bug 3003). + ssl_version_mask_ = SSLClientSocket::SSL3 | SSLClientSocket::TLS1; +#else + ssl_version_mask_ = 0; // A dummy value so that the code compiles. +#endif } void HttpNetworkTransaction::Destroy() { @@ -483,7 +489,8 @@ int HttpNetworkTransaction::DoConnect() { // If we are using a direct SSL connection, then go ahead and create the SSL // wrapper socket now. Otherwise, we need to first issue a CONNECT request. if (using_ssl_ && !using_tunnel_) - s = socket_factory_->CreateSSLClientSocket(s, request_->url.host()); + s = socket_factory_->CreateSSLClientSocket(s, request_->url.host(), + ssl_version_mask_); connection_.set_socket(s); return connection_.socket()->Connect(&io_callback_); @@ -497,6 +504,8 @@ int HttpNetworkTransaction::DoConnectComplete(int result) { next_state_ = STATE_WRITE_HEADERS; if (using_tunnel_) establishing_tunnel_ = true; + } else if (result == ERR_SSL_PROTOCOL_ERROR) { + result = HandleSSLHandshakeError(result); } else { result = ReconsiderProxyAfterError(result); } @@ -508,7 +517,8 @@ int HttpNetworkTransaction::DoSSLConnectOverTunnel() { // Add a SSL socket on top of our existing transport socket. ClientSocket* s = connection_.release_socket(); - s = socket_factory_->CreateSSLClientSocket(s, request_->url.host()); + s = socket_factory_->CreateSSLClientSocket(s, request_->url.host(), + ssl_version_mask_); connection_.set_socket(s); return connection_.socket()->Connect(&io_callback_); } @@ -517,8 +527,11 @@ int HttpNetworkTransaction::DoSSLConnectOverTunnelComplete(int result) { if (IsCertificateError(result)) result = HandleCertificateError(result); - if (result == OK) + if (result == OK) { next_state_ = STATE_WRITE_HEADERS; + } else if (result == ERR_SSL_PROTOCOL_ERROR) { + result = HandleSSLHandshakeError(result); + } return result; } @@ -874,6 +887,20 @@ int HttpNetworkTransaction::HandleCertificateError(int error) { return error; } +int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { +#if defined(OS_WIN) + if (ssl_version_mask_ & SSLClientSocket::TLS1) { + // This could be a TLS-intolerant server. Turn off TLS 1.0 and retry. + ssl_version_mask_ &= ~SSLClientSocket::TLS1; + connection_.set_socket(NULL); + connection_.Reset(); + next_state_ = STATE_INIT_CONNECTION; + error = OK; + } +#endif + return error; +} + // This method determines whether it is safe to resend the request after an // IO error. It can only be called in response to request header or body // write errors or response header read errors. It should not be used in diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index 2414050..bbbfb74 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -84,6 +84,11 @@ class HttpNetworkTransaction : public HttpTransaction { // returns the same error code. int HandleCertificateError(int error); + // Called to possibly recover from an SSL handshake error. Sets next_state_ + // and returns OK if recovering from the error. Otherwise, the same error + // code is returned. + int HandleSSLHandshakeError(int error); + // Called to possibly recover from the given error. Sets next_state_ and // returns OK if recovering from the error. Otherwise, the same error code // is returned. @@ -181,6 +186,8 @@ class HttpNetworkTransaction : public HttpTransaction { // the real request/response of the transaction. bool establishing_tunnel_; + int ssl_version_mask_; + std::string request_headers_; size_t request_headers_bytes_sent_; scoped_ptr<UploadDataStream> request_body_stream_; diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 8cfe348..b0d1964 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -158,7 +158,8 @@ class MockClientSocketFactory : public net::ClientSocketFactory { } virtual net::ClientSocket* CreateSSLClientSocket( net::ClientSocket* transport_socket, - const std::string& hostname) { + const std::string& hostname, + int protocol_version_mask) { return NULL; } }; |