Mark two tests in ImeTest.java as flaky
[chromium-blink-merge.git] / net / socket / ssl_client_socket.cc
blob2ea403f73c958b8afb51eb4a88e5b9de2c216023
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
3 // found in the LICENSE file.
5 #include "net/socket/ssl_client_socket.h"
7 #include "base/metrics/histogram.h"
8 #include "base/metrics/sparse_histogram.h"
9 #include "base/strings/string_util.h"
10 #include "crypto/ec_private_key.h"
11 #include "net/base/connection_type_histograms.h"
12 #include "net/base/host_port_pair.h"
13 #include "net/ssl/channel_id_service.h"
14 #include "net/ssl/ssl_cipher_suite_names.h"
15 #include "net/ssl/ssl_config_service.h"
16 #include "net/ssl/ssl_connection_status_flags.h"
18 namespace net {
20 SSLClientSocket::SSLClientSocket()
21 : was_npn_negotiated_(false),
22 was_spdy_negotiated_(false),
23 protocol_negotiated_(kProtoUnknown),
24 channel_id_sent_(false),
25 signed_cert_timestamps_received_(false),
26 stapled_ocsp_response_received_(false),
27 negotiation_extension_(kExtensionUnknown) {
30 // static
31 NextProto SSLClientSocket::NextProtoFromString(
32 const std::string& proto_string) {
33 if (proto_string == "http1.1" || proto_string == "http/1.1") {
34 return kProtoHTTP11;
35 } else if (proto_string == "spdy/2") {
36 return kProtoDeprecatedSPDY2;
37 } else if (proto_string == "spdy/3") {
38 return kProtoSPDY3;
39 } else if (proto_string == "spdy/3.1") {
40 return kProtoSPDY31;
41 } else if (proto_string == "h2-14") {
42 // For internal consistency, HTTP/2 is named SPDY4 within Chromium.
43 // This is the HTTP/2 draft-14 identifier.
44 return kProtoSPDY4_14;
45 } else if (proto_string == "h2-15") {
46 // This is the HTTP/2 draft-15 identifier.
47 return kProtoSPDY4_15;
48 } else if (proto_string == "quic/1+spdy/3") {
49 return kProtoQUIC1SPDY3;
50 } else {
51 return kProtoUnknown;
55 // static
56 const char* SSLClientSocket::NextProtoToString(NextProto next_proto) {
57 switch (next_proto) {
58 case kProtoHTTP11:
59 return "http/1.1";
60 case kProtoDeprecatedSPDY2:
61 return "spdy/2";
62 case kProtoSPDY3:
63 return "spdy/3";
64 case kProtoSPDY31:
65 return "spdy/3.1";
66 case kProtoSPDY4_14:
67 // For internal consistency, HTTP/2 is named SPDY4 within Chromium.
68 // This is the HTTP/2 draft-14 identifier.
69 return "h2-14";
70 case kProtoSPDY4_15:
71 // This is the HTTP/2 draft-15 identifier.
72 return "h2-15";
73 case kProtoQUIC1SPDY3:
74 return "quic/1+spdy/3";
75 case kProtoUnknown:
76 break;
78 return "unknown";
81 // static
82 const char* SSLClientSocket::NextProtoStatusToString(
83 const SSLClientSocket::NextProtoStatus status) {
84 switch (status) {
85 case kNextProtoUnsupported:
86 return "unsupported";
87 case kNextProtoNegotiated:
88 return "negotiated";
89 case kNextProtoNoOverlap:
90 return "no-overlap";
92 return NULL;
95 bool SSLClientSocket::WasNpnNegotiated() const {
96 return was_npn_negotiated_;
99 NextProto SSLClientSocket::GetNegotiatedProtocol() const {
100 return protocol_negotiated_;
103 bool SSLClientSocket::IgnoreCertError(int error, int load_flags) {
104 if (error == OK || load_flags & LOAD_IGNORE_ALL_CERT_ERRORS)
105 return true;
107 if (error == ERR_CERT_COMMON_NAME_INVALID &&
108 (load_flags & LOAD_IGNORE_CERT_COMMON_NAME_INVALID))
109 return true;
111 if (error == ERR_CERT_DATE_INVALID &&
112 (load_flags & LOAD_IGNORE_CERT_DATE_INVALID))
113 return true;
115 if (error == ERR_CERT_AUTHORITY_INVALID &&
116 (load_flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID))
117 return true;
119 return false;
122 bool SSLClientSocket::set_was_npn_negotiated(bool negotiated) {
123 return was_npn_negotiated_ = negotiated;
126 bool SSLClientSocket::was_spdy_negotiated() const {
127 return was_spdy_negotiated_;
130 bool SSLClientSocket::set_was_spdy_negotiated(bool negotiated) {
131 return was_spdy_negotiated_ = negotiated;
134 void SSLClientSocket::set_protocol_negotiated(NextProto protocol_negotiated) {
135 protocol_negotiated_ = protocol_negotiated;
138 void SSLClientSocket::set_negotiation_extension(
139 SSLNegotiationExtension negotiation_extension) {
140 negotiation_extension_ = negotiation_extension;
143 bool SSLClientSocket::WasChannelIDSent() const {
144 return channel_id_sent_;
147 void SSLClientSocket::set_channel_id_sent(bool channel_id_sent) {
148 channel_id_sent_ = channel_id_sent;
151 void SSLClientSocket::set_signed_cert_timestamps_received(
152 bool signed_cert_timestamps_received) {
153 signed_cert_timestamps_received_ = signed_cert_timestamps_received;
156 void SSLClientSocket::set_stapled_ocsp_response_received(
157 bool stapled_ocsp_response_received) {
158 stapled_ocsp_response_received_ = stapled_ocsp_response_received;
161 // static
162 void SSLClientSocket::RecordChannelIDSupport(
163 ChannelIDService* channel_id_service,
164 bool negotiated_channel_id,
165 bool channel_id_enabled,
166 bool supports_ecc) {
167 // Since this enum is used for a histogram, do not change or re-use values.
168 enum {
169 DISABLED = 0,
170 CLIENT_ONLY = 1,
171 CLIENT_AND_SERVER = 2,
172 CLIENT_NO_ECC = 3,
173 CLIENT_BAD_SYSTEM_TIME = 4,
174 CLIENT_NO_CHANNEL_ID_SERVICE = 5,
175 CHANNEL_ID_USAGE_MAX
176 } supported = DISABLED;
177 if (negotiated_channel_id) {
178 supported = CLIENT_AND_SERVER;
179 } else if (channel_id_enabled) {
180 if (!channel_id_service)
181 supported = CLIENT_NO_CHANNEL_ID_SERVICE;
182 else if (!supports_ecc)
183 supported = CLIENT_NO_ECC;
184 else if (!channel_id_service->IsSystemTimeValid())
185 supported = CLIENT_BAD_SYSTEM_TIME;
186 else
187 supported = CLIENT_ONLY;
189 UMA_HISTOGRAM_ENUMERATION("DomainBoundCerts.Support", supported,
190 CHANNEL_ID_USAGE_MAX);
193 // static
194 void SSLClientSocket::RecordConnectionTypeMetrics(int ssl_version) {
195 UpdateConnectionTypeHistograms(CONNECTION_SSL);
196 switch (ssl_version) {
197 case SSL_CONNECTION_VERSION_SSL2:
198 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL2);
199 break;
200 case SSL_CONNECTION_VERSION_SSL3:
201 UpdateConnectionTypeHistograms(CONNECTION_SSL_SSL3);
202 break;
203 case SSL_CONNECTION_VERSION_TLS1:
204 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1);
205 break;
206 case SSL_CONNECTION_VERSION_TLS1_1:
207 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1);
208 break;
209 case SSL_CONNECTION_VERSION_TLS1_2:
210 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2);
211 break;
215 // static
216 bool SSLClientSocket::IsChannelIDEnabled(
217 const SSLConfig& ssl_config,
218 ChannelIDService* channel_id_service) {
219 if (!ssl_config.channel_id_enabled)
220 return false;
221 if (!channel_id_service) {
222 DVLOG(1) << "NULL channel_id_service_, not enabling channel ID.";
223 return false;
225 if (!crypto::ECPrivateKey::IsSupported()) {
226 DVLOG(1) << "Elliptic Curve not supported, not enabling channel ID.";
227 return false;
229 if (!channel_id_service->IsSystemTimeValid()) {
230 DVLOG(1) << "System time is not within the supported range for certificate "
231 "generation, not enabling channel ID.";
232 return false;
234 return true;
237 // static
238 bool SSLClientSocket::HasCipherAdequateForHTTP2(
239 const std::vector<uint16>& cipher_suites) {
240 for (uint16 cipher : cipher_suites) {
241 if (IsSecureTLSCipherSuite(cipher))
242 return true;
244 return false;
247 // static
248 bool SSLClientSocket::IsTLSVersionAdequateForHTTP2(
249 const SSLConfig& ssl_config) {
250 return ssl_config.version_max >= SSL_PROTOCOL_VERSION_TLS1_2;
253 // static
254 std::vector<uint8_t> SSLClientSocket::SerializeNextProtos(
255 const NextProtoVector& next_protos,
256 bool can_advertise_http2) {
257 std::vector<uint8_t> wire_protos;
258 for (const NextProto next_proto : next_protos) {
259 if (!can_advertise_http2 && kProtoSPDY4MinimumVersion <= next_proto &&
260 next_proto <= kProtoSPDY4MaximumVersion) {
261 continue;
263 const std::string proto = NextProtoToString(next_proto);
264 if (proto.size() > 255) {
265 LOG(WARNING) << "Ignoring overlong NPN/ALPN protocol: " << proto;
266 continue;
268 if (proto.size() == 0) {
269 LOG(WARNING) << "Ignoring empty NPN/ALPN protocol";
270 continue;
272 wire_protos.push_back(proto.size());
273 for (const char ch : proto) {
274 wire_protos.push_back(static_cast<uint8_t>(ch));
278 return wire_protos;
281 void SSLClientSocket::RecordNegotiationExtension() {
282 if (negotiation_extension_ == kExtensionUnknown)
283 return;
284 std::string proto;
285 SSLClientSocket::NextProtoStatus status = GetNextProto(&proto);
286 if (status == kNextProtoUnsupported)
287 return;
288 // Convert protocol into numerical value for histogram.
289 NextProto protocol_negotiated = SSLClientSocket::NextProtoFromString(proto);
290 base::HistogramBase::Sample sample =
291 static_cast<base::HistogramBase::Sample>(protocol_negotiated);
292 // In addition to the protocol negotiated, we want to record which TLS
293 // extension was used, and in case of NPN, whether there was overlap between
294 // server and client list of supported protocols.
295 if (negotiation_extension_ == kExtensionNPN) {
296 if (status == kNextProtoNoOverlap) {
297 sample += 1000;
298 } else {
299 sample += 500;
301 } else {
302 DCHECK_EQ(kExtensionALPN, negotiation_extension_);
304 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLProtocolNegotiation", sample);
307 } // namespace net