Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(597)

Side by Side Diff: net/socket/ssl_server_socket_openssl.cc

Issue 274783002: Implement SSL server socket over OpenSSL. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressing comment on patch set #1 Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 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"
5 #include "base/logging.h" 11 #include "base/logging.h"
6 #include "net/socket/ssl_server_socket.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_util.h"
wtc 2014/05/16 03:57:17 Nit: There are two headers named openssl_util.h. I
byungchul 2014/05/16 17:49:59 Done.
16 #include "net/socket/ssl_error_params.h"
7 17
8 // TODO(bulach): Provide simple stubs for EnableSSLServerSockets and 18 #define GotoState(s) next_handshake_state_ = s
wtc 2014/05/16 03:57:17 Nit: I seem to remember the GotoState macro was ad
byungchul 2014/05/16 17:49:59 Many codes are shared with client socket and nss s
9 // CreateSSLServerSocket so that when building for OpenSSL rather than NSS,
10 // so that the code using SSL server sockets can be compiled and disabled
11 // programatically rather than requiring to be carved out from the compile.
12 19
13 namespace net { 20 namespace net {
14 21
15 void EnableSSLServerSockets() { 22 void EnableSSLServerSockets() {
16 NOTIMPLEMENTED(); 23 // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit().
wtc 2014/05/16 03:57:17 Nit: add a period (.) at the end of the sentence.
byungchul 2014/05/16 17:49:59 Already there :)
17 } 24 }
18 25
19 scoped_ptr<SSLServerSocket> CreateSSLServerSocket( 26 scoped_ptr<SSLServerSocket> CreateSSLServerSocket(
20 scoped_ptr<StreamSocket> socket, 27 scoped_ptr<StreamSocket> socket,
21 X509Certificate* certificate, 28 X509Certificate* certificate,
22 crypto::RSAPrivateKey* key, 29 crypto::RSAPrivateKey* key,
23 const SSLConfig& ssl_config) { 30 const SSLConfig& ssl_config) {
31 // It is safe and cheap to call crypto::EnsureOpenSSLInit() multiple times.
wtc 2014/05/16 03:57:17 Please move this comment to the header file that d
byungchul 2014/05/16 17:49:59 Done.
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 if (!Init()) {
81 LOG(ERROR) << "Failed to initialize OpenSSL";
82 int rv = ERR_UNEXPECTED;
wtc 2014/05/16 03:57:17 Nit: ideally Init() should return the int error co
byungchul 2014/05/16 17:49:59 Done.
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 int 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 if (SSL_export_keying_material(
110 ssl_, out, outlen, label.data(), label.size(),
111 reinterpret_cast<const unsigned char*>(context.data()),
112 context.length(), has_context ? 1 : 0) == 0) {
113 LOG(ERROR) << "SSL_export_keying_material error";
114 return ERR_FAILED;
wtc 2014/05/16 03:57:17 Please try to get the error code of SSL_export_key
byungchul 2014/05/16 17:49:59 Done. Copied it from ssl_client_socket_openssl.
115 }
116 return OK;
117 }
118
119 int SSLServerSocketOpenSSL::GetTLSUniqueChannelBinding(std::string* out) {
120 return ERR_NOT_IMPLEMENTED;
wtc 2014/05/16 03:57:17 Should we also call NOTIMPLEMENTED()?
byungchul 2014/05/16 17:49:59 Done though nobody calls this.
121 }
122
123 int SSLServerSocketOpenSSL::Read(IOBuffer* buf, int buf_len,
124 const CompletionCallback& callback) {
125 DCHECK(user_read_callback_.is_null());
126 DCHECK(user_handshake_callback_.is_null());
127 DCHECK(!user_read_buf_.get());
128 DCHECK(!callback.is_null());
129
130 user_read_buf_ = buf;
131 user_read_buf_len_ = buf_len;
132
133 DCHECK(completed_handshake_);
134
135 int rv = DoReadLoop(OK);
136
137 if (rv == ERR_IO_PENDING) {
138 user_read_callback_ = callback;
139 } else {
140 user_read_buf_ = NULL;
141 user_read_buf_len_ = 0;
142 }
143
144 return rv;
145 }
146
147 int SSLServerSocketOpenSSL::Write(IOBuffer* buf, int buf_len,
148 const CompletionCallback& callback) {
149 DCHECK(user_write_callback_.is_null());
150 DCHECK(!user_write_buf_.get());
151 DCHECK(!callback.is_null());
152
153 user_write_buf_ = buf;
154 user_write_buf_len_ = buf_len;
155
156 int rv = DoWriteLoop(OK);
157
158 if (rv == ERR_IO_PENDING) {
159 user_write_callback_ = callback;
160 } else {
161 user_write_buf_ = NULL;
162 user_write_buf_len_ = 0;
163 }
164 return rv;
165 }
166
167 int SSLServerSocketOpenSSL::SetReceiveBufferSize(int32 size) {
168 return transport_socket_->SetReceiveBufferSize(size);
169 }
170
171 int SSLServerSocketOpenSSL::SetSendBufferSize(int32 size) {
172 return transport_socket_->SetSendBufferSize(size);
173 }
174
175 int SSLServerSocketOpenSSL::Connect(const CompletionCallback& callback) {
24 NOTIMPLEMENTED(); 176 NOTIMPLEMENTED();
25 return scoped_ptr<SSLServerSocket>(); 177 return ERR_NOT_IMPLEMENTED;
178 }
179
180 void SSLServerSocketOpenSSL::Disconnect() {
181 transport_socket_->Disconnect();
182 }
183
184 bool SSLServerSocketOpenSSL::IsConnected() const {
185 return completed_handshake_;
wtc 2014/05/16 03:57:17 Should we also test && transport_socket_->IsConnec
byungchul 2014/05/16 17:49:59 Not sure. Left a TODO to you.
186 }
187
188 bool SSLServerSocketOpenSSL::IsConnectedAndIdle() const {
189 return completed_handshake_ && transport_socket_->IsConnectedAndIdle();
190 }
191
192 int SSLServerSocketOpenSSL::GetPeerAddress(IPEndPoint* address) const {
193 if (!IsConnected())
194 return ERR_SOCKET_NOT_CONNECTED;
195 return transport_socket_->GetPeerAddress(address);
196 }
197
198 int SSLServerSocketOpenSSL::GetLocalAddress(IPEndPoint* address) const {
199 if (!IsConnected())
200 return ERR_SOCKET_NOT_CONNECTED;
201 return transport_socket_->GetLocalAddress(address);
202 }
203
204 const BoundNetLog& SSLServerSocketOpenSSL::NetLog() const {
205 return net_log_;
206 }
207
208 void SSLServerSocketOpenSSL::SetSubresourceSpeculation() {
209 transport_socket_->SetSubresourceSpeculation();
210 }
211
212 void SSLServerSocketOpenSSL::SetOmniboxSpeculation() {
213 transport_socket_->SetOmniboxSpeculation();
214 }
215
216 bool SSLServerSocketOpenSSL::WasEverUsed() const {
217 return transport_socket_->WasEverUsed();
218 }
219
220 bool SSLServerSocketOpenSSL::UsingTCPFastOpen() const {
221 return transport_socket_->UsingTCPFastOpen();
222 }
223
224 bool SSLServerSocketOpenSSL::WasNpnNegotiated() const {
225 return false;
wtc 2014/05/16 03:57:17 This probably should call NOTIMPLEMENTED().
byungchul 2014/05/16 17:49:59 Done.
226 }
227
228 NextProto SSLServerSocketOpenSSL::GetNegotiatedProtocol() const {
229 // NPN is not supported by this class.
230 return kProtoUnknown;
231 }
232
233 bool SSLServerSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) {
234 NOTIMPLEMENTED();
235 return false;
236 }
237
238 void SSLServerSocketOpenSSL::OnSendComplete(int result) {
239 if (next_handshake_state_ == STATE_HANDSHAKE) {
240 // In handshake phase.
241 OnHandshakeIOComplete(result);
242 return;
243 }
244
245 // TODO(byungchul): This state machine is not correct. Refactor this with
246 // SSLClientSocketOpenSSL::OnSendComplete() which handles it better.
247 if (!completed_handshake_)
248 return;
249
250 if (user_write_buf_.get()) {
251 int rv = DoWriteLoop(result);
252 if (rv != ERR_IO_PENDING)
253 DoWriteCallback(rv);
254 } else {
255 // Ensure that any queued ciphertext is flushed.
256 DoTransportIO();
257 }
258 }
259
260 void SSLServerSocketOpenSSL::OnRecvComplete(int result) {
261 if (next_handshake_state_ == STATE_HANDSHAKE) {
262 // In handshake phase.
263 OnHandshakeIOComplete(result);
264 return;
265 }
266
267 // Network layer received some data, check if client requested to read
268 // decrypted data.
269 if (!user_read_buf_.get() || !completed_handshake_)
270 return;
271
272 int rv = DoReadLoop(result);
273 if (rv != ERR_IO_PENDING)
274 DoReadCallback(rv);
275 }
276
277 void SSLServerSocketOpenSSL::OnHandshakeIOComplete(int result) {
278 int rv = DoHandshakeLoop(result);
279 if (rv == ERR_IO_PENDING)
280 return;
281
282 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv);
283 if (!user_handshake_callback_.is_null())
284 DoHandshakeCallback(rv);
285 }
286
287 // Return 0 for EOF,
288 // > 0 for bytes transferred immediately,
289 // < 0 for error (or the non-error ERR_IO_PENDING).
290 int SSLServerSocketOpenSSL::BufferSend() {
291 if (transport_send_busy_)
292 return ERR_IO_PENDING;
293
294 if (!send_buffer_.get()) {
295 // Get a fresh send buffer out of the send BIO.
296 size_t max_read = BIO_ctrl_pending(transport_bio_);
297 if (!max_read)
298 return 0; // Nothing pending in the OpenSSL write BIO.
299 send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read);
300 int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read);
301 DCHECK_GT(read_bytes, 0);
302 CHECK_EQ(static_cast<int>(max_read), read_bytes);
303 }
304
305 int rv = transport_socket_->Write(
306 send_buffer_.get(),
307 send_buffer_->BytesRemaining(),
308 base::Bind(&SSLServerSocketOpenSSL::BufferSendComplete,
309 base::Unretained(this)));
310 if (rv == ERR_IO_PENDING) {
311 transport_send_busy_ = true;
312 } else {
313 TransportWriteComplete(rv);
314 }
315 return rv;
316 }
317
318 void SSLServerSocketOpenSSL::BufferSendComplete(int result) {
319 transport_send_busy_ = false;
320 TransportWriteComplete(result);
321 OnSendComplete(result);
322 }
323
324 void SSLServerSocketOpenSSL::TransportWriteComplete(int result) {
325 DCHECK(ERR_IO_PENDING != result);
326 if (result < 0) {
327 // Got a socket write error; close the BIO to indicate this upward.
328 //
329 // TODO(davidben): The value of |result| gets lost. Feed the error back into
330 // the BIO so it gets (re-)detected in OnSendComplete. Perhaps with
331 // BIO_set_callback.
332 DVLOG(1) << "TransportWriteComplete error " << result;
333 (void)BIO_shutdown_wr(SSL_get_wbio(ssl_));
334
335 // Match the fix for http://crbug.com/249848 in NSS by erroring future reads
336 // from the socket after a write error.
337 //
338 // TODO(davidben): Avoid having read and write ends interact this way.
339 transport_write_error_ = result;
340 (void)BIO_shutdown_wr(transport_bio_);
341 send_buffer_ = NULL;
342 } else {
343 DCHECK(send_buffer_.get());
344 send_buffer_->DidConsume(result);
345 DCHECK_GE(send_buffer_->BytesRemaining(), 0);
346 if (send_buffer_->BytesRemaining() <= 0)
347 send_buffer_ = NULL;
348 }
349 }
350
351 int SSLServerSocketOpenSSL::BufferRecv() {
352 if (transport_recv_busy_)
353 return ERR_IO_PENDING;
354
355 // Determine how much was requested from |transport_bio_| that was not
356 // actually available.
357 size_t requested = BIO_ctrl_get_read_request(transport_bio_);
358 if (requested == 0) {
359 // This is not a perfect match of error codes, as no operation is
360 // actually pending. However, returning 0 would be interpreted as
361 // a possible sign of EOF, which is also an inappropriate match.
362 return ERR_IO_PENDING;
363 }
364
365 // Known Issue: While only reading |requested| data is the more correct
366 // implementation, it has the downside of resulting in frequent reads:
367 // One read for the SSL record header (~5 bytes) and one read for the SSL
368 // record body. Rather than issuing these reads to the underlying socket
369 // (and constantly allocating new IOBuffers), a single Read() request to
370 // fill |transport_bio_| is issued. As long as an SSL client socket cannot
371 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL
372 // traffic, this over-subscribed Read()ing will not cause issues.
373 size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_);
374 if (!max_write)
375 return ERR_IO_PENDING;
376
377 recv_buffer_ = new IOBuffer(max_write);
378 int rv = transport_socket_->Read(
379 recv_buffer_.get(),
380 max_write,
381 base::Bind(&SSLServerSocketOpenSSL::BufferRecvComplete,
382 base::Unretained(this)));
383 if (rv == ERR_IO_PENDING) {
384 transport_recv_busy_ = true;
385 } else {
386 rv = TransportReadComplete(rv);
387 }
388 return rv;
389 }
390
391 void SSLServerSocketOpenSSL::BufferRecvComplete(int result) {
392 result = TransportReadComplete(result);
393 OnRecvComplete(result);
394 }
395
396 int SSLServerSocketOpenSSL::TransportReadComplete(int result) {
397 DCHECK(ERR_IO_PENDING != result);
398 if (result <= 0) {
399 DVLOG(1) << "TransportReadComplete result " << result;
400 // Received 0 (end of file) or an error. Either way, bubble it up to the
401 // SSL layer via the BIO. TODO(joth): consider stashing the error code, to
402 // relay up to the SSL socket client (i.e. via DoReadCallback).
403 if (result == 0)
404 transport_recv_eof_ = true;
405 (void)BIO_shutdown_wr(transport_bio_);
406 } else if (transport_write_error_ < 0) {
407 // Mirror transport write errors as read failures; transport_bio_ has been
408 // shut down by TransportWriteComplete, so the BIO_write will fail, failing
409 // the CHECK. http://crbug.com/335557.
410 result = transport_write_error_;
411 } else {
412 DCHECK(recv_buffer_.get());
413 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result);
414 // A write into a memory BIO should always succeed.
415 DCHECK_EQ(result, ret);
416 }
417 recv_buffer_ = NULL;
418 transport_recv_busy_ = false;
419 return result;
420 }
421
422 // Do as much network I/O as possible between the buffer and the
423 // transport socket. Return true if some I/O performed, false
424 // otherwise (error or ERR_IO_PENDING).
425 bool SSLServerSocketOpenSSL::DoTransportIO() {
426 bool network_moved = false;
427 int rv;
428 // Read and write as much data as possible. The loop is necessary because
429 // Write() may return synchronously.
430 do {
431 rv = BufferSend();
432 if (rv != ERR_IO_PENDING && rv != 0)
433 network_moved = true;
434 } while (rv > 0);
435 if (!transport_recv_eof_ && BufferRecv() != ERR_IO_PENDING)
436 network_moved = true;
437 return network_moved;
438 }
439
440 int SSLServerSocketOpenSSL::DoPayloadRead() {
441 DCHECK(user_read_buf_.get());
442 DCHECK_GT(user_read_buf_len_, 0);
443 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
444 int rv = SSL_read(ssl_, user_read_buf_->data(), user_read_buf_len_);
445 if (rv >= 0)
446 return rv;
447 int ssl_error = SSL_get_error(ssl_, rv);
448 int net_error = MapOpenSSLError(ssl_error, err_tracer);
449 if (net_error != ERR_IO_PENDING) {
450 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
451 CreateNetLogSSLErrorCallback(net_error, ssl_error));
452 }
453 return net_error;
454 }
455
456 int SSLServerSocketOpenSSL::DoPayloadWrite() {
457 DCHECK(user_write_buf_.get());
458 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
459 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
460 if (rv >= 0)
461 return rv;
462 int ssl_error = SSL_get_error(ssl_, rv);
463 int net_error = MapOpenSSLError(ssl_error, err_tracer);
464 if (net_error != ERR_IO_PENDING) {
465 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
466 CreateNetLogSSLErrorCallback(net_error, ssl_error));
467 }
468 return net_error;
469 }
470
471 int SSLServerSocketOpenSSL::DoHandshakeLoop(int last_io_result) {
472 int rv = last_io_result;
473 do {
474 // Default to STATE_NONE for next state.
475 // (This is a quirk carried over from the windows
476 // implementation. It makes reading the logs a bit harder.)
477 // State handlers can and often do call GotoState just
478 // to stay in the current state.
479 State state = next_handshake_state_;
480 GotoState(STATE_NONE);
481 switch (state) {
482 case STATE_HANDSHAKE:
483 rv = DoHandshake();
484 break;
485 case STATE_NONE:
486 default:
487 rv = ERR_UNEXPECTED;
488 LOG(DFATAL) << "unexpected state " << state;
489 break;
490 }
491
492 // Do the actual network I/O
493 bool network_moved = DoTransportIO();
494 if (network_moved && next_handshake_state_ == STATE_HANDSHAKE) {
495 // In general we exit the loop if rv is ERR_IO_PENDING. In this
496 // special case we keep looping even if rv is ERR_IO_PENDING because
497 // the transport IO may allow DoHandshake to make progress.
498 rv = OK; // This causes us to stay in the loop.
499 }
500 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
501 return rv;
502 }
503
504 int SSLServerSocketOpenSSL::DoReadLoop(int result) {
505 DCHECK(completed_handshake_);
506 DCHECK(next_handshake_state_ == STATE_NONE);
507
508 if (result < 0)
509 return result;
510
511 bool network_moved;
512 int rv;
513 do {
514 rv = DoPayloadRead();
515 network_moved = DoTransportIO();
516 } while (rv == ERR_IO_PENDING && network_moved);
517 return rv;
518 }
519
520 int SSLServerSocketOpenSSL::DoWriteLoop(int result) {
521 DCHECK(completed_handshake_);
522 DCHECK_EQ(next_handshake_state_, STATE_NONE);
523
524 if (result < 0)
525 return result;
526
527 bool network_moved;
528 int rv;
529 do {
530 rv = DoPayloadWrite();
531 network_moved = DoTransportIO();
532 } while (rv == ERR_IO_PENDING && network_moved);
533 return rv;
534 }
535
536 int SSLServerSocketOpenSSL::DoHandshake() {
537 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
538 int net_error = net::OK;
539 int rv = SSL_do_handshake(ssl_);
540
541 if (rv == 1) {
542 completed_handshake_ = true;
543 } else {
544 int ssl_error = SSL_get_error(ssl_, rv);
545 net_error = MapOpenSSLError(ssl_error, err_tracer);
546
547 // If not done, stay in this state
548 if (net_error == ERR_IO_PENDING) {
549 GotoState(STATE_HANDSHAKE);
550 } else {
551 LOG(ERROR) << "handshake failed; returned " << rv
552 << ", SSL error code " << ssl_error
553 << ", net_error " << net_error;
554 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
555 CreateNetLogSSLErrorCallback(net_error, ssl_error));
556 }
557 }
558 return net_error;
559 }
560
561 void SSLServerSocketOpenSSL::DoHandshakeCallback(int rv) {
562 DCHECK_NE(rv, ERR_IO_PENDING);
563 ResetAndReturn(&user_handshake_callback_).Run(rv > OK ? OK : rv);
564 }
565
566 void SSLServerSocketOpenSSL::DoReadCallback(int rv) {
567 DCHECK(rv != ERR_IO_PENDING);
568 DCHECK(!user_read_callback_.is_null());
569
570 user_read_buf_ = NULL;
571 user_read_buf_len_ = 0;
572 // Since Run may result in Read being called, clear |user_read_callback_|
573 // up front.
574 ResetAndReturn(&user_read_callback_).Run(rv);
575 }
576
577 void SSLServerSocketOpenSSL::DoWriteCallback(int rv) {
578 DCHECK(rv != ERR_IO_PENDING);
579 DCHECK(!user_write_callback_.is_null());
580
581 user_write_buf_ = NULL;
582 user_write_buf_len_ = 0;
583 // Since Run may result in Write being called, clear |user_write_callback_|
584 // up front.
585 ResetAndReturn(&user_write_callback_).Run(rv);
586 }
587
588 bool SSLServerSocketOpenSSL::Init() {
589 DCHECK(!ssl_);
590 DCHECK(!transport_bio_);
591
592 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
593
594 crypto::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx(
595 // It support SSLv2, SSLv3, and TLSv1.
596 SSL_CTX_new(SSLv23_server_method()));
597 ssl_ = SSL_new(ssl_ctx.get());
598 if (!ssl_)
599 return false;
600
601 BIO* ssl_bio = NULL;
602 // 0 => use default buffer sizes.
603 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_, 0))
604 return false;
605 DCHECK(ssl_bio);
606 DCHECK(transport_bio_);
607
608 SSL_set_bio(ssl_, ssl_bio, ssl_bio);
609
610 // Set certificate and private key.
611 DCHECK(cert_->os_cert_handle());
612 if (SSL_use_certificate(ssl_, cert_->os_cert_handle()) != 1) {
613 LOG(ERROR) << "Cannot set certificate.";
614 return false;
615 }
616
617 DCHECK(key_->key());
618 if (SSL_use_PrivateKey(ssl_, key_->key()) != 1) {
619 LOG(ERROR) << "Cannot set private key.";
620 return false;
621 }
622
623 // OpenSSL defaults some options to on, others to off. To avoid ambiguity,
624 // set everything we care about to an absolute value.
625 SslSetClearMask options;
626 options.ConfigureFlag(SSL_OP_NO_SSLv2, true);
627 bool ssl3_enabled = (ssl_config_.version_min == SSL_PROTOCOL_VERSION_SSL3);
628 options.ConfigureFlag(SSL_OP_NO_SSLv3, !ssl3_enabled);
629 bool tls1_enabled = (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1 &&
630 ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1);
631 options.ConfigureFlag(SSL_OP_NO_TLSv1, !tls1_enabled);
632 bool tls1_1_enabled =
633 (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1_1 &&
634 ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1_1);
635 options.ConfigureFlag(SSL_OP_NO_TLSv1_1, !tls1_1_enabled);
636 bool tls1_2_enabled =
637 (ssl_config_.version_min <= SSL_PROTOCOL_VERSION_TLS1_2 &&
638 ssl_config_.version_max >= SSL_PROTOCOL_VERSION_TLS1_2);
639 options.ConfigureFlag(SSL_OP_NO_TLSv1_2, !tls1_2_enabled);
640
641 options.ConfigureFlag(SSL_OP_NO_COMPRESSION, true);
642
643 SSL_set_options(ssl_, options.set_mask);
644 SSL_clear_options(ssl_, options.clear_mask);
645
646 // Same as above, this time for the SSL mode.
647 SslSetClearMask mode;
648
649 mode.ConfigureFlag(SSL_MODE_RELEASE_BUFFERS, true);
650
651 SSL_set_mode(ssl_, mode.set_mask);
652 SSL_clear_mode(ssl_, mode.clear_mask);
653
654 return true;
26 } 655 }
27 656
28 } // namespace net 657 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698