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

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

Issue 118039: Implement SSL client authentication for Windows.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Upload before checkin Created 11 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « net/http/http_network_transaction.h ('k') | net/http/http_response_info.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 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"
11 #include "base/trace_event.h" 11 #include "base/trace_event.h"
12 #include "build/build_config.h" 12 #include "build/build_config.h"
13 #include "net/base/client_socket_factory.h" 13 #include "net/base/client_socket_factory.h"
14 #include "net/base/connection_type_histograms.h" 14 #include "net/base/connection_type_histograms.h"
15 #include "net/base/dns_resolution_observer.h" 15 #include "net/base/dns_resolution_observer.h"
16 #include "net/base/io_buffer.h" 16 #include "net/base/io_buffer.h"
17 #include "net/base/load_flags.h" 17 #include "net/base/load_flags.h"
18 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
19 #include "net/base/net_util.h" 19 #include "net/base/net_util.h"
20 #include "net/base/ssl_cert_request_info.h"
20 #include "net/base/ssl_client_socket.h" 21 #include "net/base/ssl_client_socket.h"
21 #include "net/base/upload_data_stream.h" 22 #include "net/base/upload_data_stream.h"
22 #include "net/http/http_auth.h" 23 #include "net/http/http_auth.h"
23 #include "net/http/http_auth_handler.h" 24 #include "net/http/http_auth_handler.h"
24 #include "net/http/http_basic_stream.h" 25 #include "net/http/http_basic_stream.h"
25 #include "net/http/http_chunked_decoder.h" 26 #include "net/http/http_chunked_decoder.h"
26 #include "net/http/http_network_session.h" 27 #include "net/http/http_network_session.h"
27 #include "net/http/http_request_info.h" 28 #include "net/http/http_request_info.h"
28 #include "net/http/http_response_headers.h" 29 #include "net/http/http_response_headers.h"
29 #include "net/http/http_util.h" 30 #include "net/http/http_util.h"
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 connection_.socket()->Disconnect(); 183 connection_.socket()->Disconnect();
183 connection_.Reset(); 184 connection_.Reset();
184 next_state_ = STATE_INIT_CONNECTION; 185 next_state_ = STATE_INIT_CONNECTION;
185 } 186 }
186 int rv = DoLoop(OK); 187 int rv = DoLoop(OK);
187 if (rv == ERR_IO_PENDING) 188 if (rv == ERR_IO_PENDING)
188 user_callback_ = callback; 189 user_callback_ = callback;
189 return rv; 190 return rv;
190 } 191 }
191 192
193 int HttpNetworkTransaction::RestartWithCertificate(
194 X509Certificate* client_cert,
195 CompletionCallback* callback) {
196 ssl_config_.client_cert = client_cert;
197 ssl_config_.send_client_cert = true;
198 next_state_ = STATE_INIT_CONNECTION;
199 // Reset the other member variables.
200 // Note: this is necessary only with SSL renegotiation.
201 ResetStateForRestart();
202 int rv = DoLoop(OK);
203 if (rv == ERR_IO_PENDING)
204 user_callback_ = callback;
205 return rv;
206 }
207
192 int HttpNetworkTransaction::RestartWithAuth( 208 int HttpNetworkTransaction::RestartWithAuth(
193 const std::wstring& username, 209 const std::wstring& username,
194 const std::wstring& password, 210 const std::wstring& password,
195 CompletionCallback* callback) { 211 CompletionCallback* callback) {
196 HttpAuth::Target target = pending_auth_target_; 212 HttpAuth::Target target = pending_auth_target_;
197 if (target == HttpAuth::AUTH_NONE) { 213 if (target == HttpAuth::AUTH_NONE) {
198 NOTREACHED(); 214 NOTREACHED();
199 return ERR_UNEXPECTED; 215 return ERR_UNEXPECTED;
200 } 216 }
201 217
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 read_buf_len_ = buf_len; 355 read_buf_len_ = buf_len;
340 356
341 next_state_ = STATE_READ_BODY; 357 next_state_ = STATE_READ_BODY;
342 int rv = DoLoop(OK); 358 int rv = DoLoop(OK);
343 if (rv == ERR_IO_PENDING) 359 if (rv == ERR_IO_PENDING)
344 user_callback_ = callback; 360 user_callback_ = callback;
345 return rv; 361 return rv;
346 } 362 }
347 363
348 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { 364 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const {
349 return (response_.headers || response_.ssl_info.cert) ? &response_ : NULL; 365 return (response_.headers || response_.ssl_info.cert ||
366 response_.cert_request_info) ? &response_ : NULL;
350 } 367 }
351 368
352 LoadState HttpNetworkTransaction::GetLoadState() const { 369 LoadState HttpNetworkTransaction::GetLoadState() const {
353 // TODO(wtc): Define a new LoadState value for the 370 // TODO(wtc): Define a new LoadState value for the
354 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request. 371 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request.
355 switch (next_state_) { 372 switch (next_state_) {
356 case STATE_RESOLVE_PROXY_COMPLETE: 373 case STATE_RESOLVE_PROXY_COMPLETE:
357 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; 374 return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
358 case STATE_INIT_CONNECTION_COMPLETE: 375 case STATE_INIT_CONNECTION_COMPLETE:
359 return connection_.GetLoadState(); 376 return connection_.GetLoadState();
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 connection_.set_socket(s); 613 connection_.set_socket(s);
597 return connection_.socket()->Connect(&io_callback_); 614 return connection_.socket()->Connect(&io_callback_);
598 } 615 }
599 616
600 int HttpNetworkTransaction::DoSSLConnectComplete(int result) { 617 int HttpNetworkTransaction::DoSSLConnectComplete(int result) {
601 if (IsCertificateError(result)) 618 if (IsCertificateError(result))
602 result = HandleCertificateError(result); 619 result = HandleCertificateError(result);
603 620
604 if (result == OK) { 621 if (result == OK) {
605 next_state_ = STATE_WRITE_HEADERS; 622 next_state_ = STATE_WRITE_HEADERS;
623 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
624 HandleCertificateRequest();
606 } else { 625 } else {
607 result = HandleSSLHandshakeError(result); 626 result = HandleSSLHandshakeError(result);
608 } 627 }
609 return result; 628 return result;
610 } 629 }
611 630
612 int HttpNetworkTransaction::DoWriteHeaders() { 631 int HttpNetworkTransaction::DoWriteHeaders() {
613 next_state_ = STATE_WRITE_HEADERS_COMPLETE; 632 next_state_ = STATE_WRITE_HEADERS_COMPLETE;
614 633
615 // This is constructed lazily (instead of within our Start method), so that 634 // This is constructed lazily (instead of within our Start method), so that
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 return ERR_EMPTY_RESPONSE; 758 return ERR_EMPTY_RESPONSE;
740 } 759 }
741 760
742 // Assume everything else is a HTTP/0.9 response (including responses 761 // Assume everything else is a HTTP/0.9 response (including responses
743 // of 'h', 'ht', 'htt'). 762 // of 'h', 'ht', 'htt').
744 header_buf_body_offset_ = 0; 763 header_buf_body_offset_ = 0;
745 return OK; 764 return OK;
746 } 765 }
747 766
748 int HttpNetworkTransaction::DoReadHeadersComplete(int result) { 767 int HttpNetworkTransaction::DoReadHeadersComplete(int result) {
749 if (using_ssl_ && IsCertificateError(result)) { 768 // We can get a certificate error or ERR_SSL_CLIENT_AUTH_CERT_NEEDED here
750 // We don't handle a certificate error during SSL renegotiation, so we 769 // due to SSL renegotiation.
751 // have to return an error that's not in the certificate error range 770 if (using_ssl_) {
752 // (-2xx). 771 if (IsCertificateError(result)) {
753 LOG(ERROR) << "Got a server certificate with error " << result 772 // We don't handle a certificate error during SSL renegotiation, so we
754 << " during SSL renegotiation"; 773 // have to return an error that's not in the certificate error range
755 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION; 774 // (-2xx).
775 LOG(ERROR) << "Got a server certificate with error " << result
776 << " during SSL renegotiation";
777 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION;
778 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
779 HandleCertificateRequest();
780 }
756 } 781 }
757 782
758 if (result < 0) 783 if (result < 0)
759 return HandleIOError(result); 784 return HandleIOError(result);
760 785
761 if (result == 0 && ShouldResendRequest()) { 786 if (result == 0 && ShouldResendRequest()) {
762 ResetConnectionAndRequestForResend(); 787 ResetConnectionAndRequestForResend();
763 return result; 788 return result;
764 } 789 }
765 790
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 1235
1211 // Add the bad certificate to the set of allowed certificates in the 1236 // Add the bad certificate to the set of allowed certificates in the
1212 // SSL info object. This data structure will be consulted after calling 1237 // SSL info object. This data structure will be consulted after calling
1213 // RestartIgnoringLastError(). And the user will be asked interactively 1238 // RestartIgnoringLastError(). And the user will be asked interactively
1214 // before RestartIgnoringLastError() is ever called. 1239 // before RestartIgnoringLastError() is ever called.
1215 ssl_config_.allowed_bad_certs_.insert(response_.ssl_info.cert); 1240 ssl_config_.allowed_bad_certs_.insert(response_.ssl_info.cert);
1216 } 1241 }
1217 return error; 1242 return error;
1218 } 1243 }
1219 1244
1245 void HttpNetworkTransaction::HandleCertificateRequest() {
1246 response_.cert_request_info = new SSLCertRequestInfo;
1247 SSLClientSocket* ssl_socket =
1248 reinterpret_cast<SSLClientSocket*>(connection_.socket());
1249 ssl_socket->GetSSLCertRequestInfo(response_.cert_request_info);
1250
1251 // Close the connection while the user is selecting a certificate to send
1252 // to the server.
1253 connection_.socket()->Disconnect();
1254 connection_.Reset();
1255 }
1256
1220 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { 1257 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
1221 switch (error) { 1258 switch (error) {
1222 case ERR_SSL_PROTOCOL_ERROR: 1259 case ERR_SSL_PROTOCOL_ERROR:
1223 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH: 1260 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
1224 if (ssl_config_.tls1_enabled) { 1261 if (ssl_config_.tls1_enabled) {
1225 // This could be a TLS-intolerant server or an SSL 3.0 server that 1262 // This could be a TLS-intolerant server or an SSL 3.0 server that
1226 // chose a TLS-only cipher suite. Turn off TLS 1.0 and retry. 1263 // chose a TLS-only cipher suite. Turn off TLS 1.0 and retry.
1227 ssl_config_.tls1_enabled = false; 1264 ssl_config_.tls1_enabled = false;
1228 connection_.socket()->Disconnect(); 1265 connection_.socket()->Disconnect();
1229 connection_.Reset(); 1266 connection_.Reset();
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 host_and_port = proxy_info_.proxy_server().host_and_port(); 1649 host_and_port = proxy_info_.proxy_server().host_and_port();
1613 } else { 1650 } else {
1614 DCHECK(target == HttpAuth::AUTH_SERVER); 1651 DCHECK(target == HttpAuth::AUTH_SERVER);
1615 host_and_port = GetHostAndPort(request_->url); 1652 host_and_port = GetHostAndPort(request_->url);
1616 } 1653 }
1617 auth_info->host_and_port = ASCIIToWide(host_and_port); 1654 auth_info->host_and_port = ASCIIToWide(host_and_port);
1618 response_.auth_challenge = auth_info; 1655 response_.auth_challenge = auth_info;
1619 } 1656 }
1620 1657
1621 } // namespace net 1658 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_network_transaction.h ('k') | net/http/http_response_info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698