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

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

Issue 131086: Implement the backend of SSL client authentication for... (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
OLDNEW
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
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
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
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
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
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
OLDNEW
« net/base/ssl_client_socket_win.cc ('K') | « net/http/http_network_transaction.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698