Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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/scoped_ptr.h" | 7 #include "base/scoped_ptr.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/field_trial.h" | 9 #include "base/field_trial.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 int rv = DoLoop(OK); | 186 int rv = DoLoop(OK); |
| 187 if (rv == ERR_IO_PENDING) | 187 if (rv == ERR_IO_PENDING) |
| 188 user_callback_ = callback; | 188 user_callback_ = callback; |
| 189 return rv; | 189 return rv; |
| 190 } | 190 } |
| 191 | 191 |
| 192 int HttpNetworkTransaction::RestartWithCertificate( | 192 int HttpNetworkTransaction::RestartWithCertificate( |
| 193 X509Certificate* client_cert, | 193 X509Certificate* client_cert, |
| 194 CompletionCallback* callback) { | 194 CompletionCallback* callback) { |
| 195 ssl_config_.client_cert = client_cert; | 195 ssl_config_.client_cert = client_cert; |
| 196 if (client_cert) { | |
| 197 session_->ssl_client_auth_cache()->Add(GetHostAndPort(request_->url), | |
| 198 client_cert); | |
| 199 } | |
| 196 ssl_config_.send_client_cert = true; | 200 ssl_config_.send_client_cert = true; |
| 197 next_state_ = STATE_INIT_CONNECTION; | 201 next_state_ = STATE_INIT_CONNECTION; |
| 198 // Reset the other member variables. | 202 // Reset the other member variables. |
| 199 // Note: this is necessary only with SSL renegotiation. | 203 // Note: this is necessary only with SSL renegotiation. |
| 200 ResetStateForRestart(); | 204 ResetStateForRestart(); |
| 201 int rv = DoLoop(OK); | 205 int rv = DoLoop(OK); |
| 202 if (rv == ERR_IO_PENDING) | 206 if (rv == ERR_IO_PENDING) |
| 203 user_callback_ = callback; | 207 user_callback_ = callback; |
| 204 return rv; | 208 return rv; |
| 205 } | 209 } |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 627 return connection_.socket()->Connect(&io_callback_); | 631 return connection_.socket()->Connect(&io_callback_); |
| 628 } | 632 } |
| 629 | 633 |
| 630 int HttpNetworkTransaction::DoSSLConnectComplete(int result) { | 634 int HttpNetworkTransaction::DoSSLConnectComplete(int result) { |
| 631 if (IsCertificateError(result)) | 635 if (IsCertificateError(result)) |
| 632 result = HandleCertificateError(result); | 636 result = HandleCertificateError(result); |
| 633 | 637 |
| 634 if (result == OK) { | 638 if (result == OK) { |
| 635 next_state_ = STATE_WRITE_HEADERS; | 639 next_state_ = STATE_WRITE_HEADERS; |
| 636 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 640 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| 637 HandleCertificateRequest(); | 641 result = HandleCertificateRequest(result); |
| 638 } else { | 642 } else { |
| 639 result = HandleSSLHandshakeError(result); | 643 result = HandleSSLHandshakeError(result); |
| 640 } | 644 } |
| 641 return result; | 645 return result; |
| 642 } | 646 } |
| 643 | 647 |
| 644 int HttpNetworkTransaction::DoWriteHeaders() { | 648 int HttpNetworkTransaction::DoWriteHeaders() { |
| 645 next_state_ = STATE_WRITE_HEADERS_COMPLETE; | 649 next_state_ = STATE_WRITE_HEADERS_COMPLETE; |
| 646 | 650 |
| 647 // This is constructed lazily (instead of within our Start method), so that | 651 // This is constructed lazily (instead of within our Start method), so that |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 782 // due to SSL renegotiation. | 786 // due to SSL renegotiation. |
| 783 if (using_ssl_) { | 787 if (using_ssl_) { |
| 784 if (IsCertificateError(result)) { | 788 if (IsCertificateError(result)) { |
| 785 // We don't handle a certificate error during SSL renegotiation, so we | 789 // We don't handle a certificate error during SSL renegotiation, so we |
| 786 // have to return an error that's not in the certificate error range | 790 // have to return an error that's not in the certificate error range |
| 787 // (-2xx). | 791 // (-2xx). |
| 788 LOG(ERROR) << "Got a server certificate with error " << result | 792 LOG(ERROR) << "Got a server certificate with error " << result |
| 789 << " during SSL renegotiation"; | 793 << " during SSL renegotiation"; |
| 790 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION; | 794 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION; |
| 791 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | 795 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { |
| 792 HandleCertificateRequest(); | 796 result = HandleCertificateRequest(result); |
| 797 if (result == OK) | |
| 798 return result; | |
| 793 } | 799 } |
| 794 } | 800 } |
| 795 | 801 |
| 796 if (result < 0) | 802 if (result < 0) |
| 797 return HandleIOError(result); | 803 return HandleIOError(result); |
| 798 | 804 |
| 799 if (result == 0 && ShouldResendRequest()) { | 805 if (result == 0 && ShouldResendRequest()) { |
| 800 ResetConnectionAndRequestForResend(); | 806 ResetConnectionAndRequestForResend(); |
| 801 return result; | 807 return result; |
| 802 } | 808 } |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1248 | 1254 |
| 1249 // Add the bad certificate to the set of allowed certificates in the | 1255 // Add the bad certificate to the set of allowed certificates in the |
| 1250 // SSL info object. This data structure will be consulted after calling | 1256 // SSL info object. This data structure will be consulted after calling |
| 1251 // RestartIgnoringLastError(). And the user will be asked interactively | 1257 // RestartIgnoringLastError(). And the user will be asked interactively |
| 1252 // before RestartIgnoringLastError() is ever called. | 1258 // before RestartIgnoringLastError() is ever called. |
| 1253 ssl_config_.allowed_bad_certs_.insert(response_.ssl_info.cert); | 1259 ssl_config_.allowed_bad_certs_.insert(response_.ssl_info.cert); |
| 1254 } | 1260 } |
| 1255 return error; | 1261 return error; |
| 1256 } | 1262 } |
| 1257 | 1263 |
| 1258 void HttpNetworkTransaction::HandleCertificateRequest() { | 1264 int HttpNetworkTransaction::HandleCertificateRequest(int error) { |
| 1265 // Assert that the socket did not send a client certificate. | |
| 1266 // Note: If we got a reused socket, it was created with some other | |
| 1267 // transaction's ssl_config_, so we need to disable this assertion. We can | |
| 1268 // get a certificate request on a reused socket when the server requested | |
| 1269 // renegotiation (rehandshake). | |
| 1270 // TODO(wtc): add a GetSSLParams method to SSLClientSocket so we can query | |
| 1271 // the SSL parameters it was created with and get rid of the reused_socket_ | |
| 1272 // test. | |
| 1273 DCHECK(reused_socket_ || !ssl_config_.send_client_cert); | |
| 1274 | |
| 1259 response_.cert_request_info = new SSLCertRequestInfo; | 1275 response_.cert_request_info = new SSLCertRequestInfo; |
| 1260 SSLClientSocket* ssl_socket = | 1276 SSLClientSocket* ssl_socket = |
| 1261 reinterpret_cast<SSLClientSocket*>(connection_.socket()); | 1277 reinterpret_cast<SSLClientSocket*>(connection_.socket()); |
| 1262 ssl_socket->GetSSLCertRequestInfo(response_.cert_request_info); | 1278 ssl_socket->GetSSLCertRequestInfo(response_.cert_request_info); |
| 1263 | 1279 |
| 1264 // Close the connection while the user is selecting a certificate to send | 1280 // Close the connection while the user is selecting a certificate to send |
| 1265 // to the server. | 1281 // to the server. |
| 1266 connection_.socket()->Disconnect(); | 1282 connection_.socket()->Disconnect(); |
| 1267 connection_.Reset(); | 1283 connection_.Reset(); |
| 1284 | |
| 1285 // If the user selected one of the certificate in client_certs for this | |
| 1286 // server before, use it automatically. | |
| 1287 X509Certificate* client_cert = session_->ssl_client_auth_cache()-> | |
| 1288 Lookup(GetHostAndPort(request_->url)); | |
| 1289 if (client_cert) { | |
| 1290 const std::vector<scoped_refptr<X509Certificate> >& client_certs = | |
| 1291 response_.cert_request_info->client_certs; | |
| 1292 for (size_t i = 0; i < client_certs.size(); ++i) { | |
| 1293 if (memcmp(&client_cert->fingerprint(), | |
|
eroman
2009/06/19 21:42:24
I suggesting moving this into operator==.
struct
| |
| 1294 &client_certs[i]->fingerprint(), | |
| 1295 sizeof(X509Certificate::Fingerprint)) == 0) { | |
| 1296 ssl_config_.client_cert = client_cert; | |
| 1297 ssl_config_.send_client_cert = true; | |
| 1298 next_state_ = STATE_INIT_CONNECTION; | |
| 1299 // Reset the other member variables. | |
| 1300 // Note: this is necessary only with SSL renegotiation. | |
| 1301 ResetStateForRestart(); | |
| 1302 return OK; | |
| 1303 } | |
| 1304 } | |
| 1305 } | |
| 1306 return error; | |
| 1268 } | 1307 } |
| 1269 | 1308 |
| 1270 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { | 1309 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { |
| 1310 if (ssl_config_.send_client_cert && | |
| 1311 (error == ERR_SSL_PROTOCOL_ERROR || | |
| 1312 error == ERR_BAD_SSL_CLIENT_AUTH_CERT)) { | |
| 1313 session_->ssl_client_auth_cache()->Remove(GetHostAndPort(request_->url)); | |
| 1314 } | |
| 1315 | |
| 1271 switch (error) { | 1316 switch (error) { |
| 1272 case ERR_SSL_PROTOCOL_ERROR: | 1317 case ERR_SSL_PROTOCOL_ERROR: |
| 1273 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH: | 1318 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH: |
| 1274 if (ssl_config_.tls1_enabled) { | 1319 if (ssl_config_.tls1_enabled) { |
| 1275 // This could be a TLS-intolerant server or an SSL 3.0 server that | 1320 // This could be a TLS-intolerant server or an SSL 3.0 server that |
| 1276 // chose a TLS-only cipher suite. Turn off TLS 1.0 and retry. | 1321 // chose a TLS-only cipher suite. Turn off TLS 1.0 and retry. |
| 1277 ssl_config_.tls1_enabled = false; | 1322 ssl_config_.tls1_enabled = false; |
| 1278 connection_.socket()->Disconnect(); | 1323 connection_.socket()->Disconnect(); |
| 1279 connection_.Reset(); | 1324 connection_.Reset(); |
| 1280 next_state_ = STATE_INIT_CONNECTION; | 1325 next_state_ = STATE_INIT_CONNECTION; |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1662 host_and_port = proxy_info_.proxy_server().host_and_port(); | 1707 host_and_port = proxy_info_.proxy_server().host_and_port(); |
| 1663 } else { | 1708 } else { |
| 1664 DCHECK(target == HttpAuth::AUTH_SERVER); | 1709 DCHECK(target == HttpAuth::AUTH_SERVER); |
| 1665 host_and_port = GetHostAndPort(request_->url); | 1710 host_and_port = GetHostAndPort(request_->url); |
| 1666 } | 1711 } |
| 1667 auth_info->host_and_port = ASCIIToWide(host_and_port); | 1712 auth_info->host_and_port = ASCIIToWide(host_and_port); |
| 1668 response_.auth_challenge = auth_info; | 1713 response_.auth_challenge = auth_info; |
| 1669 } | 1714 } |
| 1670 | 1715 |
| 1671 } // namespace net | 1716 } // namespace net |
| OLD | NEW |