29d1ffa050861243e168c6009dafc355f7ea2e1a
[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/ssl/openssl_ssl_util.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_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   OpenSSLErrorInfo error_info;
460   int net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer,
461                                              &error_info);
462   if (net_error != ERR_IO_PENDING) {
463     net_log_.AddEvent(
464         NetLog::TYPE_SSL_READ_ERROR,
465         CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
466   }
467   return net_error;
468 }
469
470 int SSLServerSocketOpenSSL::DoPayloadWrite() {
471   DCHECK(user_write_buf_.get());
472   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
473   int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
474   if (rv >= 0)
475     return rv;
476   int ssl_error = SSL_get_error(ssl_, rv);
477   OpenSSLErrorInfo error_info;
478   int net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer,
479                                              &error_info);
480   if (net_error != ERR_IO_PENDING) {
481     net_log_.AddEvent(
482         NetLog::TYPE_SSL_WRITE_ERROR,
483         CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
484   }
485   return net_error;
486 }
487
488 int SSLServerSocketOpenSSL::DoHandshakeLoop(int last_io_result) {
489   int rv = last_io_result;
490   do {
491     // Default to STATE_NONE for next state.
492     // (This is a quirk carried over from the windows
493     // implementation.  It makes reading the logs a bit harder.)
494     // State handlers can and often do call GotoState just
495     // to stay in the current state.
496     State state = next_handshake_state_;
497     GotoState(STATE_NONE);
498     switch (state) {
499       case STATE_HANDSHAKE:
500         rv = DoHandshake();
501         break;
502       case STATE_NONE:
503       default:
504         rv = ERR_UNEXPECTED;
505         LOG(DFATAL) << "unexpected state " << state;
506         break;
507     }
508
509     // Do the actual network I/O
510     bool network_moved = DoTransportIO();
511     if (network_moved && next_handshake_state_ == STATE_HANDSHAKE) {
512       // In general we exit the loop if rv is ERR_IO_PENDING.  In this
513       // special case we keep looping even if rv is ERR_IO_PENDING because
514       // the transport IO may allow DoHandshake to make progress.
515       rv = OK;  // This causes us to stay in the loop.
516     }
517   } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
518   return rv;
519 }
520
521 int SSLServerSocketOpenSSL::DoReadLoop(int result) {
522   DCHECK(completed_handshake_);
523   DCHECK(next_handshake_state_ == STATE_NONE);
524
525   if (result < 0)
526     return result;
527
528   bool network_moved;
529   int rv;
530   do {
531     rv = DoPayloadRead();
532     network_moved = DoTransportIO();
533   } while (rv == ERR_IO_PENDING && network_moved);
534   return rv;
535 }
536
537 int SSLServerSocketOpenSSL::DoWriteLoop(int result) {
538   DCHECK(completed_handshake_);
539   DCHECK_EQ(next_handshake_state_, STATE_NONE);
540
541   if (result < 0)
542     return result;
543
544   bool network_moved;
545   int rv;
546   do {
547     rv = DoPayloadWrite();
548     network_moved = DoTransportIO();
549   } while (rv == ERR_IO_PENDING && network_moved);
550   return rv;
551 }
552
553 int SSLServerSocketOpenSSL::DoHandshake() {
554   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
555   int net_error = OK;
556   int rv = SSL_do_handshake(ssl_);
557
558   if (rv == 1) {
559     completed_handshake_ = true;
560   } else {
561     int ssl_error = SSL_get_error(ssl_, rv);
562     OpenSSLErrorInfo error_info;
563     net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info);
564
565     // If not done, stay in this state
566     if (net_error == ERR_IO_PENDING) {
567       GotoState(STATE_HANDSHAKE);
568     } else {
569       LOG(ERROR) << "handshake failed; returned " << rv
570                  << ", SSL error code " << ssl_error
571                  << ", net_error " << net_error;
572       net_log_.AddEvent(
573           NetLog::TYPE_SSL_HANDSHAKE_ERROR,
574           CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
575     }
576   }
577   return net_error;
578 }
579
580 void SSLServerSocketOpenSSL::DoHandshakeCallback(int rv) {
581   DCHECK_NE(rv, ERR_IO_PENDING);
582   ResetAndReturn(&user_handshake_callback_).Run(rv > OK ? OK : rv);
583 }
584
585 void SSLServerSocketOpenSSL::DoReadCallback(int rv) {
586   DCHECK(rv != ERR_IO_PENDING);
587   DCHECK(!user_read_callback_.is_null());
588
589   user_read_buf_ = NULL;
590   user_read_buf_len_ = 0;
591   ResetAndReturn(&user_read_callback_).Run(rv);
592 }
593
594 void SSLServerSocketOpenSSL::DoWriteCallback(int rv) {
595   DCHECK(rv != ERR_IO_PENDING);
596   DCHECK(!user_write_callback_.is_null());
597
598   user_write_buf_ = NULL;
599   user_write_buf_len_ = 0;
600   ResetAndReturn(&user_write_callback_).Run(rv);
601 }
602
603 int SSLServerSocketOpenSSL::Init() {
604   DCHECK(!ssl_);
605   DCHECK(!transport_bio_);
606
607   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
608
609   crypto::ScopedOpenSSL<SSL_CTX, SSL_CTX_free>::Type ssl_ctx(
610       // It support SSLv2, SSLv3, and TLSv1.
611       SSL_CTX_new(SSLv23_server_method()));
612   ssl_ = SSL_new(ssl_ctx.get());
613   if (!ssl_)
614     return ERR_UNEXPECTED;
615
616   BIO* ssl_bio = NULL;
617   // 0 => use default buffer sizes.
618   if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0))
619     return ERR_UNEXPECTED;
620   DCHECK(ssl_bio);
621   DCHECK(transport_bio_);
622
623   SSL_set_bio(ssl_, ssl_bio, ssl_bio);
624
625   // Set certificate and private key.
626   DCHECK(cert_->os_cert_handle());
627 #if defined(USE_OPENSSL_CERTS)
628   if (SSL_use_certificate(ssl_, cert_->os_cert_handle()) != 1) {
629     LOG(ERROR) << "Cannot set certificate.";
630     return ERR_UNEXPECTED;
631   }
632 #else
633   // Convert OSCertHandle to X509 structure.
634   std::string der_string;
635   if (!X509Certificate::GetDEREncoded(cert_->os_cert_handle(), &der_string))
636     return ERR_UNEXPECTED;
637
638   const unsigned char* der_string_array =
639       reinterpret_cast<const unsigned char*>(der_string.data());
640
641   crypto::ScopedOpenSSL<X509, X509_free>::Type x509(
642       d2i_X509(NULL, &der_string_array, der_string.length()));
643   if (!x509.get())
644     return ERR_UNEXPECTED;
645
646   // On success, SSL_use_certificate acquires a reference to |x509|.
647   if (SSL_use_certificate(ssl_, x509.get()) != 1) {
648     LOG(ERROR) << "Cannot set certificate.";
649     return ERR_UNEXPECTED;
650   }
651 #endif  // USE_OPENSSL_CERTS
652
653   DCHECK(key_->key());
654   if (SSL_use_PrivateKey(ssl_, key_->key()) != 1) {
655     LOG(ERROR) << "Cannot set private key.";
656     return ERR_UNEXPECTED;
657   }
658
659   // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
660   // set everything we care about to an absolute value.
661   SslSetClearMask options;
662   options.ConfigureFlag(SSL_OP_NO_SSLv2, true);
663   bool ssl3_enabled = (ssl_config_.version_min == SSL_PROTOCOL_VERSION_SSL3);
664   options.ConfigureFlag(SSL_OP_NO_SSLv3, !ssl3_enabled);
665   bool tls1_enabled = (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1 &&
666                        ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1);
667   options.ConfigureFlag(SSL_OP_NO_TLSv1, !tls1_enabled);
668   bool tls1_1_enabled =
669       (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1_1 &&
670        ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1_1);
671   options.ConfigureFlag(SSL_OP_NO_TLSv1_1, !tls1_1_enabled);
672   bool tls1_2_enabled =
673       (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1_2 &&
674        ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1_2);
675   options.ConfigureFlag(SSL_OP_NO_TLSv1_2, !tls1_2_enabled);
676
677   options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true);
678
679   SSL_set_options(ssl_, options.set_mask);
680   SSL_clear_options(ssl_, options.clear_mask);
681
682   // Same as above, this time for the SSL mode.
683   SslSetClearMask mode;
684
685   mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true);
686
687   SSL_set_mode(ssl_, mode.set_mask);
688   SSL_clear_mode(ssl_, mode.clear_mask);
689
690   return OK;
691 }
692
693 }  // namespace net