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 |