| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/socket/ssl_client_socket.h" | 5 #include "net/socket/ssl_client_socket.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "base/metrics/sparse_histogram.h" | 8 #include "base/metrics/sparse_histogram.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "crypto/ec_private_key.h" | 10 #include "crypto/ec_private_key.h" |
| 11 #include "net/base/connection_type_histograms.h" | 11 #include "net/base/connection_type_histograms.h" |
| 12 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
| 13 #include "net/ssl/channel_id_service.h" | 13 #include "net/ssl/channel_id_service.h" |
| 14 #include "net/ssl/ssl_cipher_suite_names.h" | 14 #include "net/ssl/ssl_cipher_suite_names.h" |
| 15 #include "net/ssl/ssl_config_service.h" | 15 #include "net/ssl/ssl_config_service.h" |
| 16 #include "net/ssl/ssl_connection_status_flags.h" | 16 #include "net/ssl/ssl_connection_status_flags.h" |
| 17 | 17 |
| 18 namespace net { | 18 namespace net { |
| 19 | 19 |
| 20 SSLClientSocket::SSLClientSocket() | 20 SSLClientSocket::SSLClientSocket() |
| 21 : was_npn_negotiated_(false), | 21 : protocol_negotiated_(kProtoUnknown), |
| 22 was_spdy_negotiated_(false), | |
| 23 protocol_negotiated_(kProtoUnknown), | |
| 24 channel_id_sent_(false), | 22 channel_id_sent_(false), |
| 25 signed_cert_timestamps_received_(false), | 23 signed_cert_timestamps_received_(false), |
| 26 stapled_ocsp_response_received_(false), | 24 stapled_ocsp_response_received_(false), |
| 27 negotiation_extension_(kExtensionUnknown) { | 25 negotiation_extension_(kExtensionUnknown) { |
| 28 } | 26 } |
| 29 | 27 |
| 30 // static | 28 // static |
| 31 NextProto SSLClientSocket::NextProtoFromString( | 29 NextProto SSLClientSocket::NextProtoFromString( |
| 32 const std::string& proto_string) { | 30 const std::string& proto_string) { |
| 33 if (proto_string == "http1.1" || proto_string == "http/1.1") { | 31 if (proto_string == "http1.1" || proto_string == "http/1.1") { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 return "unsupported"; | 82 return "unsupported"; |
| 85 case kNextProtoNegotiated: | 83 case kNextProtoNegotiated: |
| 86 return "negotiated"; | 84 return "negotiated"; |
| 87 case kNextProtoNoOverlap: | 85 case kNextProtoNoOverlap: |
| 88 return "no-overlap"; | 86 return "no-overlap"; |
| 89 } | 87 } |
| 90 return NULL; | 88 return NULL; |
| 91 } | 89 } |
| 92 | 90 |
| 93 bool SSLClientSocket::WasNpnNegotiated() const { | 91 bool SSLClientSocket::WasNpnNegotiated() const { |
| 94 return was_npn_negotiated_; | 92 std::string unused_proto; |
| 93 return GetNextProto(&unused_proto) == kNextProtoNegotiated; |
| 95 } | 94 } |
| 96 | 95 |
| 97 NextProto SSLClientSocket::GetNegotiatedProtocol() const { | 96 NextProto SSLClientSocket::GetNegotiatedProtocol() const { |
| 98 return protocol_negotiated_; | 97 std::string proto; |
| 98 if (GetNextProto(&proto) != kNextProtoNegotiated) |
| 99 return kProtoUnknown; |
| 100 return NextProtoFromString(proto); |
| 99 } | 101 } |
| 100 | 102 |
| 101 bool SSLClientSocket::IgnoreCertError(int error, int load_flags) { | 103 bool SSLClientSocket::IgnoreCertError(int error, int load_flags) { |
| 102 if (error == OK) | 104 if (error == OK) |
| 103 return true; | 105 return true; |
| 104 return (load_flags & LOAD_IGNORE_ALL_CERT_ERRORS) && | 106 return (load_flags & LOAD_IGNORE_ALL_CERT_ERRORS) && |
| 105 IsCertificateError(error); | 107 IsCertificateError(error); |
| 106 } | 108 } |
| 107 | 109 |
| 108 bool SSLClientSocket::set_was_npn_negotiated(bool negotiated) { | |
| 109 return was_npn_negotiated_ = negotiated; | |
| 110 } | |
| 111 | |
| 112 bool SSLClientSocket::was_spdy_negotiated() const { | |
| 113 return was_spdy_negotiated_; | |
| 114 } | |
| 115 | |
| 116 bool SSLClientSocket::set_was_spdy_negotiated(bool negotiated) { | |
| 117 return was_spdy_negotiated_ = negotiated; | |
| 118 } | |
| 119 | |
| 120 void SSLClientSocket::set_protocol_negotiated(NextProto protocol_negotiated) { | |
| 121 protocol_negotiated_ = protocol_negotiated; | |
| 122 } | |
| 123 | |
| 124 void SSLClientSocket::set_negotiation_extension( | 110 void SSLClientSocket::set_negotiation_extension( |
| 125 SSLNegotiationExtension negotiation_extension) { | 111 SSLNegotiationExtension negotiation_extension) { |
| 126 negotiation_extension_ = negotiation_extension; | 112 negotiation_extension_ = negotiation_extension; |
| 127 } | 113 } |
| 128 | 114 |
| 129 bool SSLClientSocket::WasChannelIDSent() const { | 115 bool SSLClientSocket::WasChannelIDSent() const { |
| 130 return channel_id_sent_; | 116 return channel_id_sent_; |
| 131 } | 117 } |
| 132 | 118 |
| 133 void SSLClientSocket::set_channel_id_sent(bool channel_id_sent) { | 119 void SSLClientSocket::set_channel_id_sent(bool channel_id_sent) { |
| 134 channel_id_sent_ = channel_id_sent; | 120 channel_id_sent_ = channel_id_sent; |
| 135 } | 121 } |
| 136 | 122 |
| 137 void SSLClientSocket::set_signed_cert_timestamps_received( | 123 void SSLClientSocket::set_signed_cert_timestamps_received( |
| 138 bool signed_cert_timestamps_received) { | 124 bool signed_cert_timestamps_received) { |
| 139 signed_cert_timestamps_received_ = signed_cert_timestamps_received; | 125 signed_cert_timestamps_received_ = signed_cert_timestamps_received; |
| 140 } | 126 } |
| 141 | 127 |
| 142 void SSLClientSocket::set_stapled_ocsp_response_received( | 128 void SSLClientSocket::set_stapled_ocsp_response_received( |
| 143 bool stapled_ocsp_response_received) { | 129 bool stapled_ocsp_response_received) { |
| 144 stapled_ocsp_response_received_ = stapled_ocsp_response_received; | 130 stapled_ocsp_response_received_ = stapled_ocsp_response_received; |
| 145 } | 131 } |
| 146 | 132 |
| 133 void SSLClientSocket::RecordNegotiationExtension() { |
| 134 if (negotiation_extension_ == kExtensionUnknown) |
| 135 return; |
| 136 std::string proto; |
| 137 SSLClientSocket::NextProtoStatus status = GetNextProto(&proto); |
| 138 if (status == kNextProtoUnsupported) |
| 139 return; |
| 140 // Convert protocol into numerical value for histogram. |
| 141 NextProto protocol_negotiated = SSLClientSocket::NextProtoFromString(proto); |
| 142 base::HistogramBase::Sample sample = |
| 143 static_cast<base::HistogramBase::Sample>(protocol_negotiated); |
| 144 // In addition to the protocol negotiated, we want to record which TLS |
| 145 // extension was used, and in case of NPN, whether there was overlap between |
| 146 // server and client list of supported protocols. |
| 147 if (negotiation_extension_ == kExtensionNPN) { |
| 148 if (status == kNextProtoNoOverlap) { |
| 149 sample += 1000; |
| 150 } else { |
| 151 sample += 500; |
| 152 } |
| 153 } else { |
| 154 DCHECK_EQ(kExtensionALPN, negotiation_extension_); |
| 155 } |
| 156 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLProtocolNegotiation", sample); |
| 157 } |
| 158 |
| 147 // static | 159 // static |
| 148 void SSLClientSocket::RecordChannelIDSupport( | 160 void SSLClientSocket::RecordChannelIDSupport( |
| 149 ChannelIDService* channel_id_service, | 161 ChannelIDService* channel_id_service, |
| 150 bool negotiated_channel_id, | 162 bool negotiated_channel_id, |
| 151 bool channel_id_enabled, | 163 bool channel_id_enabled, |
| 152 bool supports_ecc) { | 164 bool supports_ecc) { |
| 153 // Since this enum is used for a histogram, do not change or re-use values. | 165 // Since this enum is used for a histogram, do not change or re-use values. |
| 154 enum { | 166 enum { |
| 155 DISABLED = 0, | 167 DISABLED = 0, |
| 156 CLIENT_ONLY = 1, | 168 CLIENT_ONLY = 1, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 } | 247 } |
| 236 wire_protos.push_back(proto.size()); | 248 wire_protos.push_back(proto.size()); |
| 237 for (const char ch : proto) { | 249 for (const char ch : proto) { |
| 238 wire_protos.push_back(static_cast<uint8_t>(ch)); | 250 wire_protos.push_back(static_cast<uint8_t>(ch)); |
| 239 } | 251 } |
| 240 } | 252 } |
| 241 | 253 |
| 242 return wire_protos; | 254 return wire_protos; |
| 243 } | 255 } |
| 244 | 256 |
| 245 void SSLClientSocket::RecordNegotiationExtension() { | |
| 246 if (negotiation_extension_ == kExtensionUnknown) | |
| 247 return; | |
| 248 std::string proto; | |
| 249 SSLClientSocket::NextProtoStatus status = GetNextProto(&proto); | |
| 250 if (status == kNextProtoUnsupported) | |
| 251 return; | |
| 252 // Convert protocol into numerical value for histogram. | |
| 253 NextProto protocol_negotiated = SSLClientSocket::NextProtoFromString(proto); | |
| 254 base::HistogramBase::Sample sample = | |
| 255 static_cast<base::HistogramBase::Sample>(protocol_negotiated); | |
| 256 // In addition to the protocol negotiated, we want to record which TLS | |
| 257 // extension was used, and in case of NPN, whether there was overlap between | |
| 258 // server and client list of supported protocols. | |
| 259 if (negotiation_extension_ == kExtensionNPN) { | |
| 260 if (status == kNextProtoNoOverlap) { | |
| 261 sample += 1000; | |
| 262 } else { | |
| 263 sample += 500; | |
| 264 } | |
| 265 } else { | |
| 266 DCHECK_EQ(kExtensionALPN, negotiation_extension_); | |
| 267 } | |
| 268 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLProtocolNegotiation", sample); | |
| 269 } | |
| 270 | |
| 271 } // namespace net | 257 } // namespace net |
| OLD | NEW |