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

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

Issue 12025040: When reading from an SSL socket, attempt to fully fill the caller's buffer (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Initialization order Created 7 years, 10 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 819 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 //////////////////////////////////////////////////////////////////////////// 830 ////////////////////////////////////////////////////////////////////////////
831 HostPortPair host_and_port_; 831 HostPortPair host_and_port_;
832 SSLConfig ssl_config_; 832 SSLConfig ssl_config_;
833 833
834 // NSS SSL socket. 834 // NSS SSL socket.
835 PRFileDesc* nss_fd_; 835 PRFileDesc* nss_fd_;
836 836
837 // Buffers for the network end of the SSL state machine 837 // Buffers for the network end of the SSL state machine
838 memio_Private* nss_bufs_; 838 memio_Private* nss_bufs_;
839 839
840 // Used by DoPayloadRead() when attempting to completely fill the caller's
841 // buffer.
wtc 2013/02/13 22:06:51 The goal should be: when data has been received, f
842 // If DoPayloadRead() encounters an error after having read some data, stores
843 // the results to return on the *next* call to DoPayloadRead(). A value > 0
844 // indicates there is no pending result (as 0 indicates EOF, < 0 indicates
845 // error).
846 int pending_read_result_;
847 PRErrorCode pending_read_prerror_;
wtc 2013/02/13 22:06:51 prerror => nss_error Document that this member is
848
840 // The certificate chain, in DER form, that is expected to be received from 849 // The certificate chain, in DER form, that is expected to be received from
841 // the server. 850 // the server.
842 std::vector<std::string> predicted_certs_; 851 std::vector<std::string> predicted_certs_;
843 852
844 State next_handshake_state_; 853 State next_handshake_state_;
845 854
846 // True if channel ID extension was negotiated. 855 // True if channel ID extension was negotiated.
847 bool channel_id_xtn_negotiated_; 856 bool channel_id_xtn_negotiated_;
848 // True if the handshake state machine was interrupted for channel ID. 857 // True if the handshake state machine was interrupted for channel ID.
849 bool channel_id_needed_; 858 bool channel_id_needed_;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 weak_net_log_factory_(net_log), 914 weak_net_log_factory_(net_log),
906 server_bound_cert_service_(server_bound_cert_service), 915 server_bound_cert_service_(server_bound_cert_service),
907 unhandled_buffer_size_(0), 916 unhandled_buffer_size_(0),
908 nss_waiting_read_(false), 917 nss_waiting_read_(false),
909 nss_waiting_write_(false), 918 nss_waiting_write_(false),
910 nss_is_closed_(false), 919 nss_is_closed_(false),
911 host_and_port_(host_and_port), 920 host_and_port_(host_and_port),
912 ssl_config_(ssl_config), 921 ssl_config_(ssl_config),
913 nss_fd_(NULL), 922 nss_fd_(NULL),
914 nss_bufs_(NULL), 923 nss_bufs_(NULL),
924 pending_read_result_(1),
925 pending_read_prerror_(0),
915 next_handshake_state_(STATE_NONE), 926 next_handshake_state_(STATE_NONE),
916 channel_id_xtn_negotiated_(false), 927 channel_id_xtn_negotiated_(false),
917 channel_id_needed_(false), 928 channel_id_needed_(false),
918 client_auth_cert_needed_(false), 929 client_auth_cert_needed_(false),
919 handshake_callback_called_(false), 930 handshake_callback_called_(false),
920 transport_recv_busy_(false), 931 transport_recv_busy_(false),
921 transport_recv_eof_(false), 932 transport_recv_eof_(false),
922 transport_send_busy_(false), 933 transport_send_busy_(false),
923 user_read_buf_len_(0), 934 user_read_buf_len_(0),
924 user_write_buf_len_(0), 935 user_write_buf_len_(0),
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after
1938 SetChannelIDProvided(); 1949 SetChannelIDProvided();
1939 GotoState(STATE_HANDSHAKE); 1950 GotoState(STATE_HANDSHAKE);
1940 return OK; 1951 return OK;
1941 } 1952 }
1942 1953
1943 int SSLClientSocketNSS::Core::DoPayloadRead() { 1954 int SSLClientSocketNSS::Core::DoPayloadRead() {
1944 DCHECK(OnNSSTaskRunner()); 1955 DCHECK(OnNSSTaskRunner());
1945 DCHECK(user_read_buf_); 1956 DCHECK(user_read_buf_);
1946 DCHECK_GT(user_read_buf_len_, 0); 1957 DCHECK_GT(user_read_buf_len_, 0);
1947 1958
1948 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); 1959 int rv;
1949 // Update NSSTaskRunner status because PR_Read may consume |nss_bufs_|, then 1960 // If a previous greedy read resulted in an error that was not consumed (eg:
1950 // following |amount_in_read_buffer| may be changed here. 1961 // due to the caller having read some data successfully), then return that
1951 int amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); 1962 // pending error now.
wtc 2013/02/13 22:06:51 Just wanted to verify that you meant to delete thi
Ryan Sleevi 2013/02/13 22:55:48 Nope. Rebase bug. Good catch.
1952 PostOrRunCallback( 1963 if (pending_read_result_ <= 0) {
1953 FROM_HERE, 1964 rv = pending_read_result_;
1954 base::Bind(&Core::OnNSSBufferUpdated, this, amount_in_read_buffer)); 1965 PRErrorCode prerr = pending_read_prerror_;
1966 pending_read_result_ = 1;
1967 pending_read_prerror_ = 0;
1955 1968
1956 if (client_auth_cert_needed_) { 1969 if (rv != ERR_IO_PENDING) {
wtc 2013/02/13 22:06:51 We should add && rv != 0. A graceful connection cl
1957 // We don't need to invalidate the non-client-authenticated SSL session 1970 PostOrRunCallback(
1958 // because the server will renegotiate anyway. 1971 FROM_HERE,
1959 rv = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; 1972 base::Bind(&AddLogEventWithCallback, weak_net_log_,
1960 PostOrRunCallback( 1973 NetLog::TYPE_SSL_READ_ERROR,
1961 FROM_HERE, 1974 CreateNetLogSSLErrorCallback(rv, prerr)));
1962 base::Bind(&AddLogEventWithCallback, weak_net_log_, 1975 }
1963 NetLog::TYPE_SSL_READ_ERROR,
1964 CreateNetLogSSLErrorCallback(rv, 0)));
1965 return rv; 1976 return rv;
1966 } 1977 }
1978
1979 // Perform a greedy read, attempting to read as much as the caller has
1980 // requested. Normally, PR_Read will return exactly one SSL application data
wtc 2013/02/13 22:06:51 Please add "in the current NSS implementation". We
Ryan Sleevi 2013/02/13 22:55:48 I'm not sure I agree, for reasons I explained prev
wtc 2013/02/15 23:30:04 The techniques you're using here (calling PR_Read
1981 // record's worth of data per invocation. The record size is dictated by the
1982 // server, and may be noticably smaller than the caller's buffer.
1983 //
1984 // However, this greedy read may result in renegotiations/re-handshakes
1985 // happening or may lead to some data being read, followed by an EOF (such as
1986 // a TLS close-notify). If at least some data was read, then the error should
1987 // be deferred until the next call to DoPayloadRead(). Otherwise, the error
1988 // should be returned immediately.
wtc 2013/02/13 22:06:51 I believe that if renegotiation happens, PR_Read w
Ryan Sleevi 2013/02/13 22:55:48 My focus was in highlighting that SSL is not alway
1989 int total_bytes_read = 0;
1990 do {
1991 rv = PR_Read(nss_fd_, user_read_buf_->data() + total_bytes_read,
1992 user_read_buf_len_ - total_bytes_read);
1993 if (rv > 0)
1994 total_bytes_read += rv;
1995 } while (total_bytes_read < user_read_buf_len_ && rv > 0);
1996
1997 if (total_bytes_read == user_read_buf_len_) {
1998 // The caller's entire request was satisfied without error. No further
1999 // processing needed.
2000 rv = total_bytes_read;
2001 } else {
2002 // Otherwise, an error occurred (rv <= 0). The error needs to be handled
2003 // immediately, while the NSPR/NSS errors are still available in
2004 // thread-local storage. However, the handled/remapped error code should
2005 // only be returned if no application data was already read; if it was, the
2006 // error code should be deferred until the next call of DoPayloadRead.
2007 int* next_result = &rv;
wtc 2013/02/13 22:06:51 Just a commentary: the use of next_result makes th
2008 if (total_bytes_read > 0) {
2009 pending_read_result_ = rv;
Ryan Hamilton 2013/02/13 17:23:18 same comment about using a const kNoPendingReadRes
2010 rv = total_bytes_read;
2011 next_result = &pending_read_result_;
2012 }
2013
2014 if (client_auth_cert_needed_) {
2015 *next_result = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
wtc 2013/02/13 22:06:51 We should set pending_read_prerror_ to 0 in this c
2016 } else if (*next_result < 0) {
2017 // If *next_result == 0, then that indicates EOF, and no special error
2018 // handling is needed.
2019 pending_read_prerror_ = PR_GetError();
2020 if (pending_read_prerror_ == PR_WOULD_BLOCK_ERROR) {
2021 *next_result = ERR_IO_PENDING;
2022 pending_read_prerror_ = 0;
wtc 2013/02/13 22:06:51 It seems OK for pending_read_prerror_ to be PR_WOU
Ryan Sleevi 2013/02/13 22:55:48 I'm not sure I fully follow, but what I understand
2023 } else {
2024 *next_result = HandleNSSError(pending_read_prerror_, false);
2025 }
2026 }
2027 }
2028
1967 if (rv >= 0) { 2029 if (rv >= 0) {
1968 PostOrRunCallback( 2030 PostOrRunCallback(
1969 FROM_HERE, 2031 FROM_HERE,
1970 base::Bind(&LogByteTransferEvent, weak_net_log_, 2032 base::Bind(&LogByteTransferEvent, weak_net_log_,
1971 NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv, 2033 NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv,
1972 scoped_refptr<IOBuffer>(user_read_buf_))); 2034 scoped_refptr<IOBuffer>(user_read_buf_)));
1973 return rv; 2035 } else if (rv != ERR_IO_PENDING) {
2036 PostOrRunCallback(
2037 FROM_HERE,
2038 base::Bind(&AddLogEventWithCallback, weak_net_log_,
2039 NetLog::TYPE_SSL_READ_ERROR,
2040 CreateNetLogSSLErrorCallback(rv, pending_read_prerror_)));
2041 pending_read_prerror_ = 0;
1974 } 2042 }
1975 PRErrorCode prerr = PR_GetError();
1976 if (prerr == PR_WOULD_BLOCK_ERROR)
1977 return ERR_IO_PENDING;
1978
1979 rv = HandleNSSError(prerr, false);
1980 PostOrRunCallback(
1981 FROM_HERE,
1982 base::Bind(&AddLogEventWithCallback, weak_net_log_,
1983 NetLog::TYPE_SSL_READ_ERROR,
1984 CreateNetLogSSLErrorCallback(rv, prerr)));
1985 return rv; 2043 return rv;
1986 } 2044 }
1987 2045
1988 int SSLClientSocketNSS::Core::DoPayloadWrite() { 2046 int SSLClientSocketNSS::Core::DoPayloadWrite() {
1989 DCHECK(OnNSSTaskRunner()); 2047 DCHECK(OnNSSTaskRunner());
1990 2048
1991 DCHECK(user_write_buf_); 2049 DCHECK(user_write_buf_);
1992 2050
1993 int old_amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_); 2051 int old_amount_in_read_buffer = memio_GetReadableBufferSize(nss_bufs_);
1994 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_); 2052 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
(...skipping 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after
3439 EnsureThreadIdAssigned(); 3497 EnsureThreadIdAssigned();
3440 base::AutoLock auto_lock(lock_); 3498 base::AutoLock auto_lock(lock_);
3441 return valid_thread_id_ == base::PlatformThread::CurrentId(); 3499 return valid_thread_id_ == base::PlatformThread::CurrentId();
3442 } 3500 }
3443 3501
3444 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { 3502 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const {
3445 return server_bound_cert_service_; 3503 return server_bound_cert_service_;
3446 } 3504 }
3447 3505
3448 } // namespace net 3506 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/socket/ssl_client_socket_openssl.h » ('j') | net/socket/ssl_client_socket_openssl.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698