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

Side by Side Diff: net/socket/ssl_client_socket_nss.cc

Issue 2870030: Implement SSLClientSocketPool. (Closed)
Patch Set: Rebase and fix mac compile error Created 10 years, 5 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
OLDNEW
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 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived
6 // from AuthCertificateCallback() in 6 // from AuthCertificateCallback() in
7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp.
8 8
9 /* ***** BEGIN LICENSE BLOCK ***** 9 /* ***** BEGIN LICENSE BLOCK *****
10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 #include "base/string_util.h" 66 #include "base/string_util.h"
67 #include "net/base/address_list.h" 67 #include "net/base/address_list.h"
68 #include "net/base/cert_verifier.h" 68 #include "net/base/cert_verifier.h"
69 #include "net/base/io_buffer.h" 69 #include "net/base/io_buffer.h"
70 #include "net/base/net_log.h" 70 #include "net/base/net_log.h"
71 #include "net/base/net_errors.h" 71 #include "net/base/net_errors.h"
72 #include "net/base/ssl_cert_request_info.h" 72 #include "net/base/ssl_cert_request_info.h"
73 #include "net/base/ssl_info.h" 73 #include "net/base/ssl_info.h"
74 #include "net/base/sys_addrinfo.h" 74 #include "net/base/sys_addrinfo.h"
75 #include "net/ocsp/nss_ocsp.h" 75 #include "net/ocsp/nss_ocsp.h"
76 #include "net/socket/client_socket_handle.h"
76 77
77 static const int kRecvBufferSize = 4096; 78 static const int kRecvBufferSize = 4096;
78 79
79 namespace net { 80 namespace net {
80 81
81 // State machines are easier to debug if you log state transitions. 82 // State machines are easier to debug if you log state transitions.
82 // Enable these if you want to see what's going on. 83 // Enable these if you want to see what's going on.
83 #if 1 84 #if 1
84 #define EnterFunction(x) 85 #define EnterFunction(x)
85 #define LeaveFunction(x) 86 #define LeaveFunction(x)
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 271
271 #endif 272 #endif
272 273
273 } // namespace 274 } // namespace
274 275
275 #if defined(OS_WIN) 276 #if defined(OS_WIN)
276 // static 277 // static
277 HCERTSTORE SSLClientSocketNSS::cert_store_ = NULL; 278 HCERTSTORE SSLClientSocketNSS::cert_store_ = NULL;
278 #endif 279 #endif
279 280
280 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket, 281 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket,
281 const std::string& hostname, 282 const std::string& hostname,
282 const SSLConfig& ssl_config) 283 const SSLConfig& ssl_config)
283 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_( 284 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_(
284 this, &SSLClientSocketNSS::BufferSendComplete)), 285 this, &SSLClientSocketNSS::BufferSendComplete)),
285 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_( 286 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_(
286 this, &SSLClientSocketNSS::BufferRecvComplete)), 287 this, &SSLClientSocketNSS::BufferRecvComplete)),
287 transport_send_busy_(false), 288 transport_send_busy_(false),
288 transport_recv_busy_(false), 289 transport_recv_busy_(false),
289 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_( 290 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_(
290 this, &SSLClientSocketNSS::OnHandshakeIOComplete)), 291 this, &SSLClientSocketNSS::OnHandshakeIOComplete)),
291 transport_(transport_socket), 292 transport_(transport_socket),
292 hostname_(hostname), 293 hostname_(hostname),
293 ssl_config_(ssl_config), 294 ssl_config_(ssl_config),
294 user_connect_callback_(NULL), 295 user_connect_callback_(NULL),
295 user_read_callback_(NULL), 296 user_read_callback_(NULL),
296 user_write_callback_(NULL), 297 user_write_callback_(NULL),
297 user_read_buf_len_(0), 298 user_read_buf_len_(0),
298 user_write_buf_len_(0), 299 user_write_buf_len_(0),
299 server_cert_nss_(NULL), 300 server_cert_nss_(NULL),
300 client_auth_cert_needed_(false), 301 client_auth_cert_needed_(false),
301 handshake_callback_called_(false), 302 handshake_callback_called_(false),
302 completed_handshake_(false), 303 completed_handshake_(false),
303 next_handshake_state_(STATE_NONE), 304 next_handshake_state_(STATE_NONE),
304 nss_fd_(NULL), 305 nss_fd_(NULL),
305 nss_bufs_(NULL), 306 nss_bufs_(NULL),
306 net_log_(transport_socket->NetLog()) { 307 net_log_(transport_socket->socket()->NetLog()) {
307 EnterFunction(""); 308 EnterFunction("");
308 } 309 }
309 310
310 SSLClientSocketNSS::~SSLClientSocketNSS() { 311 SSLClientSocketNSS::~SSLClientSocketNSS() {
311 EnterFunction(""); 312 EnterFunction("");
312 Disconnect(); 313 Disconnect();
313 LeaveFunction(""); 314 LeaveFunction("");
314 } 315 }
315 316
316 int SSLClientSocketNSS::Init() { 317 int SSLClientSocketNSS::Init() {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 int SSLClientSocketNSS::InitializeSSLOptions() { 371 int SSLClientSocketNSS::InitializeSSLOptions() {
371 // Transport connected, now hook it up to nss 372 // Transport connected, now hook it up to nss
372 // TODO(port): specify rx and tx buffer sizes separately 373 // TODO(port): specify rx and tx buffer sizes separately
373 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); 374 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize);
374 if (nss_fd_ == NULL) { 375 if (nss_fd_ == NULL) {
375 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. 376 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code.
376 } 377 }
377 378
378 // Tell NSS who we're connected to 379 // Tell NSS who we're connected to
379 AddressList peer_address; 380 AddressList peer_address;
380 int err = transport_->GetPeerAddress(&peer_address); 381 int err = transport_->socket()->GetPeerAddress(&peer_address);
381 if (err != OK) 382 if (err != OK)
382 return err; 383 return err;
383 384
384 const struct addrinfo* ai = peer_address.head(); 385 const struct addrinfo* ai = peer_address.head();
385 386
386 PRNetAddr peername; 387 PRNetAddr peername;
387 memset(&peername, 0, sizeof(peername)); 388 memset(&peername, 0, sizeof(peername));
388 DCHECK_LE(ai->ai_addrlen, sizeof(peername)); 389 DCHECK_LE(ai->ai_addrlen, sizeof(peername));
389 size_t len = std::min(static_cast<size_t>(ai->ai_addrlen), sizeof(peername)); 390 size_t len = std::min(static_cast<size_t>(ai->ai_addrlen), sizeof(peername));
390 memcpy(&peername, ai->ai_addr, len); 391 memcpy(&peername, ai->ai_addr, len);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 // TODO(wtc): Send SSL close_notify alert. 542 // TODO(wtc): Send SSL close_notify alert.
542 if (nss_fd_ != NULL) { 543 if (nss_fd_ != NULL) {
543 InvalidateSessionIfBadCertificate(); 544 InvalidateSessionIfBadCertificate();
544 PR_Close(nss_fd_); 545 PR_Close(nss_fd_);
545 nss_fd_ = NULL; 546 nss_fd_ = NULL;
546 } 547 }
547 548
548 // Shut down anything that may call us back (through buffer_send_callback_, 549 // Shut down anything that may call us back (through buffer_send_callback_,
549 // buffer_recv_callback, or handshake_io_callback_). 550 // buffer_recv_callback, or handshake_io_callback_).
550 verifier_.reset(); 551 verifier_.reset();
551 transport_->Disconnect(); 552 transport_->socket()->Disconnect();
552 553
553 // Reset object state 554 // Reset object state
554 transport_send_busy_ = false; 555 transport_send_busy_ = false;
555 transport_recv_busy_ = false; 556 transport_recv_busy_ = false;
556 user_connect_callback_ = NULL; 557 user_connect_callback_ = NULL;
557 user_read_callback_ = NULL; 558 user_read_callback_ = NULL;
558 user_write_callback_ = NULL; 559 user_write_callback_ = NULL;
559 user_read_buf_ = NULL; 560 user_read_buf_ = NULL;
560 user_read_buf_len_ = 0; 561 user_read_buf_len_ = 0;
561 user_write_buf_ = NULL; 562 user_write_buf_ = NULL;
(...skipping 13 matching lines...) Expand all
575 } 576 }
576 577
577 bool SSLClientSocketNSS::IsConnected() const { 578 bool SSLClientSocketNSS::IsConnected() const {
578 // Ideally, we should also check if we have received the close_notify alert 579 // Ideally, we should also check if we have received the close_notify alert
579 // message from the server, and return false in that case. We're not doing 580 // message from the server, and return false in that case. We're not doing
580 // that, so this function may return a false positive. Since the upper 581 // that, so this function may return a false positive. Since the upper
581 // layer (HttpNetworkTransaction) needs to handle a persistent connection 582 // layer (HttpNetworkTransaction) needs to handle a persistent connection
582 // closed by the server when we send a request anyway, a false positive in 583 // closed by the server when we send a request anyway, a false positive in
583 // exchange for simpler code is a good trade-off. 584 // exchange for simpler code is a good trade-off.
584 EnterFunction(""); 585 EnterFunction("");
585 bool ret = completed_handshake_ && transport_->IsConnected(); 586 bool ret = completed_handshake_ && transport_->socket()->IsConnected();
586 LeaveFunction(""); 587 LeaveFunction("");
587 return ret; 588 return ret;
588 } 589 }
589 590
590 bool SSLClientSocketNSS::IsConnectedAndIdle() const { 591 bool SSLClientSocketNSS::IsConnectedAndIdle() const {
591 // Unlike IsConnected, this method doesn't return a false positive. 592 // Unlike IsConnected, this method doesn't return a false positive.
592 // 593 //
593 // Strictly speaking, we should check if we have received the close_notify 594 // Strictly speaking, we should check if we have received the close_notify
594 // alert message from the server, and return false in that case. Although 595 // alert message from the server, and return false in that case. Although
595 // the close_notify alert message means EOF in the SSL layer, it is just 596 // the close_notify alert message means EOF in the SSL layer, it is just
596 // bytes to the transport layer below, so transport_->IsConnectedAndIdle() 597 // bytes to the transport layer below, so
597 // returns the desired false when we receive close_notify. 598 // transport_->socket()->IsConnectedAndIdle() returns the desired false
599 // when we receive close_notify.
598 EnterFunction(""); 600 EnterFunction("");
599 bool ret = completed_handshake_ && transport_->IsConnectedAndIdle(); 601 bool ret = completed_handshake_ && transport_->socket()->IsConnectedAndIdle();
600 LeaveFunction(""); 602 LeaveFunction("");
601 return ret; 603 return ret;
602 } 604 }
603 605
604 int SSLClientSocketNSS::GetPeerAddress(AddressList* address) const { 606 int SSLClientSocketNSS::GetPeerAddress(AddressList* address) const {
605 return transport_->GetPeerAddress(address); 607 return transport_->socket()->GetPeerAddress(address);
606 } 608 }
607 609
608 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len, 610 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len,
609 CompletionCallback* callback) { 611 CompletionCallback* callback) {
610 EnterFunction(buf_len); 612 EnterFunction(buf_len);
611 DCHECK(completed_handshake_); 613 DCHECK(completed_handshake_);
612 DCHECK(next_handshake_state_ == STATE_NONE); 614 DCHECK(next_handshake_state_ == STATE_NONE);
613 DCHECK(!user_read_callback_); 615 DCHECK(!user_read_callback_);
614 DCHECK(!user_connect_callback_); 616 DCHECK(!user_connect_callback_);
615 DCHECK(!user_read_buf_); 617 DCHECK(!user_read_buf_);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 user_write_callback_ = callback; 651 user_write_callback_ = callback;
650 } else { 652 } else {
651 user_write_buf_ = NULL; 653 user_write_buf_ = NULL;
652 user_write_buf_len_ = 0; 654 user_write_buf_len_ = 0;
653 } 655 }
654 LeaveFunction(rv); 656 LeaveFunction(rv);
655 return rv; 657 return rv;
656 } 658 }
657 659
658 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) { 660 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
659 return transport_->SetReceiveBufferSize(size); 661 return transport_->socket()->SetReceiveBufferSize(size);
660 } 662 }
661 663
662 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) { 664 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) {
663 return transport_->SetSendBufferSize(size); 665 return transport_->socket()->SetSendBufferSize(size);
664 } 666 }
665 667
666 #if defined(OS_WIN) 668 #if defined(OS_WIN)
667 // static 669 // static
668 X509Certificate::OSCertHandle SSLClientSocketNSS::CreateOSCert( 670 X509Certificate::OSCertHandle SSLClientSocketNSS::CreateOSCert(
669 const SECItem& der_cert) { 671 const SECItem& der_cert) {
670 // TODO(wtc): close cert_store_ at shutdown. 672 // TODO(wtc): close cert_store_ at shutdown.
671 if (!cert_store_) 673 if (!cert_store_)
672 cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); 674 cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL);
673 675
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 // nss_bufs_ is a circular buffer. It may have two contiguous parts 1012 // nss_bufs_ is a circular buffer. It may have two contiguous parts
1011 // (before and after the wrap). So this for loop needs two iterations. 1013 // (before and after the wrap). So this for loop needs two iterations.
1012 for (int i = 0; i < 2; ++i) { 1014 for (int i = 0; i < 2; ++i) {
1013 const char* buf; 1015 const char* buf;
1014 int nb = memio_GetWriteParams(nss_bufs_, &buf); 1016 int nb = memio_GetWriteParams(nss_bufs_, &buf);
1015 if (!nb) 1017 if (!nb)
1016 break; 1018 break;
1017 1019
1018 scoped_refptr<IOBuffer> send_buffer = new IOBuffer(nb); 1020 scoped_refptr<IOBuffer> send_buffer = new IOBuffer(nb);
1019 memcpy(send_buffer->data(), buf, nb); 1021 memcpy(send_buffer->data(), buf, nb);
1020 int rv = transport_->Write(send_buffer, nb, &buffer_send_callback_); 1022 int rv = transport_->socket()->Write(send_buffer, nb,
1023 &buffer_send_callback_);
1021 if (rv == ERR_IO_PENDING) { 1024 if (rv == ERR_IO_PENDING) {
1022 transport_send_busy_ = true; 1025 transport_send_busy_ = true;
1023 break; 1026 break;
1024 } else { 1027 } else {
1025 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); 1028 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv));
1026 if (rv < 0) { 1029 if (rv < 0) {
1027 // Return the error even if the previous Write succeeded. 1030 // Return the error even if the previous Write succeeded.
1028 nsent = rv; 1031 nsent = rv;
1029 break; 1032 break;
1030 } 1033 }
(...skipping 19 matching lines...) Expand all
1050 1053
1051 char *buf; 1054 char *buf;
1052 int nb = memio_GetReadParams(nss_bufs_, &buf); 1055 int nb = memio_GetReadParams(nss_bufs_, &buf);
1053 EnterFunction(nb); 1056 EnterFunction(nb);
1054 int rv; 1057 int rv;
1055 if (!nb) { 1058 if (!nb) {
1056 // buffer too full to read into, so no I/O possible at moment 1059 // buffer too full to read into, so no I/O possible at moment
1057 rv = ERR_IO_PENDING; 1060 rv = ERR_IO_PENDING;
1058 } else { 1061 } else {
1059 recv_buffer_ = new IOBuffer(nb); 1062 recv_buffer_ = new IOBuffer(nb);
1060 rv = transport_->Read(recv_buffer_, nb, &buffer_recv_callback_); 1063 rv = transport_->socket()->Read(recv_buffer_, nb, &buffer_recv_callback_);
1061 if (rv == ERR_IO_PENDING) { 1064 if (rv == ERR_IO_PENDING) {
1062 transport_recv_busy_ = true; 1065 transport_recv_busy_ = true;
1063 } else { 1066 } else {
1064 if (rv > 0) 1067 if (rv > 0)
1065 memcpy(buf, recv_buffer_->data(), rv); 1068 memcpy(buf, recv_buffer_->data(), rv);
1066 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv)); 1069 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv));
1067 recv_buffer_ = NULL; 1070 recv_buffer_ = NULL;
1068 } 1071 }
1069 } 1072 }
1070 LeaveFunction(rv); 1073 LeaveFunction(rv);
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
1552 PRErrorCode prerr = PR_GetError(); 1555 PRErrorCode prerr = PR_GetError();
1553 if (prerr == PR_WOULD_BLOCK_ERROR) { 1556 if (prerr == PR_WOULD_BLOCK_ERROR) {
1554 LeaveFunction(""); 1557 LeaveFunction("");
1555 return ERR_IO_PENDING; 1558 return ERR_IO_PENDING;
1556 } 1559 }
1557 LeaveFunction(""); 1560 LeaveFunction("");
1558 return MapNSPRError(prerr); 1561 return MapNSPRError(prerr);
1559 } 1562 }
1560 1563
1561 } // namespace net 1564 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698