1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // OpenSSL binding for SSLClientSocket. The class layout and general principle
6 // of operation is derived from SSLClientSocketNSS.
8 #include "net/socket/ssl_client_socket_openssl.h"
10 #include <openssl/ssl.h>
11 #include <openssl/err.h>
13 #include "base/bind.h"
14 #include "base/memory/singleton.h"
15 #include "base/metrics/histogram.h"
16 #include "base/synchronization/lock.h"
17 #include "crypto/openssl_util.h"
18 #include "net/base/cert_verifier.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/openssl_private_key_store.h"
21 #include "net/base/single_request_cert_verifier.h"
22 #include "net/base/ssl_cert_request_info.h"
23 #include "net/base/ssl_connection_status_flags.h"
24 #include "net/base/ssl_info.h"
25 #include "net/base/x509_certificate_net_log_param.h"
26 #include "net/socket/ssl_error_params.h"
32 // Enable this to see logging for state machine state transitions.
34 #define GotoState(s) do { DVLOG(2) << (void *)this << " " << __FUNCTION__ << \
35 " jump to state " << s; \
36 next_handshake_state_ = s; } while (0)
38 #define GotoState(s) next_handshake_state_ = s
41 const size_t kMaxRecvBufferSize
= 4096;
42 const int kSessionCacheTimeoutSeconds
= 60 * 60;
43 const size_t kSessionCacheMaxEntires
= 1024;
45 // If a client doesn't have a list of protocols that it supports, but
46 // the server supports NPN, choosing "http/1.1" is the best answer.
47 const char kDefaultSupportedNPNProtocol
[] = "http/1.1";
49 // This method doesn't seemed to have made it into the OpenSSL headers.
50 unsigned long SSL_CIPHER_get_id(const SSL_CIPHER
* cipher
) { return cipher
->id
; }
52 // Used for encoding the |connection_status| field of an SSLInfo object.
53 int EncodeSSLConnectionStatus(int cipher_suite
,
56 return ((cipher_suite
& SSL_CONNECTION_CIPHERSUITE_MASK
) <<
57 SSL_CONNECTION_CIPHERSUITE_SHIFT
) |
58 ((compression
& SSL_CONNECTION_COMPRESSION_MASK
) <<
59 SSL_CONNECTION_COMPRESSION_SHIFT
) |
60 ((version
& SSL_CONNECTION_VERSION_MASK
) <<
61 SSL_CONNECTION_VERSION_SHIFT
);
64 // Returns the net SSL version number (see ssl_connection_status_flags.h) for
65 // this SSL connection.
66 int GetNetSSLVersion(SSL
* ssl
) {
67 switch (SSL_version(ssl
)) {
69 return SSL_CONNECTION_VERSION_SSL2
;
71 return SSL_CONNECTION_VERSION_SSL3
;
73 return SSL_CONNECTION_VERSION_TLS1
;
75 return SSL_CONNECTION_VERSION_TLS1_1
;
77 return SSL_CONNECTION_VERSION_TLS1_2
;
79 return SSL_CONNECTION_VERSION_UNKNOWN
;
83 int MapOpenSSLErrorSSL() {
84 // Walk down the error stack to find the SSLerr generated reason.
85 unsigned long error_code
;
87 error_code
= ERR_get_error();
89 return ERR_SSL_PROTOCOL_ERROR
;
90 } while (ERR_GET_LIB(error_code
) != ERR_LIB_SSL
);
92 DVLOG(1) << "OpenSSL SSL error, reason: " << ERR_GET_REASON(error_code
)
93 << ", name: " << ERR_error_string(error_code
, NULL
);
94 switch (ERR_GET_REASON(error_code
)) {
95 case SSL_R_READ_TIMEOUT_EXPIRED
:
97 case SSL_R_BAD_RESPONSE_ARGUMENT
:
98 return ERR_INVALID_ARGUMENT
;
99 case SSL_R_UNKNOWN_CERTIFICATE_TYPE
:
100 case SSL_R_UNKNOWN_CIPHER_TYPE
:
101 case SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE
:
102 case SSL_R_UNKNOWN_PKEY_TYPE
:
103 case SSL_R_UNKNOWN_REMOTE_ERROR_TYPE
:
104 case SSL_R_UNKNOWN_SSL_VERSION
:
105 return ERR_NOT_IMPLEMENTED
;
106 case SSL_R_UNSUPPORTED_SSL_VERSION
:
107 case SSL_R_NO_CIPHER_MATCH
:
108 case SSL_R_NO_SHARED_CIPHER
:
109 case SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY
:
110 case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION
:
111 return ERR_SSL_VERSION_OR_CIPHER_MISMATCH
;
112 case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
:
113 case SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE
:
114 case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED
:
115 case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED
:
116 case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
:
117 case SSL_R_TLSV1_ALERT_ACCESS_DENIED
:
118 case SSL_R_TLSV1_ALERT_UNKNOWN_CA
:
119 return ERR_BAD_SSL_CLIENT_AUTH_CERT
;
120 case SSL_R_BAD_DECOMPRESSION
:
121 case SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE
:
122 return ERR_SSL_DECOMPRESSION_FAILURE_ALERT
;
123 case SSL_R_SSLV3_ALERT_BAD_RECORD_MAC
:
124 return ERR_SSL_BAD_RECORD_MAC_ALERT
;
125 case SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED
:
126 return ERR_SSL_UNSAFE_NEGOTIATION
;
127 case SSL_R_WRONG_NUMBER_OF_KEY_BITS
:
128 return ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY
;
129 // SSL_R_UNKNOWN_PROTOCOL is reported if premature application data is
130 // received (see http://crbug.com/42538), and also if all the protocol
131 // versions supported by the server were disabled in this socket instance.
132 // Mapped to ERR_SSL_PROTOCOL_ERROR for compatibility with other SSL sockets
133 // in the former scenario.
134 case SSL_R_UNKNOWN_PROTOCOL
:
135 case SSL_R_SSL_HANDSHAKE_FAILURE
:
136 case SSL_R_DECRYPTION_FAILED
:
137 case SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC
:
138 case SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG
:
139 case SSL_R_DIGEST_CHECK_FAILED
:
140 case SSL_R_DUPLICATE_COMPRESSION_ID
:
141 case SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER
:
142 case SSL_R_ENCRYPTED_LENGTH_TOO_LONG
:
143 case SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST
:
144 case SSL_R_EXCESSIVE_MESSAGE_SIZE
:
145 case SSL_R_EXTRA_DATA_IN_MESSAGE
:
146 case SSL_R_GOT_A_FIN_BEFORE_A_CCS
:
147 case SSL_R_ILLEGAL_PADDING
:
148 case SSL_R_INVALID_CHALLENGE_LENGTH
:
149 case SSL_R_INVALID_COMMAND
:
150 case SSL_R_INVALID_PURPOSE
:
151 case SSL_R_INVALID_STATUS_RESPONSE
:
152 case SSL_R_INVALID_TICKET_KEYS_LENGTH
:
153 case SSL_R_KEY_ARG_TOO_LONG
:
154 case SSL_R_READ_WRONG_PACKET_TYPE
:
155 case SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE
:
156 // TODO(joth): SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE may be returned from the
157 // server after receiving ClientHello if there's no common supported cipher.
158 // Ideally we'd map that specific case to ERR_SSL_VERSION_OR_CIPHER_MISMATCH
159 // to match the NSS implementation. See also http://goo.gl/oMtZW
160 case SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE
:
161 case SSL_R_SSLV3_ALERT_NO_CERTIFICATE
:
162 case SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER
:
163 case SSL_R_TLSV1_ALERT_DECODE_ERROR
:
164 case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED
:
165 case SSL_R_TLSV1_ALERT_DECRYPT_ERROR
:
166 case SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION
:
167 case SSL_R_TLSV1_ALERT_INTERNAL_ERROR
:
168 case SSL_R_TLSV1_ALERT_NO_RENEGOTIATION
:
169 case SSL_R_TLSV1_ALERT_RECORD_OVERFLOW
:
170 case SSL_R_TLSV1_ALERT_USER_CANCELLED
:
171 return ERR_SSL_PROTOCOL_ERROR
;
173 LOG(WARNING
) << "Unmapped error reason: " << ERR_GET_REASON(error_code
);
178 // Converts an OpenSSL error code into a net error code, walking the OpenSSL
179 // error stack if needed. Note that |tracer| is not currently used in the
180 // implementation, but is passed in anyway as this ensures the caller will clear
181 // any residual codes left on the error stack.
182 int MapOpenSSLError(int err
, const crypto::OpenSSLErrStackTracer
& tracer
) {
184 case SSL_ERROR_WANT_READ
:
185 case SSL_ERROR_WANT_WRITE
:
186 return ERR_IO_PENDING
;
187 case SSL_ERROR_SYSCALL
:
188 DVLOG(1) << "OpenSSL SYSCALL error, errno " << errno
;
189 return ERR_SSL_PROTOCOL_ERROR
;
191 return MapOpenSSLErrorSSL();
193 // TODO(joth): Implement full mapping.
194 LOG(WARNING
) << "Unknown OpenSSL error " << err
;
195 return ERR_SSL_PROTOCOL_ERROR
;
199 // We do certificate verification after handshake, so we disable the default
200 // by registering a no-op verify function.
201 int NoOpVerifyCallback(X509_STORE_CTX
*, void *) {
202 DVLOG(3) << "skipping cert verify";
206 // OpenSSL manages a cache of SSL_SESSION, this class provides the application
207 // side policy for that cache about session re-use: we retain one session per
208 // unique HostPortPair, per shard.
209 class SSLSessionCache
{
213 void OnSessionAdded(const HostPortPair
& host_and_port
,
214 const std::string
& shard
,
215 SSL_SESSION
* session
) {
216 // Declare the session cleaner-upper before the lock, so any call into
217 // OpenSSL to free the session will happen after the lock is released.
218 crypto::ScopedOpenSSL
<SSL_SESSION
, SSL_SESSION_free
> session_to_free
;
219 base::AutoLock
lock(lock_
);
221 DCHECK_EQ(0U, session_map_
.count(session
));
222 const std::string cache_key
= GetCacheKey(host_and_port
, shard
);
224 std::pair
<HostPortMap::iterator
, bool> res
=
225 host_port_map_
.insert(std::make_pair(cache_key
, session
));
226 if (!res
.second
) { // Already exists: replace old entry.
227 session_to_free
.reset(res
.first
->second
);
228 session_map_
.erase(session_to_free
.get());
229 res
.first
->second
= session
;
231 DVLOG(2) << "Adding session " << session
<< " => "
232 << cache_key
<< ", new entry = " << res
.second
;
233 DCHECK(host_port_map_
[cache_key
] == session
);
234 session_map_
[session
] = res
.first
;
235 DCHECK_EQ(host_port_map_
.size(), session_map_
.size());
236 DCHECK_LE(host_port_map_
.size(), kSessionCacheMaxEntires
);
239 void OnSessionRemoved(SSL_SESSION
* session
) {
240 // Declare the session cleaner-upper before the lock, so any call into
241 // OpenSSL to free the session will happen after the lock is released.
242 crypto::ScopedOpenSSL
<SSL_SESSION
, SSL_SESSION_free
> session_to_free
;
243 base::AutoLock
lock(lock_
);
245 SessionMap::iterator it
= session_map_
.find(session
);
246 if (it
== session_map_
.end())
248 DVLOG(2) << "Remove session " << session
<< " => " << it
->second
->first
;
249 DCHECK(it
->second
->second
== session
);
250 host_port_map_
.erase(it
->second
);
251 session_map_
.erase(it
);
252 session_to_free
.reset(session
);
253 DCHECK_EQ(host_port_map_
.size(), session_map_
.size());
256 // Looks up the host:port in the cache, and if a session is found it is added
257 // to |ssl|, returning true on success.
258 bool SetSSLSession(SSL
* ssl
, const HostPortPair
& host_and_port
,
259 const std::string
& shard
) {
260 base::AutoLock
lock(lock_
);
261 const std::string cache_key
= GetCacheKey(host_and_port
, shard
);
262 HostPortMap::iterator it
= host_port_map_
.find(cache_key
);
263 if (it
== host_port_map_
.end())
265 DVLOG(2) << "Lookup session: " << it
->second
<< " => " << cache_key
;
266 SSL_SESSION
* session
= it
->second
;
268 DCHECK(session_map_
[session
] == it
);
269 // Ideally we'd release |lock_| before calling into OpenSSL here, however
270 // that opens a small risk |session| will go out of scope before it is used.
271 // Alternatively we would take a temporary local refcount on |session|,
272 // except OpenSSL does not provide a public API for adding a ref (c.f.
273 // SSL_SESSION_free which decrements the ref).
274 return SSL_set_session(ssl
, session
) == 1;
277 // Flush removes all entries from the cache. This is called when a client
278 // certificate is added.
280 for (HostPortMap::iterator i
= host_port_map_
.begin();
281 i
!= host_port_map_
.end(); i
++) {
282 SSL_SESSION_free(i
->second
);
284 host_port_map_
.clear();
285 session_map_
.clear();
289 static std::string
GetCacheKey(const HostPortPair
& host_and_port
,
290 const std::string
& shard
) {
291 return host_and_port
.ToString() + "/" + shard
;
294 // A pair of maps to allow bi-directional lookups between host:port and an
295 // associated session.
296 typedef std::map
<std::string
, SSL_SESSION
*> HostPortMap
;
297 typedef std::map
<SSL_SESSION
*, HostPortMap::iterator
> SessionMap
;
298 HostPortMap host_port_map_
;
299 SessionMap session_map_
;
301 // Protects access to both the above maps.
304 DISALLOW_COPY_AND_ASSIGN(SSLSessionCache
);
309 static SSLContext
* GetInstance() { return Singleton
<SSLContext
>::get(); }
310 SSL_CTX
* ssl_ctx() { return ssl_ctx_
.get(); }
311 SSLSessionCache
* session_cache() { return &session_cache_
; }
313 SSLClientSocketOpenSSL
* GetClientSocketFromSSL(SSL
* ssl
) {
315 SSLClientSocketOpenSSL
* socket
= static_cast<SSLClientSocketOpenSSL
*>(
316 SSL_get_ex_data(ssl
, ssl_socket_data_index_
));
321 bool SetClientSocketForSSL(SSL
* ssl
, SSLClientSocketOpenSSL
* socket
) {
322 return SSL_set_ex_data(ssl
, ssl_socket_data_index_
, socket
) != 0;
326 friend struct DefaultSingletonTraits
<SSLContext
>;
329 crypto::EnsureOpenSSLInit();
330 ssl_socket_data_index_
= SSL_get_ex_new_index(0, 0, 0, 0, 0);
331 DCHECK_NE(ssl_socket_data_index_
, -1);
332 ssl_ctx_
.reset(SSL_CTX_new(SSLv23_client_method()));
333 SSL_CTX_set_cert_verify_callback(ssl_ctx_
.get(), NoOpVerifyCallback
, NULL
);
334 SSL_CTX_set_session_cache_mode(ssl_ctx_
.get(), SSL_SESS_CACHE_CLIENT
);
335 SSL_CTX_sess_set_new_cb(ssl_ctx_
.get(), NewSessionCallbackStatic
);
336 SSL_CTX_sess_set_remove_cb(ssl_ctx_
.get(), RemoveSessionCallbackStatic
);
337 SSL_CTX_set_timeout(ssl_ctx_
.get(), kSessionCacheTimeoutSeconds
);
338 SSL_CTX_sess_set_cache_size(ssl_ctx_
.get(), kSessionCacheMaxEntires
);
339 SSL_CTX_set_client_cert_cb(ssl_ctx_
.get(), ClientCertCallback
);
340 #if defined(OPENSSL_NPN_NEGOTIATED)
341 // TODO(kristianm): Only select this if ssl_config_.next_proto is not empty.
342 // It would be better if the callback were not a global setting,
343 // but that is an OpenSSL issue.
344 SSL_CTX_set_next_proto_select_cb(ssl_ctx_
.get(), SelectNextProtoCallback
,
349 static int NewSessionCallbackStatic(SSL
* ssl
, SSL_SESSION
* session
) {
350 return GetInstance()->NewSessionCallback(ssl
, session
);
353 int NewSessionCallback(SSL
* ssl
, SSL_SESSION
* session
) {
354 SSLClientSocketOpenSSL
* socket
= GetClientSocketFromSSL(ssl
);
355 session_cache_
.OnSessionAdded(socket
->host_and_port(),
356 socket
->ssl_session_cache_shard(),
358 return 1; // 1 => We took ownership of |session|.
361 static void RemoveSessionCallbackStatic(SSL_CTX
* ctx
, SSL_SESSION
* session
) {
362 return GetInstance()->RemoveSessionCallback(ctx
, session
);
365 void RemoveSessionCallback(SSL_CTX
* ctx
, SSL_SESSION
* session
) {
366 DCHECK(ctx
== ssl_ctx());
367 session_cache_
.OnSessionRemoved(session
);
370 static int ClientCertCallback(SSL
* ssl
, X509
** x509
, EVP_PKEY
** pkey
) {
371 SSLClientSocketOpenSSL
* socket
= GetInstance()->GetClientSocketFromSSL(ssl
);
373 return socket
->ClientCertRequestCallback(ssl
, x509
, pkey
);
376 static int SelectNextProtoCallback(SSL
* ssl
,
377 unsigned char** out
, unsigned char* outlen
,
378 const unsigned char* in
,
379 unsigned int inlen
, void* arg
) {
380 SSLClientSocketOpenSSL
* socket
= GetInstance()->GetClientSocketFromSSL(ssl
);
381 return socket
->SelectNextProtoCallback(out
, outlen
, in
, inlen
);
384 // This is the index used with SSL_get_ex_data to retrieve the owner
385 // SSLClientSocketOpenSSL object from an SSL instance.
386 int ssl_socket_data_index_
;
388 // session_cache_ must appear before |ssl_ctx_| because the destruction of
389 // |ssl_ctx_| may trigger callbacks into |session_cache_|. Therefore,
390 // |session_cache_| must be destructed after |ssl_ctx_|.
391 SSLSessionCache session_cache_
;
392 crypto::ScopedOpenSSL
<SSL_CTX
, SSL_CTX_free
> ssl_ctx_
;
395 // Utility to construct the appropriate set & clear masks for use the OpenSSL
396 // options and mode configuration functions. (SSL_set_options etc)
397 struct SslSetClearMask
{
398 SslSetClearMask() : set_mask(0), clear_mask(0) {}
399 void ConfigureFlag(long flag
, bool state
) {
400 (state
? set_mask
: clear_mask
) |= flag
;
401 // Make sure we haven't got any intersection in the set & clear options.
402 DCHECK_EQ(0, set_mask
& clear_mask
) << flag
<< ":" << state
;
411 void SSLClientSocket::ClearSessionCache() {
412 SSLContext
* context
= SSLContext::GetInstance();
413 context
->session_cache()->Flush();
416 SSLClientSocketOpenSSL::SSLClientSocketOpenSSL(
417 ClientSocketHandle
* transport_socket
,
418 const HostPortPair
& host_and_port
,
419 const SSLConfig
& ssl_config
,
420 const SSLClientSocketContext
& context
)
421 : transport_send_busy_(false),
422 transport_recv_busy_(false),
423 transport_recv_eof_(false),
424 completed_handshake_(false),
425 client_auth_cert_needed_(false),
426 cert_verifier_(context
.cert_verifier
),
428 transport_bio_(NULL
),
429 transport_(transport_socket
),
430 host_and_port_(host_and_port
),
431 ssl_config_(ssl_config
),
432 ssl_session_cache_shard_(context
.ssl_session_cache_shard
),
433 trying_cached_session_(false),
434 next_handshake_state_(STATE_NONE
),
435 npn_status_(kNextProtoUnsupported
),
436 net_log_(transport_socket
->socket()->NetLog()) {
439 SSLClientSocketOpenSSL::~SSLClientSocketOpenSSL() {
443 bool SSLClientSocketOpenSSL::Init() {
445 DCHECK(!transport_bio_
);
447 SSLContext
* context
= SSLContext::GetInstance();
448 crypto::OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
450 ssl_
= SSL_new(context
->ssl_ctx());
451 if (!ssl_
|| !context
->SetClientSocketForSSL(ssl_
, this))
454 if (!SSL_set_tlsext_host_name(ssl_
, host_and_port_
.host().c_str()))
457 trying_cached_session_
=
458 context
->session_cache()->SetSSLSession(ssl_
, host_and_port_
,
459 ssl_session_cache_shard_
);
462 // 0 => use default buffer sizes.
463 if (!BIO_new_bio_pair(&ssl_bio
, 0, &transport_bio_
, 0))
466 DCHECK(transport_bio_
);
468 SSL_set_bio(ssl_
, ssl_bio
, ssl_bio
);
470 // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
471 // set everything we care about to an absolute value.
472 SslSetClearMask options
;
473 options
.ConfigureFlag(SSL_OP_NO_SSLv2
, true);
474 bool ssl3_enabled
= (ssl_config_
.version_min
== SSL_PROTOCOL_VERSION_SSL3
);
475 options
.ConfigureFlag(SSL_OP_NO_SSLv3
, !ssl3_enabled
);
476 bool tls1_enabled
= (ssl_config_
.version_min
<= SSL_PROTOCOL_VERSION_TLS1
&&
477 ssl_config_
.version_max
>= SSL_PROTOCOL_VERSION_TLS1
);
478 options
.ConfigureFlag(SSL_OP_NO_TLSv1
, !tls1_enabled
);
479 #if defined(SSL_OP_NO_TLSv1_1)
480 bool tls1_1_enabled
=
481 (ssl_config_
.version_min
<= SSL_PROTOCOL_VERSION_TLS1_1
&&
482 ssl_config_
.version_max
>= SSL_PROTOCOL_VERSION_TLS1_1
);
483 options
.ConfigureFlag(SSL_OP_NO_TLSv1_1
, !tls1_1_enabled
);
485 #if defined(SSL_OP_NO_TLSv1_2)
486 bool tls1_2_enabled
=
487 (ssl_config_
.version_min
<= SSL_PROTOCOL_VERSION_TLS1_2
&&
488 ssl_config_
.version_max
>= SSL_PROTOCOL_VERSION_TLS1_2
);
489 options
.ConfigureFlag(SSL_OP_NO_TLSv1_2
, !tls1_2_enabled
);
492 #if defined(SSL_OP_NO_COMPRESSION)
493 // If TLS was disabled also disable compression, to provide maximum site
494 // compatibility in the case of protocol fallback. See http://crbug.com/31628
495 options
.ConfigureFlag(SSL_OP_NO_COMPRESSION
,
496 ssl_config_
.version_max
< SSL_PROTOCOL_VERSION_TLS1
);
499 // TODO(joth): Set this conditionally, see http://crbug.com/55410
500 options
.ConfigureFlag(SSL_OP_LEGACY_SERVER_CONNECT
, true);
502 SSL_set_options(ssl_
, options
.set_mask
);
503 SSL_clear_options(ssl_
, options
.clear_mask
);
505 // Same as above, this time for the SSL mode.
506 SslSetClearMask mode
;
508 #if defined(SSL_MODE_RELEASE_BUFFERS)
509 mode
.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS
, true);
512 #if defined(SSL_MODE_SMALL_BUFFERS)
513 mode
.ConfigureFlag(SSL_MODE_SMALL_BUFFERS
, true);
516 SSL_set_mode(ssl_
, mode
.set_mask
);
517 SSL_clear_mode(ssl_
, mode
.clear_mask
);
519 // Removing ciphers by ID from OpenSSL is a bit involved as we must use the
520 // textual name with SSL_set_cipher_list because there is no public API to
521 // directly remove a cipher by ID.
522 STACK_OF(SSL_CIPHER
)* ciphers
= SSL_get_ciphers(ssl_
);
524 // See SSLConfig::disabled_cipher_suites for description of the suites
525 // disabled by default.
526 std::string
command("DEFAULT:!NULL:!aNULL:!IDEA:!FZA");
527 // Walk through all the installed ciphers, seeing if any need to be
528 // appended to the cipher removal |command|.
529 for (int i
= 0; i
< sk_SSL_CIPHER_num(ciphers
); ++i
) {
530 const SSL_CIPHER
* cipher
= sk_SSL_CIPHER_value(ciphers
, i
);
531 const uint16 id
= SSL_CIPHER_get_id(cipher
);
532 // Remove any ciphers with a strength of less than 80 bits. Note the NSS
533 // implementation uses "effective" bits here but OpenSSL does not provide
534 // this detail. This only impacts Triple DES: reports 112 vs. 168 bits,
535 // both of which are greater than 80 anyway.
536 bool disable
= SSL_CIPHER_get_bits(cipher
, NULL
) < 80;
538 disable
= std::find(ssl_config_
.disabled_cipher_suites
.begin(),
539 ssl_config_
.disabled_cipher_suites
.end(), id
) !=
540 ssl_config_
.disabled_cipher_suites
.end();
543 const char* name
= SSL_CIPHER_get_name(cipher
);
544 DVLOG(3) << "Found cipher to remove: '" << name
<< "', ID: " << id
545 << " strength: " << SSL_CIPHER_get_bits(cipher
, NULL
);
546 command
.append(":!");
547 command
.append(name
);
550 int rv
= SSL_set_cipher_list(ssl_
, command
.c_str());
551 // If this fails (rv = 0) it means there are no ciphers enabled on this SSL.
552 // This will almost certainly result in the socket failing to complete the
553 // handshake at which point the appropriate error is bubbled up to the client.
554 LOG_IF(WARNING
, rv
!= 1) << "SSL_set_cipher_list('" << command
<< "') "
559 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL
* ssl
,
562 DVLOG(3) << "OpenSSL ClientCertRequestCallback called";
564 DCHECK(*x509
== NULL
);
565 DCHECK(*pkey
== NULL
);
567 if (!ssl_config_
.send_client_cert
) {
568 client_auth_cert_needed_
= true;
569 return -1; // Suspends handshake.
572 // Second pass: a client certificate should have been selected.
573 if (ssl_config_
.client_cert
) {
574 EVP_PKEY
* privkey
= OpenSSLPrivateKeyStore::GetInstance()->FetchPrivateKey(
575 X509_PUBKEY_get(X509_get_X509_PUBKEY(
576 ssl_config_
.client_cert
->os_cert_handle())));
578 // TODO(joth): (copied from NSS) We should wait for server certificate
579 // verification before sending our credentials. See http://crbug.com/13934
580 *x509
= X509Certificate::DupOSCertHandle(
581 ssl_config_
.client_cert
->os_cert_handle());
585 LOG(WARNING
) << "Client cert found without private key";
588 // Send no client certificate.
592 // SSLClientSocket methods
594 void SSLClientSocketOpenSSL::GetSSLInfo(SSLInfo
* ssl_info
) {
599 ssl_info
->cert
= server_cert_verify_result_
.verified_cert
;
600 ssl_info
->cert_status
= server_cert_verify_result_
.cert_status
;
601 ssl_info
->is_issued_by_known_root
=
602 server_cert_verify_result_
.is_issued_by_known_root
;
603 ssl_info
->public_key_hashes
=
604 server_cert_verify_result_
.public_key_hashes
;
605 ssl_info
->client_cert_sent
= WasDomainBoundCertSent() ||
606 (ssl_config_
.send_client_cert
&& ssl_config_
.client_cert
);
608 const SSL_CIPHER
* cipher
= SSL_get_current_cipher(ssl_
);
610 ssl_info
->security_bits
= SSL_CIPHER_get_bits(cipher
, NULL
);
611 const COMP_METHOD
* compression
= SSL_get_current_compression(ssl_
);
613 ssl_info
->connection_status
= EncodeSSLConnectionStatus(
614 SSL_CIPHER_get_id(cipher
),
615 compression
? compression
->type
: 0,
616 GetNetSSLVersion(ssl_
));
618 bool peer_supports_renego_ext
= !!SSL_get_secure_renegotiation_support(ssl_
);
619 if (!peer_supports_renego_ext
)
620 ssl_info
->connection_status
|= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION
;
621 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported",
622 implicit_cast
<int>(peer_supports_renego_ext
), 2);
624 if (ssl_config_
.version_fallback
)
625 ssl_info
->connection_status
|= SSL_CONNECTION_VERSION_FALLBACK
;
627 DVLOG(3) << "Encoded connection status: cipher suite = "
628 << SSLConnectionStatusToCipherSuite(ssl_info
->connection_status
)
630 << SSLConnectionStatusToCompression(ssl_info
->connection_status
)
632 << SSLConnectionStatusToVersion(ssl_info
->connection_status
);
635 void SSLClientSocketOpenSSL::GetSSLCertRequestInfo(
636 SSLCertRequestInfo
* cert_request_info
) {
637 cert_request_info
->host_and_port
= host_and_port_
.ToString();
638 cert_request_info
->client_certs
= client_certs_
;
641 int SSLClientSocketOpenSSL::ExportKeyingMaterial(
642 const base::StringPiece
& label
,
643 bool has_context
, const base::StringPiece
& context
,
644 unsigned char* out
, unsigned int outlen
) {
645 crypto::OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
647 int rv
= SSL_export_keying_material(
648 ssl_
, out
, outlen
, const_cast<char*>(label
.data()),
650 reinterpret_cast<unsigned char*>(const_cast<char*>(context
.data())),
652 context
.length() > 0);
655 int ssl_error
= SSL_get_error(ssl_
, rv
);
656 LOG(ERROR
) << "Failed to export keying material;"
657 << " returned " << rv
658 << ", SSL error code " << ssl_error
;
659 return MapOpenSSLError(ssl_error
, err_tracer
);
664 SSLClientSocket::NextProtoStatus
SSLClientSocketOpenSSL::GetNextProto(
665 std::string
* proto
, std::string
* server_protos
) {
667 *server_protos
= server_protos_
;
671 ServerBoundCertService
*
672 SSLClientSocketOpenSSL::GetServerBoundCertService() const {
676 void SSLClientSocketOpenSSL::DoReadCallback(int rv
) {
677 // Since Run may result in Read being called, clear |user_read_callback_|
679 CompletionCallback c
= user_read_callback_
;
680 user_read_callback_
.Reset();
681 user_read_buf_
= NULL
;
682 user_read_buf_len_
= 0;
686 void SSLClientSocketOpenSSL::DoWriteCallback(int rv
) {
687 // Since Run may result in Write being called, clear |user_write_callback_|
689 CompletionCallback c
= user_write_callback_
;
690 user_write_callback_
.Reset();
691 user_write_buf_
= NULL
;
692 user_write_buf_len_
= 0;
696 // StreamSocket implementation.
697 int SSLClientSocketOpenSSL::Connect(const CompletionCallback
& callback
) {
698 net_log_
.BeginEvent(NetLog::TYPE_SSL_CONNECT
);
700 // Set up new ssl object.
702 int result
= ERR_UNEXPECTED
;
703 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT
, result
);
707 // Set SSL to client mode. Handshake happens in the loop below.
708 SSL_set_connect_state(ssl_
);
710 GotoState(STATE_HANDSHAKE
);
711 int rv
= DoHandshakeLoop(net::OK
);
712 if (rv
== ERR_IO_PENDING
) {
713 user_connect_callback_
= callback
;
715 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT
, rv
);
718 return rv
> OK
? OK
: rv
;
721 void SSLClientSocketOpenSSL::Disconnect() {
723 // Calling SSL_shutdown prevents the session from being marked as
729 if (transport_bio_
) {
730 BIO_free_all(transport_bio_
);
731 transport_bio_
= NULL
;
734 // Shut down anything that may call us back.
736 transport_
->socket()->Disconnect();
738 // Null all callbacks, delete all buffers.
739 transport_send_busy_
= false;
741 transport_recv_busy_
= false;
742 transport_recv_eof_
= false;
745 user_connect_callback_
.Reset();
746 user_read_callback_
.Reset();
747 user_write_callback_
.Reset();
748 user_read_buf_
= NULL
;
749 user_read_buf_len_
= 0;
750 user_write_buf_
= NULL
;
751 user_write_buf_len_
= 0;
753 server_cert_verify_result_
.Reset();
754 completed_handshake_
= false;
756 client_certs_
.clear();
757 client_auth_cert_needed_
= false;
760 int SSLClientSocketOpenSSL::DoHandshakeLoop(int last_io_result
) {
761 int rv
= last_io_result
;
763 // Default to STATE_NONE for next state.
764 // (This is a quirk carried over from the windows
765 // implementation. It makes reading the logs a bit harder.)
766 // State handlers can and often do call GotoState just
767 // to stay in the current state.
768 State state
= next_handshake_state_
;
769 GotoState(STATE_NONE
);
771 case STATE_HANDSHAKE
:
774 case STATE_VERIFY_CERT
:
776 rv
= DoVerifyCert(rv
);
778 case STATE_VERIFY_CERT_COMPLETE
:
779 rv
= DoVerifyCertComplete(rv
);
784 NOTREACHED() << "unexpected state" << state
;
788 bool network_moved
= DoTransportIO();
789 if (network_moved
&& next_handshake_state_
== STATE_HANDSHAKE
) {
790 // In general we exit the loop if rv is ERR_IO_PENDING. In this
791 // special case we keep looping even if rv is ERR_IO_PENDING because
792 // the transport IO may allow DoHandshake to make progress.
793 rv
= OK
; // This causes us to stay in the loop.
795 } while (rv
!= ERR_IO_PENDING
&& next_handshake_state_
!= STATE_NONE
);
799 int SSLClientSocketOpenSSL::DoHandshake() {
800 crypto::OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
801 int net_error
= net::OK
;
802 int rv
= SSL_do_handshake(ssl_
);
804 if (client_auth_cert_needed_
) {
805 net_error
= ERR_SSL_CLIENT_AUTH_CERT_NEEDED
;
806 // If the handshake already succeeded (because the server requests but
807 // doesn't require a client cert), we need to invalidate the SSL session
808 // so that we won't try to resume the non-client-authenticated session in
809 // the next handshake. This will cause the server to ask for a client
812 // Remove from session cache but don't clear this connection.
813 SSL_SESSION
* session
= SSL_get_session(ssl_
);
815 int rv
= SSL_CTX_remove_session(SSL_get_SSL_CTX(ssl_
), session
);
816 LOG_IF(WARNING
, !rv
) << "Couldn't invalidate SSL session: " << session
;
819 } else if (rv
== 1) {
820 if (trying_cached_session_
&& logging::DEBUG_MODE
) {
821 DVLOG(2) << "Result of session reuse for " << host_and_port_
.ToString()
822 << " is: " << (SSL_session_reused(ssl_
) ? "Success" : "Fail");
824 // SSL handshake is completed. Let's verify the certificate.
825 const bool got_cert
= !!UpdateServerCert();
828 NetLog::TYPE_SSL_CERTIFICATES_RECEIVED
,
829 base::Bind(&NetLogX509CertificateCallback
,
830 base::Unretained(server_cert_
.get())));
831 GotoState(STATE_VERIFY_CERT
);
833 int ssl_error
= SSL_get_error(ssl_
, rv
);
834 net_error
= MapOpenSSLError(ssl_error
, err_tracer
);
836 // If not done, stay in this state
837 if (net_error
== ERR_IO_PENDING
) {
838 GotoState(STATE_HANDSHAKE
);
840 LOG(ERROR
) << "handshake failed; returned " << rv
841 << ", SSL error code " << ssl_error
842 << ", net_error " << net_error
;
844 NetLog::TYPE_SSL_HANDSHAKE_ERROR
,
845 CreateNetLogSSLErrorCallback(net_error
, ssl_error
));
851 // SelectNextProtoCallback is called by OpenSSL during the handshake. If the
852 // server supports NPN, selects a protocol from the list that the server
853 // provides. According to third_party/openssl/openssl/ssl/ssl_lib.c, the
854 // callback can assume that |in| is syntactically valid.
855 int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out
,
856 unsigned char* outlen
,
857 const unsigned char* in
,
858 unsigned int inlen
) {
859 #if defined(OPENSSL_NPN_NEGOTIATED)
860 if (ssl_config_
.next_protos
.empty()) {
861 *out
= reinterpret_cast<uint8
*>(
862 const_cast<char*>(kDefaultSupportedNPNProtocol
));
863 *outlen
= arraysize(kDefaultSupportedNPNProtocol
) - 1;
864 npn_status_
= kNextProtoUnsupported
;
865 return SSL_TLSEXT_ERR_OK
;
868 // Assume there's no overlap between our protocols and the server's list.
869 npn_status_
= kNextProtoNoOverlap
;
871 // For each protocol in server preference order, see if we support it.
872 for (unsigned int i
= 0; i
< inlen
; i
+= in
[i
] + 1) {
873 for (std::vector
<std::string
>::const_iterator
874 j
= ssl_config_
.next_protos
.begin();
875 j
!= ssl_config_
.next_protos
.end(); ++j
) {
876 if (in
[i
] == j
->size() &&
877 memcmp(&in
[i
+ 1], j
->data(), in
[i
]) == 0) {
879 *out
= const_cast<unsigned char*>(in
) + i
+ 1;
881 npn_status_
= kNextProtoNegotiated
;
885 if (npn_status_
== kNextProtoNegotiated
)
889 // If we didn't find a protocol, we select the first one from our list.
890 if (npn_status_
== kNextProtoNoOverlap
) {
891 *out
= reinterpret_cast<uint8
*>(const_cast<char*>(
892 ssl_config_
.next_protos
[0].data()));
893 *outlen
= ssl_config_
.next_protos
[0].size();
896 npn_proto_
.assign(reinterpret_cast<const char*>(*out
), *outlen
);
897 server_protos_
.assign(reinterpret_cast<const char*>(in
), inlen
);
898 DVLOG(2) << "next protocol: '" << npn_proto_
<< "' status: " << npn_status_
;
900 return SSL_TLSEXT_ERR_OK
;
903 int SSLClientSocketOpenSSL::DoVerifyCert(int result
) {
904 DCHECK(server_cert_
);
905 GotoState(STATE_VERIFY_CERT_COMPLETE
);
907 CertStatus cert_status
;
908 if (ssl_config_
.IsAllowedBadCert(server_cert_
, &cert_status
)) {
909 VLOG(1) << "Received an expected bad cert with status: " << cert_status
;
910 server_cert_verify_result_
.Reset();
911 server_cert_verify_result_
.cert_status
= cert_status
;
912 server_cert_verify_result_
.verified_cert
= server_cert_
;
917 if (ssl_config_
.rev_checking_enabled
)
918 flags
|= X509Certificate::VERIFY_REV_CHECKING_ENABLED
;
919 if (ssl_config_
.verify_ev_cert
)
920 flags
|= X509Certificate::VERIFY_EV_CERT
;
921 if (ssl_config_
.cert_io_enabled
)
922 flags
|= X509Certificate::VERIFY_CERT_IO_ENABLED
;
923 verifier_
.reset(new SingleRequestCertVerifier(cert_verifier_
));
924 return verifier_
->Verify(
925 server_cert_
, host_and_port_
.host(), flags
,
926 NULL
/* no CRL set */,
927 &server_cert_verify_result_
,
928 base::Bind(&SSLClientSocketOpenSSL::OnHandshakeIOComplete
,
929 base::Unretained(this)),
933 int SSLClientSocketOpenSSL::DoVerifyCertComplete(int result
) {
937 // TODO(joth): Work out if we need to remember the intermediate CA certs
938 // when the server sends them to us, and do so here.
940 DVLOG(1) << "DoVerifyCertComplete error " << ErrorToString(result
)
941 << " (" << result
<< ")";
944 completed_handshake_
= true;
945 // Exit DoHandshakeLoop and return the result to the caller to Connect.
946 DCHECK_EQ(STATE_NONE
, next_handshake_state_
);
950 X509Certificate
* SSLClientSocketOpenSSL::UpdateServerCert() {
954 crypto::ScopedOpenSSL
<X509
, X509_free
> cert(SSL_get_peer_certificate(ssl_
));
956 LOG(WARNING
) << "SSL_get_peer_certificate returned NULL";
960 // Unlike SSL_get_peer_certificate, SSL_get_peer_cert_chain does not
961 // increment the reference so sk_X509_free does not need to be called.
962 STACK_OF(X509
)* chain
= SSL_get_peer_cert_chain(ssl_
);
963 X509Certificate::OSCertHandles intermediates
;
965 for (int i
= 0; i
< sk_X509_num(chain
); ++i
)
966 intermediates
.push_back(sk_X509_value(chain
, i
));
968 server_cert_
= X509Certificate::CreateFromHandle(cert
.get(), intermediates
);
969 DCHECK(server_cert_
);
974 bool SSLClientSocketOpenSSL::DoTransportIO() {
975 bool network_moved
= false;
976 if (BufferSend() > 0)
977 network_moved
= true;
978 if (!transport_recv_eof_
&& BufferRecv() >= 0)
979 network_moved
= true;
980 return network_moved
;
983 int SSLClientSocketOpenSSL::BufferSend(void) {
984 if (transport_send_busy_
)
985 return ERR_IO_PENDING
;
988 // Get a fresh send buffer out of the send BIO.
989 size_t max_read
= BIO_ctrl_pending(transport_bio_
);
991 send_buffer_
= new DrainableIOBuffer(new IOBuffer(max_read
), max_read
);
992 int read_bytes
= BIO_read(transport_bio_
, send_buffer_
->data(), max_read
);
993 DCHECK_GT(read_bytes
, 0);
994 CHECK_EQ(static_cast<int>(max_read
), read_bytes
);
999 while (send_buffer_
) {
1000 rv
= transport_
->socket()->Write(
1002 send_buffer_
->BytesRemaining(),
1003 base::Bind(&SSLClientSocketOpenSSL::BufferSendComplete
,
1004 base::Unretained(this)));
1005 if (rv
== ERR_IO_PENDING
) {
1006 transport_send_busy_
= true;
1009 TransportWriteComplete(rv
);
1014 void SSLClientSocketOpenSSL::BufferSendComplete(int result
) {
1015 transport_send_busy_
= false;
1016 TransportWriteComplete(result
);
1017 OnSendComplete(result
);
1020 void SSLClientSocketOpenSSL::TransportWriteComplete(int result
) {
1021 DCHECK(ERR_IO_PENDING
!= result
);
1023 // Got a socket write error; close the BIO to indicate this upward.
1024 DVLOG(1) << "TransportWriteComplete error " << result
;
1025 (void)BIO_shutdown_wr(transport_bio_
);
1026 send_buffer_
= NULL
;
1028 DCHECK(send_buffer_
);
1029 send_buffer_
->DidConsume(result
);
1030 DCHECK_GE(send_buffer_
->BytesRemaining(), 0);
1031 if (send_buffer_
->BytesRemaining() <= 0)
1032 send_buffer_
= NULL
;
1036 int SSLClientSocketOpenSSL::BufferRecv(void) {
1037 if (transport_recv_busy_
)
1038 return ERR_IO_PENDING
;
1040 size_t max_write
= BIO_ctrl_get_write_guarantee(transport_bio_
);
1041 if (max_write
> kMaxRecvBufferSize
)
1042 max_write
= kMaxRecvBufferSize
;
1045 return ERR_IO_PENDING
;
1047 recv_buffer_
= new IOBuffer(max_write
);
1048 int rv
= transport_
->socket()->Read(
1049 recv_buffer_
, max_write
,
1050 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete
,
1051 base::Unretained(this)));
1052 if (rv
== ERR_IO_PENDING
) {
1053 transport_recv_busy_
= true;
1055 TransportReadComplete(rv
);
1060 void SSLClientSocketOpenSSL::BufferRecvComplete(int result
) {
1061 TransportReadComplete(result
);
1062 OnRecvComplete(result
);
1065 void SSLClientSocketOpenSSL::TransportReadComplete(int result
) {
1066 DCHECK(ERR_IO_PENDING
!= result
);
1068 DVLOG(1) << "TransportReadComplete result " << result
;
1069 // Received 0 (end of file) or an error. Either way, bubble it up to the
1070 // SSL layer via the BIO. TODO(joth): consider stashing the error code, to
1071 // relay up to the SSL socket client (i.e. via DoReadCallback).
1073 transport_recv_eof_
= true;
1074 BIO_set_mem_eof_return(transport_bio_
, 0);
1075 (void)BIO_shutdown_wr(transport_bio_
);
1077 DCHECK(recv_buffer_
);
1078 int ret
= BIO_write(transport_bio_
, recv_buffer_
->data(), result
);
1079 // A write into a memory BIO should always succeed.
1080 CHECK_EQ(result
, ret
);
1082 recv_buffer_
= NULL
;
1083 transport_recv_busy_
= false;
1086 void SSLClientSocketOpenSSL::DoConnectCallback(int rv
) {
1087 if (!user_connect_callback_
.is_null()) {
1088 CompletionCallback c
= user_connect_callback_
;
1089 user_connect_callback_
.Reset();
1090 c
.Run(rv
> OK
? OK
: rv
);
1094 void SSLClientSocketOpenSSL::OnHandshakeIOComplete(int result
) {
1095 int rv
= DoHandshakeLoop(result
);
1096 if (rv
!= ERR_IO_PENDING
) {
1097 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_CONNECT
, rv
);
1098 DoConnectCallback(rv
);
1102 void SSLClientSocketOpenSSL::OnSendComplete(int result
) {
1103 if (next_handshake_state_
== STATE_HANDSHAKE
) {
1104 // In handshake phase.
1105 OnHandshakeIOComplete(result
);
1109 // OnSendComplete may need to call DoPayloadRead while the renegotiation
1110 // handshake is in progress.
1111 int rv_read
= ERR_IO_PENDING
;
1112 int rv_write
= ERR_IO_PENDING
;
1116 rv_read
= DoPayloadRead();
1117 if (user_write_buf_
)
1118 rv_write
= DoPayloadWrite();
1119 network_moved
= DoTransportIO();
1120 } while (rv_read
== ERR_IO_PENDING
&&
1121 rv_write
== ERR_IO_PENDING
&&
1122 (user_read_buf_
|| user_write_buf_
) &&
1125 if (user_read_buf_
&& rv_read
!= ERR_IO_PENDING
)
1126 DoReadCallback(rv_read
);
1127 if (user_write_buf_
&& rv_write
!= ERR_IO_PENDING
)
1128 DoWriteCallback(rv_write
);
1131 void SSLClientSocketOpenSSL::OnRecvComplete(int result
) {
1132 if (next_handshake_state_
== STATE_HANDSHAKE
) {
1133 // In handshake phase.
1134 OnHandshakeIOComplete(result
);
1138 // Network layer received some data, check if client requested to read
1140 if (!user_read_buf_
)
1143 int rv
= DoReadLoop(result
);
1144 if (rv
!= ERR_IO_PENDING
)
1148 bool SSLClientSocketOpenSSL::IsConnected() const {
1149 bool ret
= completed_handshake_
&& transport_
->socket()->IsConnected();
1153 bool SSLClientSocketOpenSSL::IsConnectedAndIdle() const {
1154 bool ret
= completed_handshake_
&& transport_
->socket()->IsConnectedAndIdle();
1158 int SSLClientSocketOpenSSL::GetPeerAddress(IPEndPoint
* addressList
) const {
1159 return transport_
->socket()->GetPeerAddress(addressList
);
1162 int SSLClientSocketOpenSSL::GetLocalAddress(IPEndPoint
* addressList
) const {
1163 return transport_
->socket()->GetLocalAddress(addressList
);
1166 const BoundNetLog
& SSLClientSocketOpenSSL::NetLog() const {
1170 void SSLClientSocketOpenSSL::SetSubresourceSpeculation() {
1171 if (transport_
.get() && transport_
->socket()) {
1172 transport_
->socket()->SetSubresourceSpeculation();
1178 void SSLClientSocketOpenSSL::SetOmniboxSpeculation() {
1179 if (transport_
.get() && transport_
->socket()) {
1180 transport_
->socket()->SetOmniboxSpeculation();
1186 bool SSLClientSocketOpenSSL::WasEverUsed() const {
1187 if (transport_
.get() && transport_
->socket())
1188 return transport_
->socket()->WasEverUsed();
1194 bool SSLClientSocketOpenSSL::UsingTCPFastOpen() const {
1195 if (transport_
.get() && transport_
->socket())
1196 return transport_
->socket()->UsingTCPFastOpen();
1202 int64
SSLClientSocketOpenSSL::NumBytesRead() const {
1203 if (transport_
.get() && transport_
->socket())
1204 return transport_
->socket()->NumBytesRead();
1210 base::TimeDelta
SSLClientSocketOpenSSL::GetConnectTimeMicros() const {
1211 if (transport_
.get() && transport_
->socket())
1212 return transport_
->socket()->GetConnectTimeMicros();
1215 return base::TimeDelta::FromMicroseconds(-1);
1220 int SSLClientSocketOpenSSL::Read(IOBuffer
* buf
,
1222 const CompletionCallback
& callback
) {
1223 user_read_buf_
= buf
;
1224 user_read_buf_len_
= buf_len
;
1226 int rv
= DoReadLoop(OK
);
1228 if (rv
== ERR_IO_PENDING
) {
1229 user_read_callback_
= callback
;
1231 user_read_buf_
= NULL
;
1232 user_read_buf_len_
= 0;
1238 int SSLClientSocketOpenSSL::DoReadLoop(int result
) {
1245 rv
= DoPayloadRead();
1246 network_moved
= DoTransportIO();
1247 } while (rv
== ERR_IO_PENDING
&& network_moved
);
1252 int SSLClientSocketOpenSSL::Write(IOBuffer
* buf
,
1254 const CompletionCallback
& callback
) {
1255 user_write_buf_
= buf
;
1256 user_write_buf_len_
= buf_len
;
1258 int rv
= DoWriteLoop(OK
);
1260 if (rv
== ERR_IO_PENDING
) {
1261 user_write_callback_
= callback
;
1263 user_write_buf_
= NULL
;
1264 user_write_buf_len_
= 0;
1270 int SSLClientSocketOpenSSL::DoWriteLoop(int result
) {
1277 rv
= DoPayloadWrite();
1278 network_moved
= DoTransportIO();
1279 } while (rv
== ERR_IO_PENDING
&& network_moved
);
1284 bool SSLClientSocketOpenSSL::SetReceiveBufferSize(int32 size
) {
1285 return transport_
->socket()->SetReceiveBufferSize(size
);
1288 bool SSLClientSocketOpenSSL::SetSendBufferSize(int32 size
) {
1289 return transport_
->socket()->SetSendBufferSize(size
);
1292 int SSLClientSocketOpenSSL::DoPayloadRead() {
1293 crypto::OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
1294 int rv
= SSL_read(ssl_
, user_read_buf_
->data(), user_read_buf_len_
);
1295 // We don't need to invalidate the non-client-authenticated SSL session
1296 // because the server will renegotiate anyway.
1297 if (client_auth_cert_needed_
)
1298 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED
;
1301 net_log_
.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED
, rv
,
1302 user_read_buf_
->data());
1306 int err
= SSL_get_error(ssl_
, rv
);
1307 return MapOpenSSLError(err
, err_tracer
);
1310 int SSLClientSocketOpenSSL::DoPayloadWrite() {
1311 crypto::OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
1312 int rv
= SSL_write(ssl_
, user_write_buf_
->data(), user_write_buf_len_
);
1315 net_log_
.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_SENT
, rv
,
1316 user_write_buf_
->data());
1320 int err
= SSL_get_error(ssl_
, rv
);
1321 return MapOpenSSLError(err
, err_tracer
);