Home | History | Annotate | Download | only in socket
      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.
      4 
      5 #include "net/socket/ssl_server_socket_openssl.h"
      6 
      7 #include <openssl/err.h>
      8 #include <openssl/ssl.h>
      9 
     10 #include "base/callback_helpers.h"
     11 #include "base/logging.h"
     12 #include "crypto/openssl_util.h"
     13 #include "crypto/rsa_private_key.h"
     14 #include "net/base/net_errors.h"
     15 #include "net/socket/openssl_ssl_util.h"
     16 #include "net/socket/ssl_error_params.h"
     17 
     18 #define GotoState(s) next_handshake_state_ = s
     19 
     20 namespace net {
     21 
     22 void EnableSSLServerSockets() {
     23   // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit().
     24 }
     25 
     26 scoped_ptr<SSLServerSocket> CreateSSLServerSocket(
     27     scoped_ptr<StreamSocket> socket,
     28     X509Certificate* certificate,
     29     crypto::RSAPrivateKey* key,
     30     const SSLConfig& ssl_config) {
     31   crypto::EnsureOpenSSLInit();
     32   return scoped_ptr<SSLServerSocket>(
     33       new SSLServerSocketOpenSSL(socket.Pass(), certificate, key, ssl_config));
     34 }
     35 
     36 SSLServerSocketOpenSSL::SSLServerSocketOpenSSL(
     37     scoped_ptr<StreamSocket> transport_socket,
     38     scoped_refptr<X509Certificate> certificate,
     39     crypto::RSAPrivateKey* key,
     40     const SSLConfig& ssl_config)
     41     : transport_send_busy_(false),
     42       transport_recv_busy_(false),
     43       transport_recv_eof_(false),
     44       user_read_buf_len_(0),
     45       user_write_buf_len_(0),
     46       transport_write_error_(OK),
     47       ssl_(NULL),
     48       transport_bio_(NULL),
     49       transport_socket_(transport_socket.Pass()),
     50       ssl_config_(ssl_config),
     51       cert_(certificate),
     52       next_handshake_state_(STATE_NONE),
     53       completed_handshake_(false) {
     54   // TODO(byungchul): Need a better way to clone a key.
     55   std::vector<uint8> key_bytes;
     56   CHECK(key->ExportPrivateKey(&key_bytes));
     57   key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes));
     58   CHECK(key_.get());
     59 }
     60 
     61 SSLServerSocketOpenSSL::~SSLServerSocketOpenSSL() {
     62   if (ssl_) {
     63     // Calling SSL_shutdown prevents the session from being marked as
     64     // unresumable.
     65     SSL_shutdown(ssl_);
     66     SSL_free(ssl_);
     67     ssl_ = NULL;
     68   }
     69   if (transport_bio_) {
     70     BIO_free_all(transport_bio_);
     71     transport_bio_ = NULL;
     72   }
     73 }
     74 
     75 int SSLServerSocketOpenSSL::Handshake(const CompletionCallback& callback) {
     76   net_log_.BeginEvent(NetLog::TYPE_SSL_SERVER_HANDSHAKE);
     77 
     78   // Set up new ssl object.
     79   int rv = Init();
     80   if (rv != OK) {
     81     LOG(ERROR) << "Failed to initialize OpenSSL: rv=" << rv;
     82     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv);
     83     return rv;
     84   }
     85 
     86   // Set SSL to server mode. Handshake happens in the loop below.
     87   SSL_set_accept_state(ssl_);
     88 
     89   GotoState(STATE_HANDSHAKE);
     90   rv = DoHandshakeLoop(OK);
     91   if (rv == ERR_IO_PENDING) {
     92     user_handshake_callback_ = callback;
     93   } else {
     94     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv);
     95   }
     96 
     97   return rv > OK ? OK : rv;
     98 }
     99 
    100 int SSLServerSocketOpenSSL::ExportKeyingMaterial(
    101     const base::StringPiece& label,
    102     bool has_context,
    103     const base::StringPiece& context,
    104     unsigned char* out,
    105     unsigned int outlen) {
    106   if (!IsConnected())
    107     return ERR_SOCKET_NOT_CONNECTED;
    108 
    109   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
    110 
    111   int rv = SSL_export_keying_material(
    112       ssl_, out, outlen, label.data(), label.size(),
    113       reinterpret_cast<const unsigned char*>(context.data()),
    114       context.length(), context.length() > 0);
    115 
    116   if (rv != 1) {
    117     int ssl_error = SSL_get_error(ssl_, rv);
    118     LOG(ERROR) << "Failed to export keying material;"
    119                << " returned " << rv
    120                << ", SSL error code " << ssl_error;
    121     return MapOpenSSLError(ssl_error, err_tracer);
    122   }
    123   return OK;
    124 }
    125 
    126 int SSLServerSocketOpenSSL::GetTLSUniqueChannelBinding(std::string* out) {
    127   NOTIMPLEMENTED();
    128   return ERR_NOT_IMPLEMENTED;
    129 }
    130 
    131 int SSLServerSocketOpenSSL::Read(IOBuffer* buf, int buf_len,
    132                                  const CompletionCallback& callback) {
    133   DCHECK(user_read_callback_.is_null());
    134   DCHECK(user_handshake_callback_.is_null());
    135   DCHECK(!user_read_buf_.get());
    136   DCHECK(!callback.is_null());
    137 
    138   user_read_buf_ = buf;
    139   user_read_buf_len_ = buf_len;
    140 
    141   DCHECK(completed_handshake_);
    142 
    143   int rv = DoReadLoop(OK);
    144 
    145   if (rv == ERR_IO_PENDING) {
    146     user_read_callback_ = callback;
    147   } else {
    148     user_read_buf_ = NULL;
    149     user_read_buf_len_ = 0;
    150   }
    151 
    152   return rv;
    153 }
    154 
    155 int SSLServerSocketOpenSSL::Write(IOBuffer* buf, int buf_len,
    156                                   const CompletionCallback& callback) {
    157   DCHECK(user_write_callback_.is_null());
    158   DCHECK(!user_write_buf_.get());
    159   DCHECK(!callback.is_null());
    160 
    161   user_write_buf_ = buf;
    162   user_write_buf_len_ = buf_len;
    163 
    164   int rv = DoWriteLoop(OK);
    165 
    166   if (rv == ERR_IO_PENDING) {
    167     user_write_callback_ = callback;
    168   } else {
    169     user_write_buf_ = NULL;
    170     user_write_buf_len_ = 0;
    171   }
    172   return rv;
    173 }
    174 
    175 int SSLServerSocketOpenSSL::SetReceiveBufferSize(int32 size) {
    176   return transport_socket_->SetReceiveBufferSize(size);
    177 }
    178 
    179 int SSLServerSocketOpenSSL::SetSendBufferSize(int32 size) {
    180   return transport_socket_->SetSendBufferSize(size);
    181 }
    182 
    183 int SSLServerSocketOpenSSL::Connect(const CompletionCallback& callback) {
    184   NOTIMPLEMENTED();
    185   return ERR_NOT_IMPLEMENTED;
    186 }
    187 
    188 void SSLServerSocketOpenSSL::Disconnect() {
    189   transport_socket_->Disconnect();
    190 }
    191 
    192 bool SSLServerSocketOpenSSL::IsConnected() const {
    193   // TODO(wtc): Find out if we should check transport_socket_->IsConnected()
    194   // as well.
    195   return completed_handshake_;
    196 }
    197 
    198 bool SSLServerSocketOpenSSL::IsConnectedAndIdle() const {
    199   return completed_handshake_ && transport_socket_->IsConnectedAndIdle();
    200 }
    201 
    202 int SSLServerSocketOpenSSL::GetPeerAddress(IPEndPoint* address) const {
    203   if (!IsConnected())
    204     return ERR_SOCKET_NOT_CONNECTED;
    205   return transport_socket_->GetPeerAddress(address);
    206 }
    207 
    208 int SSLServerSocketOpenSSL::GetLocalAddress(IPEndPoint* address) const {
    209   if (!IsConnected())
    210     return ERR_SOCKET_NOT_CONNECTED;
    211   return transport_socket_->GetLocalAddress(address);
    212 }
    213 
    214 const BoundNetLog& SSLServerSocketOpenSSL::NetLog() const {
    215   return net_log_;
    216 }
    217 
    218 void SSLServerSocketOpenSSL::SetSubresourceSpeculation() {
    219   transport_socket_->SetSubresourceSpeculation();
    220 }
    221 
    222 void SSLServerSocketOpenSSL::SetOmniboxSpeculation() {
    223   transport_socket_->SetOmniboxSpeculation();
    224 }
    225 
    226 bool SSLServerSocketOpenSSL::WasEverUsed() const {
    227   return transport_socket_->WasEverUsed();
    228 }
    229 
    230 bool SSLServerSocketOpenSSL::UsingTCPFastOpen() const {
    231   return transport_socket_->UsingTCPFastOpen();
    232 }
    233 
    234 bool SSLServerSocketOpenSSL::WasNpnNegotiated() const {
    235   NOTIMPLEMENTED();
    236   return false;
    237 }
    238 
    239 NextProto SSLServerSocketOpenSSL::GetNegotiatedProtocol() const {
    240   // NPN is not supported by this class.
    241   return kProtoUnknown;
    242 }
    243 
    244 bool SSLServerSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) {
    245   NOTIMPLEMENTED();
    246   return false;
    247 }
    248 
    249 void SSLServerSocketOpenSSL::OnSendComplete(int result) {
    250   if (next_handshake_state_ == STATE_HANDSHAKE) {
    251     // In handshake phase.
    252     OnHandshakeIOComplete(result);
    253     return;
    254   }
    255 
    256   // TODO(byungchul): This state machine is not correct. Copy the state machine
    257   // of SSLClientSocketOpenSSL::OnSendComplete() which handles it better.
    258   if (!completed_handshake_)
    259     return;
    260 
    261   if (user_write_buf_.get()) {
    262     int rv = DoWriteLoop(result);
    263     if (rv != ERR_IO_PENDING)
    264       DoWriteCallback(rv);
    265   } else {
    266     // Ensure that any queued ciphertext is flushed.
    267     DoTransportIO();
    268   }
    269 }
    270 
    271 void SSLServerSocketOpenSSL::OnRecvComplete(int result) {
    272   if (next_handshake_state_ == STATE_HANDSHAKE) {
    273     // In handshake phase.
    274     OnHandshakeIOComplete(result);
    275     return;
    276   }
    277 
    278   // Network layer received some data, check if client requested to read
    279   // decrypted data.
    280   if (!user_read_buf_.get() || !completed_handshake_)
    281     return;
    282 
    283   int rv = DoReadLoop(result);
    284   if (rv != ERR_IO_PENDING)
    285     DoReadCallback(rv);
    286 }
    287 
    288 void SSLServerSocketOpenSSL::OnHandshakeIOComplete(int result) {
    289   int rv = DoHandshakeLoop(result);
    290   if (rv == ERR_IO_PENDING)
    291     return;
    292 
    293   net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv);
    294   if (!user_handshake_callback_.is_null())
    295     DoHandshakeCallback(rv);
    296 }
    297 
    298 // Return 0 for EOF,
    299 // > 0 for bytes transferred immediately,
    300 // < 0 for error (or the non-error ERR_IO_PENDING).
    301 int SSLServerSocketOpenSSL::BufferSend() {
    302   if (transport_send_busy_)
    303     return ERR_IO_PENDING;
    304 
    305   if (!send_buffer_.get()) {
    306     // Get a fresh send buffer out of the send BIO.
    307     size_t max_read = BIO_ctrl_pending(transport_bio_);
    308     if (!max_read)
    309       return 0;  // Nothing pending in the OpenSSL write BIO.
    310     send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read);
    311     int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read);
    312     DCHECK_GT(read_bytes, 0);
    313     CHECK_EQ(static_cast<int>(max_read), read_bytes);
    314   }
    315 
    316   int rv = transport_socket_->Write(
    317       send_buffer_.get(),
    318       send_buffer_->BytesRemaining(),
    319       base::Bind(&SSLServerSocketOpenSSL::BufferSendComplete,
    320                  base::Unretained(this)));
    321   if (rv == ERR_IO_PENDING) {
    322     transport_send_busy_ = true;
    323   } else {
    324     TransportWriteComplete(rv);
    325   }
    326   return rv;
    327 }
    328 
    329 void SSLServerSocketOpenSSL::BufferSendComplete(int result) {
    330   transport_send_busy_ = false;
    331   TransportWriteComplete(result);
    332   OnSendComplete(result);
    333 }
    334 
    335 void SSLServerSocketOpenSSL::TransportWriteComplete(int result) {
    336   DCHECK(ERR_IO_PENDING != result);
    337   if (result < 0) {
    338     // Got a socket write error; close the BIO to indicate this upward.
    339     //
    340     // TODO(davidben): The value of |result| gets lost. Feed the error back into
    341     // the BIO so it gets (re-)detected in OnSendComplete. Perhaps with
    342     // BIO_set_callback.
    343     DVLOG(1) << "TransportWriteComplete error " << result;
    344     (void)BIO_shutdown_wr(SSL_get_wbio(ssl_));
    345 
    346     // Match the fix for http://crbug.com/249848 in NSS by erroring future reads
    347     // from the socket after a write error.
    348     //
    349     // TODO(davidben): Avoid having read and write ends interact this way.
    350     transport_write_error_ = result;
    351     (void)BIO_shutdown_wr(transport_bio_);
    352     send_buffer_ = NULL;
    353   } else {
    354     DCHECK(send_buffer_.get());
    355     send_buffer_->DidConsume(result);
    356     DCHECK_GE(send_buffer_->BytesRemaining(), 0);
    357     if (send_buffer_->BytesRemaining() <= 0)
    358       send_buffer_ = NULL;
    359   }
    360 }
    361 
    362 int SSLServerSocketOpenSSL::BufferRecv() {
    363   if (transport_recv_busy_)
    364     return ERR_IO_PENDING;
    365 
    366   // Determine how much was requested from |transport_bio_| that was not
    367   // actually available.
    368   size_t requested = BIO_ctrl_get_read_request(transport_bio_);
    369   if (requested == 0) {
    370     // This is not a perfect match of error codes, as no operation is
    371     // actually pending. However, returning 0 would be interpreted as
    372     // a possible sign of EOF, which is also an inappropriate match.
    373     return ERR_IO_PENDING;
    374   }
    375 
    376   // Known Issue: While only reading |requested| data is the more correct
    377   // implementation, it has the downside of resulting in frequent reads:
    378   // One read for the SSL record header (~5 bytes) and one read for the SSL
    379   // record body. Rather than issuing these reads to the underlying socket
    380   // (and constantly allocating new IOBuffers), a single Read() request to
    381   // fill |transport_bio_| is issued. As long as an SSL client socket cannot
    382   // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL
    383   // traffic, this over-subscribed Read()ing will not cause issues.
    384   size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_);
    385   if (!max_write)
    386     return ERR_IO_PENDING;
    387 
    388   recv_buffer_ = new IOBuffer(max_write);
    389   int rv = transport_socket_->Read(
    390       recv_buffer_.get(),
    391       max_write,
    392       base::Bind(&SSLServerSocketOpenSSL::BufferRecvComplete,
    393                  base::Unretained(this)));
    394   if (rv == ERR_IO_PENDING) {
    395     transport_recv_busy_ = true;
    396   } else {
    397     rv = TransportReadComplete(rv);
    398   }
    399   return rv;
    400 }
    401 
    402 void SSLServerSocketOpenSSL::BufferRecvComplete(int result) {
    403   result = TransportReadComplete(result);
    404   OnRecvComplete(result);
    405 }
    406 
    407 int SSLServerSocketOpenSSL::TransportReadComplete(int result) {
    408   DCHECK(ERR_IO_PENDING != result);
    409   if (result <= 0) {
    410     DVLOG(1) << "TransportReadComplete result " << result;
    411     // Received 0 (end of file) or an error. Either way, bubble it up to the
    412     // SSL layer via the BIO. TODO(joth): consider stashing the error code, to
    413     // relay up to the SSL socket client (i.e. via DoReadCallback).
    414     if (result == 0)
    415       transport_recv_eof_ = true;
    416     (void)BIO_shutdown_wr(transport_bio_);
    417   } else if (transport_write_error_ < 0) {
    418     // Mirror transport write errors as read failures; transport_bio_ has been
    419     // shut down by TransportWriteComplete, so the BIO_write will fail, failing
    420     // the CHECK. http://crbug.com/335557.
    421     result = transport_write_error_;
    422   } else {
    423     DCHECK(recv_buffer_.get());
    424     int ret = BIO_write(transport_bio_, recv_buffer_->data(), result);
    425     // A write into a memory BIO should always succeed.
    426     DCHECK_EQ(result, ret);
    427   }
    428   recv_buffer_ = NULL;
    429   transport_recv_busy_ = false;
    430   return result;
    431 }
    432 
    433 // Do as much network I/O as possible between the buffer and the
    434 // transport socket. Return true if some I/O performed, false
    435 // otherwise (error or ERR_IO_PENDING).
    436 bool SSLServerSocketOpenSSL::DoTransportIO() {
    437   bool network_moved = false;
    438   int rv;
    439   // Read and write as much data as possible. The loop is necessary because
    440   // Write() may return synchronously.
    441   do {
    442     rv = BufferSend();
    443     if (rv != ERR_IO_PENDING && rv != 0)
    444       network_moved = true;
    445   } while (rv > 0);
    446   if (!transport_recv_eof_ && BufferRecv() != ERR_IO_PENDING)
    447     network_moved = true;
    448   return network_moved;
    449 }
    450 
    451 int SSLServerSocketOpenSSL::DoPayloadRead() {
    452   DCHECK(user_read_buf_.get());
    453   DCHECK_GT(user_read_buf_len_, 0);
    454   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
    455   int rv = SSL_read(ssl_, user_read_buf_->data(), user_read_buf_len_);
    456   if (rv >= 0)
    457     return rv;
    458   int ssl_error = SSL_get_error(ssl_, rv);
    459   int net_error = MapOpenSSLError(ssl_error, err_tracer);
    460   if (net_error != ERR_IO_PENDING) {
    461     net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
    462                       CreateNetLogSSLErrorCallback(net_error, ssl_error));
    463   }
    464   return net_error;
    465 }
    466 
    467 int SSLServerSocketOpenSSL::DoPayloadWrite() {
    468   DCHECK(user_write_buf_.get());
    469   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
    470   int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
    471   if (rv >= 0)
    472     return rv;
    473   int ssl_error = SSL_get_error(ssl_, rv);
    474   int net_error = MapOpenSSLError(ssl_error, err_tracer);
    475   if (net_error != ERR_IO_PENDING) {
    476     net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
    477                       CreateNetLogSSLErrorCallback(net_error, ssl_error));
    478   }
    479   return net_error;
    480 }
    481 
    482 int SSLServerSocketOpenSSL::DoHandshakeLoop(int last_io_result) {
    483   int rv = last_io_result;
    484   do {
    485     // Default to STATE_NONE for next state.
    486     // (This is a quirk carried over from the windows
    487     // implementation.  It makes reading the logs a bit harder.)
    488     // State handlers can and often do call GotoState just
    489     // to stay in the current state.
    490     State state = next_handshake_state_;
    491     GotoState(STATE_NONE);
    492     switch (state) {
    493       case STATE_HANDSHAKE:
    494         rv = DoHandshake();
    495         break;
    496       case STATE_NONE:
    497       default:
    498         rv = ERR_UNEXPECTED;
    499         LOG(DFATAL) << "unexpected state " << state;
    500         break;
    501     }
    502 
    503     // Do the actual network I/O
    504     bool network_moved = DoTransportIO();
    505     if (network_moved && next_handshake_state_ == STATE_HANDSHAKE) {
    506       // In general we exit the loop if rv is ERR_IO_PENDING.  In this
    507       // special case we keep looping even if rv is ERR_IO_PENDING because
    508       // the transport IO may allow DoHandshake to make progress.
    509       rv = OK;  // This causes us to stay in the loop.
    510     }
    511   } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
    512   return rv;
    513 }
    514 
    515 int SSLServerSocketOpenSSL::DoReadLoop(int result) {
    516   DCHECK(completed_handshake_);
    517   DCHECK(next_handshake_state_ == STATE_NONE);
    518 
    519   if (result < 0)
    520     return result;
    521 
    522   bool network_moved;
    523   int rv;
    524   do {
    525     rv = DoPayloadRead();
    526     network_moved = DoTransportIO();
    527   } while (rv == ERR_IO_PENDING && network_moved);
    528   return rv;
    529 }
    530 
    531 int SSLServerSocketOpenSSL::DoWriteLoop(int result) {
    532   DCHECK(completed_handshake_);
    533   DCHECK_EQ(next_handshake_state_, STATE_NONE);
    534 
    535   if (result < 0)
    536     return result;
    537 
    538   bool network_moved;
    539   int rv;
    540   do {
    541     rv = DoPayloadWrite();
    542     network_moved = DoTransportIO();
    543   } while (rv == ERR_IO_PENDING && network_moved);
    544   return rv;
    545 }
    546 
    547 int SSLServerSocketOpenSSL::DoHandshake() {
    548   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
    549   int net_error = OK;
    550   int rv = SSL_do_handshake(ssl_);
    551 
    552   if (rv == 1) {
    553     completed_handshake_ = true;
    554   } else {
    555     int ssl_error = SSL_get_error(ssl_, rv);
    556     net_error = MapOpenSSLError(ssl_error, err_tracer);
    557 
    558     // If not done, stay in this state
    559     if (net_error == ERR_IO_PENDING) {
    560       GotoState(STATE_HANDSHAKE);
    561     } else {
    562       LOG(ERROR) << "handshake failed; returned " << rv
    563                  << ", SSL error code " << ssl_error
    564                  << ", net_error " << net_error;
    565       net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
    566                         CreateNetLogSSLErrorCallback(net_error, ssl_error));
    567     }
    568   }
    569   return net_error;
    570 }
    571 
    572 void SSLServerSocketOpenSSL::DoHandshakeCallback(int rv) {
    573   DCHECK_NE(rv, ERR_IO_PENDING);
    574   ResetAndReturn(&user_handshake_callback_).Run(rv > OK ? OK : rv);
    575 }
    576 
    577 void SSLServerSocketOpenSSL::DoReadCallback(int rv) {
    578   DCHECK(rv != ERR_IO_PENDING);
    579   DCHECK(!user_read_callback_.is_null());
    580 
    581   user_read_buf_ = NULL;
    582   user_read_buf_len_ = 0;
    583   ResetAndReturn(&user_read_callback_).Run(rv);
    584 }
    585 
    586 void SSLServerSocketOpenSSL::DoWriteCallback(int rv) {
    587   DCHECK(rv != ERR_IO_PENDING);
    588   DCHECK(!user_write_callback_.is_null());
    589 
    590   user_write_buf_ = NULL;
    591   user_write_buf_len_ = 0;
    592   ResetAndReturn(&user_write_callback_).Run(rv);
    593 }
    594 
    595 int SSLServerSocketOpenSSL::Init() {
    596   DCHECK(!ssl_);
    597   DCHECK(!transport_bio_);
    598 
    599   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
    600 
    601   crypto::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx(
    602       // It support SSLv2, SSLv3, and TLSv1.
    603       SSL_CTX_new(SSLv23_server_method()));
    604   ssl_ = SSL_new(ssl_ctx.get());
    605   if (!ssl_)
    606     return ERR_UNEXPECTED;
    607 
    608   BIO* ssl_bio = NULL;
    609   // 0 => use default buffer sizes.
    610   if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0))
    611     return ERR_UNEXPECTED;
    612   DCHECK(ssl_bio);
    613   DCHECK(transport_bio_);
    614 
    615   SSL_set_bio(ssl_, ssl_bio, ssl_bio);
    616 
    617   // Set certificate and private key.
    618   DCHECK(cert_->os_cert_handle());
    619 #if defined(USE_OPENSSL_CERTS)
    620   if (SSL_use_certificate(ssl_, cert_->os_cert_handle()) != 1) {
    621     LOG(ERROR) << "Cannot set certificate.";
    622     return ERR_UNEXPECTED;
    623   }
    624 #else
    625   // Convert OSCertHandle to X509 structure.
    626   std::string der_string;
    627   if (!X509Certificate::GetDEREncoded(cert_->os_cert_handle(), &der_string))
    628     return ERR_UNEXPECTED;
    629 
    630   const unsigned char* der_string_array =
    631       reinterpret_cast<const unsigned char*>(der_string.data());
    632 
    633   crypto::ScopedOpenSSL<X509, X509_free>
    634       x509(d2i_X509(NULL, &der_string_array, der_string.length()));
    635   if (!x509.get())
    636     return ERR_UNEXPECTED;
    637 
    638   // On success, SSL_use_certificate acquires a reference to |x509|.
    639   if (SSL_use_certificate(ssl_, x509.get()) != 1) {
    640     LOG(ERROR) << "Cannot set certificate.";
    641     return ERR_UNEXPECTED;
    642   }
    643 #endif  // USE_OPENSSL_CERTS
    644 
    645   DCHECK(key_->key());
    646   if (SSL_use_PrivateKey(ssl_, key_->key()) != 1) {
    647     LOG(ERROR) << "Cannot set private key.";
    648     return ERR_UNEXPECTED;
    649   }
    650 
    651   // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
    652   // set everything we care about to an absolute value.
    653   SslSetClearMask options;
    654   options.ConfigureFlag(SSL_OP_NO_SSLv2, true);
    655   bool ssl3_enabled = (ssl_config_.version_min == SSL_PROTOCOL_VERSION_SSL3);
    656   options.ConfigureFlag(SSL_OP_NO_SSLv3, !ssl3_enabled);
    657   bool tls1_enabled = (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1 &&
    658                        ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1);
    659   options.ConfigureFlag(SSL_OP_NO_TLSv1, !tls1_enabled);
    660   bool tls1_1_enabled =
    661       (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1_1 &&
    662        ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1_1);
    663   options.ConfigureFlag(SSL_OP_NO_TLSv1_1, !tls1_1_enabled);
    664   bool tls1_2_enabled =
    665       (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1_2 &&
    666        ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1_2);
    667   options.ConfigureFlag(SSL_OP_NO_TLSv1_2, !tls1_2_enabled);
    668 
    669   options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true);
    670 
    671   SSL_set_options(ssl_, options.set_mask);
    672   SSL_clear_options(ssl_, options.clear_mask);
    673 
    674   // Same as above, this time for the SSL mode.
    675   SslSetClearMask mode;
    676 
    677   mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true);
    678 
    679   SSL_set_mode(ssl_, mode.set_mask);
    680   SSL_clear_mode(ssl_, mode.clear_mask);
    681 
    682   return OK;
    683 }
    684 
    685 }  // namespace net
    686