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

Side by Side Diff: net/base/ssl_client_socket_win.cc

Issue 42380: Implement SSL renegotiation.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Upload before checkin Created 11 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « net/base/ssl_client_socket_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-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_win.h" 5 #include "net/base/ssl_client_socket_win.h"
6 6
7 #include <schnlsp.h> 7 #include <schnlsp.h>
8 8
9 #include "base/lock.h" 9 #include "base/lock.h"
10 #include "base/singleton.h" 10 #include "base/singleton.h"
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 #pragma warning(suppress: 4355) 209 #pragma warning(suppress: 4355)
210 : io_callback_(this, &SSLClientSocketWin::OnIOComplete), 210 : io_callback_(this, &SSLClientSocketWin::OnIOComplete),
211 transport_(transport_socket), 211 transport_(transport_socket),
212 hostname_(hostname), 212 hostname_(hostname),
213 ssl_config_(ssl_config), 213 ssl_config_(ssl_config),
214 user_callback_(NULL), 214 user_callback_(NULL),
215 user_buf_(NULL), 215 user_buf_(NULL),
216 user_buf_len_(0), 216 user_buf_len_(0),
217 next_state_(STATE_NONE), 217 next_state_(STATE_NONE),
218 creds_(NULL), 218 creds_(NULL),
219 isc_status_(SEC_E_OK),
219 payload_send_buffer_len_(0), 220 payload_send_buffer_len_(0),
220 bytes_sent_(0), 221 bytes_sent_(0),
221 decrypted_ptr_(NULL), 222 decrypted_ptr_(NULL),
222 bytes_decrypted_(0), 223 bytes_decrypted_(0),
223 received_ptr_(NULL), 224 received_ptr_(NULL),
224 bytes_received_(0), 225 bytes_received_(0),
226 writing_first_token_(false),
225 completed_handshake_(false), 227 completed_handshake_(false),
226 complete_handshake_on_write_complete_(false),
227 ignore_ok_result_(false), 228 ignore_ok_result_(false),
228 no_client_cert_(false) { 229 no_client_cert_(false),
230 renegotiating_(false) {
229 memset(&stream_sizes_, 0, sizeof(stream_sizes_)); 231 memset(&stream_sizes_, 0, sizeof(stream_sizes_));
232 memset(in_buffers_, 0, sizeof(in_buffers_));
230 memset(&send_buffer_, 0, sizeof(send_buffer_)); 233 memset(&send_buffer_, 0, sizeof(send_buffer_));
231 memset(&ctxt_, 0, sizeof(ctxt_)); 234 memset(&ctxt_, 0, sizeof(ctxt_));
232 } 235 }
233 236
234 SSLClientSocketWin::~SSLClientSocketWin() { 237 SSLClientSocketWin::~SSLClientSocketWin() {
235 Disconnect(); 238 Disconnect();
236 } 239 }
237 240
238 void SSLClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) { 241 void SSLClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) {
239 if (!server_cert_) 242 if (!server_cert_)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 CompletionCallback* callback) { 284 CompletionCallback* callback) {
282 // TODO(darin): implement me! 285 // TODO(darin): implement me!
283 return ERR_FAILED; 286 return ERR_FAILED;
284 } 287 }
285 288
286 void SSLClientSocketWin::Disconnect() { 289 void SSLClientSocketWin::Disconnect() {
287 // TODO(wtc): Send SSL close_notify alert. 290 // TODO(wtc): Send SSL close_notify alert.
288 completed_handshake_ = false; 291 completed_handshake_ = false;
289 transport_->Disconnect(); 292 transport_->Disconnect();
290 293
291 if (send_buffer_.pvBuffer) { 294 if (send_buffer_.pvBuffer)
292 FreeContextBuffer(send_buffer_.pvBuffer); 295 FreeSendBuffer();
293 memset(&send_buffer_, 0, sizeof(send_buffer_));
294 }
295 if (ctxt_.dwLower || ctxt_.dwUpper) { 296 if (ctxt_.dwLower || ctxt_.dwUpper) {
296 DeleteSecurityContext(&ctxt_); 297 DeleteSecurityContext(&ctxt_);
297 memset(&ctxt_, 0, sizeof(ctxt_)); 298 memset(&ctxt_, 0, sizeof(ctxt_));
298 } 299 }
299 if (server_cert_) 300 if (server_cert_)
300 server_cert_ = NULL; 301 server_cert_ = NULL;
301 302
302 // TODO(wtc): reset more members? 303 // TODO(wtc): reset more members?
303 bytes_decrypted_ = 0; 304 bytes_decrypted_ = 0;
304 bytes_received_ = 0; 305 bytes_received_ = 0;
306 writing_first_token_ = false;
307 renegotiating_ = false;
305 } 308 }
306 309
307 bool SSLClientSocketWin::IsConnected() const { 310 bool SSLClientSocketWin::IsConnected() const {
308 // Ideally, we should also check if we have received the close_notify alert 311 // Ideally, we should also check if we have received the close_notify alert
309 // message from the server, and return false in that case. We're not doing 312 // message from the server, and return false in that case. We're not doing
310 // that, so this function may return a false positive. Since the upper 313 // that, so this function may return a false positive. Since the upper
311 // layer (HttpNetworkTransaction) needs to handle a persistent connection 314 // layer (HttpNetworkTransaction) needs to handle a persistent connection
312 // closed by the server when we send a request anyway, a false positive in 315 // closed by the server when we send a request anyway, a false positive in
313 // exchange for simpler code is a good trade-off. 316 // exchange for simpler code is a good trade-off.
314 return completed_handshake_ && transport_->IsConnected(); 317 return completed_handshake_ && transport_->IsConnected();
(...skipping 29 matching lines...) Expand all
344 memmove(recv_buffer_.get(), received_ptr_, bytes_received_); 347 memmove(recv_buffer_.get(), received_ptr_, bytes_received_);
345 received_ptr_ = recv_buffer_.get(); 348 received_ptr_ = recv_buffer_.get();
346 } 349 }
347 } 350 }
348 return len; 351 return len;
349 } 352 }
350 353
351 user_buf_ = buf; 354 user_buf_ = buf;
352 user_buf_len_ = buf_len; 355 user_buf_len_ = buf_len;
353 356
354 if (bytes_received_ == 0) { 357 SetNextStateForRead();
355 next_state_ = STATE_PAYLOAD_READ;
356 } else {
357 next_state_ = STATE_PAYLOAD_READ_COMPLETE;
358 ignore_ok_result_ = true; // OK doesn't mean EOF.
359 }
360 int rv = DoLoop(OK); 358 int rv = DoLoop(OK);
361 if (rv == ERR_IO_PENDING) 359 if (rv == ERR_IO_PENDING)
362 user_callback_ = callback; 360 user_callback_ = callback;
363 return rv; 361 return rv;
364 } 362 }
365 363
366 int SSLClientSocketWin::Write(const char* buf, int buf_len, 364 int SSLClientSocketWin::Write(const char* buf, int buf_len,
367 CompletionCallback* callback) { 365 CompletionCallback* callback) {
368 DCHECK(completed_handshake_); 366 DCHECK(completed_handshake_);
369 DCHECK(next_state_ == STATE_NONE); 367 DCHECK(next_state_ == STATE_NONE);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 0, // Reserved 490 0, // Reserved
493 &ctxt_, // Receives the new context handle 491 &ctxt_, // Receives the new context handle
494 &buffer_desc, 492 &buffer_desc,
495 &out_flags, 493 &out_flags,
496 &expiry); 494 &expiry);
497 if (status != SEC_I_CONTINUE_NEEDED) { 495 if (status != SEC_I_CONTINUE_NEEDED) {
498 DLOG(ERROR) << "InitializeSecurityContext failed: " << status; 496 DLOG(ERROR) << "InitializeSecurityContext failed: " << status;
499 return MapSecurityError(status); 497 return MapSecurityError(status);
500 } 498 }
501 499
500 writing_first_token_ = true;
502 next_state_ = STATE_HANDSHAKE_WRITE; 501 next_state_ = STATE_HANDSHAKE_WRITE;
503 return OK; 502 return OK;
504 } 503 }
505 504
506 int SSLClientSocketWin::DoHandshakeRead() { 505 int SSLClientSocketWin::DoHandshakeRead() {
507 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; 506 next_state_ = STATE_HANDSHAKE_READ_COMPLETE;
508 507
509 if (!recv_buffer_.get()) 508 if (!recv_buffer_.get())
510 recv_buffer_.reset(new char[kRecvBufferSize]); 509 recv_buffer_.reset(new char[kRecvBufferSize]);
511 510
(...skipping 12 matching lines...) Expand all
524 if (result < 0) 523 if (result < 0)
525 return result; 524 return result;
526 if (result == 0 && !ignore_ok_result_) 525 if (result == 0 && !ignore_ok_result_)
527 return ERR_SSL_PROTOCOL_ERROR; // Incomplete response :( 526 return ERR_SSL_PROTOCOL_ERROR; // Incomplete response :(
528 527
529 ignore_ok_result_ = false; 528 ignore_ok_result_ = false;
530 529
531 bytes_received_ += result; 530 bytes_received_ += result;
532 531
533 // Process the contents of recv_buffer_. 532 // Process the contents of recv_buffer_.
534 SECURITY_STATUS status;
535 TimeStamp expiry; 533 TimeStamp expiry;
536 DWORD out_flags; 534 DWORD out_flags;
537 535
538 DWORD flags = ISC_REQ_SEQUENCE_DETECT | 536 DWORD flags = ISC_REQ_SEQUENCE_DETECT |
539 ISC_REQ_REPLAY_DETECT | 537 ISC_REQ_REPLAY_DETECT |
540 ISC_REQ_CONFIDENTIALITY | 538 ISC_REQ_CONFIDENTIALITY |
541 ISC_RET_EXTENDED_ERROR | 539 ISC_RET_EXTENDED_ERROR |
542 ISC_REQ_ALLOCATE_MEMORY | 540 ISC_REQ_ALLOCATE_MEMORY |
543 ISC_REQ_STREAM; 541 ISC_REQ_STREAM;
544 542
545 // When InitializeSecurityContext returns SEC_I_INCOMPLETE_CREDENTIALS, 543 // When InitializeSecurityContext returns SEC_I_INCOMPLETE_CREDENTIALS,
546 // John Banes (a Microsoft security developer) said we need to pass in the 544 // John Banes (a Microsoft security developer) said we need to pass in the
547 // ISC_REQ_USE_SUPPLIED_CREDS flag if we skip finding a client certificate 545 // ISC_REQ_USE_SUPPLIED_CREDS flag if we skip finding a client certificate
548 // and just call InitializeSecurityContext again. (See 546 // and just call InitializeSecurityContext again. (See
549 // (http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/ 2004-08/0187.html.) 547 // (http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/ 2004-08/0187.html.)
550 // My testing on XP SP2 and Vista SP1 shows that it still works without 548 // My testing on XP SP2 and Vista SP1 shows that it still works without
551 // passing in this flag, but I pass it in to be safe. 549 // passing in this flag, but I pass it in to be safe.
552 if (no_client_cert_) 550 if (no_client_cert_)
553 flags |= ISC_REQ_USE_SUPPLIED_CREDS; 551 flags |= ISC_REQ_USE_SUPPLIED_CREDS;
554 552
555 SecBufferDesc in_buffer_desc, out_buffer_desc; 553 SecBufferDesc in_buffer_desc, out_buffer_desc;
556 SecBuffer in_buffers[2];
557 554
558 in_buffer_desc.cBuffers = 2; 555 in_buffer_desc.cBuffers = 2;
559 in_buffer_desc.pBuffers = in_buffers; 556 in_buffer_desc.pBuffers = in_buffers_;
560 in_buffer_desc.ulVersion = SECBUFFER_VERSION; 557 in_buffer_desc.ulVersion = SECBUFFER_VERSION;
561 558
562 in_buffers[0].pvBuffer = &recv_buffer_[0]; 559 in_buffers_[0].pvBuffer = recv_buffer_.get();
563 in_buffers[0].cbBuffer = bytes_received_; 560 in_buffers_[0].cbBuffer = bytes_received_;
564 in_buffers[0].BufferType = SECBUFFER_TOKEN; 561 in_buffers_[0].BufferType = SECBUFFER_TOKEN;
565 562
566 in_buffers[1].pvBuffer = NULL; 563 in_buffers_[1].pvBuffer = NULL;
567 in_buffers[1].cbBuffer = 0; 564 in_buffers_[1].cbBuffer = 0;
568 in_buffers[1].BufferType = SECBUFFER_EMPTY; 565 in_buffers_[1].BufferType = SECBUFFER_EMPTY;
569 566
570 out_buffer_desc.cBuffers = 1; 567 out_buffer_desc.cBuffers = 1;
571 out_buffer_desc.pBuffers = &send_buffer_; 568 out_buffer_desc.pBuffers = &send_buffer_;
572 out_buffer_desc.ulVersion = SECBUFFER_VERSION; 569 out_buffer_desc.ulVersion = SECBUFFER_VERSION;
573 570
574 send_buffer_.pvBuffer = NULL; 571 send_buffer_.pvBuffer = NULL;
575 send_buffer_.BufferType = SECBUFFER_TOKEN; 572 send_buffer_.BufferType = SECBUFFER_TOKEN;
576 send_buffer_.cbBuffer = 0; 573 send_buffer_.cbBuffer = 0;
577 574
578 status = InitializeSecurityContext( 575 isc_status_ = InitializeSecurityContext(
579 creds_, 576 creds_,
580 &ctxt_, 577 &ctxt_,
581 NULL, 578 NULL,
582 flags, 579 flags,
583 0, 580 0,
584 SECURITY_NATIVE_DREP, 581 SECURITY_NATIVE_DREP,
585 &in_buffer_desc, 582 &in_buffer_desc,
586 0, 583 0,
587 NULL, 584 NULL,
588 &out_buffer_desc, 585 &out_buffer_desc,
589 &out_flags, 586 &out_flags,
590 &expiry); 587 &expiry);
591 588
592 if (status == SEC_E_INCOMPLETE_MESSAGE) { 589 if (send_buffer_.cbBuffer != 0 &&
593 DCHECK(FAILED(status)); 590 (isc_status_ == SEC_E_OK ||
594 DCHECK(send_buffer_.cbBuffer == 0 || 591 isc_status_ == SEC_I_CONTINUE_NEEDED ||
595 !(out_flags & ISC_RET_EXTENDED_ERROR)); 592 (FAILED(isc_status_) && (out_flags & ISC_RET_EXTENDED_ERROR)))) {
593 next_state_ = STATE_HANDSHAKE_WRITE;
594 return OK;
595 }
596 return DidCallInitializeSecurityContext();
597 }
598
599 int SSLClientSocketWin::DidCallInitializeSecurityContext() {
600 if (isc_status_ == SEC_E_INCOMPLETE_MESSAGE) {
596 next_state_ = STATE_HANDSHAKE_READ; 601 next_state_ = STATE_HANDSHAKE_READ;
597 return OK; 602 return OK;
598 } 603 }
599 604
600 if (send_buffer_.cbBuffer != 0 && 605 if (isc_status_ == SEC_E_OK) {
601 (status == SEC_E_OK || 606 if (in_buffers_[1].BufferType == SECBUFFER_EXTRA) {
602 status == SEC_I_CONTINUE_NEEDED || 607 // Save this data for later.
603 FAILED(status) && (out_flags & ISC_RET_EXTENDED_ERROR))) { 608 memmove(recv_buffer_.get(),
604 // If FAILED(status) is true, we should terminate the connection after 609 recv_buffer_.get() + (bytes_received_ - in_buffers_[1].cbBuffer),
605 // sending send_buffer_. 610 in_buffers_[1].cbBuffer);
606 if (status == SEC_E_OK) 611 bytes_received_ = in_buffers_[1].cbBuffer;
607 complete_handshake_on_write_complete_ = true; 612 } else {
608 // We only handle these cases correctly. 613 bytes_received_ = 0;
609 DCHECK(status == SEC_E_OK || status == SEC_I_CONTINUE_NEEDED);
610 next_state_ = STATE_HANDSHAKE_WRITE;
611 bytes_received_ = 0;
612 return OK;
613 }
614
615 if (status == SEC_E_OK) {
616 if (in_buffers[1].BufferType == SECBUFFER_EXTRA) {
617 // TODO(darin) need to save this data for later.
618 NOTREACHED() << "should not occur for HTTPS traffic";
619 return ERR_FAILED;
620 } 614 }
621 bytes_received_ = 0;
622 return DidCompleteHandshake(); 615 return DidCompleteHandshake();
623 } 616 }
624 617
625 if (FAILED(status)) 618 if (FAILED(isc_status_))
626 return MapSecurityError(status); 619 return MapSecurityError(isc_status_);
627 620
628 if (status == SEC_I_INCOMPLETE_CREDENTIALS) { 621 if (isc_status_ == SEC_I_INCOMPLETE_CREDENTIALS) {
629 // We don't support SSL client authentication yet. For now we just set 622 // We don't support SSL client authentication yet. For now we just set
630 // no_client_cert_ to true and call InitializeSecurityContext again. 623 // no_client_cert_ to true and call InitializeSecurityContext again.
631 no_client_cert_ = true; 624 no_client_cert_ = true;
632 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; 625 next_state_ = STATE_HANDSHAKE_READ_COMPLETE;
633 ignore_ok_result_ = true; // OK doesn't mean EOF. 626 ignore_ok_result_ = true; // OK doesn't mean EOF.
634 return OK; 627 return OK;
635 } 628 }
636 629
637 DCHECK(status == SEC_I_CONTINUE_NEEDED); 630 DCHECK(isc_status_ == SEC_I_CONTINUE_NEEDED);
638 if (in_buffers[1].BufferType == SECBUFFER_EXTRA) { 631 if (in_buffers_[1].BufferType == SECBUFFER_EXTRA) {
639 memmove(&recv_buffer_[0], 632 memmove(recv_buffer_.get(),
640 &recv_buffer_[0] + (bytes_received_ - in_buffers[1].cbBuffer), 633 recv_buffer_.get() + (bytes_received_ - in_buffers_[1].cbBuffer),
641 in_buffers[1].cbBuffer); 634 in_buffers_[1].cbBuffer);
642 bytes_received_ = in_buffers[1].cbBuffer; 635 bytes_received_ = in_buffers_[1].cbBuffer;
643 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; 636 next_state_ = STATE_HANDSHAKE_READ_COMPLETE;
644 ignore_ok_result_ = true; // OK doesn't mean EOF. 637 ignore_ok_result_ = true; // OK doesn't mean EOF.
645 return OK; 638 return OK;
646 } 639 }
647 640
648 bytes_received_ = 0; 641 bytes_received_ = 0;
649 next_state_ = STATE_HANDSHAKE_READ; 642 next_state_ = STATE_HANDSHAKE_READ;
650 return OK; 643 return OK;
651 } 644 }
652 645
(...skipping 14 matching lines...) Expand all
667 if (result < 0) 660 if (result < 0)
668 return result; 661 return result;
669 662
670 DCHECK(result != 0); 663 DCHECK(result != 0);
671 664
672 bytes_sent_ += result; 665 bytes_sent_ += result;
673 DCHECK(bytes_sent_ <= static_cast<int>(send_buffer_.cbBuffer)); 666 DCHECK(bytes_sent_ <= static_cast<int>(send_buffer_.cbBuffer));
674 667
675 if (bytes_sent_ >= static_cast<int>(send_buffer_.cbBuffer)) { 668 if (bytes_sent_ >= static_cast<int>(send_buffer_.cbBuffer)) {
676 bool overflow = (bytes_sent_ > static_cast<int>(send_buffer_.cbBuffer)); 669 bool overflow = (bytes_sent_ > static_cast<int>(send_buffer_.cbBuffer));
677 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); 670 FreeSendBuffer();
678 DCHECK(status == SEC_E_OK);
679 memset(&send_buffer_, 0, sizeof(send_buffer_));
680 bytes_sent_ = 0; 671 bytes_sent_ = 0;
681 if (overflow) // Bug! 672 if (overflow) // Bug!
682 return ERR_UNEXPECTED; 673 return ERR_UNEXPECTED;
683 if (complete_handshake_on_write_complete_) 674 if (writing_first_token_) {
684 return DidCompleteHandshake(); 675 writing_first_token_ = false;
685 next_state_ = STATE_HANDSHAKE_READ; 676 DCHECK(bytes_received_ == 0);
686 } else { 677 next_state_ = STATE_HANDSHAKE_READ;
687 // Send the remaining bytes. 678 return OK;
688 next_state_ = STATE_HANDSHAKE_WRITE; 679 }
680 return DidCallInitializeSecurityContext();
689 } 681 }
690 682
683 // Send the remaining bytes.
684 next_state_ = STATE_HANDSHAKE_WRITE;
691 return OK; 685 return OK;
692 } 686 }
693 687
694 // Set server_cert_status_ and return OK or a network error. 688 // Set server_cert_status_ and return OK or a network error.
695 int SSLClientSocketWin::DoVerifyCert() { 689 int SSLClientSocketWin::DoVerifyCert() {
696 next_state_ = STATE_VERIFY_CERT_COMPLETE; 690 next_state_ = STATE_VERIFY_CERT_COMPLETE;
697 691
698 DCHECK(server_cert_); 692 DCHECK(server_cert_);
699 return verifier_.Verify(server_cert_, hostname_, 693 return verifier_.Verify(server_cert_, hostname_,
700 ssl_config_.rev_checking_enabled, 694 ssl_config_.rev_checking_enabled,
701 &server_cert_verify_result_, &io_callback_); 695 &server_cert_verify_result_, &io_callback_);
702 } 696 }
703 697
704 int SSLClientSocketWin::DoVerifyCertComplete(int result) { 698 int SSLClientSocketWin::DoVerifyCertComplete(int result) {
705 LogConnectionTypeMetrics(); 699 LogConnectionTypeMetrics();
700 if (renegotiating_) {
701 renegotiating_ = false;
702 // Pick up where we left off. Go back to reading data.
703 if (result == OK)
704 SetNextStateForRead();
705 }
706 return result; 706 return result;
707 } 707 }
708 708
709 int SSLClientSocketWin::DoPayloadRead() { 709 int SSLClientSocketWin::DoPayloadRead() {
710 next_state_ = STATE_PAYLOAD_READ_COMPLETE; 710 next_state_ = STATE_PAYLOAD_READ_COMPLETE;
711 711
712 DCHECK(recv_buffer_.get()); 712 DCHECK(recv_buffer_.get());
713 713
714 char* buf = recv_buffer_.get() + bytes_received_; 714 char* buf = recv_buffer_.get() + bytes_received_;
715 int buf_len = kRecvBufferSize - bytes_received_; 715 int buf_len = kRecvBufferSize - bytes_received_;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 } 799 }
800 if (bytes_decrypted_ == 0) { 800 if (bytes_decrypted_ == 0) {
801 decrypted_ptr_ = NULL; 801 decrypted_ptr_ = NULL;
802 if (bytes_received_ != 0) { 802 if (bytes_received_ != 0) {
803 memmove(recv_buffer_.get(), received_ptr_, bytes_received_); 803 memmove(recv_buffer_.get(), received_ptr_, bytes_received_);
804 received_ptr_ = recv_buffer_.get(); 804 received_ptr_ = recv_buffer_.get();
805 } 805 }
806 } 806 }
807 807
808 if (status == SEC_I_RENEGOTIATE) { 808 if (status == SEC_I_RENEGOTIATE) {
809 // TODO(wtc): support renegotiation. 809 if (bytes_received_ != 0) {
810 // Should ideally send a no_renegotiation alert to the server. 810 // The server requested renegotiation, but there are some data yet to
811 return ERR_SSL_RENEGOTIATION_REQUESTED; 811 // be decrypted. The Platform SDK WebClient.c sample doesn't handle
812 // this, so we don't know how to handle this. Assume this cannot
813 // happen.
814 LOG(ERROR) << "DecryptMessage returned SEC_I_RENEGOTIATE with a buffer "
815 << "of type SECBUFFER_EXTRA.";
816 return ERR_SSL_RENEGOTIATION_REQUESTED;
817 }
818 if (len != 0) {
819 // The server requested renegotiation, but there are some decrypted
820 // data. We can't start renegotiation until we have returned all
821 // decrypted data to the caller.
822 //
823 // This hasn't happened during testing. Assume this cannot happen even
824 // though we know how to handle this.
825 LOG(ERROR) << "DecryptMessage returned SEC_I_RENEGOTIATE with a buffer "
826 << "of type SECBUFFER_DATA.";
827 return ERR_SSL_RENEGOTIATION_REQUESTED;
828 }
829 // Jump to the handshake sequence. Will come back when the rehandshake is
830 // done.
831 renegotiating_ = true;
832 next_state_ = STATE_HANDSHAKE_READ_COMPLETE;
833 ignore_ok_result_ = true; // OK doesn't mean EOF.
834 return len;
812 } 835 }
813 836
814 // If we decrypted 0 bytes, don't report 0 bytes read, which would be 837 // If we decrypted 0 bytes, don't report 0 bytes read, which would be
815 // mistaken for EOF. Continue decrypting or read more. 838 // mistaken for EOF. Continue decrypting or read more.
816 if (len == 0) { 839 if (len == 0)
817 if (bytes_received_ == 0) { 840 SetNextStateForRead();
818 next_state_ = STATE_PAYLOAD_READ;
819 } else {
820 next_state_ = STATE_PAYLOAD_READ_COMPLETE;
821 ignore_ok_result_ = true; // OK doesn't mean EOF.
822 }
823 }
824 return len; 841 return len;
825 } 842 }
826 843
827 int SSLClientSocketWin::DoPayloadEncrypt() { 844 int SSLClientSocketWin::DoPayloadEncrypt() {
828 DCHECK(user_buf_); 845 DCHECK(user_buf_);
829 DCHECK(user_buf_len_ > 0); 846 DCHECK(user_buf_len_ > 0);
830 847
831 ULONG message_len = std::min( 848 ULONG message_len = std::min(
832 stream_sizes_.cbMaximumMessage, static_cast<ULONG>(user_buf_len_)); 849 stream_sizes_.cbMaximumMessage, static_cast<ULONG>(user_buf_len_));
833 ULONG alloc_len = 850 ULONG alloc_len =
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 return OK; 928 return OK;
912 } 929 }
913 930
914 int SSLClientSocketWin::DidCompleteHandshake() { 931 int SSLClientSocketWin::DidCompleteHandshake() {
915 SECURITY_STATUS status = QueryContextAttributes( 932 SECURITY_STATUS status = QueryContextAttributes(
916 &ctxt_, SECPKG_ATTR_STREAM_SIZES, &stream_sizes_); 933 &ctxt_, SECPKG_ATTR_STREAM_SIZES, &stream_sizes_);
917 if (status != SEC_E_OK) { 934 if (status != SEC_E_OK) {
918 DLOG(ERROR) << "QueryContextAttributes failed: " << status; 935 DLOG(ERROR) << "QueryContextAttributes failed: " << status;
919 return MapSecurityError(status); 936 return MapSecurityError(status);
920 } 937 }
921 DCHECK(!server_cert_); 938 DCHECK(!server_cert_ || renegotiating_);
922 PCCERT_CONTEXT server_cert_handle = NULL; 939 PCCERT_CONTEXT server_cert_handle = NULL;
923 status = QueryContextAttributes( 940 status = QueryContextAttributes(
924 &ctxt_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &server_cert_handle); 941 &ctxt_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &server_cert_handle);
925 if (status != SEC_E_OK) { 942 if (status != SEC_E_OK) {
926 DLOG(ERROR) << "QueryContextAttributes failed: " << status; 943 DLOG(ERROR) << "QueryContextAttributes failed: " << status;
927 return MapSecurityError(status); 944 return MapSecurityError(status);
928 } 945 }
929 server_cert_ = X509Certificate::CreateFromHandle( 946 server_cert_ = X509Certificate::CreateFromHandle(
930 server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK); 947 server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK);
931 948
932 completed_handshake_ = true; 949 completed_handshake_ = true;
933 next_state_ = STATE_VERIFY_CERT; 950 next_state_ = STATE_VERIFY_CERT;
934 return OK; 951 return OK;
935 } 952 }
936 953
937 void SSLClientSocketWin::LogConnectionTypeMetrics() const { 954 void SSLClientSocketWin::LogConnectionTypeMetrics() const {
938 UpdateConnectionTypeHistograms(CONNECTION_SSL); 955 UpdateConnectionTypeHistograms(CONNECTION_SSL);
939 if (server_cert_verify_result_.has_md5) 956 if (server_cert_verify_result_.has_md5)
940 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5); 957 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5);
941 if (server_cert_verify_result_.has_md2) 958 if (server_cert_verify_result_.has_md2)
942 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2); 959 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2);
943 if (server_cert_verify_result_.has_md4) 960 if (server_cert_verify_result_.has_md4)
944 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4); 961 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4);
945 if (server_cert_verify_result_.has_md5_ca) 962 if (server_cert_verify_result_.has_md5_ca)
946 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA); 963 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA);
947 if (server_cert_verify_result_.has_md2_ca) 964 if (server_cert_verify_result_.has_md2_ca)
948 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); 965 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA);
949 } 966 }
950 967
968 void SSLClientSocketWin::SetNextStateForRead() {
969 if (bytes_received_ == 0) {
970 next_state_ = STATE_PAYLOAD_READ;
971 } else {
972 next_state_ = STATE_PAYLOAD_READ_COMPLETE;
973 ignore_ok_result_ = true; // OK doesn't mean EOF.
974 }
975 }
976
977 void SSLClientSocketWin::FreeSendBuffer() {
978 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer);
979 DCHECK(status == SEC_E_OK);
980 memset(&send_buffer_, 0, sizeof(send_buffer_));
981 }
982
951 } // namespace net 983 } // namespace net
OLDNEW
« no previous file with comments | « net/base/ssl_client_socket_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698