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

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

Issue 6017010: Ensure that when using False Start + client auth, bad client certificates are not cached (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix mac compile Created 9 years, 11 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) 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 <set> 7 #include <set>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 next_state_ = STATE_INIT_STREAM; 547 next_state_ = STATE_INIT_STREAM;
548 DCHECK(stream_.get()); 548 DCHECK(stream_.get());
549 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 549 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
550 result = HandleCertificateRequest(result); 550 result = HandleCertificateRequest(result);
551 } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { 551 } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
552 // Return OK and let the caller read the proxy's error page 552 // Return OK and let the caller read the proxy's error page
553 next_state_ = STATE_NONE; 553 next_state_ = STATE_NONE;
554 return OK; 554 return OK;
555 } 555 }
556 556
557 // Handle possible handshake errors that may have occurred if the stream
558 // used SSL for one or more of the layers.
559 result = HandleSSLHandshakeError(result);
560
557 // At this point we are done with the stream_request_. 561 // At this point we are done with the stream_request_.
558 stream_request_.reset(); 562 stream_request_.reset();
559 return result; 563 return result;
560 } 564 }
561 565
562 int HttpNetworkTransaction::DoInitStream() { 566 int HttpNetworkTransaction::DoInitStream() {
563 DCHECK(stream_.get()); 567 DCHECK(stream_.get());
564 next_state_ = STATE_INIT_STREAM_COMPLETE; 568 next_state_ = STATE_INIT_STREAM_COMPLETE;
565 return stream_->InitializeStream(request_, net_log_, &io_callback_); 569 return stream_->InitializeStream(request_, net_log_, &io_callback_);
566 } 570 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION; 693 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION;
690 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 694 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
691 // TODO(wtc): Need a test case for this code path! 695 // TODO(wtc): Need a test case for this code path!
692 DCHECK(stream_.get()); 696 DCHECK(stream_.get());
693 DCHECK(is_https_request()); 697 DCHECK(is_https_request());
694 response_.cert_request_info = new SSLCertRequestInfo; 698 response_.cert_request_info = new SSLCertRequestInfo;
695 stream_->GetSSLCertRequestInfo(response_.cert_request_info); 699 stream_->GetSSLCertRequestInfo(response_.cert_request_info);
696 result = HandleCertificateRequest(result); 700 result = HandleCertificateRequest(result);
697 if (result == OK) 701 if (result == OK)
698 return result; 702 return result;
699 } else if ((result == ERR_SSL_DECOMPRESSION_FAILURE_ALERT ||
700 result == ERR_SSL_BAD_RECORD_MAC_ALERT) &&
701 ssl_config_.tls1_enabled &&
702 !SSLConfigService::IsKnownStrictTLSServer(request_->url.host())) {
703 // Some buggy servers select DEFLATE compression when offered and then
704 // fail to ever decompress anything. They will send a fatal alert telling
705 // us this. Normally we would pick this up during the handshake because
706 // our Finished message is compressed and we'll never get the server's
707 // Finished if it fails to process ours.
708 //
709 // However, with False Start, we'll believe that the handshake is
710 // complete as soon as we've /sent/ our Finished message. In this case,
711 // we only find out that the server is buggy here, when we try to read
712 // the initial reply.
713 session_->http_stream_factory()->AddTLSIntolerantServer(request_->url);
714 ResetConnectionAndRequestForResend();
715 return OK;
716 } 703 }
717 704
718 if (result < 0 && result != ERR_CONNECTION_CLOSED) 705 if (result < 0 && result != ERR_CONNECTION_CLOSED)
719 return HandleIOError(result); 706 return HandleIOError(result);
720 707
721 if (result == ERR_CONNECTION_CLOSED && ShouldResendRequest(result)) { 708 if (result == ERR_CONNECTION_CLOSED && ShouldResendRequest(result)) {
722 ResetConnectionAndRequestForResend(); 709 ResetConnectionAndRequestForResend();
723 return OK; 710 return OK;
724 } 711 }
725 712
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 // SSL session cache. 1004 // SSL session cache.
1018 ssl_config_.client_cert = client_cert; 1005 ssl_config_.client_cert = client_cert;
1019 ssl_config_.send_client_cert = true; 1006 ssl_config_.send_client_cert = true;
1020 next_state_ = STATE_CREATE_STREAM; 1007 next_state_ = STATE_CREATE_STREAM;
1021 // Reset the other member variables. 1008 // Reset the other member variables.
1022 // Note: this is necessary only with SSL renegotiation. 1009 // Note: this is necessary only with SSL renegotiation.
1023 ResetStateForRestart(); 1010 ResetStateForRestart();
1024 return OK; 1011 return OK;
1025 } 1012 }
1026 1013
1014 // TODO(rch): This does not correctly handle errors when an SSL proxy is
1015 // being used, as all of the errors are handled as if they were generated
1016 // by the endpoint host, request_->url, rather than considering if they were
1017 // generated by the SSL proxy. http://crbug.com/66424
1018 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) {
1019 DCHECK(request_);
1020 if (ssl_config_.send_client_cert &&
1021 (error == ERR_SSL_PROTOCOL_ERROR ||
1022 error == ERR_BAD_SSL_CLIENT_AUTH_CERT)) {
1023 session_->ssl_client_auth_cache()->Remove(
1024 GetHostAndPort(request_->url));
1025 }
1026
1027 switch (error) {
1028 case ERR_SSL_PROTOCOL_ERROR:
1029 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
1030 case ERR_SSL_DECOMPRESSION_FAILURE_ALERT:
1031 case ERR_SSL_BAD_RECORD_MAC_ALERT:
1032 if (ssl_config_.tls1_enabled &&
1033 !SSLConfigService::IsKnownStrictTLSServer(request_->url.host())) {
1034 // This could be a TLS-intolerant server, an SSL 3.0 server that
1035 // chose a TLS-only cipher suite or a server with buggy DEFLATE
1036 // support. Turn off TLS 1.0, DEFLATE support and retry.
1037 session_->http_stream_factory()->AddTLSIntolerantServer(request_->url);
1038 ResetConnectionAndRequestForResend();
1039 error = OK;
1040 }
1041 break;
1042 case ERR_SSL_SNAP_START_NPN_MISPREDICTION:
1043 // This means that we tried to Snap Start a connection, but we
1044 // mispredicted the NPN result. This isn't a problem from the point of
1045 // view of the SSL layer because the server will ignore the application
1046 // data in the Snap Start extension. However, at the HTTP layer, we have
1047 // already decided that it's a HTTP or SPDY connection and it's easier to
1048 // abort and start again.
1049 ResetConnectionAndRequestForResend();
1050 error = OK;
1051 break;
1052 }
1053 return error;
1054 }
1055
1027 // This method determines whether it is safe to resend the request after an 1056 // This method determines whether it is safe to resend the request after an
1028 // IO error. It can only be called in response to request header or body 1057 // IO error. It can only be called in response to request header or body
1029 // write errors or response header read errors. It should not be used in 1058 // write errors or response header read errors. It should not be used in
1030 // other cases, such as a Connect error. 1059 // other cases, such as a Connect error.
1031 int HttpNetworkTransaction::HandleIOError(int error) { 1060 int HttpNetworkTransaction::HandleIOError(int error) {
1061 // SSL errors may happen at any time during the stream and indicate issues
1062 // with the underlying connection. Because the peer may request
1063 // renegotiation at any time, check and handle any possible SSL handshake
1064 // related errors. In addition to renegotiation, TLS False/Snap Start may
1065 // cause SSL handshake errors to be delayed until the first Read on the
wtc 2011/01/12 00:21:09 This should be "first Write or Read", right?
1066 // underlying connection.
1067 error = HandleSSLHandshakeError(error);
1068
1032 switch (error) { 1069 switch (error) {
1033 // If we try to reuse a connection that the server is in the process of 1070 // If we try to reuse a connection that the server is in the process of
1034 // closing, we may end up successfully writing out our request (or a 1071 // closing, we may end up successfully writing out our request (or a
1035 // portion of our request) only to find a connection error when we try to 1072 // portion of our request) only to find a connection error when we try to
1036 // read from (or finish writing to) the socket. 1073 // read from (or finish writing to) the socket.
1037 case ERR_CONNECTION_RESET: 1074 case ERR_CONNECTION_RESET:
1038 case ERR_CONNECTION_CLOSED: 1075 case ERR_CONNECTION_CLOSED:
1039 case ERR_CONNECTION_ABORTED: 1076 case ERR_CONNECTION_ABORTED:
1040 if (ShouldResendRequest(error)) { 1077 if (ShouldResendRequest(error)) {
1041 ResetConnectionAndRequestForResend(); 1078 ResetConnectionAndRequestForResend();
1042 error = OK; 1079 error = OK;
1043 } 1080 }
1044 break; 1081 break;
1045 case ERR_SSL_SNAP_START_NPN_MISPREDICTION:
1046 // This means that we tried to Snap Start a connection, but we
1047 // mispredicted the NPN result. This isn't a problem from the point of
1048 // view of the SSL layer because the server will ignore the application
1049 // data in the Snap Start extension. However, at the HTTP layer, we have
1050 // already decided that it's a HTTP or SPDY connection and it's easier to
1051 // abort and start again.
1052 ResetConnectionAndRequestForResend();
1053 error = OK;
1054 break;
1055 } 1082 }
1056 return error; 1083 return error;
1057 } 1084 }
1058 1085
1059 void HttpNetworkTransaction::ResetStateForRestart() { 1086 void HttpNetworkTransaction::ResetStateForRestart() {
1060 ResetStateForAuthRestart(); 1087 ResetStateForAuthRestart();
1061 stream_.reset(); 1088 stream_.reset();
1062 } 1089 }
1063 1090
1064 void HttpNetworkTransaction::ResetStateForAuthRestart() { 1091 void HttpNetworkTransaction::ResetStateForAuthRestart() {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1203 default: 1230 default:
1204 return priority; 1231 return priority;
1205 } 1232 }
1206 } 1233 }
1207 1234
1208 1235
1209 1236
1210 #undef STATE_CASE 1237 #undef STATE_CASE
1211 1238
1212 } // namespace net 1239 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698