| OLD | NEW |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 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/base/ssl_client_socket_mac.h" | 5 #include "net/base/ssl_client_socket_mac.h" |
| 6 | 6 |
| 7 #include "base/singleton.h" | 7 #include "base/singleton.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
| 10 #include "net/base/ssl_info.h" | 10 #include "net/base/ssl_info.h" |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 // Unlike IsConnected, this method doesn't return a false positive. | 342 // Unlike IsConnected, this method doesn't return a false positive. |
| 343 // | 343 // |
| 344 // Strictly speaking, we should check if we have received the close_notify | 344 // Strictly speaking, we should check if we have received the close_notify |
| 345 // alert message from the server, and return false in that case. Although | 345 // alert message from the server, and return false in that case. Although |
| 346 // the close_notify alert message means EOF in the SSL layer, it is just | 346 // the close_notify alert message means EOF in the SSL layer, it is just |
| 347 // bytes to the transport layer below, so transport_->IsConnectedAndIdle() | 347 // bytes to the transport layer below, so transport_->IsConnectedAndIdle() |
| 348 // returns the desired false when we receive close_notify. | 348 // returns the desired false when we receive close_notify. |
| 349 return completed_handshake_ && transport_->IsConnectedAndIdle(); | 349 return completed_handshake_ && transport_->IsConnectedAndIdle(); |
| 350 } | 350 } |
| 351 | 351 |
| 352 int SSLClientSocketMac::Read(char* buf, int buf_len, | 352 int SSLClientSocketMac::Read(IOBuffer* buf, int buf_len, |
| 353 CompletionCallback* callback) { | 353 CompletionCallback* callback) { |
| 354 DCHECK(completed_handshake_); | 354 DCHECK(completed_handshake_); |
| 355 DCHECK(next_state_ == STATE_NONE); | 355 DCHECK(next_state_ == STATE_NONE); |
| 356 DCHECK(!user_callback_); | 356 DCHECK(!user_callback_); |
| 357 DCHECK(!user_buf_); |
| 357 | 358 |
| 358 user_buf_ = buf; | 359 user_buf_ = buf; |
| 359 user_buf_len_ = buf_len; | 360 user_buf_len_ = buf_len; |
| 360 | 361 |
| 361 next_state_ = STATE_PAYLOAD_READ; | 362 next_state_ = STATE_PAYLOAD_READ; |
| 362 int rv = DoLoop(OK); | 363 int rv = DoLoop(OK); |
| 363 if (rv == ERR_IO_PENDING) | 364 if (rv == ERR_IO_PENDING) { |
| 364 user_callback_ = callback; | 365 user_callback_ = callback; |
| 366 } else { |
| 367 user_buf_ = NULL; |
| 368 } |
| 365 return rv; | 369 return rv; |
| 366 } | 370 } |
| 367 | 371 |
| 368 int SSLClientSocketMac::Write(const char* buf, int buf_len, | 372 int SSLClientSocketMac::Write(IOBuffer* buf, int buf_len, |
| 369 CompletionCallback* callback) { | 373 CompletionCallback* callback) { |
| 370 DCHECK(completed_handshake_); | 374 DCHECK(completed_handshake_); |
| 371 DCHECK(next_state_ == STATE_NONE); | 375 DCHECK(next_state_ == STATE_NONE); |
| 372 DCHECK(!user_callback_); | 376 DCHECK(!user_callback_); |
| 377 DCHECK(!user_buf_); |
| 373 | 378 |
| 374 user_buf_ = const_cast<char*>(buf); | 379 user_buf_ = buf; |
| 375 user_buf_len_ = buf_len; | 380 user_buf_len_ = buf_len; |
| 376 | 381 |
| 377 next_state_ = STATE_PAYLOAD_WRITE; | 382 next_state_ = STATE_PAYLOAD_WRITE; |
| 378 int rv = DoLoop(OK); | 383 int rv = DoLoop(OK); |
| 379 if (rv == ERR_IO_PENDING) | 384 if (rv == ERR_IO_PENDING) { |
| 380 user_callback_ = callback; | 385 user_callback_ = callback; |
| 386 } else { |
| 387 user_buf_ = NULL; |
| 388 } |
| 381 return rv; | 389 return rv; |
| 382 } | 390 } |
| 383 | 391 |
| 384 void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) { | 392 void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) { |
| 385 DCHECK(completed_handshake_); | 393 DCHECK(completed_handshake_); |
| 386 OSStatus status; | 394 OSStatus status; |
| 387 | 395 |
| 388 ssl_info->Reset(); | 396 ssl_info->Reset(); |
| 389 | 397 |
| 390 // set cert | 398 // set cert |
| (...skipping 21 matching lines...) Expand all Loading... |
| 412 ssl_info->security_bits = KeySizeOfCipherSuite(suite); | 420 ssl_info->security_bits = KeySizeOfCipherSuite(suite); |
| 413 } | 421 } |
| 414 | 422 |
| 415 void SSLClientSocketMac::DoCallback(int rv) { | 423 void SSLClientSocketMac::DoCallback(int rv) { |
| 416 DCHECK(rv != ERR_IO_PENDING); | 424 DCHECK(rv != ERR_IO_PENDING); |
| 417 DCHECK(user_callback_); | 425 DCHECK(user_callback_); |
| 418 | 426 |
| 419 // since Run may result in Read being called, clear user_callback_ up front. | 427 // since Run may result in Read being called, clear user_callback_ up front. |
| 420 CompletionCallback* c = user_callback_; | 428 CompletionCallback* c = user_callback_; |
| 421 user_callback_ = NULL; | 429 user_callback_ = NULL; |
| 430 user_buf_ = NULL; |
| 422 c->Run(rv); | 431 c->Run(rv); |
| 423 } | 432 } |
| 424 | 433 |
| 425 void SSLClientSocketMac::OnIOComplete(int result) { | 434 void SSLClientSocketMac::OnIOComplete(int result) { |
| 426 if (next_io_state_ != STATE_NONE) { | 435 if (next_io_state_ != STATE_NONE) { |
| 427 State next_state = next_state_; | 436 State next_state = next_state_; |
| 428 next_state_ = next_io_state_; | 437 next_state_ = next_io_state_; |
| 429 next_io_state_ = STATE_NONE; | 438 next_io_state_ = STATE_NONE; |
| 430 result = DoLoop(result); | 439 result = DoLoop(result); |
| 431 next_state_ = next_state; | 440 next_state_ = next_state; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 | 500 |
| 492 // TODO(wtc): for now, always check revocation. | 501 // TODO(wtc): for now, always check revocation. |
| 493 server_cert_status_ = CERT_STATUS_REV_CHECKING_ENABLED; | 502 server_cert_status_ = CERT_STATUS_REV_CHECKING_ENABLED; |
| 494 if (net_error) | 503 if (net_error) |
| 495 server_cert_status_ |= MapNetErrorToCertStatus(net_error); | 504 server_cert_status_ |= MapNetErrorToCertStatus(net_error); |
| 496 | 505 |
| 497 return net_error; | 506 return net_error; |
| 498 } | 507 } |
| 499 | 508 |
| 500 int SSLClientSocketMac::DoReadComplete(int result) { | 509 int SSLClientSocketMac::DoReadComplete(int result) { |
| 501 if (result < 0) | 510 if (result < 0) { |
| 511 read_io_buf_ = NULL; |
| 502 return result; | 512 return result; |
| 513 } |
| 514 |
| 515 char* buffer = &recv_buffer_[recv_buffer_.size() - recv_buffer_tail_slop_]; |
| 516 memcpy(buffer, read_io_buf_->data(), result); |
| 517 read_io_buf_ = NULL; |
| 503 | 518 |
| 504 recv_buffer_tail_slop_ -= result; | 519 recv_buffer_tail_slop_ -= result; |
| 505 | 520 |
| 506 return result; | 521 return result; |
| 507 } | 522 } |
| 508 | 523 |
| 509 void SSLClientSocketMac::OnWriteComplete(int result) { | 524 void SSLClientSocketMac::OnWriteComplete(int result) { |
| 510 if (result < 0) { | 525 if (result < 0) { |
| 511 pending_send_error_ = result; | 526 pending_send_error_ = result; |
| 512 return; | 527 return; |
| 513 } | 528 } |
| 514 | 529 |
| 515 send_buffer_.erase(send_buffer_.begin(), | 530 send_buffer_.erase(send_buffer_.begin(), |
| 516 send_buffer_.begin() + result); | 531 send_buffer_.begin() + result); |
| 517 | 532 |
| 518 if (!send_buffer_.empty()) | 533 if (!send_buffer_.empty()) |
| 519 SSLWriteCallback(this, NULL, NULL); | 534 SSLWriteCallback(this, NULL, NULL); |
| 520 } | 535 } |
| 521 | 536 |
| 522 int SSLClientSocketMac::DoPayloadRead() { | 537 int SSLClientSocketMac::DoPayloadRead() { |
| 523 size_t processed; | 538 size_t processed; |
| 524 OSStatus status = SSLRead(ssl_context_, | 539 OSStatus status = SSLRead(ssl_context_, |
| 525 user_buf_, | 540 user_buf_->data(), |
| 526 user_buf_len_, | 541 user_buf_len_, |
| 527 &processed); | 542 &processed); |
| 528 | 543 |
| 529 // There's a subtle difference here in semantics of the "would block" errors. | 544 // There's a subtle difference here in semantics of the "would block" errors. |
| 530 // In our code, ERR_IO_PENDING means the whole operation is async, while | 545 // In our code, ERR_IO_PENDING means the whole operation is async, while |
| 531 // errSSLWouldBlock means that the stream isn't ending (and is often returned | 546 // errSSLWouldBlock means that the stream isn't ending (and is often returned |
| 532 // along with partial data). So even though "would block" is returned, if we | 547 // along with partial data). So even though "would block" is returned, if we |
| 533 // have data, let's just return it. | 548 // have data, let's just return it. |
| 534 | 549 |
| 535 if (processed > 0) { | 550 if (processed > 0) { |
| 536 next_state_ = STATE_NONE; | 551 next_state_ = STATE_NONE; |
| 537 return processed; | 552 return processed; |
| 538 } | 553 } |
| 539 | 554 |
| 540 if (status == errSSLWouldBlock) { | 555 if (status == errSSLWouldBlock) { |
| 541 next_state_ = STATE_PAYLOAD_READ; | 556 next_state_ = STATE_PAYLOAD_READ; |
| 542 } | 557 } |
| 543 | 558 |
| 544 return NetErrorFromOSStatus(status); | 559 return NetErrorFromOSStatus(status); |
| 545 } | 560 } |
| 546 | 561 |
| 547 int SSLClientSocketMac::DoPayloadWrite() { | 562 int SSLClientSocketMac::DoPayloadWrite() { |
| 548 size_t processed; | 563 size_t processed; |
| 549 OSStatus status = SSLWrite(ssl_context_, | 564 OSStatus status = SSLWrite(ssl_context_, |
| 550 user_buf_, | 565 user_buf_->data(), |
| 551 user_buf_len_, | 566 user_buf_len_, |
| 552 &processed); | 567 &processed); |
| 553 | 568 |
| 554 if (processed > 0) | 569 if (processed > 0) |
| 555 return processed; | 570 return processed; |
| 556 | 571 |
| 557 return NetErrorFromOSStatus(status); | 572 return NetErrorFromOSStatus(status); |
| 558 } | 573 } |
| 559 | 574 |
| 560 // Handling the reading from the network is one of those things that should be | 575 // Handling the reading from the network is one of those things that should be |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 | 668 |
| 654 // Resize the buffer if needed | 669 // Resize the buffer if needed |
| 655 | 670 |
| 656 if (us->recv_buffer_.size() - us->recv_buffer_head_slop_ < *data_length) { | 671 if (us->recv_buffer_.size() - us->recv_buffer_head_slop_ < *data_length) { |
| 657 us->recv_buffer_.resize(us->recv_buffer_head_slop_ + *data_length); | 672 us->recv_buffer_.resize(us->recv_buffer_head_slop_ + *data_length); |
| 658 us->recv_buffer_tail_slop_ = *data_length - total_read; | 673 us->recv_buffer_tail_slop_ = *data_length - total_read; |
| 659 } | 674 } |
| 660 | 675 |
| 661 int rv = 1; // any old value to spin the loop below | 676 int rv = 1; // any old value to spin the loop below |
| 662 while (rv > 0 && total_read < *data_length) { | 677 while (rv > 0 && total_read < *data_length) { |
| 663 rv = us->transport_->Read(&us->recv_buffer_[us->recv_buffer_head_slop_ + | 678 char* buffer = &us->recv_buffer_[us->recv_buffer_head_slop_ + total_read]; |
| 664 total_read], | 679 us->read_io_buf_ = new IOBuffer(*data_length - total_read); |
| 665 us->recv_buffer_tail_slop_, | 680 rv = us->transport_->Read(us->read_io_buf_, |
| 681 *data_length - total_read, |
| 666 &us->io_callback_); | 682 &us->io_callback_); |
| 667 | 683 |
| 668 if (rv > 0) { | 684 if (rv >= 0) { |
| 685 memcpy(buffer, us->read_io_buf_->data(), rv); |
| 686 us->read_io_buf_ = NULL; |
| 669 total_read += rv; | 687 total_read += rv; |
| 670 us->recv_buffer_tail_slop_ -= rv; | 688 us->recv_buffer_tail_slop_ -= rv; |
| 671 } | 689 } |
| 672 } | 690 } |
| 673 | 691 |
| 674 *data_length = total_read; | 692 *data_length = total_read; |
| 675 if (total_read) { | 693 if (total_read) { |
| 676 memcpy(data, &us->recv_buffer_[us->recv_buffer_head_slop_], total_read); | 694 memcpy(data, &us->recv_buffer_[us->recv_buffer_head_slop_], total_read); |
| 677 if (rv == ERR_IO_PENDING) { | 695 if (rv == ERR_IO_PENDING) { |
| 678 // We have I/O in flight which is going to land in our buffer. We can't | 696 // We have I/O in flight which is going to land in our buffer. We can't |
| 679 // shuffle things around, so we need to just fiddle with pointers. | 697 // shuffle things around, so we need to just fiddle with pointers. |
| 680 us->recv_buffer_head_slop_ += total_read; | 698 us->recv_buffer_head_slop_ += total_read; |
| 681 } else { | 699 } else { |
| 682 us->recv_buffer_.erase(us->recv_buffer_.begin(), | 700 us->recv_buffer_.erase(us->recv_buffer_.begin(), |
| 683 us->recv_buffer_.begin() + | 701 us->recv_buffer_.begin() + |
| 684 total_read + | 702 total_read + |
| 685 us->recv_buffer_head_slop_); | 703 us->recv_buffer_head_slop_); |
| 686 us->recv_buffer_head_slop_ = 0; | 704 us->recv_buffer_head_slop_ = 0; |
| 687 } | 705 } |
| 688 } | 706 } |
| 689 | 707 |
| 690 if (rv == ERR_IO_PENDING) { | 708 if (rv == ERR_IO_PENDING) { |
| 691 us->next_io_state_ = STATE_READ_COMPLETE; | 709 us->next_io_state_ = STATE_READ_COMPLETE; |
| 710 } else { |
| 711 us->read_io_buf_ = NULL; |
| 692 } | 712 } |
| 693 | 713 |
| 694 if (rv < 0) | 714 if (rv < 0) |
| 695 return OSStatusFromNetError(rv); | 715 return OSStatusFromNetError(rv); |
| 696 | 716 |
| 697 return noErr; | 717 return noErr; |
| 698 } | 718 } |
| 699 | 719 |
| 700 // static | 720 // static |
| 701 OSStatus SSLClientSocketMac::SSLWriteCallback(SSLConnectionRef connection, | 721 OSStatus SSLClientSocketMac::SSLWriteCallback(SSLConnectionRef connection, |
| 702 const void* data, | 722 const void* data, |
| 703 size_t* data_length) { | 723 size_t* data_length) { |
| 704 SSLClientSocketMac* us = | 724 SSLClientSocketMac* us = |
| 705 const_cast<SSLClientSocketMac*>( | 725 const_cast<SSLClientSocketMac*>( |
| 706 static_cast<const SSLClientSocketMac*>(connection)); | 726 static_cast<const SSLClientSocketMac*>(connection)); |
| 707 | 727 |
| 708 if (us->pending_send_error_ != OK) { | 728 if (us->pending_send_error_ != OK) { |
| 709 OSStatus status = OSStatusFromNetError(us->pending_send_error_); | 729 OSStatus status = OSStatusFromNetError(us->pending_send_error_); |
| 710 us->pending_send_error_ = OK; | 730 us->pending_send_error_ = OK; |
| 711 return status; | 731 return status; |
| 712 } | 732 } |
| 713 | 733 |
| 714 if (data) | 734 if (data) |
| 715 us->send_buffer_.insert(us->send_buffer_.end(), | 735 us->send_buffer_.insert(us->send_buffer_.end(), |
| 716 static_cast<const char*>(data), | 736 static_cast<const char*>(data), |
| 717 static_cast<const char*>(data) + *data_length); | 737 static_cast<const char*>(data) + *data_length); |
| 718 int rv; | 738 int rv; |
| 719 do { | 739 do { |
| 720 rv = us->transport_->Write(&us->send_buffer_[0], | 740 scoped_refptr<IOBuffer> buffer = new IOBuffer(us->send_buffer_.size()); |
| 741 memcpy(buffer->data(), &us->send_buffer_[0], us->send_buffer_.size()); |
| 742 rv = us->transport_->Write(buffer, |
| 721 us->send_buffer_.size(), | 743 us->send_buffer_.size(), |
| 722 &us->write_callback_); | 744 &us->write_callback_); |
| 723 if (rv > 0) { | 745 if (rv > 0) { |
| 724 us->send_buffer_.erase(us->send_buffer_.begin(), | 746 us->send_buffer_.erase(us->send_buffer_.begin(), |
| 725 us->send_buffer_.begin() + rv); | 747 us->send_buffer_.begin() + rv); |
| 726 | 748 |
| 727 } | 749 } |
| 728 } while (rv > 0 && !us->send_buffer_.empty()); | 750 } while (rv > 0 && !us->send_buffer_.empty()); |
| 729 | 751 |
| 730 if (rv < 0 && rv != ERR_IO_PENDING) { | 752 if (rv < 0 && rv != ERR_IO_PENDING) { |
| 731 return OSStatusFromNetError(rv); | 753 return OSStatusFromNetError(rv); |
| 732 } | 754 } |
| 733 | 755 |
| 734 // always lie to our caller | 756 // always lie to our caller |
| 735 return noErr; | 757 return noErr; |
| 736 } | 758 } |
| 737 | 759 |
| 738 } // namespace net | 760 } // namespace net |
| OLD | NEW |