Update V8 to version 4.7.47.
[chromium-blink-merge.git] / net / socket / ssl_server_socket_openssl.cc
blob5a61eeb3063cd4d8a56fcc2fc3d37aaab24679b5
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/socket/ssl_server_socket_openssl.h"
7 #include <openssl/err.h>
8 #include <openssl/ssl.h>
10 #include "base/callback_helpers.h"
11 #include "base/logging.h"
12 #include "base/strings/string_util.h"
13 #include "crypto/openssl_util.h"
14 #include "crypto/rsa_private_key.h"
15 #include "crypto/scoped_openssl_types.h"
16 #include "net/base/net_errors.h"
17 #include "net/ssl/openssl_ssl_util.h"
18 #include "net/ssl/scoped_openssl_types.h"
20 #define GotoState(s) next_handshake_state_ = s
22 namespace net {
24 void EnableSSLServerSockets() {
25 // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit().
28 scoped_ptr<SSLServerSocket> CreateSSLServerSocket(
29 scoped_ptr<StreamSocket> socket,
30 X509Certificate* certificate,
31 crypto::RSAPrivateKey* key,
32 const SSLConfig& ssl_config) {
33 crypto::EnsureOpenSSLInit();
34 return scoped_ptr<SSLServerSocket>(
35 new SSLServerSocketOpenSSL(socket.Pass(), certificate, key, ssl_config));
38 SSLServerSocketOpenSSL::SSLServerSocketOpenSSL(
39 scoped_ptr<StreamSocket> transport_socket,
40 scoped_refptr<X509Certificate> certificate,
41 crypto::RSAPrivateKey* key,
42 const SSLConfig& ssl_config)
43 : transport_send_busy_(false),
44 transport_recv_busy_(false),
45 transport_recv_eof_(false),
46 user_read_buf_len_(0),
47 user_write_buf_len_(0),
48 transport_write_error_(OK),
49 ssl_(NULL),
50 transport_bio_(NULL),
51 transport_socket_(transport_socket.Pass()),
52 ssl_config_(ssl_config),
53 cert_(certificate),
54 next_handshake_state_(STATE_NONE),
55 completed_handshake_(false) {
56 // TODO(byungchul): Need a better way to clone a key.
57 std::vector<uint8> key_bytes;
58 CHECK(key->ExportPrivateKey(&key_bytes));
59 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes));
60 CHECK(key_.get());
63 SSLServerSocketOpenSSL::~SSLServerSocketOpenSSL() {
64 if (ssl_) {
65 // Calling SSL_shutdown prevents the session from being marked as
66 // unresumable.
67 SSL_shutdown(ssl_);
68 SSL_free(ssl_);
69 ssl_ = NULL;
71 if (transport_bio_) {
72 BIO_free_all(transport_bio_);
73 transport_bio_ = NULL;
77 int SSLServerSocketOpenSSL::Handshake(const CompletionCallback& callback) {
78 net_log_.BeginEvent(NetLog::TYPE_SSL_SERVER_HANDSHAKE);
80 // Set up new ssl object.
81 int rv = Init();
82 if (rv != OK) {
83 LOG(ERROR) << "Failed to initialize OpenSSL: rv=" << rv;
84 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv);
85 return rv;
88 // Set SSL to server mode. Handshake happens in the loop below.
89 SSL_set_accept_state(ssl_);
91 GotoState(STATE_HANDSHAKE);
92 rv = DoHandshakeLoop(OK);
93 if (rv == ERR_IO_PENDING) {
94 user_handshake_callback_ = callback;
95 } else {
96 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv);
99 return rv > OK ? OK : rv;
102 int SSLServerSocketOpenSSL::ExportKeyingMaterial(
103 const base::StringPiece& label,
104 bool has_context,
105 const base::StringPiece& context,
106 unsigned char* out,
107 unsigned int outlen) {
108 if (!IsConnected())
109 return ERR_SOCKET_NOT_CONNECTED;
111 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
113 int rv = SSL_export_keying_material(
114 ssl_, out, outlen, label.data(), label.size(),
115 reinterpret_cast<const unsigned char*>(context.data()),
116 context.length(), context.length() > 0);
118 if (rv != 1) {
119 int ssl_error = SSL_get_error(ssl_, rv);
120 LOG(ERROR) << "Failed to export keying material;"
121 << " returned " << rv
122 << ", SSL error code " << ssl_error;
123 return MapOpenSSLError(ssl_error, err_tracer);
125 return OK;
128 int SSLServerSocketOpenSSL::GetTLSUniqueChannelBinding(std::string* out) {
129 NOTIMPLEMENTED();
130 return ERR_NOT_IMPLEMENTED;
133 int SSLServerSocketOpenSSL::Read(IOBuffer* buf, int buf_len,
134 const CompletionCallback& callback) {
135 DCHECK(user_read_callback_.is_null());
136 DCHECK(user_handshake_callback_.is_null());
137 DCHECK(!user_read_buf_.get());
138 DCHECK(!callback.is_null());
140 user_read_buf_ = buf;
141 user_read_buf_len_ = buf_len;
143 DCHECK(completed_handshake_);
145 int rv = DoReadLoop(OK);
147 if (rv == ERR_IO_PENDING) {
148 user_read_callback_ = callback;
149 } else {
150 user_read_buf_ = NULL;
151 user_read_buf_len_ = 0;
154 return rv;
157 int SSLServerSocketOpenSSL::Write(IOBuffer* buf, int buf_len,
158 const CompletionCallback& callback) {
159 DCHECK(user_write_callback_.is_null());
160 DCHECK(!user_write_buf_.get());
161 DCHECK(!callback.is_null());
163 user_write_buf_ = buf;
164 user_write_buf_len_ = buf_len;
166 int rv = DoWriteLoop(OK);
168 if (rv == ERR_IO_PENDING) {
169 user_write_callback_ = callback;
170 } else {
171 user_write_buf_ = NULL;
172 user_write_buf_len_ = 0;
174 return rv;
177 int SSLServerSocketOpenSSL::SetReceiveBufferSize(int32 size) {
178 return transport_socket_->SetReceiveBufferSize(size);
181 int SSLServerSocketOpenSSL::SetSendBufferSize(int32 size) {
182 return transport_socket_->SetSendBufferSize(size);
185 int SSLServerSocketOpenSSL::Connect(const CompletionCallback& callback) {
186 NOTIMPLEMENTED();
187 return ERR_NOT_IMPLEMENTED;
190 void SSLServerSocketOpenSSL::Disconnect() {
191 transport_socket_->Disconnect();
194 bool SSLServerSocketOpenSSL::IsConnected() const {
195 // TODO(wtc): Find out if we should check transport_socket_->IsConnected()
196 // as well.
197 return completed_handshake_;
200 bool SSLServerSocketOpenSSL::IsConnectedAndIdle() const {
201 return completed_handshake_ && transport_socket_->IsConnectedAndIdle();
204 int SSLServerSocketOpenSSL::GetPeerAddress(IPEndPoint* address) const {
205 if (!IsConnected())
206 return ERR_SOCKET_NOT_CONNECTED;
207 return transport_socket_->GetPeerAddress(address);
210 int SSLServerSocketOpenSSL::GetLocalAddress(IPEndPoint* address) const {
211 if (!IsConnected())
212 return ERR_SOCKET_NOT_CONNECTED;
213 return transport_socket_->GetLocalAddress(address);
216 const BoundNetLog& SSLServerSocketOpenSSL::NetLog() const {
217 return net_log_;
220 void SSLServerSocketOpenSSL::SetSubresourceSpeculation() {
221 transport_socket_->SetSubresourceSpeculation();
224 void SSLServerSocketOpenSSL::SetOmniboxSpeculation() {
225 transport_socket_->SetOmniboxSpeculation();
228 bool SSLServerSocketOpenSSL::WasEverUsed() const {
229 return transport_socket_->WasEverUsed();
232 bool SSLServerSocketOpenSSL::UsingTCPFastOpen() const {
233 return transport_socket_->UsingTCPFastOpen();
236 bool SSLServerSocketOpenSSL::WasNpnNegotiated() const {
237 NOTIMPLEMENTED();
238 return false;
241 NextProto SSLServerSocketOpenSSL::GetNegotiatedProtocol() const {
242 // NPN is not supported by this class.
243 return kProtoUnknown;
246 bool SSLServerSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) {
247 NOTIMPLEMENTED();
248 return false;
251 void SSLServerSocketOpenSSL::GetConnectionAttempts(
252 ConnectionAttempts* out) const {
253 out->clear();
256 void SSLServerSocketOpenSSL::OnSendComplete(int result) {
257 if (next_handshake_state_ == STATE_HANDSHAKE) {
258 // In handshake phase.
259 OnHandshakeIOComplete(result);
260 return;
263 // TODO(byungchul): This state machine is not correct. Copy the state machine
264 // of SSLClientSocketOpenSSL::OnSendComplete() which handles it better.
265 if (!completed_handshake_)
266 return;
268 if (user_write_buf_.get()) {
269 int rv = DoWriteLoop(result);
270 if (rv != ERR_IO_PENDING)
271 DoWriteCallback(rv);
272 } else {
273 // Ensure that any queued ciphertext is flushed.
274 DoTransportIO();
278 void SSLServerSocketOpenSSL::OnRecvComplete(int result) {
279 if (next_handshake_state_ == STATE_HANDSHAKE) {
280 // In handshake phase.
281 OnHandshakeIOComplete(result);
282 return;
285 // Network layer received some data, check if client requested to read
286 // decrypted data.
287 if (!user_read_buf_.get() || !completed_handshake_)
288 return;
290 int rv = DoReadLoop(result);
291 if (rv != ERR_IO_PENDING)
292 DoReadCallback(rv);
295 void SSLServerSocketOpenSSL::OnHandshakeIOComplete(int result) {
296 int rv = DoHandshakeLoop(result);
297 if (rv == ERR_IO_PENDING)
298 return;
300 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv);
301 if (!user_handshake_callback_.is_null())
302 DoHandshakeCallback(rv);
305 // Return 0 for EOF,
306 // > 0 for bytes transferred immediately,
307 // < 0 for error (or the non-error ERR_IO_PENDING).
308 int SSLServerSocketOpenSSL::BufferSend() {
309 if (transport_send_busy_)
310 return ERR_IO_PENDING;
312 if (!send_buffer_.get()) {
313 // Get a fresh send buffer out of the send BIO.
314 size_t max_read = BIO_pending(transport_bio_);
315 if (!max_read)
316 return 0; // Nothing pending in the OpenSSL write BIO.
317 send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read);
318 int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read);
319 DCHECK_GT(read_bytes, 0);
320 CHECK_EQ(static_cast<int>(max_read), read_bytes);
323 int rv = transport_socket_->Write(
324 send_buffer_.get(),
325 send_buffer_->BytesRemaining(),
326 base::Bind(&SSLServerSocketOpenSSL::BufferSendComplete,
327 base::Unretained(this)));
328 if (rv == ERR_IO_PENDING) {
329 transport_send_busy_ = true;
330 } else {
331 TransportWriteComplete(rv);
333 return rv;
336 void SSLServerSocketOpenSSL::BufferSendComplete(int result) {
337 transport_send_busy_ = false;
338 TransportWriteComplete(result);
339 OnSendComplete(result);
342 void SSLServerSocketOpenSSL::TransportWriteComplete(int result) {
343 DCHECK(ERR_IO_PENDING != result);
344 if (result < 0) {
345 // Got a socket write error; close the BIO to indicate this upward.
347 // TODO(davidben): The value of |result| gets lost. Feed the error back into
348 // the BIO so it gets (re-)detected in OnSendComplete. Perhaps with
349 // BIO_set_callback.
350 DVLOG(1) << "TransportWriteComplete error " << result;
351 (void)BIO_shutdown_wr(SSL_get_wbio(ssl_));
353 // Match the fix for http://crbug.com/249848 in NSS by erroring future reads
354 // from the socket after a write error.
356 // TODO(davidben): Avoid having read and write ends interact this way.
357 transport_write_error_ = result;
358 (void)BIO_shutdown_wr(transport_bio_);
359 send_buffer_ = NULL;
360 } else {
361 DCHECK(send_buffer_.get());
362 send_buffer_->DidConsume(result);
363 DCHECK_GE(send_buffer_->BytesRemaining(), 0);
364 if (send_buffer_->BytesRemaining() <= 0)
365 send_buffer_ = NULL;
369 int SSLServerSocketOpenSSL::BufferRecv() {
370 if (transport_recv_busy_)
371 return ERR_IO_PENDING;
373 // Determine how much was requested from |transport_bio_| that was not
374 // actually available.
375 size_t requested = BIO_ctrl_get_read_request(transport_bio_);
376 if (requested == 0) {
377 // This is not a perfect match of error codes, as no operation is
378 // actually pending. However, returning 0 would be interpreted as
379 // a possible sign of EOF, which is also an inappropriate match.
380 return ERR_IO_PENDING;
383 // Known Issue: While only reading |requested| data is the more correct
384 // implementation, it has the downside of resulting in frequent reads:
385 // One read for the SSL record header (~5 bytes) and one read for the SSL
386 // record body. Rather than issuing these reads to the underlying socket
387 // (and constantly allocating new IOBuffers), a single Read() request to
388 // fill |transport_bio_| is issued. As long as an SSL client socket cannot
389 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL
390 // traffic, this over-subscribed Read()ing will not cause issues.
391 size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_);
392 if (!max_write)
393 return ERR_IO_PENDING;
395 recv_buffer_ = new IOBuffer(max_write);
396 int rv = transport_socket_->Read(
397 recv_buffer_.get(),
398 max_write,
399 base::Bind(&SSLServerSocketOpenSSL::BufferRecvComplete,
400 base::Unretained(this)));
401 if (rv == ERR_IO_PENDING) {
402 transport_recv_busy_ = true;
403 } else {
404 rv = TransportReadComplete(rv);
406 return rv;
409 void SSLServerSocketOpenSSL::BufferRecvComplete(int result) {
410 result = TransportReadComplete(result);
411 OnRecvComplete(result);
414 int SSLServerSocketOpenSSL::TransportReadComplete(int result) {
415 DCHECK(ERR_IO_PENDING != result);
416 if (result <= 0) {
417 DVLOG(1) << "TransportReadComplete result " << result;
418 // Received 0 (end of file) or an error. Either way, bubble it up to the
419 // SSL layer via the BIO. TODO(joth): consider stashing the error code, to
420 // relay up to the SSL socket client (i.e. via DoReadCallback).
421 if (result == 0)
422 transport_recv_eof_ = true;
423 (void)BIO_shutdown_wr(transport_bio_);
424 } else if (transport_write_error_ < 0) {
425 // Mirror transport write errors as read failures; transport_bio_ has been
426 // shut down by TransportWriteComplete, so the BIO_write will fail, failing
427 // the CHECK. http://crbug.com/335557.
428 result = transport_write_error_;
429 } else {
430 DCHECK(recv_buffer_.get());
431 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result);
432 // A write into a memory BIO should always succeed.
433 DCHECK_EQ(result, ret);
435 recv_buffer_ = NULL;
436 transport_recv_busy_ = false;
437 return result;
440 // Do as much network I/O as possible between the buffer and the
441 // transport socket. Return true if some I/O performed, false
442 // otherwise (error or ERR_IO_PENDING).
443 bool SSLServerSocketOpenSSL::DoTransportIO() {
444 bool network_moved = false;
445 int rv;
446 // Read and write as much data as possible. The loop is necessary because
447 // Write() may return synchronously.
448 do {
449 rv = BufferSend();
450 if (rv != ERR_IO_PENDING && rv != 0)
451 network_moved = true;
452 } while (rv > 0);
453 if (!transport_recv_eof_ && BufferRecv() != ERR_IO_PENDING)
454 network_moved = true;
455 return network_moved;
458 int SSLServerSocketOpenSSL::DoPayloadRead() {
459 DCHECK(user_read_buf_.get());
460 DCHECK_GT(user_read_buf_len_, 0);
461 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
462 int rv = SSL_read(ssl_, user_read_buf_->data(), user_read_buf_len_);
463 if (rv >= 0)
464 return rv;
465 int ssl_error = SSL_get_error(ssl_, rv);
466 OpenSSLErrorInfo error_info;
467 int net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer,
468 &error_info);
469 if (net_error != ERR_IO_PENDING) {
470 net_log_.AddEvent(
471 NetLog::TYPE_SSL_READ_ERROR,
472 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
474 return net_error;
477 int SSLServerSocketOpenSSL::DoPayloadWrite() {
478 DCHECK(user_write_buf_.get());
479 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
480 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
481 if (rv >= 0)
482 return rv;
483 int ssl_error = SSL_get_error(ssl_, rv);
484 OpenSSLErrorInfo error_info;
485 int net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer,
486 &error_info);
487 if (net_error != ERR_IO_PENDING) {
488 net_log_.AddEvent(
489 NetLog::TYPE_SSL_WRITE_ERROR,
490 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
492 return net_error;
495 int SSLServerSocketOpenSSL::DoHandshakeLoop(int last_io_result) {
496 int rv = last_io_result;
497 do {
498 // Default to STATE_NONE for next state.
499 // (This is a quirk carried over from the windows
500 // implementation. It makes reading the logs a bit harder.)
501 // State handlers can and often do call GotoState just
502 // to stay in the current state.
503 State state = next_handshake_state_;
504 GotoState(STATE_NONE);
505 switch (state) {
506 case STATE_HANDSHAKE:
507 rv = DoHandshake();
508 break;
509 case STATE_NONE:
510 default:
511 rv = ERR_UNEXPECTED;
512 LOG(DFATAL) << "unexpected state " << state;
513 break;
516 // Do the actual network I/O
517 bool network_moved = DoTransportIO();
518 if (network_moved && next_handshake_state_ == STATE_HANDSHAKE) {
519 // In general we exit the loop if rv is ERR_IO_PENDING. In this
520 // special case we keep looping even if rv is ERR_IO_PENDING because
521 // the transport IO may allow DoHandshake to make progress.
522 rv = OK; // This causes us to stay in the loop.
524 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
525 return rv;
528 int SSLServerSocketOpenSSL::DoReadLoop(int result) {
529 DCHECK(completed_handshake_);
530 DCHECK(next_handshake_state_ == STATE_NONE);
532 if (result < 0)
533 return result;
535 bool network_moved;
536 int rv;
537 do {
538 rv = DoPayloadRead();
539 network_moved = DoTransportIO();
540 } while (rv == ERR_IO_PENDING && network_moved);
541 return rv;
544 int SSLServerSocketOpenSSL::DoWriteLoop(int result) {
545 DCHECK(completed_handshake_);
546 DCHECK_EQ(next_handshake_state_, STATE_NONE);
548 if (result < 0)
549 return result;
551 bool network_moved;
552 int rv;
553 do {
554 rv = DoPayloadWrite();
555 network_moved = DoTransportIO();
556 } while (rv == ERR_IO_PENDING && network_moved);
557 return rv;
560 int SSLServerSocketOpenSSL::DoHandshake() {
561 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
562 int net_error = OK;
563 int rv = SSL_do_handshake(ssl_);
565 if (rv == 1) {
566 completed_handshake_ = true;
567 } else {
568 int ssl_error = SSL_get_error(ssl_, rv);
569 OpenSSLErrorInfo error_info;
570 net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info);
572 // If not done, stay in this state
573 if (net_error == ERR_IO_PENDING) {
574 GotoState(STATE_HANDSHAKE);
575 } else {
576 LOG(ERROR) << "handshake failed; returned " << rv
577 << ", SSL error code " << ssl_error
578 << ", net_error " << net_error;
579 net_log_.AddEvent(
580 NetLog::TYPE_SSL_HANDSHAKE_ERROR,
581 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
584 return net_error;
587 void SSLServerSocketOpenSSL::DoHandshakeCallback(int rv) {
588 DCHECK_NE(rv, ERR_IO_PENDING);
589 ResetAndReturn(&user_handshake_callback_).Run(rv > OK ? OK : rv);
592 void SSLServerSocketOpenSSL::DoReadCallback(int rv) {
593 DCHECK(rv != ERR_IO_PENDING);
594 DCHECK(!user_read_callback_.is_null());
596 user_read_buf_ = NULL;
597 user_read_buf_len_ = 0;
598 ResetAndReturn(&user_read_callback_).Run(rv);
601 void SSLServerSocketOpenSSL::DoWriteCallback(int rv) {
602 DCHECK(rv != ERR_IO_PENDING);
603 DCHECK(!user_write_callback_.is_null());
605 user_write_buf_ = NULL;
606 user_write_buf_len_ = 0;
607 ResetAndReturn(&user_write_callback_).Run(rv);
610 int SSLServerSocketOpenSSL::Init() {
611 DCHECK(!ssl_);
612 DCHECK(!transport_bio_);
614 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
616 ScopedSSL_CTX ssl_ctx(SSL_CTX_new(SSLv23_server_method()));
617 ssl_ = SSL_new(ssl_ctx.get());
618 if (!ssl_)
619 return ERR_UNEXPECTED;
621 BIO* ssl_bio = NULL;
622 // 0 => use default buffer sizes.
623 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0))
624 return ERR_UNEXPECTED;
625 DCHECK(ssl_bio);
626 DCHECK(transport_bio_);
628 SSL_set_bio(ssl_, ssl_bio, ssl_bio);
630 // Set certificate and private key.
631 DCHECK(cert_->os_cert_handle());
632 #if defined(USE_OPENSSL_CERTS)
633 if (SSL_use_certificate(ssl_, cert_->os_cert_handle()) != 1) {
634 LOG(ERROR) << "Cannot set certificate.";
635 return ERR_UNEXPECTED;
637 #else
638 // Convert OSCertHandle to X509 structure.
639 std::string der_string;
640 if (!X509Certificate::GetDEREncoded(cert_->os_cert_handle(), &der_string))
641 return ERR_UNEXPECTED;
643 const unsigned char* der_string_array =
644 reinterpret_cast<const unsigned char*>(der_string.data());
646 ScopedX509 x509(d2i_X509(NULL, &der_string_array, der_string.length()));
647 if (!x509.get())
648 return ERR_UNEXPECTED;
650 // On success, SSL_use_certificate acquires a reference to |x509|.
651 if (SSL_use_certificate(ssl_, x509.get()) != 1) {
652 LOG(ERROR) << "Cannot set certificate.";
653 return ERR_UNEXPECTED;
655 #endif // USE_OPENSSL_CERTS
657 DCHECK(key_->key());
658 if (SSL_use_PrivateKey(ssl_, key_->key()) != 1) {
659 LOG(ERROR) << "Cannot set private key.";
660 return ERR_UNEXPECTED;
663 DCHECK_LT(SSL3_VERSION, ssl_config_.version_min);
664 DCHECK_LT(SSL3_VERSION, ssl_config_.version_max);
665 SSL_set_min_version(ssl_, ssl_config_.version_min);
666 SSL_set_max_version(ssl_, ssl_config_.version_max);
668 // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
669 // set everything we care about to an absolute value.
670 SslSetClearMask options;
671 options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true);
673 SSL_set_options(ssl_, options.set_mask);
674 SSL_clear_options(ssl_, options.clear_mask);
676 // Same as above, this time for the SSL mode.
677 SslSetClearMask mode;
679 mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true);
681 SSL_set_mode(ssl_, mode.set_mask);
682 SSL_clear_mode(ssl_, mode.clear_mask);
684 // Removing ciphers by ID from OpenSSL is a bit involved as we must use the
685 // textual name with SSL_set_cipher_list because there is no public API to
686 // directly remove a cipher by ID.
687 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl_);
688 DCHECK(ciphers);
689 // See SSLConfig::disabled_cipher_suites for description of the suites
690 // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256
691 // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384
692 // as the handshake hash.
693 std::string command("DEFAULT:!SHA256:!SHA384:!AESGCM+AES256:!aPSK");
694 // Walk through all the installed ciphers, seeing if any need to be
695 // appended to the cipher removal |command|.
696 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) {
697 const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i);
698 const uint16_t id = static_cast<uint16_t>(SSL_CIPHER_get_id(cipher));
700 bool disable = false;
701 if (ssl_config_.require_ecdhe) {
702 base::StringPiece kx_name(SSL_CIPHER_get_kx_name(cipher));
703 disable = kx_name != "ECDHE_RSA" && kx_name != "ECDHE_ECDSA";
705 if (!disable) {
706 disable = std::find(ssl_config_.disabled_cipher_suites.begin(),
707 ssl_config_.disabled_cipher_suites.end(),
708 id) != ssl_config_.disabled_cipher_suites.end();
710 if (disable) {
711 const char* name = SSL_CIPHER_get_name(cipher);
712 DVLOG(3) << "Found cipher to remove: '" << name << "', ID: " << id
713 << " strength: " << SSL_CIPHER_get_bits(cipher, NULL);
714 command.append(":!");
715 command.append(name);
719 int rv = SSL_set_cipher_list(ssl_, command.c_str());
720 // If this fails (rv = 0) it means there are no ciphers enabled on this SSL.
721 // This will almost certainly result in the socket failing to complete the
722 // handshake at which point the appropriate error is bubbled up to the client.
723 LOG_IF(WARNING, rv != 1) << "SSL_set_cipher_list('" << command
724 << "') returned " << rv;
726 return OK;
729 } // namespace net