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