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 |