OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |