Chromium Code Reviews| 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 |