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
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
),
51 transport_socket_(transport_socket
.Pass()),
52 ssl_config_(ssl_config
),
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
));
63 SSLServerSocketOpenSSL::~SSLServerSocketOpenSSL() {
65 // Calling SSL_shutdown prevents the session from being marked as
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.
83 LOG(ERROR
) << "Failed to initialize OpenSSL: rv=" << rv
;
84 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE
, 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
;
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
,
105 const base::StringPiece
& context
,
107 unsigned int outlen
) {
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);
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
);
128 int SSLServerSocketOpenSSL::GetTLSUniqueChannelBinding(std::string
* out
) {
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
;
150 user_read_buf_
= NULL
;
151 user_read_buf_len_
= 0;
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
;
171 user_write_buf_
= NULL
;
172 user_write_buf_len_
= 0;
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
) {
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()
197 return completed_handshake_
;
200 bool SSLServerSocketOpenSSL::IsConnectedAndIdle() const {
201 return completed_handshake_
&& transport_socket_
->IsConnectedAndIdle();
204 int SSLServerSocketOpenSSL::GetPeerAddress(IPEndPoint
* address
) const {
206 return ERR_SOCKET_NOT_CONNECTED
;
207 return transport_socket_
->GetPeerAddress(address
);
210 int SSLServerSocketOpenSSL::GetLocalAddress(IPEndPoint
* address
) const {
212 return ERR_SOCKET_NOT_CONNECTED
;
213 return transport_socket_
->GetLocalAddress(address
);
216 const BoundNetLog
& SSLServerSocketOpenSSL::NetLog() const {
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 {
241 NextProto
SSLServerSocketOpenSSL::GetNegotiatedProtocol() const {
242 // NPN is not supported by this class.
243 return kProtoUnknown
;
246 bool SSLServerSocketOpenSSL::GetSSLInfo(SSLInfo
* ssl_info
) {
251 void SSLServerSocketOpenSSL::GetConnectionAttempts(
252 ConnectionAttempts
* out
) const {
256 void SSLServerSocketOpenSSL::OnSendComplete(int result
) {
257 if (next_handshake_state_
== STATE_HANDSHAKE
) {
258 // In handshake phase.
259 OnHandshakeIOComplete(result
);
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_
)
268 if (user_write_buf_
.get()) {
269 int rv
= DoWriteLoop(result
);
270 if (rv
!= ERR_IO_PENDING
)
273 // Ensure that any queued ciphertext is flushed.
278 void SSLServerSocketOpenSSL::OnRecvComplete(int result
) {
279 if (next_handshake_state_
== STATE_HANDSHAKE
) {
280 // In handshake phase.
281 OnHandshakeIOComplete(result
);
285 // Network layer received some data, check if client requested to read
287 if (!user_read_buf_
.get() || !completed_handshake_
)
290 int rv
= DoReadLoop(result
);
291 if (rv
!= ERR_IO_PENDING
)
295 void SSLServerSocketOpenSSL::OnHandshakeIOComplete(int result
) {
296 int rv
= DoHandshakeLoop(result
);
297 if (rv
== ERR_IO_PENDING
)
300 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE
, rv
);
301 if (!user_handshake_callback_
.is_null())
302 DoHandshakeCallback(rv
);
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_
);
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(
325 send_buffer_
->BytesRemaining(),
326 base::Bind(&SSLServerSocketOpenSSL::BufferSendComplete
,
327 base::Unretained(this)));
328 if (rv
== ERR_IO_PENDING
) {
329 transport_send_busy_
= true;
331 TransportWriteComplete(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
);
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
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_
);
361 DCHECK(send_buffer_
.get());
362 send_buffer_
->DidConsume(result
);
363 DCHECK_GE(send_buffer_
->BytesRemaining(), 0);
364 if (send_buffer_
->BytesRemaining() <= 0)
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_
);
393 return ERR_IO_PENDING
;
395 recv_buffer_
= new IOBuffer(max_write
);
396 int rv
= transport_socket_
->Read(
399 base::Bind(&SSLServerSocketOpenSSL::BufferRecvComplete
,
400 base::Unretained(this)));
401 if (rv
== ERR_IO_PENDING
) {
402 transport_recv_busy_
= true;
404 rv
= TransportReadComplete(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
);
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).
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_
;
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
);
436 transport_recv_busy_
= false;
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;
446 // Read and write as much data as possible. The loop is necessary because
447 // Write() may return synchronously.
450 if (rv
!= ERR_IO_PENDING
&& rv
!= 0)
451 network_moved
= true;
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_
);
465 int ssl_error
= SSL_get_error(ssl_
, rv
);
466 OpenSSLErrorInfo error_info
;
467 int net_error
= MapOpenSSLErrorWithDetails(ssl_error
, err_tracer
,
469 if (net_error
!= ERR_IO_PENDING
) {
471 NetLog::TYPE_SSL_READ_ERROR
,
472 CreateNetLogOpenSSLErrorCallback(net_error
, ssl_error
, error_info
));
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_
);
483 int ssl_error
= SSL_get_error(ssl_
, rv
);
484 OpenSSLErrorInfo error_info
;
485 int net_error
= MapOpenSSLErrorWithDetails(ssl_error
, err_tracer
,
487 if (net_error
!= ERR_IO_PENDING
) {
489 NetLog::TYPE_SSL_WRITE_ERROR
,
490 CreateNetLogOpenSSLErrorCallback(net_error
, ssl_error
, error_info
));
495 int SSLServerSocketOpenSSL::DoHandshakeLoop(int last_io_result
) {
496 int rv
= last_io_result
;
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
);
506 case STATE_HANDSHAKE
:
512 LOG(DFATAL
) << "unexpected state " << state
;
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
);
528 int SSLServerSocketOpenSSL::DoReadLoop(int result
) {
529 DCHECK(completed_handshake_
);
530 DCHECK(next_handshake_state_
== STATE_NONE
);
538 rv
= DoPayloadRead();
539 network_moved
= DoTransportIO();
540 } while (rv
== ERR_IO_PENDING
&& network_moved
);
544 int SSLServerSocketOpenSSL::DoWriteLoop(int result
) {
545 DCHECK(completed_handshake_
);
546 DCHECK_EQ(next_handshake_state_
, STATE_NONE
);
554 rv
= DoPayloadWrite();
555 network_moved
= DoTransportIO();
556 } while (rv
== ERR_IO_PENDING
&& network_moved
);
560 int SSLServerSocketOpenSSL::DoHandshake() {
561 crypto::OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
563 int rv
= SSL_do_handshake(ssl_
);
566 completed_handshake_
= true;
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
);
576 LOG(ERROR
) << "handshake failed; returned " << rv
577 << ", SSL error code " << ssl_error
578 << ", net_error " << net_error
;
580 NetLog::TYPE_SSL_HANDSHAKE_ERROR
,
581 CreateNetLogOpenSSLErrorCallback(net_error
, ssl_error
, error_info
));
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() {
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());
619 return ERR_UNEXPECTED
;
622 // 0 => use default buffer sizes.
623 if (!BIO_new_bio_pair(&ssl_bio
, 0, &transport_bio_
, 0))
624 return ERR_UNEXPECTED
;
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
;
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()));
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
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_
);
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";
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();
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
;