| OLD | NEW |
| 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_impl.h" | 5 #include "net/socket/ssl_server_socket_impl.h" |
| 6 | 6 |
| 7 #include <openssl/err.h> | 7 #include <openssl/err.h> |
| 8 #include <openssl/ssl.h> | 8 #include <openssl/ssl.h> |
| 9 #include <openssl/x509.h> | 9 #include <openssl/x509.h> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 15 #include "crypto/openssl_util.h" | 15 #include "crypto/openssl_util.h" |
| 16 #include "crypto/rsa_private_key.h" | 16 #include "crypto/rsa_private_key.h" |
| 17 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
| 18 #include "net/cert/cert_verify_result.h" | 18 #include "net/cert/cert_verify_result.h" |
| 19 #include "net/cert/client_cert_verifier.h" | 19 #include "net/cert/client_cert_verifier.h" |
| 20 #include "net/cert/x509_util_openssl.h" | 20 #include "net/cert/x509_util_openssl.h" |
| 21 #include "net/log/net_log_event_type.h" | 21 #include "net/log/net_log_event_type.h" |
| 22 #include "net/log/net_log_with_source.h" | 22 #include "net/log/net_log_with_source.h" |
| 23 #include "net/socket/socket_bio_adapter.h" |
| 23 #include "net/ssl/openssl_ssl_util.h" | 24 #include "net/ssl/openssl_ssl_util.h" |
| 24 #include "net/ssl/ssl_connection_status_flags.h" | 25 #include "net/ssl/ssl_connection_status_flags.h" |
| 25 #include "net/ssl/ssl_info.h" | 26 #include "net/ssl/ssl_info.h" |
| 26 | 27 |
| 27 #define GotoState(s) next_handshake_state_ = s | 28 #define GotoState(s) next_handshake_state_ = s |
| 28 | 29 |
| 29 namespace net { | 30 namespace net { |
| 30 | 31 |
| 31 namespace { | 32 namespace { |
| 32 | 33 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 46 for (size_t i = 0; i < sk_X509_num(chain); ++i) { | 47 for (size_t i = 0; i < sk_X509_num(chain); ++i) { |
| 47 X509* x = sk_X509_value(chain, i); | 48 X509* x = sk_X509_value(chain, i); |
| 48 if (!x509_util::GetDER(x, &der_cert)) | 49 if (!x509_util::GetDER(x, &der_cert)) |
| 49 return nullptr; | 50 return nullptr; |
| 50 der_chain.push_back(der_cert); | 51 der_chain.push_back(der_cert); |
| 51 } | 52 } |
| 52 | 53 |
| 53 return X509Certificate::CreateFromDERCertChain(der_chain); | 54 return X509Certificate::CreateFromDERCertChain(der_chain); |
| 54 } | 55 } |
| 55 | 56 |
| 56 class SSLServerSocketImpl : public SSLServerSocket { | 57 class SSLServerSocketImpl : public SSLServerSocket, |
| 58 public SocketBIOAdapter::Delegate { |
| 57 public: | 59 public: |
| 58 // See comments on CreateSSLServerSocket for details of how these | 60 // See comments on CreateSSLServerSocket for details of how these |
| 59 // parameters are used. | 61 // parameters are used. |
| 60 SSLServerSocketImpl(std::unique_ptr<StreamSocket> socket, | 62 SSLServerSocketImpl(std::unique_ptr<StreamSocket> socket, |
| 61 bssl::UniquePtr<SSL> ssl); | 63 bssl::UniquePtr<SSL> ssl); |
| 62 ~SSLServerSocketImpl() override; | 64 ~SSLServerSocketImpl() override; |
| 63 | 65 |
| 64 // SSLServerSocket interface. | 66 // SSLServerSocket interface. |
| 65 int Handshake(const CompletionCallback& callback) override; | 67 int Handshake(const CompletionCallback& callback) override; |
| 66 | 68 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 94 bool WasEverUsed() const override; | 96 bool WasEverUsed() const override; |
| 95 bool WasNpnNegotiated() const override; | 97 bool WasNpnNegotiated() const override; |
| 96 NextProto GetNegotiatedProtocol() const override; | 98 NextProto GetNegotiatedProtocol() const override; |
| 97 bool GetSSLInfo(SSLInfo* ssl_info) override; | 99 bool GetSSLInfo(SSLInfo* ssl_info) override; |
| 98 void GetConnectionAttempts(ConnectionAttempts* out) const override; | 100 void GetConnectionAttempts(ConnectionAttempts* out) const override; |
| 99 void ClearConnectionAttempts() override {} | 101 void ClearConnectionAttempts() override {} |
| 100 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {} | 102 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {} |
| 101 int64_t GetTotalReceivedBytes() const override; | 103 int64_t GetTotalReceivedBytes() const override; |
| 102 static int CertVerifyCallback(X509_STORE_CTX* store_ctx, void* arg); | 104 static int CertVerifyCallback(X509_STORE_CTX* store_ctx, void* arg); |
| 103 | 105 |
| 106 // SocketBIOAdapter::Delegate implementation. |
| 107 void OnReadReady() override; |
| 108 void OnWriteReady() override; |
| 109 |
| 104 private: | 110 private: |
| 105 enum State { | 111 enum State { |
| 106 STATE_NONE, | 112 STATE_NONE, |
| 107 STATE_HANDSHAKE, | 113 STATE_HANDSHAKE, |
| 108 }; | 114 }; |
| 109 | 115 |
| 110 void OnSendComplete(int result); | |
| 111 void OnRecvComplete(int result); | |
| 112 void OnHandshakeIOComplete(int result); | 116 void OnHandshakeIOComplete(int result); |
| 113 | 117 |
| 114 int BufferSend(); | |
| 115 void BufferSendComplete(int result); | |
| 116 void TransportWriteComplete(int result); | |
| 117 int BufferRecv(); | |
| 118 void BufferRecvComplete(int result); | |
| 119 int TransportReadComplete(int result); | |
| 120 bool DoTransportIO(); | |
| 121 int DoPayloadRead(); | 118 int DoPayloadRead(); |
| 122 int DoPayloadWrite(); | 119 int DoPayloadWrite(); |
| 123 | 120 |
| 124 int DoHandshakeLoop(int last_io_result); | 121 int DoHandshakeLoop(int last_io_result); |
| 125 int DoReadLoop(int result); | |
| 126 int DoWriteLoop(int result); | |
| 127 int DoHandshake(); | 122 int DoHandshake(); |
| 128 void DoHandshakeCallback(int result); | 123 void DoHandshakeCallback(int result); |
| 129 void DoReadCallback(int result); | 124 void DoReadCallback(int result); |
| 130 void DoWriteCallback(int result); | 125 void DoWriteCallback(int result); |
| 131 | 126 |
| 132 int Init(); | 127 int Init(); |
| 133 void ExtractClientCert(); | 128 void ExtractClientCert(); |
| 134 | 129 |
| 135 // Members used to send and receive buffer. | |
| 136 bool transport_send_busy_; | |
| 137 bool transport_recv_busy_; | |
| 138 bool transport_recv_eof_; | |
| 139 | |
| 140 scoped_refptr<DrainableIOBuffer> send_buffer_; | |
| 141 scoped_refptr<IOBuffer> recv_buffer_; | |
| 142 | |
| 143 NetLogWithSource net_log_; | 130 NetLogWithSource net_log_; |
| 144 | 131 |
| 145 CompletionCallback user_handshake_callback_; | 132 CompletionCallback user_handshake_callback_; |
| 146 CompletionCallback user_read_callback_; | 133 CompletionCallback user_read_callback_; |
| 147 CompletionCallback user_write_callback_; | 134 CompletionCallback user_write_callback_; |
| 148 | 135 |
| 149 // Used by Read function. | 136 // Used by Read function. |
| 150 scoped_refptr<IOBuffer> user_read_buf_; | 137 scoped_refptr<IOBuffer> user_read_buf_; |
| 151 int user_read_buf_len_; | 138 int user_read_buf_len_; |
| 152 | 139 |
| 153 // Used by Write function. | 140 // Used by Write function. |
| 154 scoped_refptr<IOBuffer> user_write_buf_; | 141 scoped_refptr<IOBuffer> user_write_buf_; |
| 155 int user_write_buf_len_; | 142 int user_write_buf_len_; |
| 156 | 143 |
| 157 // Used by TransportWriteComplete() and TransportReadComplete() to signify an | |
| 158 // error writing to the transport socket. A value of OK indicates no error. | |
| 159 int transport_write_error_; | |
| 160 | |
| 161 // OpenSSL stuff | 144 // OpenSSL stuff |
| 162 bssl::UniquePtr<SSL> ssl_; | 145 bssl::UniquePtr<SSL> ssl_; |
| 163 bssl::UniquePtr<BIO> transport_bio_; | |
| 164 | 146 |
| 165 // StreamSocket for sending and receiving data. | 147 // StreamSocket for sending and receiving data. |
| 166 std::unique_ptr<StreamSocket> transport_socket_; | 148 std::unique_ptr<StreamSocket> transport_socket_; |
| 149 std::unique_ptr<SocketBIOAdapter> transport_adapter_; |
| 167 | 150 |
| 168 // Certificate for the client. | 151 // Certificate for the client. |
| 169 scoped_refptr<X509Certificate> client_cert_; | 152 scoped_refptr<X509Certificate> client_cert_; |
| 170 | 153 |
| 171 State next_handshake_state_; | 154 State next_handshake_state_; |
| 172 bool completed_handshake_; | 155 bool completed_handshake_; |
| 173 | 156 |
| 174 DISALLOW_COPY_AND_ASSIGN(SSLServerSocketImpl); | 157 DISALLOW_COPY_AND_ASSIGN(SSLServerSocketImpl); |
| 175 }; | 158 }; |
| 176 | 159 |
| 177 SSLServerSocketImpl::SSLServerSocketImpl( | 160 SSLServerSocketImpl::SSLServerSocketImpl( |
| 178 std::unique_ptr<StreamSocket> transport_socket, | 161 std::unique_ptr<StreamSocket> transport_socket, |
| 179 bssl::UniquePtr<SSL> ssl) | 162 bssl::UniquePtr<SSL> ssl) |
| 180 : transport_send_busy_(false), | 163 : user_read_buf_len_(0), |
| 181 transport_recv_busy_(false), | |
| 182 transport_recv_eof_(false), | |
| 183 user_read_buf_len_(0), | |
| 184 user_write_buf_len_(0), | 164 user_write_buf_len_(0), |
| 185 transport_write_error_(OK), | |
| 186 ssl_(std::move(ssl)), | 165 ssl_(std::move(ssl)), |
| 187 transport_socket_(std::move(transport_socket)), | 166 transport_socket_(std::move(transport_socket)), |
| 188 next_handshake_state_(STATE_NONE), | 167 next_handshake_state_(STATE_NONE), |
| 189 completed_handshake_(false) {} | 168 completed_handshake_(false) {} |
| 190 | 169 |
| 191 SSLServerSocketImpl::~SSLServerSocketImpl() { | 170 SSLServerSocketImpl::~SSLServerSocketImpl() { |
| 192 if (ssl_) { | 171 if (ssl_) { |
| 193 // Calling SSL_shutdown prevents the session from being marked as | 172 // Calling SSL_shutdown prevents the session from being marked as |
| 194 // unresumable. | 173 // unresumable. |
| 195 SSL_shutdown(ssl_.get()); | 174 SSL_shutdown(ssl_.get()); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 DCHECK(user_read_callback_.is_null()); | 233 DCHECK(user_read_callback_.is_null()); |
| 255 DCHECK(user_handshake_callback_.is_null()); | 234 DCHECK(user_handshake_callback_.is_null()); |
| 256 DCHECK(!user_read_buf_); | 235 DCHECK(!user_read_buf_); |
| 257 DCHECK(!callback.is_null()); | 236 DCHECK(!callback.is_null()); |
| 258 | 237 |
| 259 user_read_buf_ = buf; | 238 user_read_buf_ = buf; |
| 260 user_read_buf_len_ = buf_len; | 239 user_read_buf_len_ = buf_len; |
| 261 | 240 |
| 262 DCHECK(completed_handshake_); | 241 DCHECK(completed_handshake_); |
| 263 | 242 |
| 264 int rv = DoReadLoop(OK); | 243 int rv = DoPayloadRead(); |
| 265 | 244 |
| 266 if (rv == ERR_IO_PENDING) { | 245 if (rv == ERR_IO_PENDING) { |
| 267 user_read_callback_ = callback; | 246 user_read_callback_ = callback; |
| 268 } else { | 247 } else { |
| 269 user_read_buf_ = NULL; | 248 user_read_buf_ = NULL; |
| 270 user_read_buf_len_ = 0; | 249 user_read_buf_len_ = 0; |
| 271 } | 250 } |
| 272 | 251 |
| 273 return rv; | 252 return rv; |
| 274 } | 253 } |
| 275 | 254 |
| 276 int SSLServerSocketImpl::Write(IOBuffer* buf, | 255 int SSLServerSocketImpl::Write(IOBuffer* buf, |
| 277 int buf_len, | 256 int buf_len, |
| 278 const CompletionCallback& callback) { | 257 const CompletionCallback& callback) { |
| 279 DCHECK(user_write_callback_.is_null()); | 258 DCHECK(user_write_callback_.is_null()); |
| 280 DCHECK(!user_write_buf_); | 259 DCHECK(!user_write_buf_); |
| 281 DCHECK(!callback.is_null()); | 260 DCHECK(!callback.is_null()); |
| 282 | 261 |
| 283 user_write_buf_ = buf; | 262 user_write_buf_ = buf; |
| 284 user_write_buf_len_ = buf_len; | 263 user_write_buf_len_ = buf_len; |
| 285 | 264 |
| 286 int rv = DoWriteLoop(OK); | 265 int rv = DoPayloadWrite(); |
| 287 | 266 |
| 288 if (rv == ERR_IO_PENDING) { | 267 if (rv == ERR_IO_PENDING) { |
| 289 user_write_callback_ = callback; | 268 user_write_callback_ = callback; |
| 290 } else { | 269 } else { |
| 291 user_write_buf_ = NULL; | 270 user_write_buf_ = NULL; |
| 292 user_write_buf_len_ = 0; | 271 user_write_buf_len_ = 0; |
| 293 } | 272 } |
| 294 return rv; | 273 return rv; |
| 295 } | 274 } |
| 296 | 275 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 } | 366 } |
| 388 | 367 |
| 389 void SSLServerSocketImpl::GetConnectionAttempts(ConnectionAttempts* out) const { | 368 void SSLServerSocketImpl::GetConnectionAttempts(ConnectionAttempts* out) const { |
| 390 out->clear(); | 369 out->clear(); |
| 391 } | 370 } |
| 392 | 371 |
| 393 int64_t SSLServerSocketImpl::GetTotalReceivedBytes() const { | 372 int64_t SSLServerSocketImpl::GetTotalReceivedBytes() const { |
| 394 return transport_socket_->GetTotalReceivedBytes(); | 373 return transport_socket_->GetTotalReceivedBytes(); |
| 395 } | 374 } |
| 396 | 375 |
| 397 void SSLServerSocketImpl::OnSendComplete(int result) { | 376 void SSLServerSocketImpl::OnReadReady() { |
| 398 if (next_handshake_state_ == STATE_HANDSHAKE) { | 377 if (next_handshake_state_ == STATE_HANDSHAKE) { |
| 399 // In handshake phase. | 378 // In handshake phase. The parameter to OnHandshakeIOComplete is unused. |
| 400 OnHandshakeIOComplete(result); | 379 OnHandshakeIOComplete(OK); |
| 401 return; | 380 return; |
| 402 } | 381 } |
| 403 | 382 |
| 404 // TODO(byungchul): This state machine is not correct. Copy the state machine | 383 // BoringSSL does not support renegotiation as a server, so the only other |
| 405 // of SSLClientSocketImpl::OnSendComplete() which handles it better. | 384 // operation blocked on Read is DoPayloadRead. |
| 406 if (!completed_handshake_) | 385 if (!user_read_buf_) |
| 407 return; | 386 return; |
| 408 | 387 |
| 409 if (user_write_buf_) { | 388 int rv = DoPayloadRead(); |
| 410 int rv = DoWriteLoop(result); | |
| 411 if (rv != ERR_IO_PENDING) | |
| 412 DoWriteCallback(rv); | |
| 413 } else { | |
| 414 // Ensure that any queued ciphertext is flushed. | |
| 415 DoTransportIO(); | |
| 416 } | |
| 417 } | |
| 418 | |
| 419 void SSLServerSocketImpl::OnRecvComplete(int result) { | |
| 420 if (next_handshake_state_ == STATE_HANDSHAKE) { | |
| 421 // In handshake phase. | |
| 422 OnHandshakeIOComplete(result); | |
| 423 return; | |
| 424 } | |
| 425 | |
| 426 // Network layer received some data, check if client requested to read | |
| 427 // decrypted data. | |
| 428 if (!user_read_buf_ || !completed_handshake_) | |
| 429 return; | |
| 430 | |
| 431 int rv = DoReadLoop(result); | |
| 432 if (rv != ERR_IO_PENDING) | 389 if (rv != ERR_IO_PENDING) |
| 433 DoReadCallback(rv); | 390 DoReadCallback(rv); |
| 434 } | 391 } |
| 435 | 392 |
| 393 void SSLServerSocketImpl::OnWriteReady() { |
| 394 if (next_handshake_state_ == STATE_HANDSHAKE) { |
| 395 // In handshake phase. The parameter to OnHandshakeIOComplete is unused. |
| 396 OnHandshakeIOComplete(OK); |
| 397 return; |
| 398 } |
| 399 |
| 400 // BoringSSL does not support renegotiation as a server, so the only other |
| 401 // operation blocked on Read is DoPayloadWrite. |
| 402 if (!user_write_buf_) |
| 403 return; |
| 404 |
| 405 int rv = DoPayloadWrite(); |
| 406 if (rv != ERR_IO_PENDING) |
| 407 DoWriteCallback(rv); |
| 408 } |
| 409 |
| 436 void SSLServerSocketImpl::OnHandshakeIOComplete(int result) { | 410 void SSLServerSocketImpl::OnHandshakeIOComplete(int result) { |
| 437 int rv = DoHandshakeLoop(result); | 411 int rv = DoHandshakeLoop(result); |
| 438 if (rv == ERR_IO_PENDING) | 412 if (rv == ERR_IO_PENDING) |
| 439 return; | 413 return; |
| 440 | 414 |
| 441 net_log_.EndEventWithNetErrorCode(NetLogEventType::SSL_SERVER_HANDSHAKE, rv); | 415 net_log_.EndEventWithNetErrorCode(NetLogEventType::SSL_SERVER_HANDSHAKE, rv); |
| 442 if (!user_handshake_callback_.is_null()) | 416 if (!user_handshake_callback_.is_null()) |
| 443 DoHandshakeCallback(rv); | 417 DoHandshakeCallback(rv); |
| 444 } | 418 } |
| 445 | 419 |
| 446 // Return 0 for EOF, | |
| 447 // > 0 for bytes transferred immediately, | |
| 448 // < 0 for error (or the non-error ERR_IO_PENDING). | |
| 449 int SSLServerSocketImpl::BufferSend() { | |
| 450 if (transport_send_busy_) | |
| 451 return ERR_IO_PENDING; | |
| 452 | |
| 453 if (!send_buffer_) { | |
| 454 // Get a fresh send buffer out of the send BIO. | |
| 455 size_t max_read = BIO_pending(transport_bio_.get()); | |
| 456 if (!max_read) | |
| 457 return 0; // Nothing pending in the OpenSSL write BIO. | |
| 458 send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read); | |
| 459 int read_bytes = | |
| 460 BIO_read(transport_bio_.get(), send_buffer_->data(), max_read); | |
| 461 DCHECK_GT(read_bytes, 0); | |
| 462 CHECK_EQ(static_cast<int>(max_read), read_bytes); | |
| 463 } | |
| 464 | |
| 465 int rv = transport_socket_->Write( | |
| 466 send_buffer_.get(), send_buffer_->BytesRemaining(), | |
| 467 base::Bind(&SSLServerSocketImpl::BufferSendComplete, | |
| 468 base::Unretained(this))); | |
| 469 if (rv == ERR_IO_PENDING) { | |
| 470 transport_send_busy_ = true; | |
| 471 } else { | |
| 472 TransportWriteComplete(rv); | |
| 473 } | |
| 474 return rv; | |
| 475 } | |
| 476 | |
| 477 void SSLServerSocketImpl::BufferSendComplete(int result) { | |
| 478 transport_send_busy_ = false; | |
| 479 TransportWriteComplete(result); | |
| 480 OnSendComplete(result); | |
| 481 } | |
| 482 | |
| 483 void SSLServerSocketImpl::TransportWriteComplete(int result) { | |
| 484 DCHECK(ERR_IO_PENDING != result); | |
| 485 if (result < 0) { | |
| 486 // Got a socket write error; close the BIO to indicate this upward. | |
| 487 // | |
| 488 // TODO(davidben): The value of |result| gets lost. Feed the error back into | |
| 489 // the BIO so it gets (re-)detected in OnSendComplete. Perhaps with | |
| 490 // BIO_set_callback. | |
| 491 DVLOG(1) << "TransportWriteComplete error " << result; | |
| 492 (void)BIO_shutdown_wr(SSL_get_wbio(ssl_.get())); | |
| 493 | |
| 494 // Match the fix for http://crbug.com/249848 in NSS by erroring future reads | |
| 495 // from the socket after a write error. | |
| 496 // | |
| 497 // TODO(davidben): Avoid having read and write ends interact this way. | |
| 498 transport_write_error_ = result; | |
| 499 (void)BIO_shutdown_wr(transport_bio_.get()); | |
| 500 send_buffer_ = NULL; | |
| 501 } else { | |
| 502 DCHECK(send_buffer_); | |
| 503 send_buffer_->DidConsume(result); | |
| 504 DCHECK_GE(send_buffer_->BytesRemaining(), 0); | |
| 505 if (send_buffer_->BytesRemaining() <= 0) | |
| 506 send_buffer_ = NULL; | |
| 507 } | |
| 508 } | |
| 509 | |
| 510 int SSLServerSocketImpl::BufferRecv() { | |
| 511 if (transport_recv_busy_) | |
| 512 return ERR_IO_PENDING; | |
| 513 | |
| 514 // Determine how much was requested from |transport_bio_| that was not | |
| 515 // actually available. | |
| 516 size_t requested = BIO_ctrl_get_read_request(transport_bio_.get()); | |
| 517 if (requested == 0) { | |
| 518 // This is not a perfect match of error codes, as no operation is | |
| 519 // actually pending. However, returning 0 would be interpreted as | |
| 520 // a possible sign of EOF, which is also an inappropriate match. | |
| 521 return ERR_IO_PENDING; | |
| 522 } | |
| 523 | |
| 524 // Known Issue: While only reading |requested| data is the more correct | |
| 525 // implementation, it has the downside of resulting in frequent reads: | |
| 526 // One read for the SSL record header (~5 bytes) and one read for the SSL | |
| 527 // record body. Rather than issuing these reads to the underlying socket | |
| 528 // (and constantly allocating new IOBuffers), a single Read() request to | |
| 529 // fill |transport_bio_| is issued. As long as an SSL client socket cannot | |
| 530 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL | |
| 531 // traffic, this over-subscribed Read()ing will not cause issues. | |
| 532 size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_.get()); | |
| 533 if (!max_write) | |
| 534 return ERR_IO_PENDING; | |
| 535 | |
| 536 recv_buffer_ = new IOBuffer(max_write); | |
| 537 int rv = transport_socket_->Read( | |
| 538 recv_buffer_.get(), max_write, | |
| 539 base::Bind(&SSLServerSocketImpl::BufferRecvComplete, | |
| 540 base::Unretained(this))); | |
| 541 if (rv == ERR_IO_PENDING) { | |
| 542 transport_recv_busy_ = true; | |
| 543 } else { | |
| 544 rv = TransportReadComplete(rv); | |
| 545 } | |
| 546 return rv; | |
| 547 } | |
| 548 | |
| 549 void SSLServerSocketImpl::BufferRecvComplete(int result) { | |
| 550 result = TransportReadComplete(result); | |
| 551 OnRecvComplete(result); | |
| 552 } | |
| 553 | |
| 554 int SSLServerSocketImpl::TransportReadComplete(int result) { | |
| 555 DCHECK(ERR_IO_PENDING != result); | |
| 556 if (result <= 0) { | |
| 557 DVLOG(1) << "TransportReadComplete result " << result; | |
| 558 // Received 0 (end of file) or an error. Either way, bubble it up to the | |
| 559 // SSL layer via the BIO. TODO(joth): consider stashing the error code, to | |
| 560 // relay up to the SSL socket client (i.e. via DoReadCallback). | |
| 561 if (result == 0) | |
| 562 transport_recv_eof_ = true; | |
| 563 (void)BIO_shutdown_wr(transport_bio_.get()); | |
| 564 } else if (transport_write_error_ < 0) { | |
| 565 // Mirror transport write errors as read failures; transport_bio_ has been | |
| 566 // shut down by TransportWriteComplete, so the BIO_write will fail, failing | |
| 567 // the CHECK. http://crbug.com/335557. | |
| 568 result = transport_write_error_; | |
| 569 } else { | |
| 570 DCHECK(recv_buffer_); | |
| 571 int ret = BIO_write(transport_bio_.get(), recv_buffer_->data(), result); | |
| 572 // A write into a memory BIO should always succeed. | |
| 573 DCHECK_EQ(result, ret); | |
| 574 } | |
| 575 recv_buffer_ = NULL; | |
| 576 transport_recv_busy_ = false; | |
| 577 return result; | |
| 578 } | |
| 579 | |
| 580 // Do as much network I/O as possible between the buffer and the | |
| 581 // transport socket. Return true if some I/O performed, false | |
| 582 // otherwise (error or ERR_IO_PENDING). | |
| 583 bool SSLServerSocketImpl::DoTransportIO() { | |
| 584 bool network_moved = false; | |
| 585 int rv; | |
| 586 // Read and write as much data as possible. The loop is necessary because | |
| 587 // Write() may return synchronously. | |
| 588 do { | |
| 589 rv = BufferSend(); | |
| 590 if (rv != ERR_IO_PENDING && rv != 0) | |
| 591 network_moved = true; | |
| 592 } while (rv > 0); | |
| 593 if (!transport_recv_eof_ && BufferRecv() != ERR_IO_PENDING) | |
| 594 network_moved = true; | |
| 595 return network_moved; | |
| 596 } | |
| 597 | 420 |
| 598 int SSLServerSocketImpl::DoPayloadRead() { | 421 int SSLServerSocketImpl::DoPayloadRead() { |
| 422 DCHECK(completed_handshake_); |
| 423 DCHECK_EQ(STATE_NONE, next_handshake_state_); |
| 599 DCHECK(user_read_buf_); | 424 DCHECK(user_read_buf_); |
| 600 DCHECK_GT(user_read_buf_len_, 0); | 425 DCHECK_GT(user_read_buf_len_, 0); |
| 426 |
| 601 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 427 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 602 int rv = SSL_read(ssl_.get(), user_read_buf_->data(), user_read_buf_len_); | 428 int rv = SSL_read(ssl_.get(), user_read_buf_->data(), user_read_buf_len_); |
| 603 if (rv >= 0) | 429 if (rv >= 0) |
| 604 return rv; | 430 return rv; |
| 605 int ssl_error = SSL_get_error(ssl_.get(), rv); | 431 int ssl_error = SSL_get_error(ssl_.get(), rv); |
| 606 OpenSSLErrorInfo error_info; | 432 OpenSSLErrorInfo error_info; |
| 607 int net_error = | 433 int net_error = |
| 608 MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); | 434 MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); |
| 609 if (net_error != ERR_IO_PENDING) { | 435 if (net_error != ERR_IO_PENDING) { |
| 610 net_log_.AddEvent( | 436 net_log_.AddEvent( |
| 611 NetLogEventType::SSL_READ_ERROR, | 437 NetLogEventType::SSL_READ_ERROR, |
| 612 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); | 438 CreateNetLogOpenSSLErrorCallback(net_error, ssl_error, error_info)); |
| 613 } | 439 } |
| 614 return net_error; | 440 return net_error; |
| 615 } | 441 } |
| 616 | 442 |
| 617 int SSLServerSocketImpl::DoPayloadWrite() { | 443 int SSLServerSocketImpl::DoPayloadWrite() { |
| 444 DCHECK(completed_handshake_); |
| 445 DCHECK_EQ(STATE_NONE, next_handshake_state_); |
| 618 DCHECK(user_write_buf_); | 446 DCHECK(user_write_buf_); |
| 447 |
| 619 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 448 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 620 int rv = SSL_write(ssl_.get(), user_write_buf_->data(), user_write_buf_len_); | 449 int rv = SSL_write(ssl_.get(), user_write_buf_->data(), user_write_buf_len_); |
| 621 if (rv >= 0) | 450 if (rv >= 0) |
| 622 return rv; | 451 return rv; |
| 623 int ssl_error = SSL_get_error(ssl_.get(), rv); | 452 int ssl_error = SSL_get_error(ssl_.get(), rv); |
| 624 OpenSSLErrorInfo error_info; | 453 OpenSSLErrorInfo error_info; |
| 625 int net_error = | 454 int net_error = |
| 626 MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); | 455 MapOpenSSLErrorWithDetails(ssl_error, err_tracer, &error_info); |
| 627 if (net_error != ERR_IO_PENDING) { | 456 if (net_error != ERR_IO_PENDING) { |
| 628 net_log_.AddEvent( | 457 net_log_.AddEvent( |
| (...skipping 16 matching lines...) Expand all Loading... |
| 645 switch (state) { | 474 switch (state) { |
| 646 case STATE_HANDSHAKE: | 475 case STATE_HANDSHAKE: |
| 647 rv = DoHandshake(); | 476 rv = DoHandshake(); |
| 648 break; | 477 break; |
| 649 case STATE_NONE: | 478 case STATE_NONE: |
| 650 default: | 479 default: |
| 651 rv = ERR_UNEXPECTED; | 480 rv = ERR_UNEXPECTED; |
| 652 LOG(DFATAL) << "unexpected state " << state; | 481 LOG(DFATAL) << "unexpected state " << state; |
| 653 break; | 482 break; |
| 654 } | 483 } |
| 655 | |
| 656 // Do the actual network I/O | |
| 657 bool network_moved = DoTransportIO(); | |
| 658 if (network_moved && next_handshake_state_ == STATE_HANDSHAKE) { | |
| 659 // In general we exit the loop if rv is ERR_IO_PENDING. In this | |
| 660 // special case we keep looping even if rv is ERR_IO_PENDING because | |
| 661 // the transport IO may allow DoHandshake to make progress. | |
| 662 rv = OK; // This causes us to stay in the loop. | |
| 663 } | |
| 664 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE); | 484 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE); |
| 665 return rv; | 485 return rv; |
| 666 } | 486 } |
| 667 | 487 |
| 668 int SSLServerSocketImpl::DoReadLoop(int result) { | |
| 669 DCHECK(completed_handshake_); | |
| 670 DCHECK(next_handshake_state_ == STATE_NONE); | |
| 671 | |
| 672 if (result < 0) | |
| 673 return result; | |
| 674 | |
| 675 bool network_moved; | |
| 676 int rv; | |
| 677 do { | |
| 678 rv = DoPayloadRead(); | |
| 679 network_moved = DoTransportIO(); | |
| 680 } while (rv == ERR_IO_PENDING && network_moved); | |
| 681 return rv; | |
| 682 } | |
| 683 | |
| 684 int SSLServerSocketImpl::DoWriteLoop(int result) { | |
| 685 DCHECK(completed_handshake_); | |
| 686 DCHECK_EQ(next_handshake_state_, STATE_NONE); | |
| 687 | |
| 688 if (result < 0) | |
| 689 return result; | |
| 690 | |
| 691 bool network_moved; | |
| 692 int rv; | |
| 693 do { | |
| 694 rv = DoPayloadWrite(); | |
| 695 network_moved = DoTransportIO(); | |
| 696 } while (rv == ERR_IO_PENDING && network_moved); | |
| 697 return rv; | |
| 698 } | |
| 699 | |
| 700 int SSLServerSocketImpl::DoHandshake() { | 488 int SSLServerSocketImpl::DoHandshake() { |
| 701 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 489 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 702 int net_error = OK; | 490 int net_error = OK; |
| 703 int rv = SSL_do_handshake(ssl_.get()); | 491 int rv = SSL_do_handshake(ssl_.get()); |
| 704 | 492 |
| 705 if (rv == 1) { | 493 if (rv == 1) { |
| 706 completed_handshake_ = true; | 494 completed_handshake_ = true; |
| 707 // The results of SSL_get_peer_certificate() must be explicitly freed. | 495 // The results of SSL_get_peer_certificate() must be explicitly freed. |
| 708 bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl_.get())); | 496 bssl::UniquePtr<X509> cert(SSL_get_peer_certificate(ssl_.get())); |
| 709 if (cert) { | 497 if (cert) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 void SSLServerSocketImpl::DoWriteCallback(int rv) { | 545 void SSLServerSocketImpl::DoWriteCallback(int rv) { |
| 758 DCHECK(rv != ERR_IO_PENDING); | 546 DCHECK(rv != ERR_IO_PENDING); |
| 759 DCHECK(!user_write_callback_.is_null()); | 547 DCHECK(!user_write_callback_.is_null()); |
| 760 | 548 |
| 761 user_write_buf_ = NULL; | 549 user_write_buf_ = NULL; |
| 762 user_write_buf_len_ = 0; | 550 user_write_buf_len_ = 0; |
| 763 base::ResetAndReturn(&user_write_callback_).Run(rv); | 551 base::ResetAndReturn(&user_write_callback_).Run(rv); |
| 764 } | 552 } |
| 765 | 553 |
| 766 int SSLServerSocketImpl::Init() { | 554 int SSLServerSocketImpl::Init() { |
| 767 DCHECK(!transport_bio_); | 555 static const int kBufferSize = 17 * 1024; |
| 768 | 556 |
| 769 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 557 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 770 | 558 |
| 771 if (!ssl_) | 559 if (!ssl_) |
| 772 return ERR_UNEXPECTED; | 560 return ERR_UNEXPECTED; |
| 773 | 561 |
| 774 BIO* ssl_bio = nullptr; | 562 transport_adapter_.reset(new SocketBIOAdapter( |
| 775 BIO* transport_bio_raw = nullptr; | 563 transport_socket_.get(), kBufferSize, kBufferSize, this)); |
| 776 // 0 => use default buffer sizes. | 564 BIO* transport_bio = transport_adapter_->bio(); |
| 777 if (!BIO_new_bio_pair(&ssl_bio, 0, &transport_bio_raw, 0)) | |
| 778 return ERR_UNEXPECTED; | |
| 779 transport_bio_.reset(transport_bio_raw); | |
| 780 DCHECK(ssl_bio); | |
| 781 DCHECK(transport_bio_); | |
| 782 | 565 |
| 783 SSL_set_bio(ssl_.get(), ssl_bio, ssl_bio); | 566 BIO_up_ref(transport_bio); // SSL_set0_rbio takes ownership. |
| 567 SSL_set0_rbio(ssl_.get(), transport_bio); |
| 568 |
| 569 BIO_up_ref(transport_bio); // SSL_set0_wbio takes ownership. |
| 570 SSL_set0_wbio(ssl_.get(), transport_bio); |
| 784 | 571 |
| 785 return OK; | 572 return OK; |
| 786 } | 573 } |
| 787 | 574 |
| 788 // static | 575 // static |
| 789 int SSLServerSocketImpl::CertVerifyCallback(X509_STORE_CTX* store_ctx, | 576 int SSLServerSocketImpl::CertVerifyCallback(X509_STORE_CTX* store_ctx, |
| 790 void* arg) { | 577 void* arg) { |
| 791 ClientCertVerifier* verifier = reinterpret_cast<ClientCertVerifier*>(arg); | 578 ClientCertVerifier* verifier = reinterpret_cast<ClientCertVerifier*>(arg); |
| 792 // If a verifier was not supplied, all certificates are accepted. | 579 // If a verifier was not supplied, all certificates are accepted. |
| 793 if (!verifier) | 580 if (!verifier) |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 950 bssl::UniquePtr<SSL> ssl(SSL_new(ssl_ctx_.get())); | 737 bssl::UniquePtr<SSL> ssl(SSL_new(ssl_ctx_.get())); |
| 951 return std::unique_ptr<SSLServerSocket>( | 738 return std::unique_ptr<SSLServerSocket>( |
| 952 new SSLServerSocketImpl(std::move(socket), std::move(ssl))); | 739 new SSLServerSocketImpl(std::move(socket), std::move(ssl))); |
| 953 } | 740 } |
| 954 | 741 |
| 955 void EnableSSLServerSockets() { | 742 void EnableSSLServerSockets() { |
| 956 // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit(). | 743 // No-op because CreateSSLServerSocket() calls crypto::EnsureOpenSSLInit(). |
| 957 } | 744 } |
| 958 | 745 |
| 959 } // namespace net | 746 } // namespace net |
| OLD | NEW |