blob: 16cbcdc21b961006483770a6a61e88c7f68afb31 [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"
David Benjamin9ba36b02017-11-10 19:01:5315#include "base/containers/span.h"
davidben1d489522015-07-01 18:48:4616#include "base/lazy_instance.h"
Avi Drissman13fc8932015-12-20 04:40:4617#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:1518#include "base/memory/singleton.h"
mmenke1beda3d2016-07-22 03:33:4519#include "base/metrics/field_trial.h"
asvitkinec3c93722015-06-17 14:48:3720#include "base/metrics/histogram_macros.h"
davidben4fe4f982015-11-11 22:00:1221#include "base/metrics/sparse_histogram.h"
nharper49b27d992016-02-09 18:28:5122#include "base/strings/string_number_conversions.h"
davidben018aad62014-09-12 02:25:1923#include "base/strings/string_piece.h"
xunjieli9f8c5fb52016-12-07 22:59:3324#include "base/strings/stringprintf.h"
[email protected]20305ec2011-01-21 04:55:5225#include "base/synchronization/lock.h"
vadimt6b43dec22015-01-06 01:59:5826#include "base/threading/thread_local.h"
xunjieli9f8c5fb52016-12-07 22:59:3327#include "base/trace_event/process_memory_dump.h"
ssid6d6b40102016-04-05 18:59:5628#include "base/trace_event/trace_event.h"
estade5e5529d2015-05-21 20:59:1129#include "base/values.h"
[email protected]ee0f2aa82013-10-25 11:59:2630#include "crypto/ec_private_key.h"
[email protected]4b559b4d2011-04-14 17:37:1431#include "crypto/openssl_util.h"
martijna2e83bd2016-03-18 13:10:4532#include "net/base/ip_address.h"
[email protected]d518cd92010-09-29 12:27:4433#include "net/base/net_errors.h"
xunjieli0b7f5b62016-12-06 20:43:4834#include "net/base/trace_constants.h"
[email protected]6e7845ae2013-03-29 21:48:1135#include "net/cert/cert_verifier.h"
estark6f9b3d82016-01-12 21:37:0536#include "net/cert/ct_policy_enforcer.h"
estark723b5eeb2016-02-18 21:01:1237#include "net/cert/ct_policy_status.h"
davidbeneb5f8ef32014-09-04 14:14:3238#include "net/cert/ct_verifier.h"
[email protected]6e7845ae2013-03-29 21:48:1139#include "net/cert/x509_certificate_net_log_param.h"
mattm316af822017-02-23 04:05:5640#include "net/cert/x509_util.h"
[email protected]8bd4e7a2014-08-09 14:49:1741#include "net/http/transport_security_state.h"
mikecironef22f9812016-10-04 03:40:1942#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0043#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1944#include "net/log/net_log_parameters_callback.h"
[email protected]536fd0b2013-03-14 17:41:5745#include "net/ssl/ssl_cert_request_info.h"
davidben281d13f02016-04-27 20:43:2846#include "net/ssl/ssl_cipher_suite_names.h"
svaldeze83af292016-04-26 14:33:3747#include "net/ssl/ssl_client_session_cache.h"
[email protected]536fd0b2013-03-14 17:41:5748#include "net/ssl/ssl_connection_status_flags.h"
49#include "net/ssl/ssl_info.h"
davidben1d489522015-07-01 18:48:4650#include "net/ssl/ssl_private_key.h"
nharperd5cddca2016-02-27 03:37:5251#include "net/ssl/token_binding.h"
tfarinae8cb8aa2016-10-21 02:44:0152#include "third_party/boringssl/src/include/openssl/bio.h"
53#include "third_party/boringssl/src/include/openssl/bytestring.h"
54#include "third_party/boringssl/src/include/openssl/err.h"
55#include "third_party/boringssl/src/include/openssl/evp.h"
56#include "third_party/boringssl/src/include/openssl/mem.h"
57#include "third_party/boringssl/src/include/openssl/ssl.h"
[email protected]d518cd92010-09-29 12:27:4458
davidben2a811e4e2015-12-01 10:49:3459#if !defined(OS_NACL)
60#include "net/ssl/ssl_key_logger.h"
61#endif
62
svaldez2135be52016-04-20 16:34:5363#if defined(USE_NSS_CERTS)
davidbena477a70a2015-10-06 04:38:2964#include "net/cert_net/nss_ocsp.h"
65#endif
66
[email protected]d518cd92010-09-29 12:27:4467namespace net {
68
69namespace {
70
[email protected]4b768562013-02-16 04:10:0771// This constant can be any non-negative/non-zero value (eg: it does not
72// overlap with any value of the net::Error range, including net::OK).
davidben1d489522015-07-01 18:48:4673const int kNoPendingResult = 1;
[email protected]4b768562013-02-16 04:10:0774
haavardm2d92e722014-12-19 13:45:4475// Default size of the internal BoringSSL buffers.
mmenke1beda3d2016-07-22 03:33:4576const int kDefaultOpenSSLBufferSize = 17 * 1024;
haavardm2d92e722014-12-19 13:45:4477
nharper736ceda2015-11-07 00:16:5978// TLS extension number use for Token Binding.
nharperb5ad8a802016-02-05 19:40:0079const unsigned int kTbExtNum = 24;
nharper736ceda2015-11-07 00:16:5980
81// Token Binding ProtocolVersions supported.
82const uint8_t kTbProtocolVersionMajor = 0;
nharper96d085c2017-02-22 20:10:2183const uint8_t kTbProtocolVersionMinor = 13;
nharper736ceda2015-11-07 00:16:5984const uint8_t kTbMinProtocolVersionMajor = 0;
nharper78e6d2b2016-09-21 05:42:3585const uint8_t kTbMinProtocolVersionMinor = 10;
nharper736ceda2015-11-07 00:16:5986
danakj655b66c2016-04-16 00:51:3887std::unique_ptr<base::Value> NetLogPrivateKeyOperationCallback(
David Benjaminb9bafbe2017-11-07 21:41:3888 uint16_t algorithm,
davidben752bcf22015-12-21 22:55:5089 NetLogCaptureMode mode) {
danakj655b66c2016-04-16 00:51:3890 std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue);
David Benjaminb9bafbe2017-11-07 21:41:3891 value->SetString("algorithm", SSL_get_signature_algorithm_name(
92 algorithm, 0 /* exclude curve */));
davidben752bcf22015-12-21 22:55:5093 return std::move(value);
94}
95
danakj655b66c2016-04-16 00:51:3896std::unique_ptr<base::Value> NetLogChannelIDLookupCallback(
nharper49b27d992016-02-09 18:28:5197 ChannelIDService* channel_id_service,
98 NetLogCaptureMode capture_mode) {
99 ChannelIDStore* store = channel_id_service->GetChannelIDStore();
danakj655b66c2016-04-16 00:51:38100 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
nharper49b27d992016-02-09 18:28:51101 dict->SetBoolean("ephemeral", store->IsEphemeral());
102 dict->SetString("service", base::HexEncode(&channel_id_service,
103 sizeof(channel_id_service)));
104 dict->SetString("store", base::HexEncode(&store, sizeof(store)));
105 return std::move(dict);
106}
107
danakj655b66c2016-04-16 00:51:38108std::unique_ptr<base::Value> NetLogChannelIDLookupCompleteCallback(
nharper49b27d992016-02-09 18:28:51109 crypto::ECPrivateKey* key,
110 int result,
111 NetLogCaptureMode capture_mode) {
danakj655b66c2016-04-16 00:51:38112 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
nharper49b27d992016-02-09 18:28:51113 dict->SetInteger("net_error", result);
114 std::string raw_key;
115 if (result == OK && key && key->ExportRawPublicKey(&raw_key)) {
nharper837b2af2016-12-21 21:48:36116 std::string key_to_log = base::HexEncode(raw_key.data(), raw_key.length());
nharper49b27d992016-02-09 18:28:51117 dict->SetString("key", key_to_log);
118 }
119 return std::move(dict);
120}
121
davidben281d13f02016-04-27 20:43:28122std::unique_ptr<base::Value> NetLogSSLInfoCallback(
123 SSLClientSocketImpl* socket,
124 NetLogCaptureMode capture_mode) {
125 SSLInfo ssl_info;
126 if (!socket->GetSSLInfo(&ssl_info))
127 return nullptr;
128
129 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
130 const char* version_str;
131 SSLVersionToString(&version_str,
132 SSLConnectionStatusToVersion(ssl_info.connection_status));
133 dict->SetString("version", version_str);
134 dict->SetBoolean("is_resumed",
135 ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME);
136 dict->SetInteger("cipher_suite", SSLConnectionStatusToCipherSuite(
137 ssl_info.connection_status));
138
bnc3472afd2016-11-17 15:27:21139 dict->SetString("next_proto",
140 NextProtoToString(socket->GetNegotiatedProtocol()));
davidben281d13f02016-04-27 20:43:28141
142 return std::move(dict);
143}
144
davidben3418e81f2016-10-19 00:09:45145int GetBufferSize(const char* field_trial) {
146 // Get buffer sizes from field trials, if possible. If values not present,
147 // use default. Also make sure values are in reasonable range.
148 int buffer_size = kDefaultOpenSSLBufferSize;
149#if !defined(OS_NACL)
150 int override_buffer_size;
151 if (base::StringToInt(base::FieldTrialList::FindFullName(field_trial),
152 &override_buffer_size)) {
153 buffer_size = override_buffer_size;
154 buffer_size = std::max(buffer_size, 1000);
155 buffer_size = std::min(buffer_size, 2 * kDefaultOpenSSLBufferSize);
156 }
157#endif // !defined(OS_NACL)
158 return buffer_size;
159}
160
davidbencef9e212017-04-19 15:00:10161std::unique_ptr<base::Value> NetLogSSLAlertCallback(
162 const void* bytes,
163 size_t len,
164 NetLogCaptureMode capture_mode) {
165 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
166 dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, len));
167 return std::move(dict);
168}
169
170std::unique_ptr<base::Value> NetLogSSLMessageCallback(
171 bool is_write,
172 const void* bytes,
173 size_t len,
174 NetLogCaptureMode capture_mode) {
175 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
176 if (len == 0) {
177 NOTREACHED();
178 return std::move(dict);
179 }
180
181 // The handshake message type is the first byte. Include it so elided messages
182 // still report their type.
183 uint8_t type = reinterpret_cast<const uint8_t*>(bytes)[0];
184 dict->SetInteger("type", type);
185
186 // Elide client certificate messages unless logging socket bytes. The client
187 // certificate does not contain information needed to impersonate the user
188 // (that's the private key which isn't sent over the wire), but it may contain
189 // information on the user's identity.
190 if (!is_write || type != SSL3_MT_CERTIFICATE ||
191 capture_mode.include_socket_bytes()) {
192 dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, len));
193 }
194
195 return std::move(dict);
196}
197
[email protected]821e3bb2013-11-08 01:06:01198} // namespace
199
svaldeze83af292016-04-26 14:33:37200class SSLClientSocketImpl::SSLContext {
[email protected]fbef13932010-11-23 12:38:53201 public:
olli.raula36aa8be2015-09-10 11:14:22202 static SSLContext* GetInstance() {
fdoray33e7c3c52017-01-19 18:37:23203 return base::Singleton<SSLContext,
204 base::LeakySingletonTraits<SSLContext>>::get();
olli.raula36aa8be2015-09-10 11:14:22205 }
[email protected]fbef13932010-11-23 12:38:53206 SSL_CTX* ssl_ctx() { return ssl_ctx_.get(); }
svaldeze83af292016-04-26 14:33:37207 SSLClientSessionCache* session_cache() { return &session_cache_; }
[email protected]fbef13932010-11-23 12:38:53208
svaldeze83af292016-04-26 14:33:37209 SSLClientSocketImpl* GetClientSocketFromSSL(const SSL* ssl) {
[email protected]fbef13932010-11-23 12:38:53210 DCHECK(ssl);
svaldeze83af292016-04-26 14:33:37211 SSLClientSocketImpl* socket = static_cast<SSLClientSocketImpl*>(
[email protected]fbef13932010-11-23 12:38:53212 SSL_get_ex_data(ssl, ssl_socket_data_index_));
213 DCHECK(socket);
214 return socket;
215 }
216
svaldeze83af292016-04-26 14:33:37217 bool SetClientSocketForSSL(SSL* ssl, SSLClientSocketImpl* socket) {
[email protected]fbef13932010-11-23 12:38:53218 return SSL_set_ex_data(ssl, ssl_socket_data_index_, socket) != 0;
219 }
220
davidben2a811e4e2015-12-01 10:49:34221#if !defined(OS_NACL)
David Benjamindc2f4b02017-07-27 23:59:02222 void SetSSLKeyLogFile(const base::FilePath& path) {
davidben2a811e4e2015-12-01 10:49:34223 DCHECK(!ssl_key_logger_);
David Benjamindc2f4b02017-07-27 23:59:02224 ssl_key_logger_.reset(new SSLKeyLogger(path));
davidben2a811e4e2015-12-01 10:49:34225 SSL_CTX_set_keylog_callback(ssl_ctx_.get(), KeyLogCallback);
226 }
227#endif
228
davidben1d489522015-07-01 18:48:46229 static const SSL_PRIVATE_KEY_METHOD kPrivateKeyMethod;
230
[email protected]fbef13932010-11-23 12:38:53231 private:
olli.raula36aa8be2015-09-10 11:14:22232 friend struct base::DefaultSingletonTraits<SSLContext>;
[email protected]fbef13932010-11-23 12:38:53233
svaldeze83af292016-04-26 14:33:37234 SSLContext() : session_cache_(SSLClientSessionCache::Config()) {
[email protected]4b559b4d2011-04-14 17:37:14235 crypto::EnsureOpenSSLInit();
[email protected]fbef13932010-11-23 12:38:53236 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0);
237 DCHECK_NE(ssl_socket_data_index_, -1);
davidbena35b40c32017-03-09 17:33:45238 ssl_ctx_.reset(SSL_CTX_new(TLS_with_buffers_method()));
[email protected]82c59022014-08-15 09:38:27239 SSL_CTX_set_cert_cb(ssl_ctx_.get(), ClientCertRequestCallback, NULL);
davidbena35b40c32017-03-09 17:33:45240
241 // The server certificate is verified after the handshake in DoVerifyCert.
Steven Valdez3eaa9962017-07-18 21:51:05242 SSL_CTX_set_custom_verify(ssl_ctx_.get(), SSL_VERIFY_PEER,
243 CertVerifyCallback);
davidbendafe4e52015-04-08 22:53:52244
245 // Disable the internal session cache. Session caching is handled
svaldeze83af292016-04-26 14:33:37246 // externally (i.e. by SSLClientSessionCache).
davidbendafe4e52015-04-08 22:53:52247 SSL_CTX_set_session_cache_mode(
248 ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
davidben44aeae62015-06-24 20:47:43249 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallback);
davidben99ce6302016-11-09 17:30:28250 SSL_CTX_set_timeout(ssl_ctx_.get(), 1 * 60 * 60 /* one hour */);
nharper736ceda2015-11-07 00:16:59251
davidbenfacfac7b2016-09-27 22:39:53252 SSL_CTX_set_grease_enabled(ssl_ctx_.get(), 1);
253
davidbenbf0fcf12017-02-10 21:00:34254 // Deduplicate all certificates minted from the SSL_CTX in memory.
255 SSL_CTX_set0_buffer_pool(ssl_ctx_.get(), x509_util::GetBufferPool());
256
davidbencef9e212017-04-19 15:00:10257 SSL_CTX_set_msg_callback(ssl_ctx_.get(), MessageCallback);
258
nharper736ceda2015-11-07 00:16:59259 if (!SSL_CTX_add_client_custom_ext(ssl_ctx_.get(), kTbExtNum,
260 &TokenBindingAddCallback,
261 &TokenBindingFreeCallback, nullptr,
262 &TokenBindingParseCallback, nullptr)) {
263 NOTREACHED();
264 }
265 }
266
267 static int TokenBindingAddCallback(SSL* ssl,
268 unsigned int extension_value,
269 const uint8_t** out,
270 size_t* out_len,
271 int* out_alert_value,
272 void* add_arg) {
273 DCHECK_EQ(extension_value, kTbExtNum);
svaldeze83af292016-04-26 14:33:37274 SSLClientSocketImpl* socket =
275 SSLClientSocketImpl::SSLContext::GetInstance()->GetClientSocketFromSSL(
276 ssl);
nharper736ceda2015-11-07 00:16:59277 return socket->TokenBindingAdd(out, out_len, out_alert_value);
278 }
279
280 static void TokenBindingFreeCallback(SSL* ssl,
281 unsigned extension_value,
282 const uint8_t* out,
283 void* add_arg) {
284 DCHECK_EQ(extension_value, kTbExtNum);
285 OPENSSL_free(const_cast<unsigned char*>(out));
286 }
287
288 static int TokenBindingParseCallback(SSL* ssl,
289 unsigned int extension_value,
290 const uint8_t* contents,
291 size_t contents_len,
292 int* out_alert_value,
293 void* parse_arg) {
294 DCHECK_EQ(extension_value, kTbExtNum);
svaldeze83af292016-04-26 14:33:37295 SSLClientSocketImpl* socket =
296 SSLClientSocketImpl::SSLContext::GetInstance()->GetClientSocketFromSSL(
297 ssl);
nharper736ceda2015-11-07 00:16:59298 return socket->TokenBindingParse(contents, contents_len, out_alert_value);
[email protected]fbef13932010-11-23 12:38:53299 }
300
[email protected]82c59022014-08-15 09:38:27301 static int ClientCertRequestCallback(SSL* ssl, void* arg) {
svaldeze83af292016-04-26 14:33:37302 SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
[email protected]82c59022014-08-15 09:38:27303 DCHECK(socket);
304 return socket->ClientCertRequestCallback(ssl);
[email protected]718c9672010-12-02 10:04:10305 }
306
Steven Valdez3eaa9962017-07-18 21:51:05307 static ssl_verify_result_t CertVerifyCallback(SSL* ssl, uint8_t* out_alert) {
308 // The certificate is verified after the handshake in DoVerifyCert.
309 return ssl_verify_ok;
310 }
311
davidben44aeae62015-06-24 20:47:43312 static int NewSessionCallback(SSL* ssl, SSL_SESSION* session) {
svaldeze83af292016-04-26 14:33:37313 SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
davidben44aeae62015-06-24 20:47:43314 return socket->NewSessionCallback(session);
davidbendafe4e52015-04-08 22:53:52315 }
316
David Benjaminb9bafbe2017-11-07 21:41:38317 static ssl_private_key_result_t PrivateKeySignCallback(SSL* ssl,
318 uint8_t* out,
319 size_t* out_len,
320 size_t max_out,
321 uint16_t algorithm,
322 const uint8_t* in,
323 size_t in_len) {
svaldeze83af292016-04-26 14:33:37324 SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
David Benjaminb9bafbe2017-11-07 21:41:38325 return socket->PrivateKeySignCallback(out, out_len, max_out, algorithm, in,
326 in_len);
davidben0bca07fd2016-07-18 15:12:03327 }
328
329 static ssl_private_key_result_t PrivateKeyCompleteCallback(SSL* ssl,
330 uint8_t* out,
331 size_t* out_len,
332 size_t max_out) {
333 SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
334 return socket->PrivateKeyCompleteCallback(out, out_len, max_out);
davidben1d489522015-07-01 18:48:46335 }
336
davidben2a811e4e2015-12-01 10:49:34337#if !defined(OS_NACL)
338 static void KeyLogCallback(const SSL* ssl, const char* line) {
339 GetInstance()->ssl_key_logger_->WriteLine(line);
340 }
341#endif
342
davidbencef9e212017-04-19 15:00:10343 static void MessageCallback(int is_write,
344 int version,
345 int content_type,
346 const void* buf,
347 size_t len,
348 SSL* ssl,
349 void* arg) {
350 SSLClientSocketImpl* socket = GetInstance()->GetClientSocketFromSSL(ssl);
351 return socket->MessageCallback(is_write, content_type, buf, len);
352 }
353
[email protected]fbef13932010-11-23 12:38:53354 // This is the index used with SSL_get_ex_data to retrieve the owner
svaldeze83af292016-04-26 14:33:37355 // SSLClientSocketImpl object from an SSL instance.
[email protected]fbef13932010-11-23 12:38:53356 int ssl_socket_data_index_;
357
davidbend80c12c2016-10-11 00:13:49358 bssl::UniquePtr<SSL_CTX> ssl_ctx_;
davidbendafe4e52015-04-08 22:53:52359
davidben2a811e4e2015-12-01 10:49:34360#if !defined(OS_NACL)
danakj655b66c2016-04-16 00:51:38361 std::unique_ptr<SSLKeyLogger> ssl_key_logger_;
davidben2a811e4e2015-12-01 10:49:34362#endif
363
davidbendafe4e52015-04-08 22:53:52364 // TODO(davidben): Use a separate cache per URLRequestContext.
365 // https://crbug.com/458365
366 //
367 // TODO(davidben): Sessions should be invalidated on fatal
368 // alerts. https://crbug.com/466352
svaldeze83af292016-04-26 14:33:37369 SSLClientSessionCache session_cache_;
[email protected]1279de12013-12-03 15:13:32370};
371
davidben0bca07fd2016-07-18 15:12:03372// TODO(davidben): Switch from sign_digest to sign.
davidben1d489522015-07-01 18:48:46373const SSL_PRIVATE_KEY_METHOD
svaldeze83af292016-04-26 14:33:37374 SSLClientSocketImpl::SSLContext::kPrivateKeyMethod = {
davidbene422380772017-04-19 22:20:01375 nullptr /* type (unused) */,
376 nullptr /* max_signature_len (unused) */,
David Benjaminb9bafbe2017-11-07 21:41:38377 &SSLClientSocketImpl::SSLContext::PrivateKeySignCallback,
378 nullptr /* sign_digest */,
davidben0bca07fd2016-07-18 15:12:03379 nullptr /* decrypt */,
380 &SSLClientSocketImpl::SSLContext::PrivateKeyCompleteCallback,
davidben1d489522015-07-01 18:48:46381};
382
[email protected]1279de12013-12-03 15:13:32383// static
[email protected]c3456bb2011-12-12 22:22:19384void SSLClientSocket::ClearSessionCache() {
svaldeze83af292016-04-26 14:33:37385 SSLClientSocketImpl::SSLContext* context =
386 SSLClientSocketImpl::SSLContext::GetInstance();
[email protected]c3456bb2011-12-12 22:22:19387 context->session_cache()->Flush();
388}
389
svaldeze83af292016-04-26 14:33:37390SSLClientSocketImpl::SSLClientSocketImpl(
danakj655b66c2016-04-16 00:51:38391 std::unique_ptr<ClientSocketHandle> transport_socket,
[email protected]055d7f22010-11-15 12:03:12392 const HostPortPair& host_and_port,
[email protected]822581d2010-12-16 17:27:15393 const SSLConfig& ssl_config,
[email protected]feb79bcd2011-07-21 16:55:17394 const SSLClientSocketContext& context)
davidben3418e81f2016-10-19 00:09:45395 : pending_read_error_(kNoPendingResult),
davidbenb8c23212014-10-28 00:12:16396 pending_read_ssl_error_(SSL_ERROR_NONE),
[email protected]64b5c892014-08-08 09:39:26397 completed_connect_(false),
[email protected]0dc88b32014-03-26 20:12:28398 was_ever_used_(false),
[email protected]feb79bcd2011-07-21 16:55:17399 cert_verifier_(context.cert_verifier),
davidbeneb5f8ef32014-09-04 14:14:32400 cert_transparency_verifier_(context.cert_transparency_verifier),
[email protected]6b8a3c742014-07-25 00:25:35401 channel_id_service_(context.channel_id_service),
nharper736ceda2015-11-07 00:16:59402 tb_was_negotiated_(false),
403 tb_negotiated_param_(TB_PARAM_ECDSAP256),
nharper78e6d2b2016-09-21 05:42:35404 tb_signature_map_(10),
dchengc7eeda422015-12-26 03:56:48405 transport_(std::move(transport_socket)),
[email protected]055d7f22010-11-15 12:03:12406 host_and_port_(host_and_port),
[email protected]d518cd92010-09-29 12:27:44407 ssl_config_(ssl_config),
[email protected]c3456bb2011-12-12 22:22:19408 ssl_session_cache_shard_(context.ssl_session_cache_shard),
[email protected]013c17c2012-01-21 19:09:01409 next_handshake_state_(STATE_NONE),
svaldez4af14d22015-08-20 13:48:24410 disconnected_(false),
bnc3cf2a592016-08-11 14:48:36411 negotiated_protocol_(kProtoUnknown),
davidben52053b382015-04-27 19:22:29412 channel_id_sent_(false),
davidbendafe4e52015-04-08 22:53:52413 certificate_verified_(false),
davidbenfe132d92016-09-27 18:07:21414 certificate_requested_(false),
davidben1d489522015-07-01 18:48:46415 signature_result_(kNoPendingResult),
[email protected]8bd4e7a2014-08-09 14:49:17416 transport_security_state_(context.transport_security_state),
estark6f9b3d82016-01-12 21:37:05417 policy_enforcer_(context.ct_policy_enforcer),
dadriandf302c42016-06-10 18:48:59418 pkp_bypassed_(false),
David Benjamine34d74242017-06-29 20:35:16419 connect_error_details_(SSLErrorDetails::kOther),
kulkarni.acd7b4462014-08-28 07:41:34420 net_log_(transport_->socket()->NetLog()),
421 weak_factory_(this) {
rsleevibe81cd62016-06-24 01:38:59422 CHECK(cert_verifier_);
423 CHECK(transport_security_state_);
424 CHECK(cert_transparency_verifier_);
425 CHECK(policy_enforcer_);
[email protected]8e458552014-08-05 00:02:15426}
[email protected]d518cd92010-09-29 12:27:44427
svaldeze83af292016-04-26 14:33:37428SSLClientSocketImpl::~SSLClientSocketImpl() {
[email protected]d518cd92010-09-29 12:27:44429 Disconnect();
430}
431
davidben2a811e4e2015-12-01 10:49:34432#if !defined(OS_NACL)
svaldeze83af292016-04-26 14:33:37433void SSLClientSocketImpl::SetSSLKeyLogFile(
David Benjamindc2f4b02017-07-27 23:59:02434 const base::FilePath& ssl_keylog_file) {
435 SSLContext::GetInstance()->SetSSLKeyLogFile(ssl_keylog_file);
zhongyi81f85c6d92015-10-16 19:34:14436}
davidben2a811e4e2015-12-01 10:49:34437#endif
zhongyi81f85c6d92015-10-16 19:34:14438
svaldeze83af292016-04-26 14:33:37439void SSLClientSocketImpl::GetSSLCertRequestInfo(
[email protected]b9b651f2013-11-09 04:32:22440 SSLCertRequestInfo* cert_request_info) {
davidbenb11fd212017-01-12 17:08:03441 if (!ssl_) {
442 NOTREACHED();
443 return;
444 }
445
[email protected]791879c2013-12-17 07:22:41446 cert_request_info->host_and_port = host_and_port_;
davidbenb11fd212017-01-12 17:08:03447
448 cert_request_info->cert_authorities.clear();
davidbena35b40c32017-03-09 17:33:45449 const STACK_OF(CRYPTO_BUFFER)* authorities =
450 SSL_get0_server_requested_CAs(ssl_.get());
451 for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(authorities); i++) {
452 const CRYPTO_BUFFER* ca_name = sk_CRYPTO_BUFFER_value(authorities, i);
453 cert_request_info->cert_authorities.push_back(
454 std::string(reinterpret_cast<const char*>(CRYPTO_BUFFER_data(ca_name)),
455 CRYPTO_BUFFER_len(ca_name)));
davidbenb11fd212017-01-12 17:08:03456 }
457
458 cert_request_info->cert_key_types.clear();
459 const uint8_t* client_cert_types;
460 size_t num_client_cert_types =
461 SSL_get0_certificate_types(ssl_.get(), &client_cert_types);
462 for (size_t i = 0; i < num_client_cert_types; i++) {
463 cert_request_info->cert_key_types.push_back(
464 static_cast<SSLClientCertType>(client_cert_types[i]));
465 }
[email protected]b9b651f2013-11-09 04:32:22466}
467
svaldeze83af292016-04-26 14:33:37468ChannelIDService* SSLClientSocketImpl::GetChannelIDService() const {
[email protected]6b8a3c742014-07-25 00:25:35469 return channel_id_service_;
[email protected]b9b651f2013-11-09 04:32:22470}
471
nharper78e6d2b2016-09-21 05:42:35472Error SSLClientSocketImpl::GetTokenBindingSignature(crypto::ECPrivateKey* key,
473 TokenBindingType tb_type,
474 std::vector<uint8_t>* out) {
nharperb7441ef2016-01-25 23:54:14475 // The same key will be used across multiple requests to sign the same value,
476 // so the signature is cached.
477 std::string raw_public_key;
478 if (!key->ExportRawPublicKey(&raw_public_key))
479 return ERR_FAILED;
nharper78e6d2b2016-09-21 05:42:35480 auto it = tb_signature_map_.Get(std::make_pair(tb_type, raw_public_key));
481 if (it != tb_signature_map_.end()) {
nharperb7441ef2016-01-25 23:54:14482 *out = it->second;
483 return OK;
484 }
485
486 uint8_t tb_ekm_buf[32];
487 static const char kTokenBindingExporterLabel[] = "EXPORTER-Token-Binding";
davidbend80c12c2016-10-11 00:13:49488 if (!SSL_export_keying_material(ssl_.get(), tb_ekm_buf, sizeof(tb_ekm_buf),
nharperb7441ef2016-01-25 23:54:14489 kTokenBindingExporterLabel,
490 strlen(kTokenBindingExporterLabel), nullptr,
491 0, false /* no context */)) {
492 return ERR_FAILED;
493 }
494
nharper78e6d2b2016-09-21 05:42:35495 if (!CreateTokenBindingSignature(
nharperd5cddca2016-02-27 03:37:52496 base::StringPiece(reinterpret_cast<char*>(tb_ekm_buf),
497 sizeof(tb_ekm_buf)),
nharper78e6d2b2016-09-21 05:42:35498 tb_type, key, out))
nharperb7441ef2016-01-25 23:54:14499 return ERR_FAILED;
nharperb7441ef2016-01-25 23:54:14500
nharper78e6d2b2016-09-21 05:42:35501 tb_signature_map_.Put(std::make_pair(tb_type, raw_public_key), *out);
nharperb7441ef2016-01-25 23:54:14502 return OK;
503}
504
svaldeze83af292016-04-26 14:33:37505crypto::ECPrivateKey* SSLClientSocketImpl::GetChannelIDKey() const {
nharperb36644f2016-02-22 23:14:43506 return channel_id_key_.get();
507}
508
David Benjamine34d74242017-06-29 20:35:16509SSLErrorDetails SSLClientSocketImpl::GetConnectErrorDetails() const {
510 return connect_error_details_;
511}
512
svaldeze83af292016-04-26 14:33:37513int SSLClientSocketImpl::ExportKeyingMaterial(const base::StringPiece& label,
514 bool has_context,
515 const base::StringPiece& context,
516 unsigned char* out,
517 unsigned int outlen) {
davidben86935f72015-05-06 22:24:49518 if (!IsConnected())
519 return ERR_SOCKET_NOT_CONNECTED;
520
[email protected]b9b651f2013-11-09 04:32:22521 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
522
davidbenf225b262016-09-15 22:09:22523 if (!SSL_export_keying_material(
davidbend80c12c2016-10-11 00:13:49524 ssl_.get(), out, outlen, label.data(), label.size(),
davidbenf225b262016-09-15 22:09:22525 reinterpret_cast<const unsigned char*>(context.data()),
526 context.length(), has_context ? 1 : 0)) {
527 LOG(ERROR) << "Failed to export keying material.";
528 return ERR_FAILED;
[email protected]b9b651f2013-11-09 04:32:22529 }
davidbenf225b262016-09-15 22:09:22530
[email protected]b9b651f2013-11-09 04:32:22531 return OK;
532}
533
svaldeze83af292016-04-26 14:33:37534int SSLClientSocketImpl::Connect(const CompletionCallback& callback) {
svaldez4af14d22015-08-20 13:48:24535 // Although StreamSocket does allow calling Connect() after Disconnect(),
536 // this has never worked for layered sockets. CHECK to detect any consumers
537 // reconnecting an SSL socket.
538 //
539 // TODO(davidben,mmenke): Remove this API feature. See
540 // https://crbug.com/499289.
541 CHECK(!disconnected_);
542
mikecirone8b85c432016-09-08 19:11:00543 net_log_.BeginEvent(NetLogEventType::SSL_CONNECT);
[email protected]b9b651f2013-11-09 04:32:22544
545 // Set up new ssl object.
[email protected]c8a80e92014-05-17 16:02:08546 int rv = Init();
547 if (rv != OK) {
davidben281d13f02016-04-27 20:43:28548 LogConnectEndEvent(rv);
[email protected]c8a80e92014-05-17 16:02:08549 return rv;
[email protected]b9b651f2013-11-09 04:32:22550 }
551
552 // Set SSL to client mode. Handshake happens in the loop below.
davidbend80c12c2016-10-11 00:13:49553 SSL_set_connect_state(ssl_.get());
[email protected]b9b651f2013-11-09 04:32:22554
rsleeviadbd4982016-06-13 22:10:27555 next_handshake_state_ = STATE_HANDSHAKE;
[email protected]c8a80e92014-05-17 16:02:08556 rv = DoHandshakeLoop(OK);
[email protected]b9b651f2013-11-09 04:32:22557 if (rv == ERR_IO_PENDING) {
558 user_connect_callback_ = callback;
559 } else {
davidben281d13f02016-04-27 20:43:28560 LogConnectEndEvent(rv);
[email protected]b9b651f2013-11-09 04:32:22561 }
562
563 return rv > OK ? OK : rv;
564}
565
svaldeze83af292016-04-26 14:33:37566void SSLClientSocketImpl::Disconnect() {
svaldez4af14d22015-08-20 13:48:24567 disconnected_ = true;
568
[email protected]b9b651f2013-11-09 04:32:22569 // Shut down anything that may call us back.
eroman7f9236a2015-05-11 21:23:43570 cert_verifier_request_.reset();
davidben67e83912016-10-12 18:36:32571 channel_id_request_.Cancel();
572 weak_factory_.InvalidateWeakPtrs();
davidben3418e81f2016-10-19 00:09:45573 transport_adapter_.reset();
[email protected]b9b651f2013-11-09 04:32:22574
davidben67e83912016-10-12 18:36:32575 // Release user callbacks.
[email protected]b9b651f2013-11-09 04:32:22576 user_connect_callback_.Reset();
577 user_read_callback_.Reset();
578 user_write_callback_.Reset();
svaldeze83af292016-04-26 14:33:37579 user_read_buf_ = NULL;
580 user_read_buf_len_ = 0;
581 user_write_buf_ = NULL;
582 user_write_buf_len_ = 0;
[email protected]b9b651f2013-11-09 04:32:22583
davidben67e83912016-10-12 18:36:32584 transport_->socket()->Disconnect();
[email protected]b9b651f2013-11-09 04:32:22585}
586
svaldeze83af292016-04-26 14:33:37587bool SSLClientSocketImpl::IsConnected() const {
davidben67e83912016-10-12 18:36:32588 // If the handshake has not yet completed or the socket has been explicitly
589 // disconnected.
590 if (!completed_connect_ || disconnected_)
[email protected]b9b651f2013-11-09 04:32:22591 return false;
592 // If an asynchronous operation is still pending.
593 if (user_read_buf_.get() || user_write_buf_.get())
594 return true;
595
596 return transport_->socket()->IsConnected();
597}
598
svaldeze83af292016-04-26 14:33:37599bool SSLClientSocketImpl::IsConnectedAndIdle() const {
davidben67e83912016-10-12 18:36:32600 // If the handshake has not yet completed or the socket has been explicitly
601 // disconnected.
602 if (!completed_connect_ || disconnected_)
[email protected]b9b651f2013-11-09 04:32:22603 return false;
604 // If an asynchronous operation is still pending.
605 if (user_read_buf_.get() || user_write_buf_.get())
606 return false;
davidbenfc9a6b82015-04-15 23:47:32607
608 // If there is data read from the network that has not yet been consumed, do
609 // not treat the connection as idle.
610 //
davidben3418e81f2016-10-19 00:09:45611 // Note that this does not check whether there is ciphertext that has not yet
612 // been flushed to the network. |Write| returns early, so this can cause race
613 // conditions which cause a socket to not be treated reusable when it should
614 // be. See https://crbug.com/466147.
615 if (transport_adapter_->HasPendingReadData())
[email protected]b9b651f2013-11-09 04:32:22616 return false;
[email protected]b9b651f2013-11-09 04:32:22617
618 return transport_->socket()->IsConnectedAndIdle();
619}
620
svaldeze83af292016-04-26 14:33:37621int SSLClientSocketImpl::GetPeerAddress(IPEndPoint* addressList) const {
[email protected]b9b651f2013-11-09 04:32:22622 return transport_->socket()->GetPeerAddress(addressList);
623}
624
svaldeze83af292016-04-26 14:33:37625int SSLClientSocketImpl::GetLocalAddress(IPEndPoint* addressList) const {
[email protected]b9b651f2013-11-09 04:32:22626 return transport_->socket()->GetLocalAddress(addressList);
627}
628
tfarina428341112016-09-22 13:38:20629const NetLogWithSource& SSLClientSocketImpl::NetLog() const {
[email protected]b9b651f2013-11-09 04:32:22630 return net_log_;
631}
632
svaldeze83af292016-04-26 14:33:37633void SSLClientSocketImpl::SetSubresourceSpeculation() {
[email protected]b9b651f2013-11-09 04:32:22634 if (transport_.get() && transport_->socket()) {
635 transport_->socket()->SetSubresourceSpeculation();
636 } else {
637 NOTREACHED();
638 }
639}
640
svaldeze83af292016-04-26 14:33:37641void SSLClientSocketImpl::SetOmniboxSpeculation() {
[email protected]b9b651f2013-11-09 04:32:22642 if (transport_.get() && transport_->socket()) {
643 transport_->socket()->SetOmniboxSpeculation();
644 } else {
645 NOTREACHED();
646 }
647}
648
svaldeze83af292016-04-26 14:33:37649bool SSLClientSocketImpl::WasEverUsed() const {
[email protected]0dc88b32014-03-26 20:12:28650 return was_ever_used_;
[email protected]b9b651f2013-11-09 04:32:22651}
652
tfarina2846404c2016-12-25 14:31:37653bool SSLClientSocketImpl::WasAlpnNegotiated() const {
bnc3cf2a592016-08-11 14:48:36654 return negotiated_protocol_ != kProtoUnknown;
655}
656
657NextProto SSLClientSocketImpl::GetNegotiatedProtocol() const {
658 return negotiated_protocol_;
659}
660
svaldeze83af292016-04-26 14:33:37661bool SSLClientSocketImpl::GetSSLInfo(SSLInfo* ssl_info) {
[email protected]b9b651f2013-11-09 04:32:22662 ssl_info->Reset();
davidbenc7e06c92017-03-07 18:54:11663 if (!server_cert_)
[email protected]b9b651f2013-11-09 04:32:22664 return false;
665
666 ssl_info->cert = server_cert_verify_result_.verified_cert;
estark03d644f2015-06-13 00:11:32667 ssl_info->unverified_cert = server_cert_;
[email protected]b9b651f2013-11-09 04:32:22668 ssl_info->cert_status = server_cert_verify_result_.cert_status;
669 ssl_info->is_issued_by_known_root =
670 server_cert_verify_result_.is_issued_by_known_root;
dadriandf302c42016-06-10 18:48:59671 ssl_info->pkp_bypassed = pkp_bypassed_;
svaldeze83af292016-04-26 14:33:37672 ssl_info->public_key_hashes = server_cert_verify_result_.public_key_hashes;
[email protected]b9b651f2013-11-09 04:32:22673 ssl_info->client_cert_sent =
674 ssl_config_.send_client_cert && ssl_config_.client_cert.get();
davidben52053b382015-04-27 19:22:29675 ssl_info->channel_id_sent = channel_id_sent_;
nharper736ceda2015-11-07 00:16:59676 ssl_info->token_binding_negotiated = tb_was_negotiated_;
677 ssl_info->token_binding_key_param = tb_negotiated_param_;
[email protected]8bd4e7a2014-08-09 14:49:17678 ssl_info->pinning_failure_log = pinning_failure_log_;
dadrian612337a2016-07-20 22:36:58679 ssl_info->ocsp_result = server_cert_verify_result_.ocsp_result;
[email protected]b9b651f2013-11-09 04:32:22680
estark723b5eeb2016-02-18 21:01:12681 AddCTInfoToSSLInfo(ssl_info);
davidbeneb5f8ef32014-09-04 14:14:32682
davidbend80c12c2016-10-11 00:13:49683 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_.get());
[email protected]b9b651f2013-11-09 04:32:22684 CHECK(cipher);
685 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL);
davidben3b00e402016-09-20 14:31:06686 // Historically, the "group" was known as "curve".
davidbend80c12c2016-10-11 00:13:49687 ssl_info->key_exchange_group = SSL_get_curve_id(ssl_.get());
[email protected]b9b651f2013-11-09 04:32:22688
ryanchung987b2ff2016-02-19 00:17:12689 SSLConnectionStatusSetCipherSuite(
690 static_cast<uint16_t>(SSL_CIPHER_get_id(cipher)),
691 &ssl_info->connection_status);
davidbend80c12c2016-10-11 00:13:49692 SSLConnectionStatusSetVersion(GetNetSSLVersion(ssl_.get()),
ryanchung987b2ff2016-02-19 00:17:12693 &ssl_info->connection_status);
[email protected]b9b651f2013-11-09 04:32:22694
davidbend80c12c2016-10-11 00:13:49695 ssl_info->handshake_type = SSL_session_reused(ssl_.get())
svaldeze83af292016-04-26 14:33:37696 ? SSLInfo::HANDSHAKE_RESUME
697 : SSLInfo::HANDSHAKE_FULL;
[email protected]b9b651f2013-11-09 04:32:22698
[email protected]b9b651f2013-11-09 04:32:22699 return true;
700}
701
svaldeze83af292016-04-26 14:33:37702void SSLClientSocketImpl::GetConnectionAttempts(ConnectionAttempts* out) const {
ttuttle23fdb7b2015-05-15 01:28:03703 out->clear();
704}
705
svaldeze83af292016-04-26 14:33:37706int64_t SSLClientSocketImpl::GetTotalReceivedBytes() const {
tbansalf82cc8e2015-10-14 20:05:49707 return transport_->socket()->GetTotalReceivedBytes();
708}
709
xunjieli998d2472017-01-12 01:12:28710void SSLClientSocketImpl::DumpMemoryStats(SocketMemoryStats* stats) const {
711 if (transport_adapter_)
712 stats->buffer_size = transport_adapter_->GetAllocationSize();
davidbena35b40c32017-03-09 17:33:45713 const STACK_OF(CRYPTO_BUFFER)* server_cert_chain =
714 SSL_get0_peer_certificates(ssl_.get());
davidbenc7e06c92017-03-07 18:54:11715 if (server_cert_chain) {
davidbena35b40c32017-03-09 17:33:45716 for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(server_cert_chain); ++i) {
717 const CRYPTO_BUFFER* cert = sk_CRYPTO_BUFFER_value(server_cert_chain, i);
718 stats->cert_size += CRYPTO_BUFFER_len(cert);
xunjieli9f8c5fb52016-12-07 22:59:33719 }
davidbena35b40c32017-03-09 17:33:45720 stats->cert_count = sk_CRYPTO_BUFFER_num(server_cert_chain);
xunjieli9f8c5fb52016-12-07 22:59:33721 }
xunjieliffe62df62017-02-23 18:22:41722 stats->total_size = stats->buffer_size + stats->cert_size;
xunjieli9f8c5fb52016-12-07 22:59:33723}
724
725// static
726void SSLClientSocketImpl::DumpSSLClientSessionMemoryStats(
727 base::trace_event::ProcessMemoryDump* pmd) {
728 SSLContext::GetInstance()->session_cache()->DumpMemoryStats(pmd);
729}
730
svaldeze83af292016-04-26 14:33:37731int SSLClientSocketImpl::Read(IOBuffer* buf,
732 int buf_len,
733 const CompletionCallback& callback) {
xunjieli321a96f32017-03-07 19:42:17734 int rv = ReadIfReady(buf, buf_len, callback);
735 if (rv == ERR_IO_PENDING) {
736 user_read_buf_ = buf;
737 user_read_buf_len_ = buf_len;
738 }
739 return rv;
740}
[email protected]b9b651f2013-11-09 04:32:22741
xunjieli321a96f32017-03-07 19:42:17742int SSLClientSocketImpl::ReadIfReady(IOBuffer* buf,
743 int buf_len,
744 const CompletionCallback& callback) {
745 int rv = DoPayloadRead(buf, buf_len);
[email protected]b9b651f2013-11-09 04:32:22746
747 if (rv == ERR_IO_PENDING) {
748 user_read_callback_ = callback;
749 } else {
[email protected]0dc88b32014-03-26 20:12:28750 if (rv > 0)
751 was_ever_used_ = true;
[email protected]b9b651f2013-11-09 04:32:22752 }
[email protected]b9b651f2013-11-09 04:32:22753 return rv;
754}
755
svaldeze83af292016-04-26 14:33:37756int SSLClientSocketImpl::Write(IOBuffer* buf,
757 int buf_len,
758 const CompletionCallback& callback) {
[email protected]b9b651f2013-11-09 04:32:22759 user_write_buf_ = buf;
760 user_write_buf_len_ = buf_len;
761
davidben3418e81f2016-10-19 00:09:45762 int rv = DoPayloadWrite();
[email protected]b9b651f2013-11-09 04:32:22763
764 if (rv == ERR_IO_PENDING) {
765 user_write_callback_ = callback;
766 } else {
[email protected]0dc88b32014-03-26 20:12:28767 if (rv > 0)
768 was_ever_used_ = true;
[email protected]b9b651f2013-11-09 04:32:22769 user_write_buf_ = NULL;
770 user_write_buf_len_ = 0;
771 }
772
773 return rv;
774}
775
svaldeze83af292016-04-26 14:33:37776int SSLClientSocketImpl::SetReceiveBufferSize(int32_t size) {
[email protected]b9b651f2013-11-09 04:32:22777 return transport_->socket()->SetReceiveBufferSize(size);
778}
779
svaldeze83af292016-04-26 14:33:37780int SSLClientSocketImpl::SetSendBufferSize(int32_t size) {
[email protected]b9b651f2013-11-09 04:32:22781 return transport_->socket()->SetSendBufferSize(size);
782}
783
davidben3418e81f2016-10-19 00:09:45784void SSLClientSocketImpl::OnReadReady() {
785 // During a renegotiation, either Read or Write calls may be blocked on a
786 // transport read.
787 RetryAllOperations();
788}
789
790void SSLClientSocketImpl::OnWriteReady() {
791 // During a renegotiation, either Read or Write calls may be blocked on a
792 // transport read.
793 RetryAllOperations();
794}
795
svaldeze83af292016-04-26 14:33:37796int SSLClientSocketImpl::Init() {
[email protected]9e733f32010-10-04 18:19:08797 DCHECK(!ssl_);
[email protected]9e733f32010-10-04 18:19:08798
svaldez2135be52016-04-20 16:34:53799#if defined(USE_NSS_CERTS)
davidbena477a70a2015-10-06 04:38:29800 if (ssl_config_.cert_io_enabled) {
801 // TODO(davidben): Move this out of SSLClientSocket. See
802 // https://crbug.com/539520.
803 EnsureNSSHttpIOInit();
804 }
805#endif
806
[email protected]b29af7d2010-12-14 11:52:47807 SSLContext* context = SSLContext::GetInstance();
[email protected]4b559b4d2011-04-14 17:37:14808 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
[email protected]d518cd92010-09-29 12:27:44809
davidbend80c12c2016-10-11 00:13:49810 ssl_.reset(SSL_new(context->ssl_ctx()));
811 if (!ssl_ || !context->SetClientSocketForSSL(ssl_.get(), this))
[email protected]c8a80e92014-05-17 16:02:08812 return ERR_UNEXPECTED;
[email protected]fbef13932010-11-23 12:38:53813
davidben9bc0466f2015-06-16 22:21:27814 // SNI should only contain valid DNS hostnames, not IP addresses (see RFC
815 // 6066, Section 3).
816 //
817 // TODO(rsleevi): Should this code allow hostnames that violate the LDH rule?
818 // See https://crbug.com/496472 and https://crbug.com/496468 for discussion.
martijna2e83bd2016-03-18 13:10:45819 IPAddress unused;
820 if (!unused.AssignFromIPLiteral(host_and_port_.host()) &&
davidbend80c12c2016-10-11 00:13:49821 !SSL_set_tlsext_host_name(ssl_.get(), host_and_port_.host().c_str())) {
[email protected]c8a80e92014-05-17 16:02:08822 return ERR_UNEXPECTED;
davidben9bc0466f2015-06-16 22:21:27823 }
[email protected]fbef13932010-11-23 12:38:53824
David Benjaminb3840f42017-08-03 15:50:16825 if (!ssl_session_cache_shard_.empty()) {
Steven Valdeze6112f42017-10-05 22:20:12826 bssl::UniquePtr<SSL_SESSION> session =
827 context->session_cache()->Lookup(GetSessionCacheKey());
David Benjaminb3840f42017-08-03 15:50:16828 if (session)
829 SSL_set_session(ssl_.get(), session.get());
830 }
[email protected]d518cd92010-09-29 12:27:44831
davidben3418e81f2016-10-19 00:09:45832 transport_adapter_.reset(new SocketBIOAdapter(
833 transport_->socket(), GetBufferSize("SSLBufferSizeRecv"),
834 GetBufferSize("SSLBufferSizeSend"), this));
835 BIO* transport_bio = transport_adapter_->bio();
mmenke1beda3d2016-07-22 03:33:45836
davidben3418e81f2016-10-19 00:09:45837 BIO_up_ref(transport_bio); // SSL_set0_rbio takes ownership.
838 SSL_set0_rbio(ssl_.get(), transport_bio);
haavardm2d92e722014-12-19 13:45:44839
davidben3418e81f2016-10-19 00:09:45840 BIO_up_ref(transport_bio); // SSL_set0_wbio takes ownership.
841 SSL_set0_wbio(ssl_.get(), transport_bio);
[email protected]d518cd92010-09-29 12:27:44842
davidbenb937d6c2015-05-14 04:53:42843 DCHECK_LT(SSL3_VERSION, ssl_config_.version_min);
844 DCHECK_LT(SSL3_VERSION, ssl_config_.version_max);
davidbend80c12c2016-10-11 00:13:49845 if (!SSL_set_min_proto_version(ssl_.get(), ssl_config_.version_min) ||
846 !SSL_set_max_proto_version(ssl_.get(), ssl_config_.version_max)) {
davidben952bdf22016-09-21 23:42:16847 return ERR_UNEXPECTED;
848 }
davidbenb937d6c2015-05-14 04:53:42849
Steven Valdez4584b2482017-07-14 01:11:57850 switch (ssl_config_.tls13_variant) {
851 case kTLS13VariantDraft:
852 SSL_set_tls13_variant(ssl_.get(), tls13_default);
853 break;
854 case kTLS13VariantExperiment:
855 SSL_set_tls13_variant(ssl_.get(), tls13_experiment);
856 break;
Steven Valdezf00f8782017-09-13 18:05:28857 case kTLS13VariantExperiment2:
858 SSL_set_tls13_variant(ssl_.get(), tls13_experiment2);
859 break;
860 case kTLS13VariantExperiment3:
861 SSL_set_tls13_variant(ssl_.get(), tls13_experiment3);
862 break;
Steven Valdez4584b2482017-07-14 01:11:57863 }
864
[email protected]9e733f32010-10-04 18:19:08865 // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
866 // set everything we care about to an absolute value.
[email protected]fb10e2282010-12-01 17:08:48867 SslSetClearMask options;
[email protected]d0f00492012-08-03 22:35:13868 options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true);
[email protected]9e733f32010-10-04 18:19:08869
870 // TODO(joth): Set this conditionally, see http://crbug.com/55410
[email protected]fb10e2282010-12-01 17:08:48871 options.ConfigureFlag(SSL_OP_LEGACY_SERVER_CONNECT, true);
[email protected]9e733f32010-10-04 18:19:08872
davidbend80c12c2016-10-11 00:13:49873 SSL_set_options(ssl_.get(), options.set_mask);
874 SSL_clear_options(ssl_.get(), options.clear_mask);
[email protected]9e733f32010-10-04 18:19:08875
[email protected]fb10e2282010-12-01 17:08:48876 // Same as above, this time for the SSL mode.
877 SslSetClearMask mode;
[email protected]9e733f32010-10-04 18:19:08878
[email protected]fb10e2282010-12-01 17:08:48879 mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true);
ishermane5c05e12014-09-09 20:32:15880 mode.ConfigureFlag(SSL_MODE_CBC_RECORD_SPLITTING, true);
[email protected]fb10e2282010-12-01 17:08:48881
davidben818d93b2015-02-19 22:27:32882 mode.ConfigureFlag(SSL_MODE_ENABLE_FALSE_START,
[email protected]b788de02014-04-23 18:06:07883 ssl_config_.false_start_enabled);
884
davidbend80c12c2016-10-11 00:13:49885 SSL_set_mode(ssl_.get(), mode.set_mask);
886 SSL_clear_mode(ssl_.get(), mode.clear_mask);
[email protected]109805a2010-12-07 18:17:06887
davidben4177ecb2016-10-22 01:47:18888 // Use BoringSSL defaults, but disable HMAC-SHA256 and HMAC-SHA384 ciphers
kjellander1ae83a02017-01-26 07:35:09889 // (note that SHA256 and SHA384 only select legacy CBC ciphers).
davidben0b6de432017-03-23 22:11:05890 // Additionally disable HMAC-SHA1 ciphers in ECDSA. These are the remaining
891 // CBC-mode ECDSA ciphers.
davidben1863716b2017-05-03 20:06:20892 std::string command("ALL:!SHA256:!SHA384:!aPSK:!ECDSA+SHA1");
davidben9b4a9b9c2015-10-12 18:46:51893
894 if (ssl_config_.require_ecdhe)
davidben1863716b2017-05-03 20:06:20895 command.append(":!kRSA");
davidben8ecc3072014-09-03 23:19:09896
davidben9b4a9b9c2015-10-12 18:46:51897 // Remove any disabled ciphers.
898 for (uint16_t id : ssl_config_.disabled_cipher_suites) {
899 const SSL_CIPHER* cipher = SSL_get_cipher_by_value(id);
900 if (cipher) {
901 command.append(":!");
902 command.append(SSL_CIPHER_get_name(cipher));
903 }
904 }
905
davidben1863716b2017-05-03 20:06:20906 if (!SSL_set_strict_cipher_list(ssl_.get(), command.c_str())) {
907 LOG(ERROR) << "SSL_set_cipher_list('" << command << "') failed";
908 return ERR_UNEXPECTED;
909 }
[email protected]ee0f2aa82013-10-25 11:59:26910
911 // TLS channel ids.
bnc3cf2a592016-08-11 14:48:36912 if (IsChannelIDEnabled()) {
davidbend80c12c2016-10-11 00:13:49913 SSL_enable_tls_channel_id(ssl_.get());
[email protected]ee0f2aa82013-10-25 11:59:26914 }
915
bnc1f295372015-10-21 23:24:22916 if (!ssl_config_.alpn_protos.empty()) {
bnc988e68d2016-06-27 14:03:21917 std::vector<uint8_t> wire_protos =
918 SerializeNextProtos(ssl_config_.alpn_protos);
davidbend80c12c2016-10-11 00:13:49919 SSL_set_alpn_protos(ssl_.get(),
920 wire_protos.empty() ? NULL : &wire_protos[0],
[email protected]abc44b752014-07-30 03:52:15921 wire_protos.size());
922 }
923
davidbeneb5f8ef32014-09-04 14:14:32924 if (ssl_config_.signed_cert_timestamps_enabled) {
davidbend80c12c2016-10-11 00:13:49925 SSL_enable_signed_cert_timestamps(ssl_.get());
926 SSL_enable_ocsp_stapling(ssl_.get());
davidbeneb5f8ef32014-09-04 14:14:32927 }
928
davidben15f57132015-04-27 18:08:36929 if (cert_verifier_->SupportsOCSPStapling())
davidbend80c12c2016-10-11 00:13:49930 SSL_enable_ocsp_stapling(ssl_.get());
davidbeneb5f8ef32014-09-04 14:14:32931
davidben971a681a2017-02-16 18:57:46932 // Configure BoringSSL to allow renegotiations. Once the initial handshake
933 // completes, if renegotiations are not allowed, the default reject value will
934 // be restored. This is done in this order to permit a BoringSSL
935 // optimization. See https://crbug.com/boringssl/123.
936 SSL_set_renegotiate_mode(ssl_.get(), ssl_renegotiate_freely);
937
[email protected]c8a80e92014-05-17 16:02:08938 return OK;
[email protected]d518cd92010-09-29 12:27:44939}
940
svaldeze83af292016-04-26 14:33:37941void SSLClientSocketImpl::DoReadCallback(int rv) {
[email protected]b9b651f2013-11-09 04:32:22942 // Since Run may result in Read being called, clear |user_read_callback_|
943 // up front.
[email protected]0dc88b32014-03-26 20:12:28944 if (rv > 0)
945 was_ever_used_ = true;
xunjieli321a96f32017-03-07 19:42:17946 user_read_buf_ = nullptr;
[email protected]b9b651f2013-11-09 04:32:22947 user_read_buf_len_ = 0;
948 base::ResetAndReturn(&user_read_callback_).Run(rv);
949}
950
svaldeze83af292016-04-26 14:33:37951void SSLClientSocketImpl::DoWriteCallback(int rv) {
[email protected]b9b651f2013-11-09 04:32:22952 // Since Run may result in Write being called, clear |user_write_callback_|
953 // up front.
[email protected]0dc88b32014-03-26 20:12:28954 if (rv > 0)
955 was_ever_used_ = true;
[email protected]b9b651f2013-11-09 04:32:22956 user_write_buf_ = NULL;
957 user_write_buf_len_ = 0;
958 base::ResetAndReturn(&user_write_callback_).Run(rv);
959}
960
pkasting379234c2015-04-08 04:42:12961// TODO(cbentzel): Remove including "base/threading/thread_local.h" and
vadimt6b43dec22015-01-06 01:59:58962// g_first_run_completed once crbug.com/424386 is fixed.
963base::LazyInstance<base::ThreadLocalBoolean>::Leaky g_first_run_completed =
964 LAZY_INSTANCE_INITIALIZER;
965
svaldeze83af292016-04-26 14:33:37966int SSLClientSocketImpl::DoHandshake() {
[email protected]b9b651f2013-11-09 04:32:22967 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
vadimt5a243282014-12-24 00:26:16968
969 int rv;
970
pkasting379234c2015-04-08 04:42:12971 // TODO(cbentzel): Leave only 1 call to SSL_do_handshake once crbug.com/424386
vadimt5a243282014-12-24 00:26:16972 // is fixed.
973 if (ssl_config_.send_client_cert && ssl_config_.client_cert.get()) {
davidbend80c12c2016-10-11 00:13:49974 rv = SSL_do_handshake(ssl_.get());
vadimt5a243282014-12-24 00:26:16975 } else {
vadimt6b43dec22015-01-06 01:59:58976 if (g_first_run_completed.Get().Get()) {
davidbend80c12c2016-10-11 00:13:49977 rv = SSL_do_handshake(ssl_.get());
vadimt6b43dec22015-01-06 01:59:58978 } else {
979 g_first_run_completed.Get().Set(true);
davidbend80c12c2016-10-11 00:13:49980 rv = SSL_do_handshake(ssl_.get());
vadimt6b43dec22015-01-06 01:59:58981 }
vadimt5a243282014-12-24 00:26:16982 }
[email protected]b9b651f2013-11-09 04:32:22983
davidbenc4212c02015-05-12 22:30:18984 int net_error = OK;
985 if (rv <= 0) {
davidbend80c12c2016-10-11 00:13:49986 int ssl_error = SSL_get_error(ssl_.get(), rv);
[email protected]b9b651f2013-11-09 04:32:22987 if (ssl_error == SSL_ERROR_WANT_CHANNEL_ID_LOOKUP) {
[email protected]faff9852014-06-21 06:13:46988 // The server supports channel ID. Stop to look one up before returning to
989 // the handshake.
rsleeviadbd4982016-06-13 22:10:27990 next_handshake_state_ = STATE_CHANNEL_ID_LOOKUP;
[email protected]faff9852014-06-21 06:13:46991 return OK;
[email protected]b9b651f2013-11-09 04:32:22992 }
davidbenced4aa9b2015-05-12 21:22:35993 if (ssl_error == SSL_ERROR_WANT_X509_LOOKUP &&
994 !ssl_config_.send_client_cert) {
995 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
996 }
davidben1d489522015-07-01 18:48:46997 if (ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
svaldez7872fd02015-11-19 21:10:54998 DCHECK(ssl_config_.client_private_key);
davidben1d489522015-07-01 18:48:46999 DCHECK_NE(kNoPendingResult, signature_result_);
rsleeviadbd4982016-06-13 22:10:271000 next_handshake_state_ = STATE_HANDSHAKE;
davidben1d489522015-07-01 18:48:461001 return ERR_IO_PENDING;
1002 }
[email protected]b9b651f2013-11-09 04:32:221003
davidbena4409c62014-08-27 17:05:511004 OpenSSLErrorInfo error_info;
davidbenfe132d92016-09-27 18:07:211005 net_error = MapLastOpenSSLError(ssl_error, err_tracer, &error_info);
[email protected]b9b651f2013-11-09 04:32:221006 if (net_error == ERR_IO_PENDING) {
davidbenc4212c02015-05-12 22:30:181007 // If not done, stay in this state
rsleeviadbd4982016-06-13 22:10:271008 next_handshake_state_ = STATE_HANDSHAKE;
davidbenc4212c02015-05-12 22:30:181009 return ERR_IO_PENDING;
1010 }
1011
David Benjamine34d74242017-06-29 20:35:161012 switch (net_error) {
1013 case ERR_CONNECTION_CLOSED:
1014 connect_error_details_ = SSLErrorDetails::kConnectionClosed;
1015 break;
1016 case ERR_CONNECTION_RESET:
1017 connect_error_details_ = SSLErrorDetails::kConnectionReset;
1018 break;
1019 case ERR_SSL_PROTOCOL_ERROR: {
1020 int lib = ERR_GET_LIB(error_info.error_code);
1021 int reason = ERR_GET_REASON(error_info.error_code);
1022 if (lib == ERR_LIB_SSL && reason == SSL_R_TLSV1_ALERT_ACCESS_DENIED) {
1023 connect_error_details_ = SSLErrorDetails::kAccessDeniedAlert;
1024 } else if (lib == ERR_LIB_SSL &&
1025 reason == SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE) {
1026 connect_error_details_ =
1027 SSLErrorDetails::kApplicationDataInsteadOfHandshake;
1028 } else {
1029 connect_error_details_ = SSLErrorDetails::kProtocolError;
1030 }
1031 break;
1032 }
1033 case ERR_SSL_BAD_RECORD_MAC_ALERT:
1034 connect_error_details_ = SSLErrorDetails::kBadRecordMACAlert;
1035 break;
1036 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
1037 connect_error_details_ = SSLErrorDetails::kVersionOrCipherMismatch;
1038 break;
1039 default:
1040 connect_error_details_ = SSLErrorDetails::kOther;
1041 break;
1042 }
1043
davidbenc4212c02015-05-12 22:30:181044 LOG(ERROR) << "handshake failed; returned " << rv << ", SSL error code "
1045 << ssl_error << ", net_error " << net_error;
1046 net_log_.AddEvent(
mikecirone8b85c432016-09-08 19:11:001047 NetLogEventType::SSL_HANDSHAKE_ERROR,
davidbenc4212c02015-05-12 22:30:181048 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
1049 }
1050
rsleeviadbd4982016-06-13 22:10:271051 next_handshake_state_ = STATE_HANDSHAKE_COMPLETE;
davidbenc4212c02015-05-12 22:30:181052 return net_error;
1053}
1054
svaldeze83af292016-04-26 14:33:371055int SSLClientSocketImpl::DoHandshakeComplete(int result) {
davidbenc4212c02015-05-12 22:30:181056 if (result < 0)
1057 return result;
1058
davidben095ebb52017-04-12 22:23:341059 if (ssl_config_.version_interference_probe) {
1060 DCHECK_LT(ssl_config_.version_max, TLS1_3_VERSION);
1061 return ERR_SSL_VERSION_INTERFERENCE;
1062 }
1063
David Benjaminb3840f42017-08-03 15:50:161064 if (!ssl_session_cache_shard_.empty()) {
1065 SSLContext::GetInstance()->session_cache()->ResetLookupCount(
1066 GetSessionCacheKey());
1067 }
1068
nharper736ceda2015-11-07 00:16:591069 // Check that if token binding was negotiated, then extended master secret
nharper78e6d2b2016-09-21 05:42:351070 // and renegotiation indication must also be negotiated.
1071 if (tb_was_negotiated_ &&
davidbend80c12c2016-10-11 00:13:491072 !(SSL_get_extms_support(ssl_.get()) &&
1073 SSL_get_secure_renegotiation_support(ssl_.get()))) {
nharper736ceda2015-11-07 00:16:591074 return ERR_SSL_PROTOCOL_ERROR;
nharper78e6d2b2016-09-21 05:42:351075 }
nharper736ceda2015-11-07 00:16:591076
bncce6ea242016-09-15 20:22:321077 const uint8_t* alpn_proto = NULL;
1078 unsigned alpn_len = 0;
davidbend80c12c2016-10-11 00:13:491079 SSL_get0_alpn_selected(ssl_.get(), &alpn_proto, &alpn_len);
bncce6ea242016-09-15 20:22:321080 if (alpn_len > 0) {
1081 base::StringPiece proto(reinterpret_cast<const char*>(alpn_proto),
1082 alpn_len);
1083 negotiated_protocol_ = NextProtoFromString(proto);
[email protected]b9b651f2013-11-09 04:32:221084 }
davidbenc4212c02015-05-12 22:30:181085
bncbd442c22016-09-14 20:49:161086 RecordNegotiatedProtocol();
bnc3cf2a592016-08-11 14:48:361087 RecordChannelIDSupport();
davidbenc4212c02015-05-12 22:30:181088
dadriand476e652016-07-26 21:33:241089 const uint8_t* ocsp_response_raw;
1090 size_t ocsp_response_len;
davidbend80c12c2016-10-11 00:13:491091 SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len);
dadriand476e652016-07-26 21:33:241092 set_stapled_ocsp_response_received(ocsp_response_len != 0);
1093 UMA_HISTOGRAM_BOOLEAN("Net.OCSPResponseStapled", ocsp_response_len != 0);
davidbenc4212c02015-05-12 22:30:181094
1095 const uint8_t* sct_list;
1096 size_t sct_list_len;
davidbend80c12c2016-10-11 00:13:491097 SSL_get0_signed_cert_timestamp_list(ssl_.get(), &sct_list, &sct_list_len);
davidbenc4212c02015-05-12 22:30:181098 set_signed_cert_timestamps_received(sct_list_len != 0);
1099
davidben971a681a2017-02-16 18:57:461100 if (!IsRenegotiationAllowed())
1101 SSL_set_renegotiate_mode(ssl_.get(), ssl_renegotiate_never);
davidbenc4212c02015-05-12 22:30:181102
davidbend80c12c2016-10-11 00:13:491103 uint16_t signature_algorithm = SSL_get_peer_signature_algorithm(ssl_.get());
davidben0653c8d2016-07-08 02:16:171104 if (signature_algorithm != 0) {
1105 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLSignatureAlgorithm",
1106 signature_algorithm);
davidben4fe4f982015-11-11 22:00:121107 }
1108
davidbenc4212c02015-05-12 22:30:181109 // Verify the certificate.
rsleeviadbd4982016-06-13 22:10:271110 next_handshake_state_ = STATE_VERIFY_CERT;
davidbenc4212c02015-05-12 22:30:181111 return OK;
[email protected]b9b651f2013-11-09 04:32:221112}
1113
svaldeze83af292016-04-26 14:33:371114int SSLClientSocketImpl::DoChannelIDLookup() {
mikecironef22f9812016-10-04 03:40:191115 NetLogParametersCallback callback = base::Bind(
nharper49b27d992016-02-09 18:28:511116 &NetLogChannelIDLookupCallback, base::Unretained(channel_id_service_));
mikecirone8b85c432016-09-08 19:11:001117 net_log_.BeginEvent(NetLogEventType::SSL_GET_CHANNEL_ID, callback);
rsleeviadbd4982016-06-13 22:10:271118 next_handshake_state_ = STATE_CHANNEL_ID_LOOKUP_COMPLETE;
[email protected]6b8a3c742014-07-25 00:25:351119 return channel_id_service_->GetOrCreateChannelID(
nharper2e171cf2015-06-01 20:29:231120 host_and_port_.host(), &channel_id_key_,
svaldeze83af292016-04-26 14:33:371121 base::Bind(&SSLClientSocketImpl::OnHandshakeIOComplete,
[email protected]faff9852014-06-21 06:13:461122 base::Unretained(this)),
nharper75ade892015-06-10 19:05:351123 &channel_id_request_);
[email protected]faff9852014-06-21 06:13:461124}
1125
svaldeze83af292016-04-26 14:33:371126int SSLClientSocketImpl::DoChannelIDLookupComplete(int result) {
mikecirone8b85c432016-09-08 19:11:001127 net_log_.EndEvent(NetLogEventType::SSL_GET_CHANNEL_ID,
nharper49b27d992016-02-09 18:28:511128 base::Bind(&NetLogChannelIDLookupCompleteCallback,
1129 channel_id_key_.get(), result));
[email protected]faff9852014-06-21 06:13:461130 if (result < 0)
1131 return result;
1132
[email protected]faff9852014-06-21 06:13:461133 // Hand the key to OpenSSL. Check for error in case OpenSSL rejects the key
1134 // type.
davidben8a208fc2016-01-22 17:08:081135 DCHECK(channel_id_key_);
[email protected]faff9852014-06-21 06:13:461136 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
davidbend80c12c2016-10-11 00:13:491137 if (!SSL_set1_tls_channel_id(ssl_.get(), channel_id_key_->key())) {
[email protected]faff9852014-06-21 06:13:461138 LOG(ERROR) << "Failed to set Channel ID.";
davidbenf225b262016-09-15 22:09:221139 return ERR_FAILED;
[email protected]faff9852014-06-21 06:13:461140 }
1141
1142 // Return to the handshake.
davidben52053b382015-04-27 19:22:291143 channel_id_sent_ = true;
rsleeviadbd4982016-06-13 22:10:271144 next_handshake_state_ = STATE_HANDSHAKE;
[email protected]faff9852014-06-21 06:13:461145 return OK;
1146}
1147
svaldeze83af292016-04-26 14:33:371148int SSLClientSocketImpl::DoVerifyCert(int result) {
davidben09c3d072014-08-25 20:33:581149 DCHECK(start_cert_verification_time_.is_null());
davidben30798ed82014-09-19 19:28:201150
David Benjaminb8ab3852017-08-04 00:17:321151 server_cert_ = x509_util::CreateX509CertificateFromBuffers(
1152 SSL_get0_peer_certificates(ssl_.get()));
[email protected]b9b651f2013-11-09 04:32:221153
Matt Muellerba33e862017-09-28 20:15:521154 // OpenSSL decoded the certificate, but the X509Certificate implementation
1155 // could not. This is treated as a fatal SSL-level protocol error rather than
1156 // a certificate error. See https://crbug.com/91341.
rsleevi74e99742016-09-13 20:35:251157 if (!server_cert_)
davidbenc6435a72015-08-17 18:28:521158 return ERR_SSL_SERVER_CERT_BAD_FORMAT;
1159
davidbenc7e06c92017-03-07 18:54:111160 net_log_.AddEvent(NetLogEventType::SSL_CERTIFICATES_RECEIVED,
1161 base::Bind(&NetLogX509CertificateCallback,
1162 base::Unretained(server_cert_.get())));
1163
1164 next_handshake_state_ = STATE_VERIFY_CERT_COMPLETE;
1165
davidben30798ed82014-09-19 19:28:201166 // If the certificate is bad and has been previously accepted, use
1167 // the previous status and bypass the error.
[email protected]b9b651f2013-11-09 04:32:221168 CertStatus cert_status;
rsleevi74e99742016-09-13 20:35:251169 if (ssl_config_.IsAllowedBadCert(server_cert_.get(), &cert_status)) {
[email protected]b9b651f2013-11-09 04:32:221170 server_cert_verify_result_.Reset();
1171 server_cert_verify_result_.cert_status = cert_status;
1172 server_cert_verify_result_.verified_cert = server_cert_;
1173 return OK;
1174 }
1175
davidben09c3d072014-08-25 20:33:581176 start_cert_verification_time_ = base::TimeTicks::Now();
1177
rsleevi22cae1672016-12-28 01:53:361178 const uint8_t* ocsp_response_raw;
1179 size_t ocsp_response_len;
1180 SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len);
1181 base::StringPiece ocsp_response(
1182 reinterpret_cast<const char*>(ocsp_response_raw), ocsp_response_len);
1183
eroman7f9236a2015-05-11 21:23:431184 return cert_verifier_->Verify(
rsleevi06bd78552016-06-08 22:34:461185 CertVerifier::RequestParams(server_cert_, host_and_port_.host(),
1186 ssl_config_.GetCertVerifyFlags(),
rsleevi22cae1672016-12-28 01:53:361187 ocsp_response.as_string(), CertificateList()),
[email protected]591cffcd2014-08-18 20:02:301188 // TODO(davidben): Route the CRLSet through SSLConfig so
1189 // SSLClientSocket doesn't depend on SSLConfigService.
davidben15f57132015-04-27 18:08:361190 SSLConfigService::GetCRLSet().get(), &server_cert_verify_result_,
svaldeze83af292016-04-26 14:33:371191 base::Bind(&SSLClientSocketImpl::OnHandshakeIOComplete,
[email protected]b9b651f2013-11-09 04:32:221192 base::Unretained(this)),
eroman7f9236a2015-05-11 21:23:431193 &cert_verifier_request_, net_log_);
[email protected]b9b651f2013-11-09 04:32:221194}
1195
svaldeze83af292016-04-26 14:33:371196int SSLClientSocketImpl::DoVerifyCertComplete(int result) {
eroman7f9236a2015-05-11 21:23:431197 cert_verifier_request_.reset();
[email protected]b9b651f2013-11-09 04:32:221198
davidben09c3d072014-08-25 20:33:581199 if (!start_cert_verification_time_.is_null()) {
1200 base::TimeDelta verify_time =
1201 base::TimeTicks::Now() - start_cert_verification_time_;
1202 if (result == OK) {
1203 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time);
1204 } else {
1205 UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time);
1206 }
1207 }
1208
rsleevi4a6ca8c2016-06-24 03:05:221209 // If the connection was good, check HPKP and CT status simultaneously,
1210 // but prefer to treat the HPKP error as more serious, if there was one.
[email protected]8bd4e7a2014-08-09 14:49:171211 const CertStatus cert_status = server_cert_verify_result_.cert_status;
rsleevi4a6ca8c2016-06-24 03:05:221212 if ((result == OK ||
dadrian8f8946652016-06-21 23:48:311213 (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) {
rsleevi4a6ca8c2016-06-24 03:05:221214 int ct_result = VerifyCT();
dadrian8f8946652016-06-21 23:48:311215 TransportSecurityState::PKPStatus pin_validity =
1216 transport_security_state_->CheckPublicKeyPins(
1217 host_and_port_, server_cert_verify_result_.is_issued_by_known_root,
1218 server_cert_verify_result_.public_key_hashes, server_cert_.get(),
1219 server_cert_verify_result_.verified_cert.get(),
1220 TransportSecurityState::ENABLE_PIN_REPORTS, &pinning_failure_log_);
1221 switch (pin_validity) {
1222 case TransportSecurityState::PKPStatus::VIOLATED:
1223 server_cert_verify_result_.cert_status |=
1224 CERT_STATUS_PINNED_KEY_MISSING;
1225 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
1226 break;
1227 case TransportSecurityState::PKPStatus::BYPASSED:
1228 pkp_bypassed_ = true;
1229 // Fall through.
1230 case TransportSecurityState::PKPStatus::OK:
1231 // Do nothing.
1232 break;
rsleevi9545d342016-06-21 03:17:371233 }
rsleevi4a6ca8c2016-06-24 03:05:221234 if (result != ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && ct_result != OK)
1235 result = ct_result;
[email protected]8bd4e7a2014-08-09 14:49:171236 }
1237
[email protected]b9b651f2013-11-09 04:32:221238 if (result == OK) {
davidbendafe4e52015-04-08 22:53:521239 DCHECK(!certificate_verified_);
1240 certificate_verified_ = true;
1241 MaybeCacheSession();
dadriand476e652016-07-26 21:33:241242 SSLInfo ssl_info;
1243 bool ok = GetSSLInfo(&ssl_info);
1244 DCHECK(ok);
rsleevi22cae1672016-12-28 01:53:361245
1246 const uint8_t* ocsp_response_raw;
1247 size_t ocsp_response_len;
1248 SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len);
1249 base::StringPiece ocsp_response(
1250 reinterpret_cast<const char*>(ocsp_response_raw), ocsp_response_len);
1251
dadriand476e652016-07-26 21:33:241252 transport_security_state_->CheckExpectStaple(host_and_port_, ssl_info,
rsleevi22cae1672016-12-28 01:53:361253 ocsp_response);
[email protected]b9b651f2013-11-09 04:32:221254 }
1255
[email protected]64b5c892014-08-08 09:39:261256 completed_connect_ = true;
[email protected]b9b651f2013-11-09 04:32:221257 // Exit DoHandshakeLoop and return the result to the caller to Connect.
1258 DCHECK_EQ(STATE_NONE, next_handshake_state_);
1259 return result;
1260}
1261
svaldeze83af292016-04-26 14:33:371262void SSLClientSocketImpl::DoConnectCallback(int rv) {
[email protected]b9b651f2013-11-09 04:32:221263 if (!user_connect_callback_.is_null()) {
1264 CompletionCallback c = user_connect_callback_;
1265 user_connect_callback_.Reset();
1266 c.Run(rv > OK ? OK : rv);
1267 }
1268}
1269
svaldeze83af292016-04-26 14:33:371270void SSLClientSocketImpl::OnHandshakeIOComplete(int result) {
[email protected]b9b651f2013-11-09 04:32:221271 int rv = DoHandshakeLoop(result);
1272 if (rv != ERR_IO_PENDING) {
davidben281d13f02016-04-27 20:43:281273 LogConnectEndEvent(rv);
[email protected]b9b651f2013-11-09 04:32:221274 DoConnectCallback(rv);
1275 }
1276}
1277
svaldeze83af292016-04-26 14:33:371278int SSLClientSocketImpl::DoHandshakeLoop(int last_io_result) {
xunjieli0b7f5b62016-12-06 20:43:481279 TRACE_EVENT0(kNetTracingCategory, "SSLClientSocketImpl::DoHandshakeLoop");
[email protected]b9b651f2013-11-09 04:32:221280 int rv = last_io_result;
1281 do {
1282 // Default to STATE_NONE for next state.
1283 // (This is a quirk carried over from the windows
1284 // implementation. It makes reading the logs a bit harder.)
1285 // State handlers can and often do call GotoState just
1286 // to stay in the current state.
1287 State state = next_handshake_state_;
rsleeviadbd4982016-06-13 22:10:271288 next_handshake_state_ = STATE_NONE;
[email protected]b9b651f2013-11-09 04:32:221289 switch (state) {
1290 case STATE_HANDSHAKE:
1291 rv = DoHandshake();
1292 break;
davidbenc4212c02015-05-12 22:30:181293 case STATE_HANDSHAKE_COMPLETE:
1294 rv = DoHandshakeComplete(rv);
1295 break;
[email protected]faff9852014-06-21 06:13:461296 case STATE_CHANNEL_ID_LOOKUP:
1297 DCHECK_EQ(OK, rv);
1298 rv = DoChannelIDLookup();
svaldeze83af292016-04-26 14:33:371299 break;
[email protected]faff9852014-06-21 06:13:461300 case STATE_CHANNEL_ID_LOOKUP_COMPLETE:
1301 rv = DoChannelIDLookupComplete(rv);
1302 break;
[email protected]b9b651f2013-11-09 04:32:221303 case STATE_VERIFY_CERT:
[email protected]faff9852014-06-21 06:13:461304 DCHECK_EQ(OK, rv);
[email protected]b9b651f2013-11-09 04:32:221305 rv = DoVerifyCert(rv);
svaldeze83af292016-04-26 14:33:371306 break;
[email protected]b9b651f2013-11-09 04:32:221307 case STATE_VERIFY_CERT_COMPLETE:
1308 rv = DoVerifyCertComplete(rv);
1309 break;
1310 case STATE_NONE:
1311 default:
1312 rv = ERR_UNEXPECTED;
1313 NOTREACHED() << "unexpected state" << state;
1314 break;
1315 }
[email protected]b9b651f2013-11-09 04:32:221316 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
1317 return rv;
1318}
1319
xunjieli321a96f32017-03-07 19:42:171320int SSLClientSocketImpl::DoPayloadRead(IOBuffer* buf, int buf_len) {
[email protected]b9b651f2013-11-09 04:32:221321 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
1322
xunjieli321a96f32017-03-07 19:42:171323 DCHECK_LT(0, buf_len);
1324 DCHECK(buf);
davidben7e555daf2015-03-25 17:03:291325
[email protected]b9b651f2013-11-09 04:32:221326 int rv;
davidben1d489522015-07-01 18:48:461327 if (pending_read_error_ != kNoPendingResult) {
[email protected]b9b651f2013-11-09 04:32:221328 rv = pending_read_error_;
davidben1d489522015-07-01 18:48:461329 pending_read_error_ = kNoPendingResult;
[email protected]b9b651f2013-11-09 04:32:221330 if (rv == 0) {
mikecirone8b85c432016-09-08 19:11:001331 net_log_.AddByteTransferEvent(NetLogEventType::SSL_SOCKET_BYTES_RECEIVED,
xunjieli321a96f32017-03-07 19:42:171332 rv, buf->data());
davidbenb8c23212014-10-28 00:12:161333 } else {
1334 net_log_.AddEvent(
mikecirone8b85c432016-09-08 19:11:001335 NetLogEventType::SSL_READ_ERROR,
davidbenb8c23212014-10-28 00:12:161336 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_,
1337 pending_read_error_info_));
[email protected]b9b651f2013-11-09 04:32:221338 }
davidbenb8c23212014-10-28 00:12:161339 pending_read_ssl_error_ = SSL_ERROR_NONE;
1340 pending_read_error_info_ = OpenSSLErrorInfo();
[email protected]b9b651f2013-11-09 04:32:221341 return rv;
1342 }
1343
1344 int total_bytes_read = 0;
davidben7e555daf2015-03-25 17:03:291345 int ssl_ret;
[email protected]b9b651f2013-11-09 04:32:221346 do {
xunjieli321a96f32017-03-07 19:42:171347 ssl_ret = SSL_read(ssl_.get(), buf->data() + total_bytes_read,
1348 buf_len - total_bytes_read);
davidben7e555daf2015-03-25 17:03:291349 if (ssl_ret > 0)
1350 total_bytes_read += ssl_ret;
davidben8ea6b172017-03-07 23:53:501351 // Continue processing records as long as there is more data available
1352 // synchronously.
1353 } while (total_bytes_read < buf_len && ssl_ret > 0 &&
1354 transport_adapter_->HasPendingReadData());
[email protected]b9b651f2013-11-09 04:32:221355
davidben7e555daf2015-03-25 17:03:291356 // Although only the final SSL_read call may have failed, the failure needs to
1357 // processed immediately, while the information still available in OpenSSL's
1358 // error queue.
davidbenced4aa9b2015-05-12 21:22:351359 if (ssl_ret <= 0) {
davidben7e555daf2015-03-25 17:03:291360 // A zero return from SSL_read may mean any of:
1361 // - The underlying BIO_read returned 0.
1362 // - The peer sent a close_notify.
1363 // - Any arbitrary error. https://crbug.com/466303
[email protected]b9b651f2013-11-09 04:32:221364 //
davidben7e555daf2015-03-25 17:03:291365 // TransportReadComplete converts the first to an ERR_CONNECTION_CLOSED
1366 // error, so it does not occur. The second and third are distinguished by
1367 // SSL_ERROR_ZERO_RETURN.
davidbend80c12c2016-10-11 00:13:491368 pending_read_ssl_error_ = SSL_get_error(ssl_.get(), ssl_ret);
davidben7e555daf2015-03-25 17:03:291369 if (pending_read_ssl_error_ == SSL_ERROR_ZERO_RETURN) {
1370 pending_read_error_ = 0;
davidbenced4aa9b2015-05-12 21:22:351371 } else if (pending_read_ssl_error_ == SSL_ERROR_WANT_X509_LOOKUP &&
1372 !ssl_config_.send_client_cert) {
1373 pending_read_error_ = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
davidben1d489522015-07-01 18:48:461374 } else if (pending_read_ssl_error_ ==
1375 SSL_ERROR_WANT_PRIVATE_KEY_OPERATION) {
svaldez7872fd02015-11-19 21:10:541376 DCHECK(ssl_config_.client_private_key);
davidben1d489522015-07-01 18:48:461377 DCHECK_NE(kNoPendingResult, signature_result_);
1378 pending_read_error_ = ERR_IO_PENDING;
davidben7e555daf2015-03-25 17:03:291379 } else {
davidbenfe132d92016-09-27 18:07:211380 pending_read_error_ = MapLastOpenSSLError(
davidben7e555daf2015-03-25 17:03:291381 pending_read_ssl_error_, err_tracer, &pending_read_error_info_);
[email protected]b9b651f2013-11-09 04:32:221382 }
1383
davidben7e555daf2015-03-25 17:03:291384 // Many servers do not reliably send a close_notify alert when shutting down
1385 // a connection, and instead terminate the TCP connection. This is reported
1386 // as ERR_CONNECTION_CLOSED. Because of this, map the unclean shutdown to a
1387 // graceful EOF, instead of treating it as an error as it should be.
1388 if (pending_read_error_ == ERR_CONNECTION_CLOSED)
1389 pending_read_error_ = 0;
1390 }
davidbenbe6ce7ec2014-10-20 19:15:561391
davidben7e555daf2015-03-25 17:03:291392 if (total_bytes_read > 0) {
1393 // Return any bytes read to the caller. The error will be deferred to the
1394 // next call of DoPayloadRead.
1395 rv = total_bytes_read;
davidbenbe6ce7ec2014-10-20 19:15:561396
davidben7e555daf2015-03-25 17:03:291397 // Do not treat insufficient data as an error to return in the next call to
1398 // DoPayloadRead() - instead, let the call fall through to check SSL_read()
davidben3418e81f2016-10-19 00:09:451399 // again. The transport may have data available by then.
davidben7e555daf2015-03-25 17:03:291400 if (pending_read_error_ == ERR_IO_PENDING)
davidben1d489522015-07-01 18:48:461401 pending_read_error_ = kNoPendingResult;
davidben7e555daf2015-03-25 17:03:291402 } else {
1403 // No bytes were returned. Return the pending read error immediately.
davidben1d489522015-07-01 18:48:461404 DCHECK_NE(kNoPendingResult, pending_read_error_);
davidben7e555daf2015-03-25 17:03:291405 rv = pending_read_error_;
davidben1d489522015-07-01 18:48:461406 pending_read_error_ = kNoPendingResult;
[email protected]b9b651f2013-11-09 04:32:221407 }
1408
1409 if (rv >= 0) {
mikecirone8b85c432016-09-08 19:11:001410 net_log_.AddByteTransferEvent(NetLogEventType::SSL_SOCKET_BYTES_RECEIVED,
xunjieli321a96f32017-03-07 19:42:171411 rv, buf->data());
davidbenb8c23212014-10-28 00:12:161412 } else if (rv != ERR_IO_PENDING) {
1413 net_log_.AddEvent(
mikecirone8b85c432016-09-08 19:11:001414 NetLogEventType::SSL_READ_ERROR,
davidbenb8c23212014-10-28 00:12:161415 CreateNetLogOpenSSLErrorCallback(rv, pending_read_ssl_error_,
1416 pending_read_error_info_));
1417 pending_read_ssl_error_ = SSL_ERROR_NONE;
1418 pending_read_error_info_ = OpenSSLErrorInfo();
[email protected]b9b651f2013-11-09 04:32:221419 }
1420 return rv;
1421}
1422
svaldeze83af292016-04-26 14:33:371423int SSLClientSocketImpl::DoPayloadWrite() {
[email protected]b9b651f2013-11-09 04:32:221424 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
davidbend80c12c2016-10-11 00:13:491425 int rv = SSL_write(ssl_.get(), user_write_buf_->data(), user_write_buf_len_);
rsleevif020edc2015-03-16 19:31:241426
[email protected]b9b651f2013-11-09 04:32:221427 if (rv >= 0) {
mikecirone8b85c432016-09-08 19:11:001428 net_log_.AddByteTransferEvent(NetLogEventType::SSL_SOCKET_BYTES_SENT, rv,
[email protected]b9b651f2013-11-09 04:32:221429 user_write_buf_->data());
1430 return rv;
1431 }
1432
davidbend80c12c2016-10-11 00:13:491433 int ssl_error = SSL_get_error(ssl_.get(), rv);
davidben1d489522015-07-01 18:48:461434 if (ssl_error == SSL_ERROR_WANT_PRIVATE_KEY_OPERATION)
1435 return ERR_IO_PENDING;
davidbenb8c23212014-10-28 00:12:161436 OpenSSLErrorInfo error_info;
davidbenfe132d92016-09-27 18:07:211437 int net_error = MapLastOpenSSLError(ssl_error, err_tracer, &error_info);
davidbenb8c23212014-10-28 00:12:161438
1439 if (net_error != ERR_IO_PENDING) {
1440 net_log_.AddEvent(
mikecirone8b85c432016-09-08 19:11:001441 NetLogEventType::SSL_WRITE_ERROR,
davidbenb8c23212014-10-28 00:12:161442 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
1443 }
1444 return net_error;
[email protected]b9b651f2013-11-09 04:32:221445}
1446
davidben3418e81f2016-10-19 00:09:451447void SSLClientSocketImpl::RetryAllOperations() {
1448 // SSL_do_handshake, SSL_read, and SSL_write may all be retried when blocked,
1449 // so retry all operations for simplicity. (Otherwise, SSL_get_error for each
1450 // operation may be remembered to retry only the blocked ones.)
1451
1452 if (next_handshake_state_ == STATE_HANDSHAKE) {
1453 // In handshake phase. The parameter to OnHandshakeIOComplete is unused.
1454 OnHandshakeIOComplete(OK);
1455 return;
1456 }
1457
davidben1d489522015-07-01 18:48:461458 int rv_read = ERR_IO_PENDING;
1459 int rv_write = ERR_IO_PENDING;
xunjieli321a96f32017-03-07 19:42:171460 if (user_read_buf_) {
1461 rv_read = DoPayloadRead(user_read_buf_.get(), user_read_buf_len_);
1462 } else if (!user_read_callback_.is_null()) {
1463 // ReadIfReady() is called by the user. Skip DoPayloadRead() and just let
1464 // the user know that read can be retried.
1465 rv_read = OK;
1466 }
1467
davidben3418e81f2016-10-19 00:09:451468 if (user_write_buf_)
1469 rv_write = DoPayloadWrite();
davidben1d489522015-07-01 18:48:461470
1471 // Performing the Read callback may cause |this| to be deleted. If this
1472 // happens, the Write callback should not be invoked. Guard against this by
1473 // holding a WeakPtr to |this| and ensuring it's still valid.
svaldeze83af292016-04-26 14:33:371474 base::WeakPtr<SSLClientSocketImpl> guard(weak_factory_.GetWeakPtr());
davidben3418e81f2016-10-19 00:09:451475 if (rv_read != ERR_IO_PENDING)
davidben1d489522015-07-01 18:48:461476 DoReadCallback(rv_read);
1477
1478 if (!guard.get())
1479 return;
1480
davidben3418e81f2016-10-19 00:09:451481 if (rv_write != ERR_IO_PENDING)
davidben1d489522015-07-01 18:48:461482 DoWriteCallback(rv_write);
1483}
1484
rsleevi4a6ca8c2016-06-24 03:05:221485int SSLClientSocketImpl::VerifyCT() {
rsleevi4a6ca8c2016-06-24 03:05:221486 const uint8_t* sct_list_raw;
1487 size_t sct_list_len;
davidbend80c12c2016-10-11 00:13:491488 SSL_get0_signed_cert_timestamp_list(ssl_.get(), &sct_list_raw, &sct_list_len);
rsleevi22cae1672016-12-28 01:53:361489 base::StringPiece sct_list(reinterpret_cast<const char*>(sct_list_raw),
1490 sct_list_len);
1491
1492 const uint8_t* ocsp_response_raw;
1493 size_t ocsp_response_len;
1494 SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len);
1495 base::StringPiece ocsp_response(
1496 reinterpret_cast<const char*>(ocsp_response_raw), ocsp_response_len);
rsleevi4a6ca8c2016-06-24 03:05:221497
1498 // Note that this is a completely synchronous operation: The CT Log Verifier
1499 // gets all the data it needs for SCT verification and does not do any
1500 // external communication.
1501 cert_transparency_verifier_->Verify(
rsleevi22cae1672016-12-28 01:53:361502 server_cert_verify_result_.verified_cert.get(), ocsp_response, sct_list,
eranmdcec9632016-10-10 14:16:101503 &ct_verify_result_.scts, net_log_);
rsleevi4a6ca8c2016-06-24 03:05:221504
1505 ct_verify_result_.ct_policies_applied = true;
eranm4bed0b572016-08-14 21:00:351506
1507 SCTList verified_scts =
1508 ct::SCTsMatchingStatus(ct_verify_result_.scts, ct::SCT_STATUS_OK);
1509
rsleevi4a6ca8c2016-06-24 03:05:221510 ct_verify_result_.cert_policy_compliance =
1511 policy_enforcer_->DoesConformToCertPolicy(
eranm4bed0b572016-08-14 21:00:351512 server_cert_verify_result_.verified_cert.get(), verified_scts,
1513 net_log_);
Emily Stark0d9809e2017-10-18 08:29:151514 if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) {
1515 if (ct_verify_result_.cert_policy_compliance !=
1516 ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS) {
1517 server_cert_verify_result_.cert_status |=
1518 CERT_STATUS_CT_COMPLIANCE_FAILED;
1519 server_cert_verify_result_.cert_status &= ~CERT_STATUS_IS_EV;
1520 }
1521
1522 // Record the CT compliance status for connections with EV certificates, to
1523 // distinguish how often EV status is being dropped due to failing CT
1524 // compliance.
1525 UMA_HISTOGRAM_ENUMERATION("Net.CertificateTransparency.EVCompliance.SSL",
1526 ct_verify_result_.cert_policy_compliance,
1527 ct::CertPolicyCompliance::CERT_POLICY_MAX);
rsleevicd7390e2017-06-14 10:18:261528 }
rsleevi4a6ca8c2016-06-24 03:05:221529
Emily Stark0d9809e2017-10-18 08:29:151530 // Record the CT compliance of every connection to get an overall picture of
1531 // how many connections are CT-compliant.
Emily Starkc96e9bc2017-10-10 00:10:391532 UMA_HISTOGRAM_ENUMERATION(
1533 "Net.CertificateTransparency.ConnectionComplianceStatus.SSL",
1534 ct_verify_result_.cert_policy_compliance,
1535 ct::CertPolicyCompliance::CERT_POLICY_MAX);
1536
Emily Stark0d9809e2017-10-18 08:29:151537 TransportSecurityState::CTRequirementsStatus ct_requirement_status =
1538 transport_security_state_->CheckCTRequirements(
estarkbf1b52962017-05-05 17:05:251539 host_and_port_, server_cert_verify_result_.is_issued_by_known_root,
1540 server_cert_verify_result_.public_key_hashes,
1541 server_cert_verify_result_.verified_cert.get(), server_cert_.get(),
1542 ct_verify_result_.scts,
1543 TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
Emily Stark0d9809e2017-10-18 08:29:151544 ct_verify_result_.cert_policy_compliance);
1545 if (ct_requirement_status != TransportSecurityState::CT_NOT_REQUIRED) {
1546 // Record the CT compliance of connections for which compliance is required;
1547 // this helps answer the question: "Of all connections that are supposed to
1548 // be serving valid CT information, how many fail to do so?"
1549 UMA_HISTOGRAM_ENUMERATION(
1550 "Net.CertificateTransparency.CTRequiredConnectionComplianceStatus.SSL",
1551 ct_verify_result_.cert_policy_compliance,
1552 ct::CertPolicyCompliance::CERT_POLICY_MAX);
rsleevi4a6ca8c2016-06-24 03:05:221553 }
1554
Emily Stark0d9809e2017-10-18 08:29:151555 switch (ct_requirement_status) {
1556 case TransportSecurityState::CT_REQUIREMENTS_NOT_MET:
1557 server_cert_verify_result_.cert_status |=
1558 CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED;
1559 return ERR_CERTIFICATE_TRANSPARENCY_REQUIRED;
1560 case TransportSecurityState::CT_REQUIREMENTS_MET:
1561 case TransportSecurityState::CT_NOT_REQUIRED:
1562 return OK;
1563 }
1564
1565 NOTREACHED();
rsleevi4a6ca8c2016-06-24 03:05:221566 return OK;
1567}
1568
svaldeze83af292016-04-26 14:33:371569int SSLClientSocketImpl::ClientCertRequestCallback(SSL* ssl) {
davidbend80c12c2016-10-11 00:13:491570 DCHECK(ssl == ssl_.get());
[email protected]82c59022014-08-15 09:38:271571
mikecirone8b85c432016-09-08 19:11:001572 net_log_.AddEvent(NetLogEventType::SSL_CLIENT_CERT_REQUESTED);
davidbenfe132d92016-09-27 18:07:211573 certificate_requested_ = true;
davidbenaf42cbe2014-11-13 03:27:461574
[email protected]82c59022014-08-15 09:38:271575 // Clear any currently configured certificates.
davidbend80c12c2016-10-11 00:13:491576 SSL_certs_clear(ssl_.get());
[email protected]97a854f2014-07-29 07:51:361577
1578#if defined(OS_IOS)
1579 // TODO(droger): Support client auth on iOS. See http://crbug.com/145954).
1580 LOG(WARNING) << "Client auth is not supported";
svaldeze83af292016-04-26 14:33:371581#else // !defined(OS_IOS)
[email protected]5ac981e182010-12-06 17:56:271582 if (!ssl_config_.send_client_cert) {
[email protected]515adc22013-01-09 16:01:231583 // First pass: we know that a client certificate is needed, but we do not
davidbenb11fd212017-01-12 17:08:031584 // have one at hand. Suspend the handshake. SSL_get_error will return
1585 // SSL_ERROR_WANT_X509_LOOKUP.
davidbenced4aa9b2015-05-12 21:22:351586 return -1;
[email protected]5ac981e182010-12-06 17:56:271587 }
1588
1589 // Second pass: a client certificate should have been selected.
[email protected]13914c92013-06-13 22:42:421590 if (ssl_config_.client_cert.get()) {
svaldez7872fd02015-11-19 21:10:541591 if (!ssl_config_.client_private_key) {
1592 // The caller supplied a null private key. Fail the handshake and surface
1593 // an appropriate error to the caller.
davidben1d489522015-07-01 18:48:461594 LOG(WARNING) << "Client cert found without private key";
1595 OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY);
1596 return -1;
1597 }
1598
David Benjaminb8ab3852017-08-04 00:17:321599 if (!SetSSLChainAndKey(ssl_.get(), ssl_config_.client_cert.get(), nullptr,
1600 &SSLContext::kPrivateKeyMethod)) {
davidbena35b40c32017-03-09 17:33:451601 OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_CERT_BAD_FORMAT);
1602 return -1;
1603 }
svaldezf3db006f2015-09-29 16:43:581604
David Benjaminb9bafbe2017-11-07 21:41:381605 std::vector<uint16_t> preferences =
1606 ssl_config_.client_private_key->GetAlgorithmPreferences();
1607 SSL_set_signing_algorithm_prefs(ssl_.get(), preferences.data(),
1608 preferences.size());
davidbenaf42cbe2014-11-13 03:27:461609
David Benjaminb8ab3852017-08-04 00:17:321610 net_log_.AddEvent(
1611 NetLogEventType::SSL_CLIENT_CERT_PROVIDED,
1612 NetLog::IntCallback(
1613 "cert_count",
1614 1 + ssl_config_.client_cert->GetIntermediateCertificates().size()));
[email protected]6bad5052014-07-12 01:25:131615 return 1;
[email protected]c0787702014-05-20 21:51:441616 }
[email protected]97a854f2014-07-29 07:51:361617#endif // defined(OS_IOS)
[email protected]5ac981e182010-12-06 17:56:271618
1619 // Send no client certificate.
mikecirone8b85c432016-09-08 19:11:001620 net_log_.AddEvent(NetLogEventType::SSL_CLIENT_CERT_PROVIDED,
tfarina5e24b242015-10-27 13:11:281621 NetLog::IntCallback("cert_count", 0));
[email protected]82c59022014-08-15 09:38:271622 return 1;
[email protected]5ac981e182010-12-06 17:56:271623}
1624
svaldeze83af292016-04-26 14:33:371625void SSLClientSocketImpl::MaybeCacheSession() {
davidben44aeae62015-06-24 20:47:431626 // Only cache the session once both a new session has been established and the
1627 // certificate has been verified. Due to False Start, these events may happen
1628 // in either order.
David Benjaminb3840f42017-08-03 15:50:161629 if (!pending_session_ || !certificate_verified_ ||
1630 ssl_session_cache_shard_.empty()) {
davidbendafe4e52015-04-08 22:53:521631 return;
David Benjaminb3840f42017-08-03 15:50:161632 }
davidbendafe4e52015-04-08 22:53:521633
1634 SSLContext::GetInstance()->session_cache()->Insert(GetSessionCacheKey(),
davidbenc269cc4b2016-07-27 14:55:031635 pending_session_.get());
1636 pending_session_ = nullptr;
davidbendafe4e52015-04-08 22:53:521637}
1638
svaldeze83af292016-04-26 14:33:371639int SSLClientSocketImpl::NewSessionCallback(SSL_SESSION* session) {
David Benjaminb3840f42017-08-03 15:50:161640 if (ssl_session_cache_shard_.empty())
1641 return 0;
1642
davidbenc269cc4b2016-07-27 14:55:031643 // OpenSSL passes a reference to |session|.
1644 pending_session_.reset(session);
davidbendafe4e52015-04-08 22:53:521645 MaybeCacheSession();
davidben44aeae62015-06-24 20:47:431646 return 1;
davidbendafe4e52015-04-08 22:53:521647}
1648
svaldeze83af292016-04-26 14:33:371649void SSLClientSocketImpl::AddCTInfoToSSLInfo(SSLInfo* ssl_info) const {
estark723b5eeb2016-02-18 21:01:121650 ssl_info->UpdateCertificateTransparencyInfo(ct_verify_result_);
davidbeneb5f8ef32014-09-04 14:14:321651}
1652
svaldeze83af292016-04-26 14:33:371653std::string SSLClientSocketImpl::GetSessionCacheKey() const {
David Benjaminb3840f42017-08-03 15:50:161654 // If there is no session cache shard configured, disable session
1655 // caching. GetSessionCacheKey may not be called. When
1656 // https://crbug.com/458365 is fixed, this check will not be needed.
1657 DCHECK(!ssl_session_cache_shard_.empty());
1658
rsleevif020edc2015-03-16 19:31:241659 std::string result = host_and_port_.ToString();
davidben095ebb52017-04-12 22:23:341660 result.push_back('/');
rsleevif020edc2015-03-16 19:31:241661 result.append(ssl_session_cache_shard_);
1662
davidben095ebb52017-04-12 22:23:341663 result.push_back('/');
davidben095ebb52017-04-12 22:23:341664 result.push_back(ssl_config_.channel_id_enabled ? '1' : '0');
1665 result.push_back(ssl_config_.version_interference_probe ? '1' : '0');
rsleevif020edc2015-03-16 19:31:241666 return result;
1667}
1668
svaldeze83af292016-04-26 14:33:371669bool SSLClientSocketImpl::IsRenegotiationAllowed() const {
nharper736ceda2015-11-07 00:16:591670 if (tb_was_negotiated_)
1671 return false;
1672
bncce6ea242016-09-15 20:22:321673 if (negotiated_protocol_ == kProtoUnknown)
davidben421116c2015-05-12 19:56:511674 return ssl_config_.renego_allowed_default;
1675
davidben421116c2015-05-12 19:56:511676 for (NextProto allowed : ssl_config_.renego_allowed_for_protos) {
bnc3cf2a592016-08-11 14:48:361677 if (negotiated_protocol_ == allowed)
davidben421116c2015-05-12 19:56:511678 return true;
1679 }
1680 return false;
1681}
1682
David Benjaminb9bafbe2017-11-07 21:41:381683ssl_private_key_result_t SSLClientSocketImpl::PrivateKeySignCallback(
davidben1d489522015-07-01 18:48:461684 uint8_t* out,
1685 size_t* out_len,
1686 size_t max_out,
David Benjaminb9bafbe2017-11-07 21:41:381687 uint16_t algorithm,
davidben1d489522015-07-01 18:48:461688 const uint8_t* in,
1689 size_t in_len) {
1690 DCHECK_EQ(kNoPendingResult, signature_result_);
1691 DCHECK(signature_.empty());
svaldez7872fd02015-11-19 21:10:541692 DCHECK(ssl_config_.client_private_key);
davidben1d489522015-07-01 18:48:461693
David Benjaminb9bafbe2017-11-07 21:41:381694 net_log_.BeginEvent(
1695 NetLogEventType::SSL_PRIVATE_KEY_OP,
1696 base::Bind(&NetLogPrivateKeyOperationCallback, algorithm));
1697
davidben1d489522015-07-01 18:48:461698 signature_result_ = ERR_IO_PENDING;
David Benjamin9ba36b02017-11-10 19:01:531699 ssl_config_.client_private_key->Sign(
1700 algorithm, base::make_span(in, in_len),
davidben0bca07fd2016-07-18 15:12:031701 base::Bind(&SSLClientSocketImpl::OnPrivateKeyComplete,
davidben1d489522015-07-01 18:48:461702 weak_factory_.GetWeakPtr()));
1703 return ssl_private_key_retry;
1704}
1705
davidben0bca07fd2016-07-18 15:12:031706ssl_private_key_result_t SSLClientSocketImpl::PrivateKeyCompleteCallback(
davidben1d489522015-07-01 18:48:461707 uint8_t* out,
1708 size_t* out_len,
1709 size_t max_out) {
1710 DCHECK_NE(kNoPendingResult, signature_result_);
svaldez7872fd02015-11-19 21:10:541711 DCHECK(ssl_config_.client_private_key);
davidben1d489522015-07-01 18:48:461712
1713 if (signature_result_ == ERR_IO_PENDING)
1714 return ssl_private_key_retry;
1715 if (signature_result_ != OK) {
1716 OpenSSLPutNetError(FROM_HERE, signature_result_);
1717 return ssl_private_key_failure;
1718 }
1719 if (signature_.size() > max_out) {
1720 OpenSSLPutNetError(FROM_HERE, ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED);
1721 return ssl_private_key_failure;
1722 }
davidben5f8b6bc2015-11-25 03:19:541723 memcpy(out, signature_.data(), signature_.size());
davidben1d489522015-07-01 18:48:461724 *out_len = signature_.size();
1725 signature_.clear();
1726 return ssl_private_key_success;
1727}
1728
davidben0bca07fd2016-07-18 15:12:031729void SSLClientSocketImpl::OnPrivateKeyComplete(
davidben1d489522015-07-01 18:48:461730 Error error,
1731 const std::vector<uint8_t>& signature) {
1732 DCHECK_EQ(ERR_IO_PENDING, signature_result_);
1733 DCHECK(signature_.empty());
svaldez7872fd02015-11-19 21:10:541734 DCHECK(ssl_config_.client_private_key);
davidben1d489522015-07-01 18:48:461735
mikecirone8b85c432016-09-08 19:11:001736 net_log_.EndEventWithNetErrorCode(NetLogEventType::SSL_PRIVATE_KEY_OP, error);
davidben1d489522015-07-01 18:48:461737
1738 signature_result_ = error;
1739 if (signature_result_ == OK)
1740 signature_ = signature;
1741
davidben1d489522015-07-01 18:48:461742 // During a renegotiation, either Read or Write calls may be blocked on an
1743 // asynchronous private key operation.
davidben3418e81f2016-10-19 00:09:451744 RetryAllOperations();
davidben1d489522015-07-01 18:48:461745}
1746
davidbencef9e212017-04-19 15:00:101747void SSLClientSocketImpl::MessageCallback(int is_write,
1748 int content_type,
1749 const void* buf,
1750 size_t len) {
1751 switch (content_type) {
1752 case SSL3_RT_ALERT:
1753 net_log_.AddEvent(is_write ? NetLogEventType::SSL_ALERT_SENT
1754 : NetLogEventType::SSL_ALERT_RECEIVED,
1755 base::Bind(&NetLogSSLAlertCallback, buf, len));
1756 break;
1757 case SSL3_RT_HANDSHAKE:
1758 net_log_.AddEvent(
1759 is_write ? NetLogEventType::SSL_HANDSHAKE_MESSAGE_SENT
1760 : NetLogEventType::SSL_HANDSHAKE_MESSAGE_RECEIVED,
1761 base::Bind(&NetLogSSLMessageCallback, !!is_write, buf, len));
1762 break;
David Benjamina961f5f2017-06-22 23:50:511763 case SSL3_RT_HEADER: {
1764 if (is_write)
1765 return;
1766 if (len != 5) {
1767 NOTREACHED();
1768 return;
1769 }
1770 const uint8_t* buf_bytes = reinterpret_cast<const uint8_t*>(buf);
1771 uint16_t record_len = (uint16_t(buf_bytes[3]) << 8) | buf_bytes[4];
1772 // See RFC 5246 section 6.2.3 for the maximum record size in TLS.
1773 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SSLRecordSizeRead", record_len, 1,
1774 16384 + 2048, 50);
1775 }
davidbencef9e212017-04-19 15:00:101776 default:
1777 return;
1778 }
1779}
1780
svaldeze83af292016-04-26 14:33:371781int SSLClientSocketImpl::TokenBindingAdd(const uint8_t** out,
1782 size_t* out_len,
1783 int* out_alert_value) {
nharper736ceda2015-11-07 00:16:591784 if (ssl_config_.token_binding_params.empty()) {
1785 return 0;
1786 }
davidbend80c12c2016-10-11 00:13:491787 bssl::ScopedCBB output;
nharper736ceda2015-11-07 00:16:591788 CBB parameters_list;
1789 if (!CBB_init(output.get(), 7) ||
1790 !CBB_add_u8(output.get(), kTbProtocolVersionMajor) ||
1791 !CBB_add_u8(output.get(), kTbProtocolVersionMinor) ||
1792 !CBB_add_u8_length_prefixed(output.get(), &parameters_list)) {
1793 *out_alert_value = SSL_AD_INTERNAL_ERROR;
1794 return -1;
1795 }
1796 for (size_t i = 0; i < ssl_config_.token_binding_params.size(); ++i) {
1797 if (!CBB_add_u8(&parameters_list, ssl_config_.token_binding_params[i])) {
1798 *out_alert_value = SSL_AD_INTERNAL_ERROR;
1799 return -1;
1800 }
1801 }
1802 // |*out| will be freed by TokenBindingFreeCallback.
1803 if (!CBB_finish(output.get(), const_cast<uint8_t**>(out), out_len)) {
1804 *out_alert_value = SSL_AD_INTERNAL_ERROR;
1805 return -1;
1806 }
1807
1808 return 1;
1809}
1810
svaldeze83af292016-04-26 14:33:371811int SSLClientSocketImpl::TokenBindingParse(const uint8_t* contents,
1812 size_t contents_len,
1813 int* out_alert_value) {
nharper736ceda2015-11-07 00:16:591814 if (completed_connect_) {
1815 // Token Binding may only be negotiated on the initial handshake.
1816 *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
1817 return 0;
1818 }
1819
1820 CBS extension;
1821 CBS_init(&extension, contents, contents_len);
1822
1823 CBS parameters_list;
1824 uint8_t version_major, version_minor, param;
1825 if (!CBS_get_u8(&extension, &version_major) ||
1826 !CBS_get_u8(&extension, &version_minor) ||
1827 !CBS_get_u8_length_prefixed(&extension, &parameters_list) ||
1828 !CBS_get_u8(&parameters_list, &param) || CBS_len(&parameters_list) > 0 ||
1829 CBS_len(&extension) > 0) {
1830 *out_alert_value = SSL_AD_DECODE_ERROR;
1831 return 0;
1832 }
1833 // The server-negotiated version must be less than or equal to our version.
1834 if (version_major > kTbProtocolVersionMajor ||
1835 (version_minor > kTbProtocolVersionMinor &&
1836 version_major == kTbProtocolVersionMajor)) {
1837 *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
1838 return 0;
1839 }
1840 // If the version the server negotiated is older than we support, don't fail
1841 // parsing the extension, but also don't set |negotiated_|.
1842 if (version_major < kTbMinProtocolVersionMajor ||
1843 (version_minor < kTbMinProtocolVersionMinor &&
1844 version_major == kTbMinProtocolVersionMajor)) {
1845 return 1;
1846 }
1847
1848 for (size_t i = 0; i < ssl_config_.token_binding_params.size(); ++i) {
1849 if (param == ssl_config_.token_binding_params[i]) {
1850 tb_negotiated_param_ = ssl_config_.token_binding_params[i];
1851 tb_was_negotiated_ = true;
1852 return 1;
1853 }
1854 }
1855
1856 *out_alert_value = SSL_AD_ILLEGAL_PARAMETER;
1857 return 0;
1858}
1859
davidben281d13f02016-04-27 20:43:281860void SSLClientSocketImpl::LogConnectEndEvent(int rv) {
1861 if (rv != OK) {
mikecirone8b85c432016-09-08 19:11:001862 net_log_.EndEventWithNetErrorCode(NetLogEventType::SSL_CONNECT, rv);
davidben281d13f02016-04-27 20:43:281863 return;
1864 }
1865
mikecirone8b85c432016-09-08 19:11:001866 net_log_.EndEvent(NetLogEventType::SSL_CONNECT,
davidben281d13f02016-04-27 20:43:281867 base::Bind(&NetLogSSLInfoCallback, base::Unretained(this)));
1868}
1869
bncbd442c22016-09-14 20:49:161870void SSLClientSocketImpl::RecordNegotiatedProtocol() const {
1871 UMA_HISTOGRAM_ENUMERATION("Net.SSLNegotiatedAlpnProtocol",
1872 negotiated_protocol_, kProtoLast + 1);
bnc3cf2a592016-08-11 14:48:361873}
1874
1875void SSLClientSocketImpl::RecordChannelIDSupport() const {
1876 // Since this enum is used for a histogram, do not change or re-use values.
1877 enum {
1878 DISABLED = 0,
1879 CLIENT_ONLY = 1,
1880 CLIENT_AND_SERVER = 2,
1881 // CLIENT_NO_ECC is unused now.
1882 // CLIENT_BAD_SYSTEM_TIME is unused now.
1883 CLIENT_BAD_SYSTEM_TIME = 4,
1884 CLIENT_NO_CHANNEL_ID_SERVICE = 5,
1885 CHANNEL_ID_USAGE_MAX
1886 } supported = DISABLED;
1887 if (channel_id_sent_) {
1888 supported = CLIENT_AND_SERVER;
1889 } else if (ssl_config_.channel_id_enabled) {
1890 if (!channel_id_service_)
1891 supported = CLIENT_NO_CHANNEL_ID_SERVICE;
1892 else
1893 supported = CLIENT_ONLY;
1894 }
1895 UMA_HISTOGRAM_ENUMERATION("DomainBoundCerts.Support", supported,
1896 CHANNEL_ID_USAGE_MAX);
1897}
1898
1899bool SSLClientSocketImpl::IsChannelIDEnabled() const {
1900 return ssl_config_.channel_id_enabled && channel_id_service_;
1901}
1902
davidbenfe132d92016-09-27 18:07:211903int SSLClientSocketImpl::MapLastOpenSSLError(
1904 int ssl_error,
1905 const crypto::OpenSSLErrStackTracer& tracer,
1906 OpenSSLErrorInfo* info) {
1907 int net_error = MapOpenSSLErrorWithDetails(ssl_error, tracer, info);
1908
1909 if (ssl_error == SSL_ERROR_SSL &&
1910 ERR_GET_LIB(info->error_code) == ERR_LIB_SSL) {
1911 // TLS does not provide an alert for missing client certificates, so most
1912 // servers send a generic handshake_failure alert. Detect this case by
1913 // checking if we have received a CertificateRequest but sent no
1914 // certificate. See https://crbug.com/646567.
1915 if (ERR_GET_REASON(info->error_code) ==
1916 SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE &&
1917 certificate_requested_ && ssl_config_.send_client_cert &&
1918 !ssl_config_.client_cert) {
1919 net_error = ERR_BAD_SSL_CLIENT_AUTH_CERT;
1920 }
1921
1922 // Per spec, access_denied is only for client-certificate-based access
1923 // control, but some buggy firewalls use it when blocking a page. To avoid a
1924 // confusing error, map it to a generic protocol error if no
1925 // CertificateRequest was sent. See https://crbug.com/630883.
1926 if (ERR_GET_REASON(info->error_code) == SSL_R_TLSV1_ALERT_ACCESS_DENIED &&
1927 !certificate_requested_) {
1928 net_error = ERR_SSL_PROTOCOL_ERROR;
1929 }
David Benjamin5b4410e2017-11-10 21:50:231930
1931 // This error is specific to the client, so map it here.
1932 if (ERR_GET_REASON(info->error_code) ==
1933 SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS) {
1934 net_error = ERR_SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS;
1935 }
davidbenfe132d92016-09-27 18:07:211936 }
1937
1938 return net_error;
1939}
1940
[email protected]7e5dd49f2010-12-08 18:33:491941} // namespace net