| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // OpenSSL binding for SSLClientSocket. The class layout and general principle | 5 // OpenSSL binding for SSLClientSocket. The class layout and general principle |
| 6 // of operation is derived from SSLClientSocketNSS. | 6 // of operation is derived from SSLClientSocketNSS. |
| 7 | 7 |
| 8 #include "net/socket/ssl_client_socket_openssl.h" | 8 #include "net/socket/ssl_client_socket_openssl.h" |
| 9 | 9 |
| 10 #include <openssl/ssl.h> | 10 #include <openssl/ssl.h> |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 DVLOG(1) << "SSL error " << error_num << ": " << buf; | 42 DVLOG(1) << "SSL error " << error_num << ": " << buf; |
| 43 } | 43 } |
| 44 } | 44 } |
| 45 | 45 |
| 46 int MapOpenSSLError(int err) { | 46 int MapOpenSSLError(int err) { |
| 47 switch (err) { | 47 switch (err) { |
| 48 case SSL_ERROR_WANT_READ: | 48 case SSL_ERROR_WANT_READ: |
| 49 case SSL_ERROR_WANT_WRITE: | 49 case SSL_ERROR_WANT_WRITE: |
| 50 return ERR_IO_PENDING; | 50 return ERR_IO_PENDING; |
| 51 case SSL_ERROR_SYSCALL: | 51 case SSL_ERROR_SYSCALL: |
| 52 DVLOG(1) << "OpenSSL SYSVCALL error, errno " << errno; | 52 DVLOG(1) << "OpenSSL SYSCALL error, errno " << errno; |
| 53 MaybeLogSSLError(); | 53 MaybeLogSSLError(); |
| 54 return ERR_SSL_PROTOCOL_ERROR; | 54 return ERR_SSL_PROTOCOL_ERROR; |
| 55 default: | 55 default: |
| 56 // TODO(joth): Implement full mapping. | 56 // TODO(joth): Implement full mapping. |
| 57 LOG(WARNING) << "Unknown OpenSSL error " << err; | 57 LOG(WARNING) << "Unknown OpenSSL error " << err; |
| 58 MaybeLogSSLError(); | 58 MaybeLogSSLError(); |
| 59 return ERR_SSL_PROTOCOL_ERROR; | 59 return ERR_SSL_PROTOCOL_ERROR; |
| 60 } | 60 } |
| 61 } | 61 } |
| 62 | 62 |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 next_handshake_state_ != STATE_NONE); | 372 next_handshake_state_ != STATE_NONE); |
| 373 return rv; | 373 return rv; |
| 374 } | 374 } |
| 375 | 375 |
| 376 int SSLClientSocketOpenSSL::DoHandshake() { | 376 int SSLClientSocketOpenSSL::DoHandshake() { |
| 377 int net_error = net::OK; | 377 int net_error = net::OK; |
| 378 int rv = SSL_do_handshake(ssl_); | 378 int rv = SSL_do_handshake(ssl_); |
| 379 | 379 |
| 380 if (rv == 1) { | 380 if (rv == 1) { |
| 381 // SSL handshake is completed. Let's verify the certificate. | 381 // SSL handshake is completed. Let's verify the certificate. |
| 382 if (UpdateServerCert() == NULL) { | 382 const bool got_cert = !!UpdateServerCert(); |
| 383 net_error = ERR_SSL_PROTOCOL_ERROR; | 383 DCHECK(got_cert); |
| 384 } else { | 384 GotoState(STATE_VERIFY_CERT); |
| 385 GotoState(STATE_VERIFY_CERT); | |
| 386 | |
| 387 // TODO(joth): Remove this check when X509Certificate::Verify is | |
| 388 // implemented for OpenSSL | |
| 389 long verify_result = SSL_get_verify_result(ssl_); | |
| 390 LOG_IF(WARNING, verify_result != X509_V_OK) | |
| 391 << "Built in verify failed: " << verify_result; | |
| 392 } | |
| 393 } else { | 385 } else { |
| 394 int ssl_error = SSL_get_error(ssl_, rv); | 386 int ssl_error = SSL_get_error(ssl_, rv); |
| 395 net_error = MapOpenSSLError(ssl_error); | 387 net_error = MapOpenSSLError(ssl_error); |
| 396 | 388 |
| 397 // If not done, stay in this state | 389 // If not done, stay in this state |
| 398 if (net_error == ERR_IO_PENDING) { | 390 if (net_error == ERR_IO_PENDING) { |
| 399 GotoState(STATE_HANDSHAKE); | 391 GotoState(STATE_HANDSHAKE); |
| 400 } else { | 392 } else { |
| 401 LOG(ERROR) << "handshake failed; returned " << rv | 393 LOG(ERROR) << "handshake failed; returned " << rv |
| 402 << ", SSL error code " << ssl_error | 394 << ", SSL error code " << ssl_error |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 return rv; | 515 return rv; |
| 524 } | 516 } |
| 525 | 517 |
| 526 void SSLClientSocketOpenSSL::BufferSendComplete(int result) { | 518 void SSLClientSocketOpenSSL::BufferSendComplete(int result) { |
| 527 transport_send_busy_ = false; | 519 transport_send_busy_ = false; |
| 528 TransportWriteComplete(result); | 520 TransportWriteComplete(result); |
| 529 OnSendComplete(result); | 521 OnSendComplete(result); |
| 530 } | 522 } |
| 531 | 523 |
| 532 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { | 524 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { |
| 525 DCHECK(ERR_IO_PENDING != result); |
| 533 if (result < 0) { | 526 if (result < 0) { |
| 534 // Got a socket write error; close the BIO to indicate this upward. | 527 // Got a socket write error; close the BIO to indicate this upward. |
| 528 DVLOG(1) << "TransportWriteComplete error " << result; |
| 535 (void)BIO_shutdown_wr(transport_bio_); | 529 (void)BIO_shutdown_wr(transport_bio_); |
| 536 send_buffer_ = NULL; | 530 send_buffer_ = NULL; |
| 537 } else { | 531 } else { |
| 538 DCHECK(send_buffer_); | 532 DCHECK(send_buffer_); |
| 539 send_buffer_->DidConsume(result); | 533 send_buffer_->DidConsume(result); |
| 540 DCHECK_GE(send_buffer_->BytesRemaining(), 0); | 534 DCHECK_GE(send_buffer_->BytesRemaining(), 0); |
| 541 if (send_buffer_->BytesRemaining() <= 0) | 535 if (send_buffer_->BytesRemaining() <= 0) |
| 542 send_buffer_ = NULL; | 536 send_buffer_ = NULL; |
| 543 } | 537 } |
| 544 } | 538 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 564 } | 558 } |
| 565 return rv; | 559 return rv; |
| 566 } | 560 } |
| 567 | 561 |
| 568 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { | 562 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { |
| 569 TransportReadComplete(result); | 563 TransportReadComplete(result); |
| 570 OnRecvComplete(result); | 564 OnRecvComplete(result); |
| 571 } | 565 } |
| 572 | 566 |
| 573 void SSLClientSocketOpenSSL::TransportReadComplete(int result) { | 567 void SSLClientSocketOpenSSL::TransportReadComplete(int result) { |
| 574 if (result > 0) { | 568 DCHECK(ERR_IO_PENDING != result); |
| 569 if (result <= 0) { |
| 570 DVLOG(1) << "TransportReadComplete result " << result; |
| 571 // Received 0 (end of file) or an error. Either way, bubble it up to the |
| 572 // SSL layer via the BIO. |
| 573 BIO_set_mem_eof_return(transport_bio_, 0); |
| 574 (void)BIO_shutdown_wr(transport_bio_); |
| 575 } else { |
| 576 DCHECK(recv_buffer_); |
| 575 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); | 577 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); |
| 576 // A write into a memory BIO should always succeed. | 578 // A write into a memory BIO should always succeed. |
| 577 CHECK_EQ(result, ret); | 579 CHECK_EQ(result, ret); |
| 578 } else { | |
| 579 // Received end of file: bubble it up to the SSL layer via the BIO. | |
| 580 BIO_set_mem_eof_return(transport_bio_, 0); | |
| 581 (void)BIO_shutdown_wr(transport_bio_); | |
| 582 } | 580 } |
| 583 recv_buffer_ = NULL; | 581 recv_buffer_ = NULL; |
| 584 transport_recv_busy_ = false; | 582 transport_recv_busy_ = false; |
| 585 } | 583 } |
| 586 | 584 |
| 587 void SSLClientSocketOpenSSL::DoConnectCallback(int rv) { | 585 void SSLClientSocketOpenSSL::DoConnectCallback(int rv) { |
| 588 CompletionCallback* c = user_connect_callback_; | 586 CompletionCallback* c = user_connect_callback_; |
| 589 user_connect_callback_ = NULL; | 587 user_connect_callback_ = NULL; |
| 590 c->Run(rv > OK ? OK : rv); | 588 c->Run(rv > OK ? OK : rv); |
| 591 } | 589 } |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); | 775 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); |
| 778 | 776 |
| 779 if (rv >= 0) | 777 if (rv >= 0) |
| 780 return rv; | 778 return rv; |
| 781 | 779 |
| 782 int err = SSL_get_error(ssl_, rv); | 780 int err = SSL_get_error(ssl_, rv); |
| 783 return MapOpenSSLError(err); | 781 return MapOpenSSLError(err); |
| 784 } | 782 } |
| 785 | 783 |
| 786 } // namespace net | 784 } // namespace net |
| OLD | NEW |