blob: 29d1ffa050861243e168c6009dafc355f7ea2e1a [file] [log] [blame]
[email protected]a4965c882012-06-13 20:19:441// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]c322aa92011-01-27 11:21:072// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]c8a80e92014-05-17 16:02:085#include "net/socket/ssl_server_socket_openssl.h"
[email protected]c322aa92011-01-27 11:21:076
[email protected]c8a80e92014-05-17 16:02:087#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"
[email protected]cd9b75b2014-07-10 04:39:3814#include "crypto/scoped_openssl_types.h"
[email protected]c8a80e92014-05-17 16:02:0815#include "net/base/net_errors.h"
[email protected]97a854f2014-07-29 07:51:3616#include "net/ssl/openssl_ssl_util.h"
[email protected]c8a80e92014-05-17 16:02:0817
18#define GotoState(s) next_handshake_state_ = s
[email protected]a4965c882012-06-13 20:19:4419
[email protected]c322aa92011-01-27 11:21:0720namespace net {
21
[email protected]a4965c882012-06-13 20:19:4422void EnableSSLServerSockets() {
[email protected]c8a80e92014-05-17 16:02:0823 // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit().
[email protected]a4965c882012-06-13 20:19:4424}
25
[email protected]18ccfdb2013-08-15 00:13:4426scoped_ptr<SSLServerSocket> CreateSSLServerSocket(
27 scoped_ptr<StreamSocket> socket,
28 X509Certificate* certificate,
29 crypto::RSAPrivateKey* key,
30 const SSLConfig& ssl_config) {
[email protected]c8a80e92014-05-17 16:02:0831 crypto::EnsureOpenSSLInit();
32 return scoped_ptr<SSLServerSocket>(
33 new SSLServerSocketOpenSSL(socket.Pass(), certificate, key, ssl_config));
34}
35
36SSLServerSocketOpenSSL::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
61SSLServerSocketOpenSSL::~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
75int 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
100int 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
126int SSLServerSocketOpenSSL::GetTLSUniqueChannelBinding(std::string* out) {
[email protected]a7ac3c32011-06-17 19:10:15127 NOTIMPLEMENTED();
[email protected]c8a80e92014-05-17 16:02:08128 return ERR_NOT_IMPLEMENTED;
129}
130
131int 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
155int 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
175int SSLServerSocketOpenSSL::SetReceiveBufferSize(int32 size) {
176 return transport_socket_->SetReceiveBufferSize(size);
177}
178
179int SSLServerSocketOpenSSL::SetSendBufferSize(int32 size) {
180 return transport_socket_->SetSendBufferSize(size);
181}
182
183int SSLServerSocketOpenSSL::Connect(const CompletionCallback& callback) {
184 NOTIMPLEMENTED();
185 return ERR_NOT_IMPLEMENTED;
186}
187
188void SSLServerSocketOpenSSL::Disconnect() {
189 transport_socket_->Disconnect();
190}
191
192bool SSLServerSocketOpenSSL::IsConnected() const {
193 // TODO(wtc): Find out if we should check transport_socket_->IsConnected()
194 // as well.
195 return completed_handshake_;
196}
197
198bool SSLServerSocketOpenSSL::IsConnectedAndIdle() const {
199 return completed_handshake_ && transport_socket_->IsConnectedAndIdle();
200}
201
202int SSLServerSocketOpenSSL::GetPeerAddress(IPEndPoint* address) const {
203 if (!IsConnected())
204 return ERR_SOCKET_NOT_CONNECTED;
205 return transport_socket_->GetPeerAddress(address);
206}
207
208int SSLServerSocketOpenSSL::GetLocalAddress(IPEndPoint* address) const {
209 if (!IsConnected())
210 return ERR_SOCKET_NOT_CONNECTED;
211 return transport_socket_->GetLocalAddress(address);
212}
213
214const BoundNetLog& SSLServerSocketOpenSSL::NetLog() const {
215 return net_log_;
216}
217
218void SSLServerSocketOpenSSL::SetSubresourceSpeculation() {
219 transport_socket_->SetSubresourceSpeculation();
220}
221
222void SSLServerSocketOpenSSL::SetOmniboxSpeculation() {
223 transport_socket_->SetOmniboxSpeculation();
224}
225
226bool SSLServerSocketOpenSSL::WasEverUsed() const {
227 return transport_socket_->WasEverUsed();
228}
229
230bool SSLServerSocketOpenSSL::UsingTCPFastOpen() const {
231 return transport_socket_->UsingTCPFastOpen();
232}
233
234bool SSLServerSocketOpenSSL::WasNpnNegotiated() const {
235 NOTIMPLEMENTED();
236 return false;
237}
238
239NextProto SSLServerSocketOpenSSL::GetNegotiatedProtocol() const {
240 // NPN is not supported by this class.
241 return kProtoUnknown;
242}
243
244bool SSLServerSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) {
245 NOTIMPLEMENTED();
246 return false;
247}
248
249void 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
271void 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
288void 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).
301int 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.
[email protected]edfd0f42014-07-22 18:20:37307 size_t max_read = BIO_pending(transport_bio_);
[email protected]c8a80e92014-05-17 16:02:08308 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
329void SSLServerSocketOpenSSL::BufferSendComplete(int result) {
330 transport_send_busy_ = false;
331 TransportWriteComplete(result);
332 OnSendComplete(result);
333}
334
335void 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
362int 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
402void SSLServerSocketOpenSSL::BufferRecvComplete(int result) {
403 result = TransportReadComplete(result);
404 OnRecvComplete(result);
405}
406
407int 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).
436bool 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
451int 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);
davidbena4409c62014-08-27 17:05:51459 OpenSSLErrorInfo error_info;
460 int net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer,
461 &error_info);
[email protected]c8a80e92014-05-17 16:02:08462 if (net_error != ERR_IO_PENDING) {
davidbena4409c62014-08-27 17:05:51463 net_log_.AddEvent(
464 NetLog::TYPE_SSL_READ_ERROR,
465 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
[email protected]c8a80e92014-05-17 16:02:08466 }
467 return net_error;
468}
469
470int 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);
davidbena4409c62014-08-27 17:05:51477 OpenSSLErrorInfo error_info;
478 int net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer,
479 &error_info);
[email protected]c8a80e92014-05-17 16:02:08480 if (net_error != ERR_IO_PENDING) {
davidbena4409c62014-08-27 17:05:51481 net_log_.AddEvent(
482 NetLog::TYPE_SSL_WRITE_ERROR,
483 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
[email protected]c8a80e92014-05-17 16:02:08484 }
485 return net_error;
486}
487
488int 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
521int 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
537int 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
553int 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);
davidbena4409c62014-08-27 17:05:51562 OpenSSLErrorInfo error_info;
563 net_error = MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info);
[email protected]c8a80e92014-05-17 16:02:08564
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;
davidbena4409c62014-08-27 17:05:51572 net_log_.AddEvent(
573 NetLog::TYPE_SSL_HANDSHAKE_ERROR,
574 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info));
[email protected]c8a80e92014-05-17 16:02:08575 }
576 }
577 return net_error;
578}
579
580void SSLServerSocketOpenSSL::DoHandshakeCallback(int rv) {
581 DCHECK_NE(rv, ERR_IO_PENDING);
582 ResetAndReturn(&user_handshake_callback_).Run(rv > OK ? OK : rv);
583}
584
585void 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
594void 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
603int SSLServerSocketOpenSSL::Init() {
604 DCHECK(!ssl_);
605 DCHECK(!transport_bio_);
606
607 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
608
[email protected]cd9b75b2014-07-10 04:39:38609 crypto::ScopedOpenSSL<SSL_CTX, SSL_CTX_free>::Type ssl_ctx(
[email protected]c8a80e92014-05-17 16:02:08610 // 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());
[email protected]2b85635c2014-06-12 14:36:54627#if defined(USE_OPENSSL_CERTS)
[email protected]c8a80e92014-05-17 16:02:08628 if (SSL_use_certificate(ssl_, cert_->os_cert_handle()) != 1) {
629 LOG(ERROR) << "Cannot set certificate.";
630 return ERR_UNEXPECTED;
631 }
[email protected]2b85635c2014-06-12 14:36:54632#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
[email protected]cd9b75b2014-07-10 04:39:38641 crypto::ScopedOpenSSL<X509, X509_free>::Type x509(
642 d2i_X509(NULL, &der_string_array, der_string.length()));
[email protected]2b85635c2014-06-12 14:36:54643 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
[email protected]c8a80e92014-05-17 16:02:08652
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;
[email protected]c322aa92011-01-27 11:21:07691}
692
693} // namespace net