blob: 57c12f2f56a118e60b65aeb70aede86fb2c2dacf [file] [log] [blame]
[email protected]013c17c2012-01-21 19:09:011// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]d518cd92010-09-29 12:27:442// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
svaldeze83af292016-04-26 14:33:375#include "net/socket/ssl_client_socket_impl.h"
[email protected]d518cd92010-09-29 12:27:446
[email protected]edfd0f42014-07-22 18:20:377#include <errno.h>
bnc67da3de2015-01-15 21:02:268#include <string.h>
[email protected]d518cd92010-09-29 12:27:449
mabb51c5142016-12-07 09:32:4010#include <algorithm>
davidben752bcf22015-12-21 22:55:5011#include <utility>
12
[email protected]0f7804ec2011-10-07 20:04:1813#include "base/bind.h"
[email protected]f2da6ac2013-02-04 08:22:5314#include "base/callback_helpers.h"
davidben1d489522015-07-01 18:48:4615#include "base/lazy_instance.h"
Avi Drissman13fc8932015-12-20 04:40:4616#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/singleton.h"
mmenke1beda3d2016-07-22 03:33:4518#include "base/metrics/field_trial.h"
asvitkinec3c93722015-06-17 14:48:3719#include "base/metrics/histogram_macros.h"
davidben4fe4f982015-11-11 22:00:1220#include "base/metrics/sparse_histogram.h"
nharper49b27d992016-02-09 18:28:5121#include "base/strings/string_number_conversions.h"
davidben018aad62014-09-12 02:25:1922#include "base/strings/string_piece.h"
xunjieli9f8c5fb52016-12-07 22:59:3323#include "base/strings/stringprintf.h"
[email protected]20305ec2011-01-21 04:55:5224#include "base/synchronization/lock.h"
vadimt6b43dec22015-01-06 01:59:5825#include "base/threading/thread_local.h"
xunjieli9f8c5fb52016-12-07 22:59:3326#include "base/trace_event/process_memory_dump.h"
ssid6d6b40102016-04-05 18:59:5627#include "base/trace_event/trace_event.h"
estade5e5529d2015-05-21 20:59:1128#include "base/values.h"
[email protected]ee0f2aa82013-10-25 11:59:2629#include "crypto/ec_private_key.h"
[email protected]4b559b4d2011-04-14 17:37:1430#include "crypto/openssl_util.h"
martijna2e83bd2016-03-18 13:10:4531#include "net/base/ip_address.h"
[email protected]d518cd92010-09-29 12:27:4432#include "net/base/net_errors.h"
xunjieli0b7f5b62016-12-06 20:43:4833#include "net/base/trace_constants.h"
[email protected]6e7845ae2013-03-29 21:48:1134#include "net/cert/cert_verifier.h"
estark6f9b3d82016-01-12 21:37:0535#include "net/cert/ct_policy_enforcer.h"
estark723b5eeb2016-02-18 21:01:1236#include "net/cert/ct_policy_status.h"
davidbeneb5f8ef32014-09-04 14:14:3237#include "net/cert/ct_verifier.h"
[email protected]6e7845ae2013-03-29 21:48:1138#include "net/cert/x509_certificate_net_log_param.h"
mattm316af822017-02-23 04:05:5639#include "net/cert/x509_util.h"
[email protected]8bd4e7a2014-08-09 14:49:1740#include "net/http/transport_security_state.h"
mikecironef22f9812016-10-04 03:40:1941#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0042#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1943#include "net/log/net_log_parameters_callback.h"
[email protected]536fd0b2013-03-14 17:41:5744#include "net/ssl/ssl_cert_request_info.h"
davidben281d13f02016-04-27 20:43:2845#include "net/ssl/ssl_cipher_suite_names.h"
svaldeze83af292016-04-26 14:33:3746#include "net/ssl/ssl_client_session_cache.h"
[email protected]536fd0b2013-03-14 17:41:5747#include "net/ssl/ssl_connection_status_flags.h"
48#include "net/ssl/ssl_info.h"
davidben1d489522015-07-01 18:48:4649#include "net/ssl/ssl_private_key.h"
nharperd5cddca2016-02-27 03:37:5250#include "net/ssl/token_binding.h"
tfarinae8cb8aa2016-10-21 02:44:0151#include "third_party/boringssl/src/include/openssl/bio.h"
52#include "third_party/boringssl/src/include/openssl/bytestring.h"
53#include "third_party/boringssl/src/include/openssl/err.h"
54#include "third_party/boringssl/src/include/openssl/evp.h"
55#include "third_party/boringssl/src/include/openssl/mem.h"
56#include "third_party/boringssl/src/include/openssl/ssl.h"
[email protected]d518cd92010-09-29 12:27:4457
davidben2a811e4e2015-12-01 10:49:3458#if !defined(OS_NACL)
59#include "net/ssl/ssl_key_logger.h"
60#endif
61
svaldez2135be52016-04-20 16:34:5362#if defined(USE_NSS_CERTS)
davidbena477a70a2015-10-06 04:38:2963#include "net/cert_net/nss_ocsp.h"
64#endif
65
[email protected]d518cd92010-09-29 12:27:4466namespace net {
67
68namespace {
69
[email protected]4b768562013-02-16 04:10:0770// This constant can be any non-negative/non-zero value (eg: it does not
71// overlap with any value of the net::Error range, including net::OK).
davidben1d489522015-07-01 18:48:4672const int kNoPendingResult = 1;
[email protected]4b768562013-02-16 04:10:0773
haavardm2d92e722014-12-19 13:45:4474// Default size of the internal BoringSSL buffers.
mmenke1beda3d2016-07-22 03:33:4575const int kDefaultOpenSSLBufferSize = 17 * 1024;
haavardm2d92e722014-12-19 13:45:4476
nharper736ceda2015-11-07 00:16:5977// TLS extension number use for Token Binding.
nharperb5ad8a802016-02-05 19:40:0078const unsigned int kTbExtNum = 24;
nharper736ceda2015-11-07 00:16:5979
80// Token Binding ProtocolVersions supported.
81const uint8_t kTbProtocolVersionMajor = 0;
nharper96d085c2017-02-22 20:10:2182const uint8_t kTbProtocolVersionMinor = 13;
nharper736ceda2015-11-07 00:16:5983const uint8_t kTbMinProtocolVersionMajor = 0;
nharper78e6d2b2016-09-21 05:42:3584const uint8_t kTbMinProtocolVersionMinor = 10;
nharper736ceda2015-11-07 00:16:5985
danakj655b66c2016-04-16 00:51:3886std::unique_ptr<base::Value> NetLogPrivateKeyOperationCallback(
David Benjaminb9bafbe2017-11-07 21:41:3887 uint16_t algorithm,
davidben752bcf22015-12-21 22:55:5088 NetLogCaptureMode mode) {
danakj655b66c2016-04-16 00:51:3889 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue);
David Benjaminb9bafbe2017-11-07 21:41:3890 value->SetString("algorithm", SSL_get_signature_algorithm_name(
91 algorithm, 0 /* exclude curve */));
davidben752bcf22015-12-21 22:55:5092 return std::move(value);
93}
94
danakj655b66c2016-04-16 00:51:3895std::unique_ptr<base::Value> NetLogChannelIDLookupCallback(
nharper49b27d992016-02-09 18:28:5196 ChannelIDService* channel_id_service,
97 NetLogCaptureMode capture_mode) {
98 ChannelIDStore* store = channel_id_service->GetChannelIDStore();
danakj655b66c2016-04-16 00:51:3899 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
nharper49b27d992016-02-09 18:28:51100 dict->SetBoolean("ephemeral", store->IsEphemeral());
101 dict->SetString("service", base::HexEncode(&channel_id_service,
102 sizeof(channel_id_service)));
103 dict->SetString("store", base::HexEncode(&store, sizeof(store)));
104 return std::move(dict);
105}
106
danakj655b66c2016-04-16 00:51:38107std::unique_ptr<base::Value> NetLogChannelIDLookupCompleteCallback(
nharper49b27d992016-02-09 18:28:51108 crypto::ECPrivateKey* key,
109 int result,
110 NetLogCaptureMode capture_mode) {
danakj655b66c2016-04-16 00:51:38111 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
nharper49b27d992016-02-09 18:28:51112 dict->SetInteger("net_error", result);
113 std::string raw_key;
114 if (result == OK && key && key->ExportRawPublicKey(&raw_key)) {
nharper837b2af2016-12-21 21:48:36115 std::string key_to_log = base::HexEncode(raw_key.data(), raw_key.length());
nharper49b27d992016-02-09 18:28:51116 dict->SetString("key", key_to_log);
117 }
118 return std::move(dict);
119}
120
davidben281d13f02016-04-27 20:43:28121std::unique_ptr<base::Value> NetLogSSLInfoCallback(
122 SSLClientSocketImpl* socket,
123 NetLogCaptureMode capture_mode) {
124 SSLInfo ssl_info;
125 if (!socket->GetSSLInfo(&ssl_info))
126 return nullptr;
127
128 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
129 const char* version_str;
130 SSLVersionToString(&version_str,
131 SSLConnectionStatusToVersion(ssl_info.connection_status));
132 dict->SetString("version", version_str);
133 dict->SetBoolean("is_resumed",
134 ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME);
135 dict->SetInteger("cipher_suite", SSLConnectionStatusToCipherSuite(
136 ssl_info.connection_status));
137
bnc3472afd2016-11-17 15:27:21138 dict->SetString("next_proto",
139 NextProtoToString(socket->GetNegotiatedProtocol()));
davidben281d13f02016-04-27 20:43:28140
141 return std::move(dict);
142}
143
davidben3418e81f2016-10-19 00:09:45144int GetBufferSize(const char* field_trial) {
145 // Get buffer sizes from field trials, if possible. If values not present,
146 // use default. Also make sure values are in reasonable range.
147 int buffer_size = kDefaultOpenSSLBufferSize;
148#if !defined(OS_NACL)
149 int override_buffer_size;
150 if (base::StringToInt(base::FieldTrialList::FindFullName(field_trial),
151 &override_buffer_size)) {
152 buffer_size = override_buffer_size;
153 buffer_size = std::max(buffer_size, 1000);
154 buffer_size = std::min(buffer_size, 2 * kDefaultOpenSSLBufferSize);
155 }
156#endif // !defined(OS_NACL)
157 return buffer_size;
158}
159
davidbencef9e212017-04-19 15:00:10160std::unique_ptr<base::Value> NetLogSSLAlertCallback(
161 const void* bytes,
162 size_t len,
163 NetLogCaptureMode capture_mode) {
164 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
165 dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, len));
166 return std::move(dict);
167}
168
169std::unique_ptr<base::Value> NetLogSSLMessageCallback(
170 bool is_write,
171 const void* bytes,
172 size_t len,
173 NetLogCaptureMode capture_mode) {
174 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
175 if (len == 0) {
176 NOTREACHED();
177 return std::move(dict);
178 }
179
180 // The handshake message type is the first byte. Include it so elided messages
181 // still report their type.
182 uint8_t type = reinterpret_cast<const uint8_t*>(bytes)[0];
183 dict->SetInteger("type", type);
184
185 // Elide client certificate messages unless logging socket bytes. The client
186 // certificate does not contain information needed to impersonate the user
187 // (that's the private key which isn't sent over the wire), but it may contain
188 // information on the user's identity.
189 if (!is_write || type != SSL3_MT_CERTIFICATE ||
190 capture_mode.include_socket_bytes()) {
191 dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, len));
192 }
193
194 return std::move(dict);
195}
196
[email protected]821e3bb2013-11-08 01:06:01197} // namespace
198
svaldeze83af292016-04-26 14:33:37199class SSLClientSocketImpl::SSLContext {
[email protected]fbef13932010-11-23 12:38:53200 public:
olli.raula36aa8be2015-09-10 11:14:22201 static SSLContext* GetInstance() {
fdoray33e7c3c52017-01-19 18:37:23202 return base::Singleton<SSLContext,
203 base::LeakySingletonTraits<SSLContext>>::get();
olli.raula36aa8be2015-09-10 11:14:22204 }
[email protected]fbef13932010-11-23 12:38:53205 SSL_CTX* ssl_ctx() { return ssl_ctx_.get(); }
svaldeze83af292016-04-26 14:33:37206 SSLClientSessionCache* session_cache() { return &session_cache_; }
[email protected]fbef13932010-11-23 12:38:53207
svaldeze83af292016-04-26 14:33:37208 SSLClientSocketImpl* GetClientSocketFromSSL(const SSL* ssl) {
[email protected]fbef13932010-11-23 12:38:53209 DCHECK(ssl);
svaldeze83af292016-04-26 14:33:37210 SSLClientSocketImpl* socket = static_cast<SSLClientSocketImpl*>(
[email protected]fbef13932010-11-23 12:38:53211 SSL_get_ex_data(ssl, ssl_socket_data_index_));
212 DCHECK(socket);
213 return socket;
214 }
215
svaldeze83af292016-04-26 14:33:37216 bool SetClientSocketForSSL(SSL* ssl, SSLClientSocketImpl* socket) {
[email protected]fbef13932010-11-23 12:38:53217 return SSL_set_ex_data(ssl, ssl_socket_data_index_, socket) != 0;
218 }
219
davidben2a811e4e2015-12-01 10:49:34220#if !defined(OS_NACL)
David Benjamindc2f4b02017-07-27 23:59:02221 void SetSSLKeyLogFile(const base::FilePath& path) {
davidben2a811e4e2015-12-01 10:49:34222 DCHECK(!ssl_key_logger_);
David Benjamindc2f4b02017-07-27 23:59:02223 ssl_key_logger_.reset(new SSLKeyLogger(path));
davidben2a811e4e2015-12-01 10:49:34224 SSL_CTX_set_keylog_callback(ssl_ctx_.get(), KeyLogCallback);
225 }
226#endif
227
davidben1d489522015-07-01 18:48:46228 static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
229
[email protected]fbef13932010-11-23 12:38:53230 private:
olli.raula36aa8be2015-09-10 11:14:22231 friend struct base::DefaultSingletonTraits<SSLContext>;
[email protected]fbef13932010-11-23 12:38:53232
svaldeze83af292016-04-26 14:33:37233 SSLContext() : session_cache_(SSLClientSessionCache::Config()) {
[email protected]4b559b4d2011-04-14 17:37:14234 crypto::EnsureOpenSSLInit();
[email protected]fbef13932010-11-23 12:38:53235 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0);
236 DCHECK_NE(ssl_socket_data_index_, -1);
davidbena35b40c32017-03-09 17:33:45237 ssl_ctx_.reset(SSL_CTX_new(TLS_with_buffers_method()));
[email protected]82c59022014-08-15 09:38:27238 SSL_CTX_set_cert_cb(ssl_ctx_.get(), ClientCertRequestCallback, NULL);
davidbena35b40c32017-03-09 17:33:45239
240 // The server certificate is verified after the handshake in DoVerifyCert.
Steven Valdez3eaa9962017-07-18 21:51:05241 SSL_CTX_set_custom_verify(ssl_ctx_.get(), SSL_VERIFY_PEER,
242 CertVerifyCallback);
davidbendafe4e52015-04-08 22:53:52243
244 // Disable the internal session cache. Session caching is handled
svaldeze83af292016-04-26 14:33:37245 // externally (i.e. by SSLClientSessionCache).
davidbendafe4e52015-04-08 22:53:52246 SSL_CTX_set_session_cache_mode(
247 ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
davidben44aeae62015-06-24 20:47:43248 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallback);
davidben99ce6302016-11-09 17:30:28249 SSL_CTX_set_timeout(ssl_ctx_.get(), 1 * 60 * 60 /* one hour */);
nharper736ceda2015-11-07 00:16:59250
davidbenfacfac7b2016-09-27 22:39:53251 SSL_CTX_set_grease_enabled(ssl_ctx_.get(), 1);
252
davidbenbf0fcf12017-02-10 21:00:34253 // Deduplicate all certificates minted from the SSL_CTX in memory.
254 SSL_CTX_set0_buffer_pool(ssl_ctx_.get(), x509_util::GetBufferPool());
255
davidbencef9e212017-04-19 15:00:10256 SSL_CTX_set_msg_callback(ssl_ctx_.get(), MessageCallback);
257
nharper736ceda2015-11-07 00:16:59258 if (!SSL_CTX_add_client_custom_ext(ssl_ctx_.get(), kTbExtNum,
259 &TokenBindingAddCallback,
260 &TokenBindingFreeCallback, nullptr,
261 &TokenBindingParseCallback, nullptr)) {
262 NOTREACHED();
263 }
264 }
265
266 static int TokenBindingAddCallback(SSL* ssl,
267 unsigned int extension_value,
268 const uint8_t** out,
269 size_t* out_len,
270 int* out_alert_value,
271 void* add_arg) {
272 DCHECK_EQ(extension_value, kTbExtNum);
svaldeze83af292016-04-26 14:33:37273 SSLClientSocketImpl* socket =
274 SSLClientSocketImpl::SSLContext::GetInstance()->GetClientSocketFromSSL(
275 ssl);
nharper736ceda2015-11-07 00:16:59276 return socket->TokenBindingAdd(out, out_len, out_alert_value);
277 }
278
279 static void TokenBindingFreeCallback(SSL* ssl,
280 unsigned extension_value,
281 const uint8_t* out,
282 void* add_arg) {
283 DCHECK_EQ(extension_value, kTbExtNum);
284 OPENSSL_free(const_cast<unsigned char*>(out));
285 }
286
287 static int TokenBindingParseCallback(SSL* ssl,
288 unsigned int extension_value,
289 const uint8_t* contents,
290 size_t contents_len,
291 int* out_alert_value,
292 void* parse_arg) {
293 DCHECK_EQ(extension_value, kTbExtNum);
svaldeze83af292016-04-26 14:33:37294 SSLClientSocketImpl* socket =
295 SSLClientSocketImpl::SSLContext::GetInstance()->GetClientSocketFromSSL(
296 ssl);
nharper736ceda2015-11-07 00:16:59297 return socket->TokenBindingParse(contents, contents_len, out_alert_value);
[email protected]fbef13932010-11-23 12:38:53298 }
299
[email protected]82c59022014-08-15 09:38:27300 static int ClientCertRequestCallback(SSL* ssl, void* arg) {
svaldeze83af292016-04-26 14:33:37301 SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
[email protected]82c59022014-08-15 09:38:27302 DCHECK(socket);
303 return socket->ClientCertRequestCallback(ssl);
[email protected]718c9672010-12-02 10:04:10304 }
305
Steven Valdez3eaa9962017-07-18 21:51:05306 static ssl_verify_result_t CertVerifyCallback(SSL* ssl, uint8_t* out_alert) {
307 // The certificate is verified after the handshake in DoVerifyCert.
308 return ssl_verify_ok;
309 }
310
davidben44aeae62015-06-24 20:47:43311 static int NewSessionCallback(SSL* ssl, SSL_SESSION* session) {
svaldeze83af292016-04-26 14:33:37312 SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
davidben44aeae62015-06-24 20:47:43313 return socket->NewSessionCallback(session);
davidbendafe4e52015-04-08 22:53:52314 }
315
David Benjaminb9bafbe2017-11-07 21:41:38316 static ssl_private_key_result_t PrivateKeySignCallback(SSL* ssl,
317 uint8_t* out,
318 size_t* out_len,
319 size_t max_out,
320 uint16_t algorithm,
321 const uint8_t* in,
322 size_t in_len) {
svaldeze83af292016-04-26 14:33:37323 SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
David Benjaminb9bafbe2017-11-07 21:41:38324 return socket->PrivateKeySignCallback(out, out_len, max_out, algorithm, in,
325 in_len);
davidben0bca07fd2016-07-18 15:12:03326 }
327
328 static ssl_private_key_result_t PrivateKeyCompleteCallback(SSL* ssl,
329 uint8_t* out,
330 size_t* out_len,
331 size_t max_out) {
332 SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
333 return socket->PrivateKeyCompleteCallback(out, out_len, max_out);
davidben1d489522015-07-01 18:48:46334 }
335
davidben2a811e4e2015-12-01 10:49:34336#if !defined(OS_NACL)
337 static void KeyLogCallback(const SSL* ssl, const char* line) {
338 GetInstance()->ssl_key_logger_->WriteLine(line);
339 }
340#endif
341
davidbencef9e212017-04-19 15:00:10342 static void MessageCallback(int is_write,
343 int version,
344 int content_type,
345 const void* buf,
346 size_t len,
347 SSL* ssl,
348 void* arg) {
349 SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
350 return socket->MessageCallback(is_write, content_type, buf, len);
351 }
352
[email protected]fbef13932010-11-23 12:38:53353 // This is the index used with SSL_get_ex_data to retrieve the owner
svaldeze83af292016-04-26 14:33:37354 // SSLClientSocketImpl object from an SSL instance.
[email protected]fbef13932010-11-23 12:38:53355 int ssl_socket_data_index_;
356
davidbend80c12c2016-10-11 00:13:49357 bssl::UniquePtr<SSL_CTX> ssl_ctx_;
davidbendafe4e52015-04-08 22:53:52358
davidben2a811e4e2015-12-01 10:49:34359#if !defined(OS_NACL)
danakj655b66c2016-04-16 00:51:38360 std::unique_ptr<SSLKeyLogger> ssl_key_logger_;
davidben2a811e4e2015-12-01 10:49:34361#endif
362
davidbendafe4e52015-04-08 22:53:52363 // TODO(davidben): Use a separate cache per URLRequestContext.
364 // https://crbug.com/458365
365 //
366 // TODO(davidben): Sessions should be invalidated on fatal
367 // alerts. https://crbug.com/466352
svaldeze83af292016-04-26 14:33:37368 SSLClientSessionCache session_cache_;
[email protected]1279de12013-12-03 15:13:32369};
370
davidben0bca07fd2016-07-18 15:12:03371// TODO(davidben): Switch from sign_digest to sign.
davidben1d489522015-07-01 18:48:46372const SSL_PRIVATE_KEY_METHOD
svaldeze83af292016-04-26 14:33:37373 SSLClientSocketImpl::SSLContext::kPrivateKeyMethod = {
davidbene422380772017-04-19 22:20:01374 nullptr /* type (unused) */,
375 nullptr /* max_signature_len (unused) */,
David Benjaminb9bafbe2017-11-07 21:41:38376 &SSLClientSocketImpl::SSLContext::PrivateKeySignCallback,
377 nullptr /* sign_digest */,
davidben0bca07fd2016-07-18 15:12:03378 nullptr /* decrypt */,
379 &SSLClientSocketImpl::SSLContext::PrivateKeyCompleteCallback,
davidben1d489522015-07-01 18:48:46380};
381
[email protected]1279de12013-12-03 15:13:32382// static
[email protected]c3456bb2011-12-12 22:22:19383void SSLClientSocket::ClearSessionCache() {
svaldeze83af292016-04-26 14:33:37384 SSLClientSocketImpl::SSLContext* context =
385 SSLClientSocketImpl::SSLContext::GetInstance();
[email protected]c3456bb2011-12-12 22:22:19386 context->session_cache()->Flush();
387}
388
svaldeze83af292016-04-26 14:33:37389SSLClientSocketImpl::SSLClientSocketImpl(
danakj655b66c2016-04-16 00:51:38390 std::unique_ptr<ClientSocketHandle> transport_socket,
[email protected]055d7f22010-11-15 12:03:12391 const HostPortPair& host_and_port,
[email protected]822581d2010-12-16 17:27:15392 const SSLConfig& ssl_config,
[email protected]feb79bcd2011-07-21 16:55:17393 const SSLClientSocketContext& context)
davidben3418e81f2016-10-19 00:09:45394 : pending_read_error_(kNoPendingResult),
davidbenb8c23212014-10-28 00:12:16395 pending_read_ssl_error_(SSL_ERROR_NONE),
[email protected]64b5c892014-08-08 09:39:26396 completed_connect_(false),
[email protected]0dc88b32014-03-26 20:12:28397 was_ever_used_(false),
[email protected]feb79bcd2011-07-21 16:55:17398 cert_verifier_(context.cert_verifier),
davidbeneb5f8ef32014-09-04 14:14:32399 cert_transparency_verifier_(context.cert_transparency_verifier),
[email protected]6b8a3c742014-07-25 00:25:35400 channel_id_service_(context.channel_id_service),
nharper736ceda2015-11-07 00:16:59401 tb_was_negotiated_(false),
402 tb_negotiated_param_(TB_PARAM_ECDSAP256),
nharper78e6d2b2016-09-21 05:42:35403 tb_signature_map_(10),
dchengc7eeda422015-12-26 03:56:48404 transport_(std::move(transport_socket)),
[email protected]055d7f22010-11-15 12:03:12405 host_and_port_(host_and_port),
[email protected]d518cd92010-09-29 12:27:44406 ssl_config_(ssl_config),
[email protected]c3456bb2011-12-12 22:22:19407 ssl_session_cache_shard_(context.ssl_session_cache_shard),
[email protected]013c17c2012-01-21 19:09:01408 next_handshake_state_(STATE_NONE),
svaldez4af14d22015-08-20 13:48:24409 disconnected_(false),
bnc3cf2a592016-08-11 14:48:36410 negotiated_protocol_(kProtoUnknown),
davidben52053b382015-04-27 19:22:29411 channel_id_sent_(false),
davidbendafe4e52015-04-08 22:53:52412 certificate_verified_(false),
davidbenfe132d92016-09-27 18:07:21413 certificate_requested_(false),
davidben1d489522015-07-01 18:48:46414 signature_result_(kNoPendingResult),
[email protected]8bd4e7a2014-08-09 14:49:17415 transport_security_state_(context.transport_security_state),
estark6f9b3d82016-01-12 21:37:05416 policy_enforcer_(context.ct_policy_enforcer),
dadriandf302c42016-06-10 18:48:59417 pkp_bypassed_(false),
David Benjamine34d74242017-06-29 20:35:16418 connect_error_details_(SSLErrorDetails::kOther),
kulkarni.acd7b4462014-08-28 07:41:34419 net_log_(transport_->socket()->NetLog()),
420 weak_factory_(this) {
rsleevibe81cd62016-06-24 01:38:59421 CHECK(cert_verifier_);
422 CHECK(transport_security_state_);
423 CHECK(cert_transparency_verifier_);
424 CHECK(policy_enforcer_);
[email protected]8e458552014-08-05 00:02:15425}
[email protected]d518cd92010-09-29 12:27:44426
svaldeze83af292016-04-26 14:33:37427SSLClientSocketImpl::~SSLClientSocketImpl() {
[email protected]d518cd92010-09-29 12:27:44428 Disconnect();
429}
430
davidben2a811e4e2015-12-01 10:49:34431#if !defined(OS_NACL)
svaldeze83af292016-04-26 14:33:37432void SSLClientSocketImpl::SetSSLKeyLogFile(
David Benjamindc2f4b02017-07-27 23:59:02433 const base::FilePath& ssl_keylog_file) {
434 SSLContext::GetInstance()->SetSSLKeyLogFile(ssl_keylog_file);
zhongyi81f85c6d92015-10-16 19:34:14435}
davidben2a811e4e2015-12-01 10:49:34436#endif
zhongyi81f85c6d92015-10-16 19:34:14437
svaldeze83af292016-04-26 14:33:37438void SSLClientSocketImpl::GetSSLCertRequestInfo(
[email protected]b9b651f2013-11-09 04:32:22439 SSLCertRequestInfo* cert_request_info) {
davidbenb11fd212017-01-12 17:08:03440 if (!ssl_) {
441 NOTREACHED();
442 return;
443 }
444
[email protected]791879c2013-12-17 07:22:41445 cert_request_info->host_and_port = host_and_port_;
davidbenb11fd212017-01-12 17:08:03446
447 cert_request_info->cert_authorities.clear();
davidbena35b40c32017-03-09 17:33:45448 const STACK_OF(CRYPTO_BUFFER)* authorities =
449 SSL_get0_server_requested_CAs(ssl_.get());
450 for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(authorities); i++) {
451 const CRYPTO_BUFFER* ca_name = sk_CRYPTO_BUFFER_value(authorities, i);
452 cert_request_info->cert_authorities.push_back(
453 std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(ca_name)),
454 CRYPTO_BUFFER_len(ca_name)));
davidbenb11fd212017-01-12 17:08:03455 }
456
457 cert_request_info->cert_key_types.clear();
458 const uint8_t* client_cert_types;
459 size_t num_client_cert_types =
460 SSL_get0_certificate_types(ssl_.get(), &client_cert_types);
461 for (size_t i = 0; i < num_client_cert_types; i++) {
462 cert_request_info->cert_key_types.push_back(
463 static_cast<SSLClientCertType>(client_cert_types[i]));
464 }
[email protected]b9b651f2013-11-09 04:32:22465}
466
svaldeze83af292016-04-26 14:33:37467ChannelIDService* SSLClientSocketImpl::GetChannelIDService() const {
[email protected]6b8a3c742014-07-25 00:25:35468 return channel_id_service_;
[email protected]b9b651f2013-11-09 04:32:22469}
470
nharper78e6d2b2016-09-21 05:42:35471Error SSLClientSocketImpl::GetTokenBindingSignature(crypto::ECPrivateKey* key,
472 TokenBindingType tb_type,
473 std::vector<uint8_t>* out) {
nharperb7441ef2016-01-25 23:54:14474 // The same key will be used across multiple requests to sign the same value,
475 // so the signature is cached.
476 std::string raw_public_key;
477 if (!key->ExportRawPublicKey(&raw_public_key))
478 return ERR_FAILED;
nharper78e6d2b2016-09-21 05:42:35479 auto it = tb_signature_map_.Get(std::make_pair(tb_type, raw_public_key));
480 if (it != tb_signature_map_.end()) {
nharperb7441ef2016-01-25 23:54:14481 *out = it->second;
482 return OK;
483 }
484
485 uint8_t tb_ekm_buf[32];
486 static const char kTokenBindingExporterLabel[] = "EXPORTER-Token-Binding";
davidbend80c12c2016-10-11 00:13:49487 if (!SSL_export_keying_material(ssl_.get(), tb_ekm_buf, sizeof(tb_ekm_buf),
nharperb7441ef2016-01-25 23:54:14488 kTokenBindingExporterLabel,
489 strlen(kTokenBindingExporterLabel), nullptr,
490 0, false /* no context */)) {
491 return ERR_FAILED;
492 }
493
nharper78e6d2b2016-09-21 05:42:35494 if (!CreateTokenBindingSignature(
nharperd5cddca2016-02-27 03:37:52495 base::StringPiece(reinterpret_cast<char*>(tb_ekm_buf),
496 sizeof(tb_ekm_buf)),
nharper78e6d2b2016-09-21 05:42:35497 tb_type, key, out))
nharperb7441ef2016-01-25 23:54:14498 return ERR_FAILED;
nharperb7441ef2016-01-25 23:54:14499
nharper78e6d2b2016-09-21 05:42:35500 tb_signature_map_.Put(std::make_pair(tb_type, raw_public_key), *out);
nharperb7441ef2016-01-25 23:54:14501 return OK;
502}
503
svaldeze83af292016-04-26 14:33:37504crypto::ECPrivateKey* SSLClientSocketImpl::GetChannelIDKey() const {
nharperb36644f2016-02-22 23:14:43505 return channel_id_key_.get();
506}
507
David Benjamine34d74242017-06-29 20:35:16508SSLErrorDetails SSLClientSocketImpl::GetConnectErrorDetails() const {
509 return connect_error_details_;
510}
511
svaldeze83af292016-04-26 14:33:37512int SSLClientSocketImpl::ExportKeyingMaterial(const base::StringPiece& label,
513 bool has_context,
514 const base::StringPiece& context,
515 unsigned char* out,
516 unsigned int outlen) {
davidben86935f72015-05-06 22:24:49517 if (!IsConnected())
518 return ERR_SOCKET_NOT_CONNECTED;
519
[email protected]b9b651f2013-11-09 04:32:22520 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
521
davidbenf225b262016-09-15 22:09:22522 if (!SSL_export_keying_material(
davidbend80c12c2016-10-11 00:13:49523 ssl_.get(), out, outlen, label.data(), label.size(),
davidbenf225b262016-09-15 22:09:22524 reinterpret_cast<const unsigned char*>(context.data()),
525 context.length(), has_context ? 1 : 0)) {
526 LOG(ERROR) << "Failed to export keying material.";
527 return ERR_FAILED;
[email protected]b9b651f2013-11-09 04:32:22528 }
davidbenf225b262016-09-15 22:09:22529
[email protected]b9b651f2013-11-09 04:32:22530 return OK;
531}
532
svaldeze83af292016-04-26 14:33:37533int SSLClientSocketImpl::Connect(const CompletionCallback& callback) {
svaldez4af14d22015-08-20 13:48:24534 // Although StreamSocket does allow calling Connect() after Disconnect(),
535 // this has never worked for layered sockets. CHECK to detect any consumers
536 // reconnecting an SSL socket.
537 //
538 // TODO(davidben,mmenke): Remove this API feature. See
539 // https://crbug.com/499289.
540 CHECK(!disconnected_);
541
mikecirone8b85c432016-09-08 19:11:00542 net_log_.BeginEvent(NetLogEventType::SSL_CONNECT);
[email protected]b9b651f2013-11-09 04:32:22543
544 // Set up new ssl object.
[email protected]c8a80e92014-05-17 16:02:08545 int rv = Init();
546 if (rv != OK) {
davidben281d13f02016-04-27 20:43:28547 LogConnectEndEvent(rv);
[email protected]c8a80e92014-05-17 16:02:08548 return rv;
[email protected]b9b651f2013-11-09 04:32:22549 }
550
551 // Set SSL to client mode. Handshake happens in the loop below.
davidbend80c12c2016-10-11 00:13:49552 SSL_set_connect_state(ssl_.get());
[email protected]b9b651f2013-11-09 04:32:22553
rsleeviadbd4982016-06-13 22:10:27554 next_handshake_state_ = STATE_HANDSHAKE;
[email protected]c8a80e92014-05-17 16:02:08555 rv = DoHandshakeLoop(OK);
[email protected]b9b651f2013-11-09 04:32:22556 if (rv == ERR_IO_PENDING) {
557 user_connect_callback_ = callback;
558 } else {
davidben281d13f02016-04-27 20:43:28559 LogConnectEndEvent(rv);
[email protected]b9b651f2013-11-09 04:32:22560 }
561
562 return rv > OK ? OK : rv;
563}
564
svaldeze83af292016-04-26 14:33:37565void SSLClientSocketImpl::Disconnect() {
svaldez4af14d22015-08-20 13:48:24566 disconnected_ = true;
567
[email protected]b9b651f2013-11-09 04:32:22568 // Shut down anything that may call us back.
eroman7f9236a2015-05-11 21:23:43569 cert_verifier_request_.reset();
davidben67e83912016-10-12 18:36:32570 channel_id_request_.Cancel();
571 weak_factory_.InvalidateWeakPtrs();
davidben3418e81f2016-10-19 00:09:45572 transport_adapter_.reset();
[email protected]b9b651f2013-11-09 04:32:22573
davidben67e83912016-10-12 18:36:32574 // Release user callbacks.
[email protected]b9b651f2013-11-09 04:32:22575 user_connect_callback_.Reset();
576 user_read_callback_.Reset();
577 user_write_callback_.Reset();
svaldeze83af292016-04-26 14:33:37578 user_read_buf_ = NULL;
579 user_read_buf_len_ = 0;
580 user_write_buf_ = NULL;
581 user_write_buf_len_ = 0;
[email protected]b9b651f2013-11-09 04:32:22582
davidben67e83912016-10-12 18:36:32583 transport_->socket()->Disconnect();
[email protected]b9b651f2013-11-09 04:32:22584}
585
svaldeze83af292016-04-26 14:33:37586bool SSLClientSocketImpl::IsConnected() const {
davidben67e83912016-10-12 18:36:32587 // If the handshake has not yet completed or the socket has been explicitly
588 // disconnected.
589 if (!completed_connect_ || disconnected_)
[email protected]b9b651f2013-11-09 04:32:22590 return false;
591 // If an asynchronous operation is still pending.
592 if (user_read_buf_.get() || user_write_buf_.get())
593 return true;
594
595 return transport_->socket()->IsConnected();
596}
597
svaldeze83af292016-04-26 14:33:37598bool SSLClientSocketImpl::IsConnectedAndIdle() const {
davidben67e83912016-10-12 18:36:32599 // If the handshake has not yet completed or the socket has been explicitly
600 // disconnected.
601 if (!completed_connect_ || disconnected_)
[email protected]b9b651f2013-11-09 04:32:22602 return false;
603 // If an asynchronous operation is still pending.
604 if (user_read_buf_.get() || user_write_buf_.get())
605 return false;
davidbenfc9a6b82015-04-15 23:47:32606
607 // If there is data read from the network that has not yet been consumed, do
608 // not treat the connection as idle.
609 //
davidben3418e81f2016-10-19 00:09:45610 // Note that this does not check whether there is ciphertext that has not yet
611 // been flushed to the network. |Write| returns early, so this can cause race
612 // conditions which cause a socket to not be treated reusable when it should
613 // be. See https://crbug.com/466147.
614 if (transport_adapter_->HasPendingReadData())
[email protected]b9b651f2013-11-09 04:32:22615 return false;
[email protected]b9b651f2013-11-09 04:32:22616
617 return transport_->socket()->IsConnectedAndIdle();
618}
619
svaldeze83af292016-04-26 14:33:37620int SSLClientSocketImpl::GetPeerAddress(IPEndPoint* addressList) const {
[email protected]b9b651f2013-11-09 04:32:22621 return transport_->socket()->GetPeerAddress(addressList);
622}
623
svaldeze83af292016-04-26 14:33:37624int SSLClientSocketImpl::GetLocalAddress(IPEndPoint* addressList) const {
[email protected]b9b651f2013-11-09 04:32:22625 return transport_->socket()->GetLocalAddress(addressList);
626}
627
tfarina42834112016-09-22 13:38:20628const NetLogWithSource& SSLClientSocketImpl::NetLog() const {
[email protected]b9b651f2013-11-09 04:32:22629 return net_log_;
630}
631
svaldeze83af292016-04-26 14:33:37632void SSLClientSocketImpl::SetSubresourceSpeculation() {
[email protected]b9b651f2013-11-09 04:32:22633 if (transport_.get() && transport_->socket()) {
634 transport_->socket()->SetSubresourceSpeculation();
635 } else {
636 NOTREACHED();
637 }
638}
639
svaldeze83af292016-04-26 14:33:37640void SSLClientSocketImpl::SetOmniboxSpeculation() {
[email protected]b9b651f2013-11-09 04:32:22641 if (transport_.get() && transport_->socket()) {
642 transport_->socket()->SetOmniboxSpeculation();
643 } else {
644 NOTREACHED();
645 }
646}
647
svaldeze83af292016-04-26 14:33:37648bool SSLClientSocketImpl::WasEverUsed() const {
[email protected]0dc88b32014-03-26 20:12:28649 return was_ever_used_;
[email protected]b9b651f2013-11-09 04:32:22650}
651
tfarina2846404c2016-12-25 14:31:37652bool SSLClientSocketImpl::WasAlpnNegotiated() const {
bnc3cf2a592016-08-11 14:48:36653 return negotiated_protocol_ != kProtoUnknown;
654}
655
656NextProto SSLClientSocketImpl::GetNegotiatedProtocol() const {
657 return negotiated_protocol_;
658}
659
svaldeze83af292016-04-26 14:33:37660bool SSLClientSocketImpl::GetSSLInfo(SSLInfo* ssl_info) {
[email protected]b9b651f2013-11-09 04:32:22661 ssl_info->Reset();
davidbenc7e06c92017-03-07 18:54:11662 if (!server_cert_)
[email protected]b9b651f2013-11-09 04:32:22663 return false;
664
665 ssl_info->cert = server_cert_verify_result_.verified_cert;
estark03d644f2015-06-13 00:11:32666 ssl_info->unverified_cert = server_cert_;
[email protected]b9b651f2013-11-09 04:32:22667 ssl_info->cert_status = server_cert_verify_result_.cert_status;
668 ssl_info->is_issued_by_known_root =
669 server_cert_verify_result_.is_issued_by_known_root;
dadriandf302c42016-06-10 18:48:59670 ssl_info->pkp_bypassed = pkp_bypassed_;
svaldeze83af292016-04-26 14:33:37671 ssl_info->public_key_hashes = server_cert_verify_result_.public_key_hashes;
[email protected]b9b651f2013-11-09 04:32:22672 ssl_info->client_cert_sent =
673 ssl_config_.send_client_cert && ssl_config_.client_cert.get();
davidben52053b382015-04-27 19:22:29674 ssl_info->channel_id_sent = channel_id_sent_;
nharper736ceda2015-11-07 00:16:59675 ssl_info->token_binding_negotiated = tb_was_negotiated_;
676 ssl_info->token_binding_key_param = tb_negotiated_param_;
[email protected]8bd4e7a2014-08-09 14:49:17677 ssl_info->pinning_failure_log = pinning_failure_log_;
dadrian612337a2016-07-20 22:36:58678 ssl_info->ocsp_result = server_cert_verify_result_.ocsp_result;
[email protected]b9b651f2013-11-09 04:32:22679
estark723b5eeb2016-02-18 21:01:12680 AddCTInfoToSSLInfo(ssl_info);
davidbeneb5f8ef32014-09-04 14:14:32681
davidbend80c12c2016-10-11 00:13:49682 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_.get());
[email protected]b9b651f2013-11-09 04:32:22683 CHECK(cipher);
684 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL);
davidben3b00e402016-09-20 14:31:06685 // Historically, the "group" was known as "curve".
davidbend80c12c2016-10-11 00:13:49686 ssl_info->key_exchange_group = SSL_get_curve_id(ssl_.get());
[email protected]b9b651f2013-11-09 04:32:22687
ryanchung987b2ff2016-02-19 00:17:12688 SSLConnectionStatusSetCipherSuite(
689 static_cast<uint16_t>(SSL_CIPHER_get_id(cipher)),
690 &ssl_info->connection_status);
davidbend80c12c2016-10-11 00:13:49691 SSLConnectionStatusSetVersion(GetNetSSLVersion(ssl_.get()),
ryanchung987b2ff2016-02-19 00:17:12692 &ssl_info->connection_status);
[email protected]b9b651f2013-11-09 04:32:22693
davidbend80c12c2016-10-11 00:13:49694 ssl_info->handshake_type = SSL_session_reused(ssl_.get())
svaldeze83af292016-04-26 14:33:37695 ? SSLInfo::HANDSHAKE_RESUME
696 : SSLInfo::HANDSHAKE_FULL;
[email protected]b9b651f2013-11-09 04:32:22697
[email protected]b9b651f2013-11-09 04:32:22698 return true;
699}
700
svaldeze83af292016-04-26 14:33:37701void SSLClientSocketImpl::GetConnectionAttempts(ConnectionAttempts* out) const {
ttuttle23fdb7b2015-05-15 01:28:03702 out->clear();
703}
704
svaldeze83af292016-04-26 14:33:37705int64_t SSLClientSocketImpl::GetTotalReceivedBytes() const {
tbansalf82cc8e2015-10-14 20:05:49706 return transport_->socket()->GetTotalReceivedBytes();
707}
708
xunjieli998d2472017-01-12 01:12:28709void SSLClientSocketImpl::DumpMemoryStats(SocketMemoryStats* stats) const {
710 if (transport_adapter_)
711 stats->buffer_size = transport_adapter_->GetAllocationSize();
davidbena35b40c32017-03-09 17:33:45712 const STACK_OF(CRYPTO_BUFFER)* server_cert_chain =
713 SSL_get0_peer_certificates(ssl_.get());
davidbenc7e06c92017-03-07 18:54:11714 if (server_cert_chain) {
davidbena35b40c32017-03-09 17:33:45715 for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(server_cert_chain); ++i) {
716 const CRYPTO_BUFFER* cert = sk_CRYPTO_BUFFER_value(server_cert_chain, i);
717 stats->cert_size += CRYPTO_BUFFER_len(cert);
xunjieli9f8c5fb52016-12-07 22:59:33718 }
davidbena35b40c32017-03-09 17:33:45719 stats->cert_count = sk_CRYPTO_BUFFER_num(server_cert_chain);
xunjieli9f8c5fb52016-12-07 22:59:33720 }
xunjieliffe62df62017-02-23 18:22:41721 stats->total_size = stats->buffer_size + stats->cert_size;
xunjieli9f8c5fb52016-12-07 22:59:33722}
723
724// static
725void SSLClientSocketImpl::DumpSSLClientSessionMemoryStats(
726 base::trace_event::ProcessMemoryDump* pmd) {
727 SSLContext::GetInstance()->session_cache()->DumpMemoryStats(pmd);
728}
729
svaldeze83af292016-04-26 14:33:37730int SSLClientSocketImpl::Read(IOBuffer* buf,
731 int buf_len,
732 const CompletionCallback& callback) {
xunjieli321a96f32017-03-07 19:42:17733 int rv = ReadIfReady(buf, buf_len, callback);
734 if (rv == ERR_IO_PENDING) {
735 user_read_buf_ = buf;
736 user_read_buf_len_ = buf_len;
737 }
738 return rv;
739}
[email protected]b9b651f2013-11-09 04:32:22740
xunjieli321a96f32017-03-07 19:42:17741int SSLClientSocketImpl::ReadIfReady(IOBuffer* buf,
742 int buf_len,
743 const CompletionCallback& callback) {
744 int rv = DoPayloadRead(buf, buf_len);
[email protected]b9b651f2013-11-09 04:32:22745
746 if (rv == ERR_IO_PENDING) {
747 user_read_callback_ = callback;
748 } else {
[email protected]0dc88b32014-03-26 20:12:28749 if (rv > 0)
750 was_ever_used_ = true;
[email protected]b9b651f2013-11-09 04:32:22751 }
[email protected]b9b651f2013-11-09 04:32:22752 return rv;
753}
754
svaldeze83af292016-04-26 14:33:37755int SSLClientSocketImpl::Write(IOBuffer* buf,
756 int buf_len,
757 const CompletionCallback& callback) {
[email protected]b9b651f2013-11-09 04:32:22758 user_write_buf_ = buf;
759 user_write_buf_len_ = buf_len;
760
davidben3418e81f2016-10-19 00:09:45761 int rv = DoPayloadWrite();
[email protected]b9b651f2013-11-09 04:32:22762
763 if (rv == ERR_IO_PENDING) {
764 user_write_callback_ = callback;
765 } else {
[email protected]0dc88b32014-03-26 20:12:28766 if (rv > 0)
767 was_ever_used_ = true;
[email protected]b9b651f2013-11-09 04:32:22768 user_write_buf_ = NULL;
769 user_write_buf_len_ = 0;
770 }
771
772 return rv;
773}
774
svaldeze83af292016-04-26 14:33:37775int SSLClientSocketImpl::SetReceiveBufferSize(int32_t size) {
[email protected]b9b651f2013-11-09 04:32:22776 return transport_->socket()->SetReceiveBufferSize(size);
777}
778
svaldeze83af292016-04-26 14:33:37779int SSLClientSocketImpl::SetSendBufferSize(int32_t size) {
[email protected]b9b651f2013-11-09 04:32:22780 return transport_->socket()->SetSendBufferSize(size);
781}
782
davidben3418e81f2016-10-19 00:09:45783void SSLClientSocketImpl::OnReadReady() {
784 // During a renegotiation, either Read or Write calls may be blocked on a
785 // transport read.
786 RetryAllOperations();
787}
788
789void SSLClientSocketImpl::OnWriteReady() {
790 // During a renegotiation, either Read or Write calls may be blocked on a
791 // transport read.
792 RetryAllOperations();
793}
794
svaldeze83af292016-04-26 14:33:37795int SSLClientSocketImpl::Init() {
[email protected]9e733f32010-10-04 18:19:08796 DCHECK(!ssl_);
[email protected]9e733f32010-10-04 18:19:08797
svaldez2135be52016-04-20 16:34:53798#if defined(USE_NSS_CERTS)
davidbena477a70a2015-10-06 04:38:29799 if (ssl_config_.cert_io_enabled) {
800 // TODO(davidben): Move this out of SSLClientSocket. See
801 // https://crbug.com/539520.
802 EnsureNSSHttpIOInit();
803 }
804#endif
805
[email protected]b29af7d2010-12-14 11:52:47806 SSLContext* context = SSLContext::GetInstance();
[email protected]4b559b4d2011-04-14 17:37:14807 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
[email protected]d518cd92010-09-29 12:27:44808
davidbend80c12c2016-10-11 00:13:49809 ssl_.reset(SSL_new(context->ssl_ctx()));
810 if (!ssl_ || !context->SetClientSocketForSSL(ssl_.get(), this))
[email protected]c8a80e92014-05-17 16:02:08811 return ERR_UNEXPECTED;
[email protected]fbef13932010-11-23 12:38:53812
davidben9bc0466f2015-06-16 22:21:27813 // SNI should only contain valid DNS hostnames, not IP addresses (see RFC
814 // 6066, Section 3).
815 //
816 // TODO(rsleevi): Should this code allow hostnames that violate the LDH rule?
817 // See https://crbug.com/496472 and https://crbug.com/496468 for discussion.
martijna2e83bd2016-03-18 13:10:45818 IPAddress unused;
819 if (!unused.AssignFromIPLiteral(host_and_port_.host()) &&
davidbend80c12c2016-10-11 00:13:49820 !SSL_set_tlsext_host_name(ssl_.get(), host_and_port_.host().c_str())) {
[email protected]c8a80e92014-05-17 16:02:08821 return ERR_UNEXPECTED;
davidben9bc0466f2015-06-16 22:21:27822 }
[email protected]fbef13932010-11-23 12:38:53823
David Benjaminb3840f42017-08-03 15:50:16824 if (!ssl_session_cache_shard_.empty()) {
Steven Valdeze6112f42017-10-05 22:20:12825 bssl::UniquePtr<SSL_SESSION> session =
826 context->session_cache()->Lookup(GetSessionCacheKey());
David Benjaminb3840f42017-08-03 15:50:16827 if (session)
828 SSL_set_session(ssl_.get(), session.get());
829 }
[email protected]d518cd92010-09-29 12:27:44830
davidben3418e81f2016-10-19 00:09:45831 transport_adapter_.reset(new SocketBIOAdapter(
832 transport_->socket(), GetBufferSize("SSLBufferSizeRecv"),
833 GetBufferSize("SSLBufferSizeSend"), this));
834 BIO* transport_bio = transport_adapter_->bio();
mmenke1beda3d2016-07-22 03:33:45835
davidben3418e81f2016-10-19 00:09:45836 BIO_up_ref(transport_bio); // SSL_set0_rbio takes ownership.
837 SSL_set0_rbio(ssl_.get(), transport_bio);
haavardm2d92e722014-12-19 13:45:44838
davidben3418e81f2016-10-19 00:09:45839 BIO_up_ref(transport_bio); // SSL_set0_wbio takes ownership.
840 SSL_set0_wbio(ssl_.get(), transport_bio);
[email protected]d518cd92010-09-29 12:27:44841
davidbenb937d6c2015-05-14 04:53:42842 DCHECK_LT(SSL3_VERSION, ssl_config_.version_min);
843 DCHECK_LT(SSL3_VERSION, ssl_config_.version_max);
davidbend80c12c2016-10-11 00:13:49844 if (!SSL_set_min_proto_version(ssl_.get(), ssl_config_.version_min) ||
845 !SSL_set_max_proto_version(ssl_.get(), ssl_config_.version_max)) {
davidben952bdf22016-09-21 23:42:16846 return ERR_UNEXPECTED;
847 }
davidbenb937d6c2015-05-14 04:53:42848
Steven Valdez4584b2482017-07-14 01:11:57849 switch (ssl_config_.tls13_variant) {
850 case kTLS13VariantDraft:
851 SSL_set_tls13_variant(ssl_.get(), tls13_default);
852 break;
853 case kTLS13VariantExperiment:
854 SSL_set_tls13_variant(ssl_.get(), tls13_experiment);
855 break;
Steven Valdezf00f8782017-09-13 18:05:28856 case kTLS13VariantExperiment2:
857 SSL_set_tls13_variant(ssl_.get(), tls13_experiment2);
858 break;
859 case kTLS13VariantExperiment3:
860 SSL_set_tls13_variant(ssl_.get(), tls13_experiment3);
861 break;
Steven Valdez4584b2482017-07-14 01:11:57862 }
863
[email protected]9e733f32010-10-04 18:19:08864 // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
865 // set everything we care about to an absolute value.
[email protected]fb10e2282010-12-01 17:08:48866 SslSetClearMask options;
[email protected]d0f00492012-08-03 22:35:13867 options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true);
[email protected]9e733f32010-10-04 18:19:08868
869 // TODO(joth): Set this conditionally, see http://crbug.com/55410
[email protected]fb10e2282010-12-01 17:08:48870 options.ConfigureFlag(SSL_OP_LEGACY_SERVER_CONNECT, true);
[email protected]9e733f32010-10-04 18:19:08871
davidbend80c12c2016-10-11 00:13:49872 SSL_set_options(ssl_.get(), options.set_mask);
873 SSL_clear_options(ssl_.get(), options.clear_mask);
[email protected]9e733f32010-10-04 18:19:08874
[email protected]fb10e2282010-12-01 17:08:48875 // Same as above, this time for the SSL mode.
876 SslSetClearMask mode;
[email protected]9e733f32010-10-04 18:19:08877
[email protected]fb10e2282010-12-01 17:08:48878 mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true);
ishermane5c05e12014-09-09 20:32:15879 mode.ConfigureFlag(SSL_MODE_CBC_RECORD_SPLITTING, true);
[email protected]fb10e2282010-12-01 17:08:48880
davidben818d93b2015-02-19 22:27:32881 mode.ConfigureFlag(SSL_MODE_ENABLE_FALSE_START,
[email protected]b788de02014-04-23 18:06:07882 ssl_config_.false_start_enabled);
883
davidbend80c12c2016-10-11 00:13:49884 SSL_set_mode(ssl_.get(), mode.set_mask);
885 SSL_clear_mode(ssl_.get(), mode.clear_mask);
[email protected]109805a2010-12-07 18:17:06886
davidben4177ecb2016-10-22 01:47:18887 // Use BoringSSL defaults, but disable HMAC-SHA256 and HMAC-SHA384 ciphers
kjellander1ae83a02017-01-26 07:35:09888 // (note that SHA256 and SHA384 only select legacy CBC ciphers).
davidben0b6de432017-03-23 22:11:05889 // Additionally disable HMAC-SHA1 ciphers in ECDSA. These are the remaining
890 // CBC-mode ECDSA ciphers.
davidben1863716b2017-05-03 20:06:20891 std::string command("ALL:!SHA256:!SHA384:!aPSK:!ECDSA+SHA1");
davidben9b4a9b9c2015-10-12 18:46:51892
893 if (ssl_config_.require_ecdhe)
davidben1863716b2017-05-03 20:06:20894 command.append(":!kRSA");
davidben8ecc3072014-09-03 23:19:09895
davidben9b4a9b9c2015-10-12 18:46:51896 // Remove any disabled ciphers.
897 for (uint16_t id : ssl_config_.disabled_cipher_suites) {
898 const SSL_CIPHER* cipher = SSL_get_cipher_by_value(id);
899 if (cipher) {
900 command.append(":!");
901 command.append(SSL_CIPHER_get_name(cipher));
902 }
903 }
904
davidben1863716b2017-05-03 20:06:20905 if (!SSL_set_strict_cipher_list(ssl_.get(), command.c_str())) {
906 LOG(ERROR) << "SSL_set_cipher_list('" << command << "') failed";
907 return ERR_UNEXPECTED;
908 }
[email protected]ee0f2aa82013-10-25 11:59:26909
910 // TLS channel ids.
bnc3cf2a592016-08-11 14:48:36911 if (IsChannelIDEnabled()) {
davidbend80c12c2016-10-11 00:13:49912 SSL_enable_tls_channel_id(ssl_.get());
[email protected]ee0f2aa82013-10-25 11:59:26913 }
914
bnc1f295372015-10-21 23:24:22915 if (!ssl_config_.alpn_protos.empty()) {
bnc988e68d2016-06-27 14:03:21916 std::vector<uint8_t> wire_protos =
917 SerializeNextProtos(ssl_config_.alpn_protos);
davidbend80c12c2016-10-11 00:13:49918 SSL_set_alpn_protos(ssl_.get(),
919 wire_protos.empty() ? NULL : &wire_protos[0],
[email protected]abc44b752014-07-30 03:52:15920 wire_protos.size());
921 }
922
davidbeneb5f8ef32014-09-04 14:14:32923 if (ssl_config_.signed_cert_timestamps_enabled) {
davidbend80c12c2016-10-11 00:13:49924 SSL_enable_signed_cert_timestamps(ssl_.get());
925 SSL_enable_ocsp_stapling(ssl_.get());
davidbeneb5f8ef32014-09-04 14:14:32926 }
927
davidben15f57132015-04-27 18:08:36928 if (cert_verifier_->SupportsOCSPStapling())
davidbend80c12c2016-10-11 00:13:49929 SSL_enable_ocsp_stapling(ssl_.get());
davidbeneb5f8ef32014-09-04 14:14:32930
davidben971a681a2017-02-16 18:57:46931 // Configure BoringSSL to allow renegotiations. Once the initial handshake
932 // completes, if renegotiations are not allowed, the default reject value will
933 // be restored. This is done in this order to permit a BoringSSL
934 // optimization. See https://crbug.com/boringssl/123.
935 SSL_set_renegotiate_mode(ssl_.get(), ssl_renegotiate_freely);
936
[email protected]c8a80e92014-05-17 16:02:08937 return OK;
[email protected]d518cd92010-09-29 12:27:44938}
939
svaldeze83af292016-04-26 14:33:37940void SSLClientSocketImpl::DoReadCallback(int rv) {
[email protected]b9b651f2013-11-09 04:32:22941 // Since Run may result in Read being called, clear |user_read_callback_|
942 // up front.
[email protected]0dc88b32014-03-26 20:12:28943 if (rv > 0)
944 was_ever_used_ = true;
xunjieli321a96f32017-03-07 19:42:17945 user_read_buf_ = nullptr;
[email protected]b9b651f2013-11-09 04:32:22946 user_read_buf_len_ = 0;
947 base::ResetAndReturn(&user_read_callback_).Run(rv);
948}
949
svaldeze83af292016-04-26 14:33:37950void SSLClientSocketImpl::DoWriteCallback(int rv) {
[email protected]b9b651f2013-11-09 04:32:22951 // Since Run may result in Write being called, clear |user_write_callback_|
952 // up front.
[email protected]0dc88b32014-03-26 20:12:28953 if (rv > 0)
954 was_ever_used_ = true;
[email protected]b9b651f2013-11-09 04:32:22955 user_write_buf_ = NULL;
956 user_write_buf_len_ = 0;
957 base::ResetAndReturn(&user_write_callback_).Run(rv);
958}
959
pkasting379234c2015-04-08 04:42:12960// TODO(cbentzel): Remove including "base/threading/thread_local.h" and
vadimt6b43dec22015-01-06 01:59:58961// g_first_run_completed once crbug.com/424386 is fixed.
962base::LazyInstance<base::ThreadLocalBoolean>::Leaky g_first_run_completed =
963 LAZY_INSTANCE_INITIALIZER;
964
svaldeze83af292016-04-26 14:33:37965int SSLClientSocketImpl::DoHandshake() {
[email protected]b9b651f2013-11-09 04:32:22966 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
vadimt5a243282014-12-24 00:26:16967
968 int rv;
969
pkasting379234c2015-04-08 04:42:12970 // TODO(cbentzel): Leave only 1 call to SSL_do_handshake once crbug.com/424386
vadimt5a243282014-12-24 00:26:16971 // is fixed.
972 if (ssl_config_.send_client_cert && ssl_config_.client_cert.get()) {
davidbend80c12c2016-10-11 00:13:49973 rv = SSL_do_handshake(ssl_.get());
vadimt5a243282014-12-24 00:26:16974 } else {
vadimt6b43dec22015-01-06 01:59:58975 if (g_first_run_completed.Get().Get()) {
davidbend80c12c2016-10-11 00:13:49976 rv = SSL_do_handshake(ssl_.get());
vadimt6b43dec22015-01-06 01:59:58977 } else {
978 g_first_run_completed.Get().Set(true);
davidbend80c12c2016-10-11 00:13:49979 rv = SSL_do_handshake(ssl_.get());
vadimt6b43dec22015-01-06 01:59:58980 }
vadimt5a243282014-12-24 00:26:16981 }
[email protected]b9b651f2013-11-09 04:32:22982
davidbenc4212c02015-05-12 22:30:18983 int net_error = OK;
984 if (rv <= 0) {
davidbend80c12c2016-10-11 00:13:49985 int ssl_error = SSL_get_error(ssl_.get(), rv);
[email protected]b9b651f2013-11-09 04:32:22986 if (ssl_error == SSL_ERROR_WANT_CHANNEL_ID_LOOKUP) {
[email protected]faff9852014-06-21 06:13:46987 // The server supports channel ID. Stop to look one up before returning to
988 // the handshake.
rsleeviadbd4982016-06-13 22:10:27989 next_handshake_state_ = STATE_CHANNEL_ID_LOOKUP;
[email protected]faff9852014-06-21 06:13:46990 return OK;
[email protected]b9b651f2013-11-09 04:32:22991 }
davidbenced4aa9b2015-05-12 21:22:35992 if (ssl_error == SSL_ERROR_WANT_X509_LOOKUP &&
993 !ssl_config_.send_client_cert) {
994 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
995 }
davidben1d489522015-07-01 18:48:46996 if (ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
svaldez7872fd02015-11-19 21:10:54997 DCHECK(ssl_config_.client_private_key);
davidben1d489522015-07-01 18:48:46998 DCHECK_NE(kNoPendingResult, signature_result_);
rsleeviadbd4982016-06-13 22:10:27999 next_handshake_state_ = STATE_HANDSHAKE;
davidben1d489522015-07-01 18:48:461000 return ERR_IO_PENDING;
1001 }
[email protected]b9b651f2013-11-09 04:32:221002
davidbena4409c62014-08-27 17:05:511003 OpenSSLErrorInfo error_info;
davidbenfe132d92016-09-27 18:07:211004 net_error = MapLastOpenSSLError(ssl_error, err_tracer, &error_info);
[email protected]b9b651f2013-11-09 04:32:221005 if (net_error == ERR_IO_PENDING) {
davidbenc4212c02015-05-12 22:30:181006 // If not done, stay in this state
rsleeviadbd4982016-06-13 22:10:271007 next_handshake_state_ = STATE_HANDSHAKE;
davidbenc4212c02015-05-12 22:30:181008 return ERR_IO_PENDING;
1009 }
1010
David Benjamine34d74242017-06-29 20:35:161011 switch (net_error) {
1012 case ERR_CONNECTION_CLOSED:
1013 connect_error_details_ = SSLErrorDetails::kConnectionClosed;
1014 break;
1015 case ERR_CONNECTION_RESET:
1016 connect_error_details_ = SSLErrorDetails::kConnectionReset;
1017 break;
1018 case ERR_SSL_PROTOCOL_ERROR: {
1019 int lib = ERR_GET_LIB(error_info.error_code);
1020 int reason = ERR_GET_REASON(error_info.error_code);
1021 if (lib == ERR_LIB_SSL && reason == SSL_R_TLSV1_ALERT_ACCESS_DENIED) {
1022 connect_error_details_ = SSLErrorDetails::kAccessDeniedAlert;
1023 } else if (lib == ERR_LIB_SSL &&
1024 reason == SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE) {
1025 connect_error_details_ =
1026 SSLErrorDetails::kApplicationDataInsteadOfHandshake;
1027 } else {
1028 connect_error_details_ = SSLErrorDetails::kProtocolError;
1029 }
1030 break;
1031 }
1032 case ERR_SSL_BAD_RECORD_MAC_ALERT:
1033 connect_error_details_ = SSLErrorDetails::kBadRecordMACAlert;
1034 break;
1035 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
1036 connect_error_details_ = SSLErrorDetails::kVersionOrCipherMismatch;
1037 break;
1038 default:
1039 connect_error_details_ = SSLErrorDetails::kOther;
1040 break;
1041 }
1042
davidbenc4212c02015-05-12 22:30:181043 LOG(ERROR) << "handshake failed; returned " << rv << ", SSL error code "
1044 << ssl_error << ", net_error " << net_error;
1045 net_log_.AddEvent(
mikecirone8b85c432016-09-08 19:11:001046 NetLogEventType::SSL_HANDSHAKE_ERROR,
davidbenc4212c02015-05-12 22:30:181047 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
1048 }
1049
rsleeviadbd4982016-06-13 22:10:271050 next_handshake_state_ = STATE_HANDSHAKE_COMPLETE;
davidbenc4212c02015-05-12 22:30:181051 return net_error;
1052}
1053
svaldeze83af292016-04-26 14:33:371054int SSLClientSocketImpl::DoHandshakeComplete(int result) {
davidbenc4212c02015-05-12 22:30:181055 if (result < 0)
1056 return result;
1057
davidben095ebb52017-04-12 22:23:341058 if (ssl_config_.version_interference_probe) {
1059 DCHECK_LT(ssl_config_.version_max, TLS1_3_VERSION);
1060 return ERR_SSL_VERSION_INTERFERENCE;
1061 }
1062
David Benjaminb3840f42017-08-03 15:50:161063 if (!ssl_session_cache_shard_.empty()) {
1064 SSLContext::GetInstance()->session_cache()->ResetLookupCount(
1065 GetSessionCacheKey());
1066 }
1067
nharper736ceda2015-11-07 00:16:591068 // Check that if token binding was negotiated, then extended master secret
nharper78e6d2b2016-09-21 05:42:351069 // and renegotiation indication must also be negotiated.
1070 if (tb_was_negotiated_ &&
davidbend80c12c2016-10-11 00:13:491071 !(SSL_get_extms_support(ssl_.get()) &&
1072 SSL_get_secure_renegotiation_support(ssl_.get()))) {
nharper736ceda2015-11-07 00:16:591073 return ERR_SSL_PROTOCOL_ERROR;
nharper78e6d2b2016-09-21 05:42:351074 }
nharper736ceda2015-11-07 00:16:591075
bncce6ea242016-09-15 20:22:321076 const uint8_t* alpn_proto = NULL;
1077 unsigned alpn_len = 0;
davidbend80c12c2016-10-11 00:13:491078 SSL_get0_alpn_selected(ssl_.get(), &alpn_proto, &alpn_len);
bncce6ea242016-09-15 20:22:321079 if (alpn_len > 0) {
1080 base::StringPiece proto(reinterpret_cast<const char*>(alpn_proto),
1081 alpn_len);
1082 negotiated_protocol_ = NextProtoFromString(proto);
[email protected]b9b651f2013-11-09 04:32:221083 }
davidbenc4212c02015-05-12 22:30:181084
bncbd442c22016-09-14 20:49:161085 RecordNegotiatedProtocol();
bnc3cf2a592016-08-11 14:48:361086 RecordChannelIDSupport();
davidbenc4212c02015-05-12 22:30:181087
dadriand476e652016-07-26 21:33:241088 const uint8_t* ocsp_response_raw;
1089 size_t ocsp_response_len;
davidbend80c12c2016-10-11 00:13:491090 SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len);
dadriand476e652016-07-26 21:33:241091 set_stapled_ocsp_response_received(ocsp_response_len != 0);
1092 UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_response_len != 0);
davidbenc4212c02015-05-12 22:30:181093
1094 const uint8_t* sct_list;
1095 size_t sct_list_len;
davidbend80c12c2016-10-11 00:13:491096 SSL_get0_signed_cert_timestamp_list(ssl_.get(), &sct_list, &sct_list_len);
davidbenc4212c02015-05-12 22:30:181097 set_signed_cert_timestamps_received(sct_list_len != 0);
1098
davidben971a681a2017-02-16 18:57:461099 if (!IsRenegotiationAllowed())
1100 SSL_set_renegotiate_mode(ssl_.get(), ssl_renegotiate_never);
davidbenc4212c02015-05-12 22:30:181101
davidbend80c12c2016-10-11 00:13:491102 uint16_t signature_algorithm = SSL_get_peer_signature_algorithm(ssl_.get());
davidben0653c8d2016-07-08 02:16:171103 if (signature_algorithm != 0) {
1104 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLSignatureAlgorithm",
1105 signature_algorithm);
davidben4fe4f982015-11-11 22:00:121106 }
1107
davidbenc4212c02015-05-12 22:30:181108 // Verify the certificate.
rsleeviadbd4982016-06-13 22:10:271109 next_handshake_state_ = STATE_VERIFY_CERT;
davidbenc4212c02015-05-12 22:30:181110 return OK;
[email protected]b9b651f2013-11-09 04:32:221111}
1112
svaldeze83af292016-04-26 14:33:371113int SSLClientSocketImpl::DoChannelIDLookup() {
mikecironef22f9812016-10-04 03:40:191114 NetLogParametersCallback callback = base::Bind(
nharper49b27d992016-02-09 18:28:511115 &NetLogChannelIDLookupCallback, base::Unretained(channel_id_service_));
mikecirone8b85c432016-09-08 19:11:001116 net_log_.BeginEvent(NetLogEventType::SSL_GET_CHANNEL_ID, callback);
rsleeviadbd4982016-06-13 22:10:271117 next_handshake_state_ = STATE_CHANNEL_ID_LOOKUP_COMPLETE;
[email protected]6b8a3c742014-07-25 00:25:351118 return channel_id_service_->GetOrCreateChannelID(
nharper2e171cf2015-06-01 20:29:231119 host_and_port_.host(), &channel_id_key_,
svaldeze83af292016-04-26 14:33:371120 base::Bind(&SSLClientSocketImpl::OnHandshakeIOComplete,
[email protected]faff9852014-06-21 06:13:461121 base::Unretained(this)),
nharper75ade892015-06-10 19:05:351122 &channel_id_request_);
[email protected]faff9852014-06-21 06:13:461123}
1124
svaldeze83af292016-04-26 14:33:371125int SSLClientSocketImpl::DoChannelIDLookupComplete(int result) {
mikecirone8b85c432016-09-08 19:11:001126 net_log_.EndEvent(NetLogEventType::SSL_GET_CHANNEL_ID,
nharper49b27d992016-02-09 18:28:511127 base::Bind(&NetLogChannelIDLookupCompleteCallback,
1128 channel_id_key_.get(), result));
[email protected]faff9852014-06-21 06:13:461129 if (result < 0)
1130 return result;
1131
[email protected]faff9852014-06-21 06:13:461132 // Hand the key to OpenSSL. Check for error in case OpenSSL rejects the key
1133 // type.
davidben8a208fc2016-01-22 17:08:081134 DCHECK(channel_id_key_);
[email protected]faff9852014-06-21 06:13:461135 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
davidbend80c12c2016-10-11 00:13:491136 if (!SSL_set1_tls_channel_id(ssl_.get(), channel_id_key_->key())) {
[email protected]faff9852014-06-21 06:13:461137 LOG(ERROR) << "Failed to set Channel ID.";
davidbenf225b262016-09-15 22:09:221138 return ERR_FAILED;
[email protected]faff9852014-06-21 06:13:461139 }
1140
1141 // Return to the handshake.
davidben52053b382015-04-27 19:22:291142 channel_id_sent_ = true;
rsleeviadbd4982016-06-13 22:10:271143 next_handshake_state_ = STATE_HANDSHAKE;
[email protected]faff9852014-06-21 06:13:461144 return OK;
1145}
1146
svaldeze83af292016-04-26 14:33:371147int SSLClientSocketImpl::DoVerifyCert(int result) {
davidben09c3d072014-08-25 20:33:581148 DCHECK(start_cert_verification_time_.is_null());
davidben30798ed82014-09-19 19:28:201149
David Benjaminb8ab3852017-08-04 00:17:321150 server_cert_ = x509_util::CreateX509CertificateFromBuffers(
1151 SSL_get0_peer_certificates(ssl_.get()));
[email protected]b9b651f2013-11-09 04:32:221152
Matt Muellerba33e862017-09-28 20:15:521153 // OpenSSL decoded the certificate, but the X509Certificate implementation
1154 // could not. This is treated as a fatal SSL-level protocol error rather than
1155 // a certificate error. See https://crbug.com/91341.
rsleevi74e99742016-09-13 20:35:251156 if (!server_cert_)
davidbenc6435a72015-08-17 18:28:521157 return ERR_SSL_SERVER_CERT_BAD_FORMAT;
1158
davidbenc7e06c92017-03-07 18:54:111159 net_log_.AddEvent(NetLogEventType::SSL_CERTIFICATES_RECEIVED,
1160 base::Bind(&NetLogX509CertificateCallback,
1161 base::Unretained(server_cert_.get())));
1162
1163 next_handshake_state_ = STATE_VERIFY_CERT_COMPLETE;
1164
davidben30798ed82014-09-19 19:28:201165 // If the certificate is bad and has been previously accepted, use
1166 // the previous status and bypass the error.
[email protected]b9b651f2013-11-09 04:32:221167 CertStatus cert_status;
rsleevi74e99742016-09-13 20:35:251168 if (ssl_config_.IsAllowedBadCert(server_cert_.get(), &cert_status)) {
[email protected]b9b651f2013-11-09 04:32:221169 server_cert_verify_result_.Reset();
1170 server_cert_verify_result_.cert_status = cert_status;
1171 server_cert_verify_result_.verified_cert = server_cert_;
1172 return OK;
1173 }
1174
davidben09c3d072014-08-25 20:33:581175 start_cert_verification_time_ = base::TimeTicks::Now();
1176
rsleevi22cae1672016-12-28 01:53:361177 const uint8_t* ocsp_response_raw;
1178 size_t ocsp_response_len;
1179 SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len);
1180 base::StringPiece ocsp_response(
1181 reinterpret_cast<const char*>(ocsp_response_raw), ocsp_response_len);
1182
eroman7f9236a2015-05-11 21:23:431183 return cert_verifier_->Verify(
rsleevi06bd78552016-06-08 22:34:461184 CertVerifier::RequestParams(server_cert_, host_and_port_.host(),
1185 ssl_config_.GetCertVerifyFlags(),
rsleevi22cae1672016-12-28 01:53:361186 ocsp_response.as_string(), CertificateList()),
[email protected]591cffcd2014-08-18 20:02:301187 // TODO(davidben): Route the CRLSet through SSLConfig so
1188 // SSLClientSocket doesn't depend on SSLConfigService.
davidben15f57132015-04-27 18:08:361189 SSLConfigService::GetCRLSet().get(), &server_cert_verify_result_,
svaldeze83af292016-04-26 14:33:371190 base::Bind(&SSLClientSocketImpl::OnHandshakeIOComplete,
[email protected]b9b651f2013-11-09 04:32:221191 base::Unretained(this)),
eroman7f9236a2015-05-11 21:23:431192 &cert_verifier_request_, net_log_);
[email protected]b9b651f2013-11-09 04:32:221193}
1194
svaldeze83af292016-04-26 14:33:371195int SSLClientSocketImpl::DoVerifyCertComplete(int result) {
eroman7f9236a2015-05-11 21:23:431196 cert_verifier_request_.reset();
[email protected]b9b651f2013-11-09 04:32:221197
davidben09c3d072014-08-25 20:33:581198 if (!start_cert_verification_time_.is_null()) {
1199 base::TimeDelta verify_time =
1200 base::TimeTicks::Now() - start_cert_verification_time_;
1201 if (result == OK) {
1202 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time);
1203 } else {
1204 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time);
1205 }
1206 }
1207
rsleevi4a6ca8c2016-06-24 03:05:221208 // If the connection was good, check HPKP and CT status simultaneously,
1209 // but prefer to treat the HPKP error as more serious, if there was one.
[email protected]8bd4e7a2014-08-09 14:49:171210 const CertStatus cert_status = server_cert_verify_result_.cert_status;
rsleevi4a6ca8c2016-06-24 03:05:221211 if ((result == OK ||
dadrian8f8946652016-06-21 23:48:311212 (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) {
rsleevi4a6ca8c2016-06-24 03:05:221213 int ct_result = VerifyCT();
dadrian8f8946652016-06-21 23:48:311214 TransportSecurityState::PKPStatus pin_validity =
1215 transport_security_state_->CheckPublicKeyPins(
1216 host_and_port_, server_cert_verify_result_.is_issued_by_known_root,
1217 server_cert_verify_result_.public_key_hashes, server_cert_.get(),
1218 server_cert_verify_result_.verified_cert.get(),
1219 TransportSecurityState::ENABLE_PIN_REPORTS, &pinning_failure_log_);
1220 switch (pin_validity) {
1221 case TransportSecurityState::PKPStatus::VIOLATED:
1222 server_cert_verify_result_.cert_status |=
1223 CERT_STATUS_PINNED_KEY_MISSING;
1224 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
1225 break;
1226 case TransportSecurityState::PKPStatus::BYPASSED:
1227 pkp_bypassed_ = true;
1228 // Fall through.
1229 case TransportSecurityState::PKPStatus::OK:
1230 // Do nothing.
1231 break;
rsleevi9545d342016-06-21 03:17:371232 }
rsleevi4a6ca8c2016-06-24 03:05:221233 if (result != ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && ct_result != OK)
1234 result = ct_result;
[email protected]8bd4e7a2014-08-09 14:49:171235 }
1236
[email protected]b9b651f2013-11-09 04:32:221237 if (result == OK) {
davidbendafe4e52015-04-08 22:53:521238 DCHECK(!certificate_verified_);
1239 certificate_verified_ = true;
1240 MaybeCacheSession();
dadriand476e652016-07-26 21:33:241241 SSLInfo ssl_info;
1242 bool ok = GetSSLInfo(&ssl_info);
1243 DCHECK(ok);
rsleevi22cae1672016-12-28 01:53:361244
1245 const uint8_t* ocsp_response_raw;
1246 size_t ocsp_response_len;
1247 SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len);
1248 base::StringPiece ocsp_response(
1249 reinterpret_cast<const char*>(ocsp_response_raw), ocsp_response_len);
1250
dadriand476e652016-07-26 21:33:241251 transport_security_state_->CheckExpectStaple(host_and_port_, ssl_info,
rsleevi22cae1672016-12-28 01:53:361252 ocsp_response);
[email protected]b9b651f2013-11-09 04:32:221253 }
1254
[email protected]64b5c892014-08-08 09:39:261255 completed_connect_ = true;
[email protected]b9b651f2013-11-09 04:32:221256 // Exit DoHandshakeLoop and return the result to the caller to Connect.
1257 DCHECK_EQ(STATE_NONE, next_handshake_state_);
1258 return result;
1259}
1260
svaldeze83af292016-04-26 14:33:371261void SSLClientSocketImpl::DoConnectCallback(int rv) {
[email protected]b9b651f2013-11-09 04:32:221262 if (!user_connect_callback_.is_null()) {
1263 CompletionCallback c = user_connect_callback_;
1264 user_connect_callback_.Reset();
1265 c.Run(rv > OK ? OK : rv);
1266 }
1267}
1268
svaldeze83af292016-04-26 14:33:371269void SSLClientSocketImpl::OnHandshakeIOComplete(int result) {
[email protected]b9b651f2013-11-09 04:32:221270 int rv = DoHandshakeLoop(result);
1271 if (rv != ERR_IO_PENDING) {
davidben281d13f02016-04-27 20:43:281272 LogConnectEndEvent(rv);
[email protected]b9b651f2013-11-09 04:32:221273 DoConnectCallback(rv);
1274 }
1275}
1276
svaldeze83af292016-04-26 14:33:371277int SSLClientSocketImpl::DoHandshakeLoop(int last_io_result) {
xunjieli0b7f5b62016-12-06 20:43:481278 TRACE_EVENT0(kNetTracingCategory, "SSLClientSocketImpl::DoHandshakeLoop");
[email protected]b9b651f2013-11-09 04:32:221279 int rv = last_io_result;
1280 do {
1281 // Default to STATE_NONE for next state.
1282 // (This is a quirk carried over from the windows
1283 // implementation. It makes reading the logs a bit harder.)
1284 // State handlers can and often do call GotoState just
1285 // to stay in the current state.
1286 State state = next_handshake_state_;
rsleeviadbd4982016-06-13 22:10:271287 next_handshake_state_ = STATE_NONE;
[email protected]b9b651f2013-11-09 04:32:221288 switch (state) {
1289 case STATE_HANDSHAKE:
1290 rv = DoHandshake();
1291 break;
davidbenc4212c02015-05-12 22:30:181292 case STATE_HANDSHAKE_COMPLETE:
1293 rv = DoHandshakeComplete(rv);
1294 break;
[email protected]faff9852014-06-21 06:13:461295 case STATE_CHANNEL_ID_LOOKUP:
1296 DCHECK_EQ(OK, rv);
1297 rv = DoChannelIDLookup();
svaldeze83af292016-04-26 14:33:371298 break;
[email protected]faff9852014-06-21 06:13:461299 case STATE_CHANNEL_ID_LOOKUP_COMPLETE:
1300 rv = DoChannelIDLookupComplete(rv);
1301 break;
[email protected]b9b651f2013-11-09 04:32:221302 case STATE_VERIFY_CERT:
[email protected]faff9852014-06-21 06:13:461303 DCHECK_EQ(OK, rv);
[email protected]b9b651f2013-11-09 04:32:221304 rv = DoVerifyCert(rv);
svaldeze83af292016-04-26 14:33:371305 break;
[email protected]b9b651f2013-11-09 04:32:221306 case STATE_VERIFY_CERT_COMPLETE:
1307 rv = DoVerifyCertComplete(rv);
1308 break;
1309 case STATE_NONE:
1310 default:
1311 rv = ERR_UNEXPECTED;
1312 NOTREACHED() << "unexpected state" << state;
1313 break;
1314 }
[email protected]b9b651f2013-11-09 04:32:221315 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
1316 return rv;
1317}
1318
xunjieli321a96f32017-03-07 19:42:171319int SSLClientSocketImpl::DoPayloadRead(IOBuffer* buf, int buf_len) {
[email protected]b9b651f2013-11-09 04:32:221320 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
1321
xunjieli321a96f32017-03-07 19:42:171322 DCHECK_LT(0, buf_len);
1323 DCHECK(buf);
davidben7e555daf2015-03-25 17:03:291324
[email protected]b9b651f2013-11-09 04:32:221325 int rv;
davidben1d489522015-07-01 18:48:461326 if (pending_read_error_ != kNoPendingResult) {
[email protected]b9b651f2013-11-09 04:32:221327 rv = pending_read_error_;
davidben1d489522015-07-01 18:48:461328 pending_read_error_ = kNoPendingResult;
[email protected]b9b651f2013-11-09 04:32:221329 if (rv == 0) {
mikecirone8b85c432016-09-08 19:11:001330 net_log_.AddByteTransferEvent(NetLogEventType::SSL_SOCKET_BYTES_RECEIVED,
xunjieli321a96f32017-03-07 19:42:171331 rv, buf->data());
davidbenb8c23212014-10-28 00:12:161332 } else {
1333 net_log_.AddEvent(
mikecirone8b85c432016-09-08 19:11:001334 NetLogEventType::SSL_READ_ERROR,
davidbenb8c23212014-10-28 00:12:161335 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_,
1336 pending_read_error_info_));
[email protected]b9b651f2013-11-09 04:32:221337 }
davidbenb8c23212014-10-28 00:12:161338 pending_read_ssl_error_ = SSL_ERROR_NONE;
1339 pending_read_error_info_ = OpenSSLErrorInfo();
[email protected]b9b651f2013-11-09 04:32:221340 return rv;
1341 }
1342
1343 int total_bytes_read = 0;
davidben7e555daf2015-03-25 17:03:291344 int ssl_ret;
[email protected]b9b651f2013-11-09 04:32:221345 do {
xunjieli321a96f32017-03-07 19:42:171346 ssl_ret = SSL_read(ssl_.get(), buf->data() + total_bytes_read,
1347 buf_len - total_bytes_read);
davidben7e555daf2015-03-25 17:03:291348 if (ssl_ret > 0)
1349 total_bytes_read += ssl_ret;
davidben8ea6b172017-03-07 23:53:501350 // Continue processing records as long as there is more data available
1351 // synchronously.
1352 } while (total_bytes_read < buf_len && ssl_ret > 0 &&
1353 transport_adapter_->HasPendingReadData());
[email protected]b9b651f2013-11-09 04:32:221354
davidben7e555daf2015-03-25 17:03:291355 // Although only the final SSL_read call may have failed, the failure needs to
1356 // processed immediately, while the information still available in OpenSSL's
1357 // error queue.
davidbenced4aa9b2015-05-12 21:22:351358 if (ssl_ret <= 0) {
davidben7e555daf2015-03-25 17:03:291359 // A zero return from SSL_read may mean any of:
1360 // - The underlying BIO_read returned 0.
1361 // - The peer sent a close_notify.
1362 // - Any arbitrary error. https://crbug.com/466303
[email protected]b9b651f2013-11-09 04:32:221363 //
davidben7e555daf2015-03-25 17:03:291364 // TransportReadComplete converts the first to an ERR_CONNECTION_CLOSED
1365 // error, so it does not occur. The second and third are distinguished by
1366 // SSL_ERROR_ZERO_RETURN.
davidbend80c12c2016-10-11 00:13:491367 pending_read_ssl_error_ = SSL_get_error(ssl_.get(), ssl_ret);
davidben7e555daf2015-03-25 17:03:291368 if (pending_read_ssl_error_ == SSL_ERROR_ZERO_RETURN) {
1369 pending_read_error_ = 0;
davidbenced4aa9b2015-05-12 21:22:351370 } else if (pending_read_ssl_error_ == SSL_ERROR_WANT_X509_LOOKUP &&
1371 !ssl_config_.send_client_cert) {
1372 pending_read_error_ = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
davidben1d489522015-07-01 18:48:461373 } else if (pending_read_ssl_error_ ==
1374 SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
svaldez7872fd02015-11-19 21:10:541375 DCHECK(ssl_config_.client_private_key);
davidben1d489522015-07-01 18:48:461376 DCHECK_NE(kNoPendingResult, signature_result_);
1377 pending_read_error_ = ERR_IO_PENDING;
davidben7e555daf2015-03-25 17:03:291378 } else {
davidbenfe132d92016-09-27 18:07:211379 pending_read_error_ = MapLastOpenSSLError(
davidben7e555daf2015-03-25 17:03:291380 pending_read_ssl_error_, err_tracer, &pending_read_error_info_);
[email protected]b9b651f2013-11-09 04:32:221381 }
1382
davidben7e555daf2015-03-25 17:03:291383 // Many servers do not reliably send a close_notify alert when shutting down
1384 // a connection, and instead terminate the TCP connection. This is reported
1385 // as ERR_CONNECTION_CLOSED. Because of this, map the unclean shutdown to a
1386 // graceful EOF, instead of treating it as an error as it should be.
1387 if (pending_read_error_ == ERR_CONNECTION_CLOSED)
1388 pending_read_error_ = 0;
1389 }
davidbenbe6ce7ec2014-10-20 19:15:561390
davidben7e555daf2015-03-25 17:03:291391 if (total_bytes_read > 0) {
1392 // Return any bytes read to the caller. The error will be deferred to the
1393 // next call of DoPayloadRead.
1394 rv = total_bytes_read;
davidbenbe6ce7ec2014-10-20 19:15:561395
davidben7e555daf2015-03-25 17:03:291396 // Do not treat insufficient data as an error to return in the next call to
1397 // DoPayloadRead() - instead, let the call fall through to check SSL_read()
davidben3418e81f2016-10-19 00:09:451398 // again. The transport may have data available by then.
davidben7e555daf2015-03-25 17:03:291399 if (pending_read_error_ == ERR_IO_PENDING)
davidben1d489522015-07-01 18:48:461400 pending_read_error_ = kNoPendingResult;
davidben7e555daf2015-03-25 17:03:291401 } else {
1402 // No bytes were returned. Return the pending read error immediately.
davidben1d489522015-07-01 18:48:461403 DCHECK_NE(kNoPendingResult, pending_read_error_);
davidben7e555daf2015-03-25 17:03:291404 rv = pending_read_error_;
davidben1d489522015-07-01 18:48:461405 pending_read_error_ = kNoPendingResult;
[email protected]b9b651f2013-11-09 04:32:221406 }
1407
1408 if (rv >= 0) {
mikecirone8b85c432016-09-08 19:11:001409 net_log_.AddByteTransferEvent(NetLogEventType::SSL_SOCKET_BYTES_RECEIVED,
xunjieli321a96f32017-03-07 19:42:171410 rv, buf->data());
davidbenb8c23212014-10-28 00:12:161411 } else if (rv != ERR_IO_PENDING) {
1412 net_log_.AddEvent(
mikecirone8b85c432016-09-08 19:11:001413 NetLogEventType::SSL_READ_ERROR,
davidbenb8c23212014-10-28 00:12:161414 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_,
1415 pending_read_error_info_));
1416 pending_read_ssl_error_ = SSL_ERROR_NONE;
1417 pending_read_error_info_ = OpenSSLErrorInfo();
[email protected]b9b651f2013-11-09 04:32:221418 }
1419 return rv;
1420}
1421
svaldeze83af292016-04-26 14:33:371422int SSLClientSocketImpl::DoPayloadWrite() {
[email protected]b9b651f2013-11-09 04:32:221423 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
davidbend80c12c2016-10-11 00:13:491424 int rv = SSL_write(ssl_.get(), user_write_buf_->data(), user_write_buf_len_);
rsleevif020edc2015-03-16 19:31:241425
[email protected]b9b651f2013-11-09 04:32:221426 if (rv >= 0) {
mikecirone8b85c432016-09-08 19:11:001427 net_log_.AddByteTransferEvent(NetLogEventType::SSL_SOCKET_BYTES_SENT, rv,
[email protected]b9b651f2013-11-09 04:32:221428 user_write_buf_->data());
1429 return rv;
1430 }
1431
davidbend80c12c2016-10-11 00:13:491432 int ssl_error = SSL_get_error(ssl_.get(), rv);
davidben1d489522015-07-01 18:48:461433 if (ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION)
1434 return ERR_IO_PENDING;
davidbenb8c23212014-10-28 00:12:161435 OpenSSLErrorInfo error_info;
davidbenfe132d92016-09-27 18:07:211436 int net_error = MapLastOpenSSLError(ssl_error, err_tracer, &error_info);
davidbenb8c23212014-10-28 00:12:161437
1438 if (net_error != ERR_IO_PENDING) {
1439 net_log_.AddEvent(
mikecirone8b85c432016-09-08 19:11:001440 NetLogEventType::SSL_WRITE_ERROR,
davidbenb8c23212014-10-28 00:12:161441 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
1442 }
1443 return net_error;
[email protected]b9b651f2013-11-09 04:32:221444}
1445
davidben3418e81f2016-10-19 00:09:451446void SSLClientSocketImpl::RetryAllOperations() {
1447 // SSL_do_handshake, SSL_read, and SSL_write may all be retried when blocked,
1448 // so retry all operations for simplicity. (Otherwise, SSL_get_error for each
1449 // operation may be remembered to retry only the blocked ones.)
1450
1451 if (next_handshake_state_ == STATE_HANDSHAKE) {
1452 // In handshake phase. The parameter to OnHandshakeIOComplete is unused.
1453 OnHandshakeIOComplete(OK);
1454 return;
1455 }
1456
davidben1d489522015-07-01 18:48:461457 int rv_read = ERR_IO_PENDING;
1458 int rv_write = ERR_IO_PENDING;
xunjieli321a96f32017-03-07 19:42:171459 if (user_read_buf_) {
1460 rv_read = DoPayloadRead(user_read_buf_.get(), user_read_buf_len_);
1461 } else if (!user_read_callback_.is_null()) {
1462 // ReadIfReady() is called by the user. Skip DoPayloadRead() and just let
1463 // the user know that read can be retried.
1464 rv_read = OK;
1465 }
1466
davidben3418e81f2016-10-19 00:09:451467 if (user_write_buf_)
1468 rv_write = DoPayloadWrite();
davidben1d489522015-07-01 18:48:461469
1470 // Performing the Read callback may cause |this| to be deleted. If this
1471 // happens, the Write callback should not be invoked. Guard against this by
1472 // holding a WeakPtr to |this| and ensuring it's still valid.
svaldeze83af292016-04-26 14:33:371473 base::WeakPtr<SSLClientSocketImpl> guard(weak_factory_.GetWeakPtr());
davidben3418e81f2016-10-19 00:09:451474 if (rv_read != ERR_IO_PENDING)
davidben1d489522015-07-01 18:48:461475 DoReadCallback(rv_read);
1476
1477 if (!guard.get())
1478 return;
1479
davidben3418e81f2016-10-19 00:09:451480 if (rv_write != ERR_IO_PENDING)
davidben1d489522015-07-01 18:48:461481 DoWriteCallback(rv_write);
1482}
1483
rsleevi4a6ca8c2016-06-24 03:05:221484int SSLClientSocketImpl::VerifyCT() {
rsleevi4a6ca8c2016-06-24 03:05:221485 const uint8_t* sct_list_raw;
1486 size_t sct_list_len;
davidbend80c12c2016-10-11 00:13:491487 SSL_get0_signed_cert_timestamp_list(ssl_.get(), &sct_list_raw, &sct_list_len);
rsleevi22cae1672016-12-28 01:53:361488 base::StringPiece sct_list(reinterpret_cast<const char*>(sct_list_raw),
1489 sct_list_len);
1490
1491 const uint8_t* ocsp_response_raw;
1492 size_t ocsp_response_len;
1493 SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len);
1494 base::StringPiece ocsp_response(
1495 reinterpret_cast<const char*>(ocsp_response_raw), ocsp_response_len);
rsleevi4a6ca8c2016-06-24 03:05:221496
1497 // Note that this is a completely synchronous operation: The CT Log Verifier
1498 // gets all the data it needs for SCT verification and does not do any
1499 // external communication.
1500 cert_transparency_verifier_->Verify(
rsleevi22cae1672016-12-28 01:53:361501 server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list,
eranmdcec9632016-10-10 14:16:101502 &ct_verify_result_.scts, net_log_);
rsleevi4a6ca8c2016-06-24 03:05:221503
1504 ct_verify_result_.ct_policies_applied = true;
eranm4bed0b572016-08-14 21:00:351505
1506 SCTList verified_scts =
1507 ct::SCTsMatchingStatus(ct_verify_result_.scts, ct::SCT_STATUS_OK);
1508
rsleevi4a6ca8c2016-06-24 03:05:221509 ct_verify_result_.cert_policy_compliance =
1510 policy_enforcer_->DoesConformToCertPolicy(
eranm4bed0b572016-08-14 21:00:351511 server_cert_verify_result_.verified_cert.get(), verified_scts,
1512 net_log_);
Emily Stark0d9809e2017-10-18 08:29:151513 if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) {
1514 if (ct_verify_result_.cert_policy_compliance !=
1515 ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS) {
1516 server_cert_verify_result_.cert_status |=
1517 CERT_STATUS_CT_COMPLIANCE_FAILED;
1518 server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV;
1519 }
1520
1521 // Record the CT compliance status for connections with EV certificates, to
1522 // distinguish how often EV status is being dropped due to failing CT
1523 // compliance.
1524 UMA_HISTOGRAM_ENUMERATION("Net.CertificateTransparency.EVCompliance.SSL",
1525 ct_verify_result_.cert_policy_compliance,
1526 ct::CertPolicyCompliance::CERT_POLICY_MAX);
rsleevicd7390e2017-06-14 10:18:261527 }
rsleevi4a6ca8c2016-06-24 03:05:221528
Emily Stark0d9809e2017-10-18 08:29:151529 // Record the CT compliance of every connection to get an overall picture of
1530 // how many connections are CT-compliant.
Emily Starkc96e9bc2017-10-10 00:10:391531 UMA_HISTOGRAM_ENUMERATION(
1532 "Net.CertificateTransparency.ConnectionComplianceStatus.SSL",
1533 ct_verify_result_.cert_policy_compliance,
1534 ct::CertPolicyCompliance::CERT_POLICY_MAX);
1535
Emily Stark0d9809e2017-10-18 08:29:151536 TransportSecurityState::CTRequirementsStatus ct_requirement_status =
1537 transport_security_state_->CheckCTRequirements(
estarkbf1b52962017-05-05 17:05:251538 host_and_port_, server_cert_verify_result_.is_issued_by_known_root,
1539 server_cert_verify_result_.public_key_hashes,
1540 server_cert_verify_result_.verified_cert.get(), server_cert_.get(),
1541 ct_verify_result_.scts,
1542 TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
Emily Stark0d9809e2017-10-18 08:29:151543 ct_verify_result_.cert_policy_compliance);
1544 if (ct_requirement_status != TransportSecurityState::CT_NOT_REQUIRED) {
1545 // Record the CT compliance of connections for which compliance is required;
1546 // this helps answer the question: "Of all connections that are supposed to
1547 // be serving valid CT information, how many fail to do so?"
1548 UMA_HISTOGRAM_ENUMERATION(
1549 "Net.CertificateTransparency.CTRequiredConnectionComplianceStatus.SSL",
1550 ct_verify_result_.cert_policy_compliance,
1551 ct::CertPolicyCompliance::CERT_POLICY_MAX);
rsleevi4a6ca8c2016-06-24 03:05:221552 }
1553
Emily Stark0d9809e2017-10-18 08:29:151554 switch (ct_requirement_status) {
1555 case TransportSecurityState::CT_REQUIREMENTS_NOT_MET:
1556 server_cert_verify_result_.cert_status |=
1557 CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED;
1558 return ERR_CERTIFICATE_TRANSPARENCY_REQUIRED;
1559 case TransportSecurityState::CT_REQUIREMENTS_MET:
1560 case TransportSecurityState::CT_NOT_REQUIRED:
1561 return OK;
1562 }
1563
1564 NOTREACHED();
rsleevi4a6ca8c2016-06-24 03:05:221565 return OK;
1566}
1567
svaldeze83af292016-04-26 14:33:371568int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) {
davidbend80c12c2016-10-11 00:13:491569 DCHECK(ssl == ssl_.get());
[email protected]82c59022014-08-15 09:38:271570
mikecirone8b85c432016-09-08 19:11:001571 net_log_.AddEvent(NetLogEventType::SSL_CLIENT_CERT_REQUESTED);
davidbenfe132d92016-09-27 18:07:211572 certificate_requested_ = true;
davidbenaf42cbe2014-11-13 03:27:461573
[email protected]82c59022014-08-15 09:38:271574 // Clear any currently configured certificates.
davidbend80c12c2016-10-11 00:13:491575 SSL_certs_clear(ssl_.get());
[email protected]97a854f2014-07-29 07:51:361576
1577#if defined(OS_IOS)
1578 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954).
1579 LOG(WARNING) << "Client auth is not supported";
svaldeze83af292016-04-26 14:33:371580#else // !defined(OS_IOS)
[email protected]5ac981e182010-12-06 17:56:271581 if (!ssl_config_.send_client_cert) {
[email protected]515adc22013-01-09 16:01:231582 // First pass: we know that a client certificate is needed, but we do not
davidbenb11fd212017-01-12 17:08:031583 // have one at hand. Suspend the handshake. SSL_get_error will return
1584 // SSL_ERROR_WANT_X509_LOOKUP.
davidbenced4aa9b2015-05-12 21:22:351585 return -1;
[email protected]5ac981e182010-12-06 17:56:271586 }
1587
1588 // Second pass: a client certificate should have been selected.
[email protected]13914c92013-06-13 22:42:421589 if (ssl_config_.client_cert.get()) {
svaldez7872fd02015-11-19 21:10:541590 if (!ssl_config_.client_private_key) {
1591 // The caller supplied a null private key. Fail the handshake and surface
1592 // an appropriate error to the caller.
davidben1d489522015-07-01 18:48:461593 LOG(WARNING) << "Client cert found without private key";
1594 OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY);
1595 return -1;
1596 }
1597
David Benjaminb8ab3852017-08-04 00:17:321598 if (!SetSSLChainAndKey(ssl_.get(), ssl_config_.client_cert.get(), nullptr,
1599 &SSLContext::kPrivateKeyMethod)) {
davidbena35b40c32017-03-09 17:33:451600 OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_CERT_BAD_FORMAT);
1601 return -1;
1602 }
svaldezf3db006f2015-09-29 16:43:581603
David Benjaminb9bafbe2017-11-07 21:41:381604 std::vector<uint16_t> preferences =
1605 ssl_config_.client_private_key->GetAlgorithmPreferences();
1606 SSL_set_signing_algorithm_prefs(ssl_.get(), preferences.data(),
1607 preferences.size());
davidbenaf42cbe2014-11-13 03:27:461608
David Benjaminb8ab3852017-08-04 00:17:321609 net_log_.AddEvent(
1610 NetLogEventType::SSL_CLIENT_CERT_PROVIDED,
1611 NetLog::IntCallback(
1612 "cert_count",
1613 1 + ssl_config_.client_cert->GetIntermediateCertificates().size()));
[email protected]6bad5052014-07-12 01:25:131614 return 1;
[email protected]c0787702014-05-20 21:51:441615 }
[email protected]97a854f2014-07-29 07:51:361616#endif // defined(OS_IOS)
[email protected]5ac981e182010-12-06 17:56:271617
1618 // Send no client certificate.
mikecirone8b85c432016-09-08 19:11:001619 net_log_.AddEvent(NetLogEventType::SSL_CLIENT_CERT_PROVIDED,
tfarina5e24b242015-10-27 13:11:281620 NetLog::IntCallback("cert_count", 0));
[email protected]82c59022014-08-15 09:38:271621 return 1;
[email protected]5ac981e182010-12-06 17:56:271622}
1623
svaldeze83af292016-04-26 14:33:371624void SSLClientSocketImpl::MaybeCacheSession() {
davidben44aeae62015-06-24 20:47:431625 // Only cache the session once both a new session has been established and the
1626 // certificate has been verified. Due to False Start, these events may happen
1627 // in either order.
David Benjaminb3840f42017-08-03 15:50:161628 if (!pending_session_ || !certificate_verified_ ||
1629 ssl_session_cache_shard_.empty()) {
davidbendafe4e52015-04-08 22:53:521630 return;
David Benjaminb3840f42017-08-03 15:50:161631 }
davidbendafe4e52015-04-08 22:53:521632
1633 SSLContext::GetInstance()->session_cache()->Insert(GetSessionCacheKey(),
davidbenc269cc4b2016-07-27 14:55:031634 pending_session_.get());
1635 pending_session_ = nullptr;
davidbendafe4e52015-04-08 22:53:521636}
1637
svaldeze83af292016-04-26 14:33:371638int SSLClientSocketImpl::NewSessionCallback(SSL_SESSION* session) {
David Benjaminb3840f42017-08-03 15:50:161639 if (ssl_session_cache_shard_.empty())
1640 return 0;
1641
davidbenc269cc4b2016-07-27 14:55:031642 // OpenSSL passes a reference to |session|.
1643 pending_session_.reset(session);
davidbendafe4e52015-04-08 22:53:521644 MaybeCacheSession();
davidben44aeae62015-06-24 20:47:431645 return 1;
davidbendafe4e52015-04-08 22:53:521646}
1647
svaldeze83af292016-04-26 14:33:371648void SSLClientSocketImpl::AddCTInfoToSSLInfo(SSLInfo* ssl_info) const {
estark723b5eeb2016-02-18 21:01:121649 ssl_info->UpdateCertificateTransparencyInfo(ct_verify_result_);
davidbeneb5f8ef32014-09-04 14:14:321650}
1651
svaldeze83af292016-04-26 14:33:371652std::string SSLClientSocketImpl::GetSessionCacheKey() const {
David Benjaminb3840f42017-08-03 15:50:161653 // If there is no session cache shard configured, disable session
1654 // caching. GetSessionCacheKey may not be called. When
1655 // https://crbug.com/458365 is fixed, this check will not be needed.
1656 DCHECK(!ssl_session_cache_shard_.empty());
1657
rsleevif020edc2015-03-16 19:31:241658 std::string result = host_and_port_.ToString();
davidben095ebb52017-04-12 22:23:341659 result.push_back('/');
rsleevif020edc2015-03-16 19:31:241660 result.append(ssl_session_cache_shard_);
1661
davidben095ebb52017-04-12 22:23:341662 result.push_back('/');
davidben095ebb52017-04-12 22:23:341663 result.push_back(ssl_config_.channel_id_enabled ? '1' : '0');
1664 result.push_back(ssl_config_.version_interference_probe ? '1' : '0');
rsleevif020edc2015-03-16 19:31:241665 return result;
1666}
1667
svaldeze83af292016-04-26 14:33:371668bool SSLClientSocketImpl::IsRenegotiationAllowed() const {
nharper736ceda2015-11-07 00:16:591669 if (tb_was_negotiated_)
1670 return false;
1671
bncce6ea242016-09-15 20:22:321672 if (negotiated_protocol_ == kProtoUnknown)
davidben421116c2015-05-12 19:56:511673 return ssl_config_.renego_allowed_default;
1674
davidben421116c2015-05-12 19:56:511675 for (NextProto allowed : ssl_config_.renego_allowed_for_protos) {
bnc3cf2a592016-08-11 14:48:361676 if (negotiated_protocol_ == allowed)
davidben421116c2015-05-12 19:56:511677 return true;
1678 }
1679 return false;
1680}
1681
David Benjaminb9bafbe2017-11-07 21:41:381682ssl_private_key_result_t SSLClientSocketImpl::PrivateKeySignCallback(
davidben1d489522015-07-01 18:48:461683 uint8_t* out,
1684 size_t* out_len,
1685 size_t max_out,
David Benjaminb9bafbe2017-11-07 21:41:381686 uint16_t algorithm,
davidben1d489522015-07-01 18:48:461687 const uint8_t* in,
1688 size_t in_len) {
1689 DCHECK_EQ(kNoPendingResult, signature_result_);
1690 DCHECK(signature_.empty());
svaldez7872fd02015-11-19 21:10:541691 DCHECK(ssl_config_.client_private_key);
davidben1d489522015-07-01 18:48:461692
David Benjaminb9bafbe2017-11-07 21:41:381693 net_log_.BeginEvent(
1694 NetLogEventType::SSL_PRIVATE_KEY_OP,
1695 base::Bind(&NetLogPrivateKeyOperationCallback, algorithm));
1696
1697 // SSLPrivateKey expects the input to be prehashed.
1698 const EVP_MD* md = SSL_get_signature_algorithm_digest(algorithm);
1699 uint8_t digest[EVP_MAX_MD_SIZE];
1700 unsigned digest_len;
1701 if (!md || !EVP_Digest(in, in_len, digest, &digest_len, md, nullptr)) {
davidben1d489522015-07-01 18:48:461702 return ssl_private_key_failure;
1703 }
1704
1705 signature_result_ = ERR_IO_PENDING;
svaldez7872fd02015-11-19 21:10:541706 ssl_config_.client_private_key->SignDigest(
David Benjaminb9bafbe2017-11-07 21:41:381707 algorithm,
1708 base::StringPiece(reinterpret_cast<const char*>(digest), digest_len),
davidben0bca07fd2016-07-18 15:12:031709 base::Bind(&SSLClientSocketImpl::OnPrivateKeyComplete,
davidben1d489522015-07-01 18:48:461710 weak_factory_.GetWeakPtr()));
1711 return ssl_private_key_retry;
1712}
1713
davidben0bca07fd2016-07-18 15:12:031714ssl_private_key_result_t SSLClientSocketImpl::PrivateKeyCompleteCallback(
davidben1d489522015-07-01 18:48:461715 uint8_t* out,
1716 size_t* out_len,
1717 size_t max_out) {
1718 DCHECK_NE(kNoPendingResult, signature_result_);
svaldez7872fd02015-11-19 21:10:541719 DCHECK(ssl_config_.client_private_key);
davidben1d489522015-07-01 18:48:461720
1721 if (signature_result_ == ERR_IO_PENDING)
1722 return ssl_private_key_retry;
1723 if (signature_result_ != OK) {
1724 OpenSSLPutNetError(FROM_HERE, signature_result_);
1725 return ssl_private_key_failure;
1726 }
1727 if (signature_.size() > max_out) {
1728 OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED);
1729 return ssl_private_key_failure;
1730 }
davidben5f8b6bc2015-11-25 03:19:541731 memcpy(out, signature_.data(), signature_.size());
davidben1d489522015-07-01 18:48:461732 *out_len = signature_.size();
1733 signature_.clear();
1734 return ssl_private_key_success;
1735}
1736
davidben0bca07fd2016-07-18 15:12:031737void SSLClientSocketImpl::OnPrivateKeyComplete(
davidben1d489522015-07-01 18:48:461738 Error error,
1739 const std::vector<uint8_t>& signature) {
1740 DCHECK_EQ(ERR_IO_PENDING, signature_result_);
1741 DCHECK(signature_.empty());
svaldez7872fd02015-11-19 21:10:541742 DCHECK(ssl_config_.client_private_key);
davidben1d489522015-07-01 18:48:461743
mikecirone8b85c432016-09-08 19:11:001744 net_log_.EndEventWithNetErrorCode(NetLogEventType::SSL_PRIVATE_KEY_OP, error);
davidben1d489522015-07-01 18:48:461745
1746 signature_result_ = error;
1747 if (signature_result_ == OK)
1748 signature_ = signature;
1749
davidben1d489522015-07-01 18:48:461750 // During a renegotiation, either Read or Write calls may be blocked on an
1751 // asynchronous private key operation.
davidben3418e81f2016-10-19 00:09:451752 RetryAllOperations();
davidben1d489522015-07-01 18:48:461753}
1754
davidbencef9e212017-04-19 15:00:101755void SSLClientSocketImpl::MessageCallback(int is_write,
1756 int content_type,
1757 const void* buf,
1758 size_t len) {
1759 switch (content_type) {
1760 case SSL3_RT_ALERT:
1761 net_log_.AddEvent(is_write ? NetLogEventType::SSL_ALERT_SENT
1762 : NetLogEventType::SSL_ALERT_RECEIVED,
1763 base::Bind(&NetLogSSLAlertCallback, buf, len));
1764 break;
1765 case SSL3_RT_HANDSHAKE:
1766 net_log_.AddEvent(
1767 is_write ? NetLogEventType::SSL_HANDSHAKE_MESSAGE_SENT
1768 : NetLogEventType::SSL_HANDSHAKE_MESSAGE_RECEIVED,
1769 base::Bind(&NetLogSSLMessageCallback, !!is_write, buf, len));
1770 break;
David Benjamina961f5f2017-06-22 23:50:511771 case SSL3_RT_HEADER: {
1772 if (is_write)
1773 return;
1774 if (len != 5) {
1775 NOTREACHED();
1776 return;
1777 }
1778 const uint8_t* buf_bytes = reinterpret_cast<const uint8_t*>(buf);
1779 uint16_t record_len = (uint16_t(buf_bytes[3]) << 8) | buf_bytes[4];
1780 // See RFC 5246 section 6.2.3 for the maximum record size in TLS.
1781 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SSLRecordSizeRead", record_len, 1,
1782 16384 + 2048, 50);
1783 }
davidbencef9e212017-04-19 15:00:101784 default:
1785 return;
1786 }
1787}
1788
svaldeze83af292016-04-26 14:33:371789int SSLClientSocketImpl::TokenBindingAdd(const uint8_t** out,
1790 size_t* out_len,
1791 int* out_alert_value) {
nharper736ceda2015-11-07 00:16:591792 if (ssl_config_.token_binding_params.empty()) {
1793 return 0;
1794 }
davidbend80c12c2016-10-11 00:13:491795 bssl::ScopedCBB output;
nharper736ceda2015-11-07 00:16:591796 CBB parameters_list;
1797 if (!CBB_init(output.get(), 7) ||
1798 !CBB_add_u8(output.get(), kTbProtocolVersionMajor) ||
1799 !CBB_add_u8(output.get(), kTbProtocolVersionMinor) ||
1800 !CBB_add_u8_length_prefixed(output.get(), &parameters_list)) {
1801 *out_alert_value = SSL_AD_INTERNAL_ERROR;
1802 return -1;
1803 }
1804 for (size_t i = 0; i < ssl_config_.token_binding_params.size(); ++i) {
1805 if (!CBB_add_u8(&parameters_list, ssl_config_.token_binding_params[i])) {
1806 *out_alert_value = SSL_AD_INTERNAL_ERROR;
1807 return -1;
1808 }
1809 }
1810 // |*out| will be freed by TokenBindingFreeCallback.
1811 if (!CBB_finish(output.get(), const_cast<uint8_t**>(out), out_len)) {
1812 *out_alert_value = SSL_AD_INTERNAL_ERROR;
1813 return -1;
1814 }
1815
1816 return 1;
1817}
1818
svaldeze83af292016-04-26 14:33:371819int SSLClientSocketImpl::TokenBindingParse(const uint8_t* contents,
1820 size_t contents_len,
1821 int* out_alert_value) {
nharper736ceda2015-11-07 00:16:591822 if (completed_connect_) {
1823 // Token Binding may only be negotiated on the initial handshake.
1824 *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
1825 return 0;
1826 }
1827
1828 CBS extension;
1829 CBS_init(&extension, contents, contents_len);
1830
1831 CBS parameters_list;
1832 uint8_t version_major, version_minor, param;
1833 if (!CBS_get_u8(&extension, &version_major) ||
1834 !CBS_get_u8(&extension, &version_minor) ||
1835 !CBS_get_u8_length_prefixed(&extension, &parameters_list) ||
1836 !CBS_get_u8(&parameters_list, &param) || CBS_len(&parameters_list) > 0 ||
1837 CBS_len(&extension) > 0) {
1838 *out_alert_value = SSL_AD_DECODE_ERROR;
1839 return 0;
1840 }
1841 // The server-negotiated version must be less than or equal to our version.
1842 if (version_major > kTbProtocolVersionMajor ||
1843 (version_minor > kTbProtocolVersionMinor &&
1844 version_major == kTbProtocolVersionMajor)) {
1845 *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
1846 return 0;
1847 }
1848 // If the version the server negotiated is older than we support, don't fail
1849 // parsing the extension, but also don't set |negotiated_|.
1850 if (version_major < kTbMinProtocolVersionMajor ||
1851 (version_minor < kTbMinProtocolVersionMinor &&
1852 version_major == kTbMinProtocolVersionMajor)) {
1853 return 1;
1854 }
1855
1856 for (size_t i = 0; i < ssl_config_.token_binding_params.size(); ++i) {
1857 if (param == ssl_config_.token_binding_params[i]) {
1858 tb_negotiated_param_ = ssl_config_.token_binding_params[i];
1859 tb_was_negotiated_ = true;
1860 return 1;
1861 }
1862 }
1863
1864 *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
1865 return 0;
1866}
1867
davidben281d13f02016-04-27 20:43:281868void SSLClientSocketImpl::LogConnectEndEvent(int rv) {
1869 if (rv != OK) {
mikecirone8b85c432016-09-08 19:11:001870 net_log_.EndEventWithNetErrorCode(NetLogEventType::SSL_CONNECT, rv);
davidben281d13f02016-04-27 20:43:281871 return;
1872 }
1873
mikecirone8b85c432016-09-08 19:11:001874 net_log_.EndEvent(NetLogEventType::SSL_CONNECT,
davidben281d13f02016-04-27 20:43:281875 base::Bind(&NetLogSSLInfoCallback, base::Unretained(this)));
1876}
1877
bncbd442c22016-09-14 20:49:161878void SSLClientSocketImpl::RecordNegotiatedProtocol() const {
1879 UMA_HISTOGRAM_ENUMERATION("Net.SSLNegotiatedAlpnProtocol",
1880 negotiated_protocol_, kProtoLast + 1);
bnc3cf2a592016-08-11 14:48:361881}
1882
1883void SSLClientSocketImpl::RecordChannelIDSupport() const {
1884 // Since this enum is used for a histogram, do not change or re-use values.
1885 enum {
1886 DISABLED = 0,
1887 CLIENT_ONLY = 1,
1888 CLIENT_AND_SERVER = 2,
1889 // CLIENT_NO_ECC is unused now.
1890 // CLIENT_BAD_SYSTEM_TIME is unused now.
1891 CLIENT_BAD_SYSTEM_TIME = 4,
1892 CLIENT_NO_CHANNEL_ID_SERVICE = 5,
1893 CHANNEL_ID_USAGE_MAX
1894 } supported = DISABLED;
1895 if (channel_id_sent_) {
1896 supported = CLIENT_AND_SERVER;
1897 } else if (ssl_config_.channel_id_enabled) {
1898 if (!channel_id_service_)
1899 supported = CLIENT_NO_CHANNEL_ID_SERVICE;
1900 else
1901 supported = CLIENT_ONLY;
1902 }
1903 UMA_HISTOGRAM_ENUMERATION("DomainBoundCerts.Support", supported,
1904 CHANNEL_ID_USAGE_MAX);
1905}
1906
1907bool SSLClientSocketImpl::IsChannelIDEnabled() const {
1908 return ssl_config_.channel_id_enabled && channel_id_service_;
1909}
1910
davidbenfe132d92016-09-27 18:07:211911int SSLClientSocketImpl::MapLastOpenSSLError(
1912 int ssl_error,
1913 const crypto::OpenSSLErrStackTracer& tracer,
1914 OpenSSLErrorInfo* info) {
1915 int net_error = MapOpenSSLErrorWithDetails(ssl_error, tracer, info);
1916
1917 if (ssl_error == SSL_ERROR_SSL &&
1918 ERR_GET_LIB(info->error_code) == ERR_LIB_SSL) {
1919 // TLS does not provide an alert for missing client certificates, so most
1920 // servers send a generic handshake_failure alert. Detect this case by
1921 // checking if we have received a CertificateRequest but sent no
1922 // certificate. See https://crbug.com/646567.
1923 if (ERR_GET_REASON(info->error_code) ==
1924 SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE &&
1925 certificate_requested_ && ssl_config_.send_client_cert &&
1926 !ssl_config_.client_cert) {
1927 net_error = ERR_BAD_SSL_CLIENT_AUTH_CERT;
1928 }
1929
1930 // Per spec, access_denied is only for client-certificate-based access
1931 // control, but some buggy firewalls use it when blocking a page. To avoid a
1932 // confusing error, map it to a generic protocol error if no
1933 // CertificateRequest was sent. See https://crbug.com/630883.
1934 if (ERR_GET_REASON(info->error_code) == SSL_R_TLSV1_ALERT_ACCESS_DENIED &&
1935 !certificate_requested_) {
1936 net_error = ERR_SSL_PROTOCOL_ERROR;
1937 }
1938 }
1939
1940 return net_error;
1941}
1942
[email protected]7e5dd49f2010-12-08 18:33:491943} // namespace net