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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 #include <Security/SecBase.h> | 109 #include <Security/SecBase.h> |
110 #include <Security/SecCertificate.h> | 110 #include <Security/SecCertificate.h> |
111 #include <Security/SecIdentity.h> | 111 #include <Security/SecIdentity.h> |
112 #include "base/mac/mac_logging.h" | 112 #include "base/mac/mac_logging.h" |
113 #elif defined(USE_NSS) | 113 #elif defined(USE_NSS) |
114 #include <dlfcn.h> | 114 #include <dlfcn.h> |
115 #endif | 115 #endif |
116 | 116 |
117 static const int kRecvBufferSize = 4096; | 117 static const int kRecvBufferSize = 4096; |
118 | 118 |
119 // kCorkTimeoutMs is the number of milliseconds for which we'll wait for a | |
120 // Write to an SSL socket which we're False Starting. Since corking stops the | |
121 // Finished message from being sent, the server sees an incomplete handshake | |
122 // and some will time out such sockets quite aggressively. | |
123 static const int kCorkTimeoutMs = 200; | |
Ryan Sleevi
2012/04/09 22:42:56
This seems unrelated to the description. That is,
agl
2012/04/09 23:05:31
The cork aims to put the CKX, CCS, Finished and Ap
| |
124 | |
125 #if defined(OS_WIN) | 119 #if defined(OS_WIN) |
126 // CERT_OCSP_RESPONSE_PROP_ID is only implemented on Vista+, but it can be | 120 // CERT_OCSP_RESPONSE_PROP_ID is only implemented on Vista+, but it can be |
127 // set on Windows XP without error. There is some overhead from the server | 121 // set on Windows XP without error. There is some overhead from the server |
128 // sending the OCSP response if it supports the extension, for the subset of | 122 // sending the OCSP response if it supports the extension, for the subset of |
129 // XP clients who will request it but be unable to use it, but this is an | 123 // XP clients who will request it but be unable to use it, but this is an |
130 // acceptable trade-off for simplicity of implementation. | 124 // acceptable trade-off for simplicity of implementation. |
131 static bool IsOCSPStaplingSupported() { | 125 static bool IsOCSPStaplingSupported() { |
132 return true; | 126 return true; |
133 } | 127 } |
134 #elif defined(USE_NSS) | 128 #elif defined(USE_NSS) |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
430 | 424 |
431 } // namespace | 425 } // namespace |
432 | 426 |
433 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket, | 427 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket, |
434 const HostPortPair& host_and_port, | 428 const HostPortPair& host_and_port, |
435 const SSLConfig& ssl_config, | 429 const SSLConfig& ssl_config, |
436 SSLHostInfo* ssl_host_info, | 430 SSLHostInfo* ssl_host_info, |
437 const SSLClientSocketContext& context) | 431 const SSLClientSocketContext& context) |
438 : transport_send_busy_(false), | 432 : transport_send_busy_(false), |
439 transport_recv_busy_(false), | 433 transport_recv_busy_(false), |
440 corked_(false), | |
441 transport_(transport_socket), | 434 transport_(transport_socket), |
442 host_and_port_(host_and_port), | 435 host_and_port_(host_and_port), |
443 ssl_config_(ssl_config), | 436 ssl_config_(ssl_config), |
444 user_read_buf_len_(0), | 437 user_read_buf_len_(0), |
445 user_write_buf_len_(0), | 438 user_write_buf_len_(0), |
446 server_cert_nss_(NULL), | 439 server_cert_nss_(NULL), |
447 server_cert_verify_result_(NULL), | 440 server_cert_verify_result_(NULL), |
448 ssl_connection_status_(0), | 441 ssl_connection_status_(0), |
449 client_auth_cert_needed_(false), | 442 client_auth_cert_needed_(false), |
450 cert_verifier_(context.cert_verifier), | 443 cert_verifier_(context.cert_verifier), |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
784 DCHECK(completed_handshake_); | 777 DCHECK(completed_handshake_); |
785 DCHECK(next_handshake_state_ == STATE_NONE); | 778 DCHECK(next_handshake_state_ == STATE_NONE); |
786 DCHECK(user_write_callback_.is_null()); | 779 DCHECK(user_write_callback_.is_null()); |
787 DCHECK(user_connect_callback_.is_null()); | 780 DCHECK(user_connect_callback_.is_null()); |
788 DCHECK(!user_write_buf_); | 781 DCHECK(!user_write_buf_); |
789 DCHECK(nss_bufs_); | 782 DCHECK(nss_bufs_); |
790 | 783 |
791 user_write_buf_ = buf; | 784 user_write_buf_ = buf; |
792 user_write_buf_len_ = buf_len; | 785 user_write_buf_len_ = buf_len; |
793 | 786 |
794 if (corked_) { | |
795 corked_ = false; | |
796 uncork_timer_.Reset(); | |
797 } | |
798 int rv = DoWriteLoop(OK); | 787 int rv = DoWriteLoop(OK); |
799 | 788 |
800 if (rv == ERR_IO_PENDING) { | 789 if (rv == ERR_IO_PENDING) { |
801 user_write_callback_ = callback; | 790 user_write_callback_ = callback; |
802 } else { | 791 } else { |
803 user_write_buf_ = NULL; | 792 user_write_buf_ = NULL; |
804 user_write_buf_len_ = 0; | 793 user_write_buf_len_ = 0; |
805 } | 794 } |
806 LeaveFunction(rv); | 795 LeaveFunction(rv); |
807 return rv; | 796 return rv; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
910 #ifdef SSL_ENABLE_DEFLATE | 899 #ifdef SSL_ENABLE_DEFLATE |
911 // Some web servers have been found to break if TLS is used *or* if DEFLATE | 900 // Some web servers have been found to break if TLS is used *or* if DEFLATE |
912 // is advertised. Thus, if TLS is disabled (probably because we are doing | 901 // is advertised. Thus, if TLS is disabled (probably because we are doing |
913 // SSLv3 fallback), we disable DEFLATE also. | 902 // SSLv3 fallback), we disable DEFLATE also. |
914 // See http://crbug.com/31628 | 903 // See http://crbug.com/31628 |
915 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_DEFLATE, ssl_config_.tls1_enabled); | 904 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_DEFLATE, ssl_config_.tls1_enabled); |
916 if (rv != SECSuccess) | 905 if (rv != SECSuccess) |
917 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_DEFLATE"); | 906 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_DEFLATE"); |
918 #endif | 907 #endif |
919 | 908 |
920 PRBool false_start_enabled = | |
921 ssl_config_.false_start_enabled && | |
922 !SSLConfigService::IsKnownFalseStartIncompatibleServer( | |
923 host_and_port_.host()); | |
924 #ifdef SSL_ENABLE_FALSE_START | 909 #ifdef SSL_ENABLE_FALSE_START |
925 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, false_start_enabled); | 910 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, |
911 ssl_config_.false_start_enabled); | |
926 if (rv != SECSuccess) | 912 if (rv != SECSuccess) |
927 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START"); | 913 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START"); |
928 #endif | 914 #endif |
929 | 915 |
930 #ifdef SSL_ENABLE_RENEGOTIATION | 916 #ifdef SSL_ENABLE_RENEGOTIATION |
931 // We allow servers to request renegotiation. Since we're a client, | 917 // We allow servers to request renegotiation. Since we're a client, |
932 // prohibiting this is rather a waste of time. Only servers are in a | 918 // prohibiting this is rather a waste of time. Only servers are in a |
933 // position to prevent renegotiation attacks. | 919 // position to prevent renegotiation attacks. |
934 // http://extendedsubset.com/?p=8 | 920 // http://extendedsubset.com/?p=8 |
935 | 921 |
936 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, | 922 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, |
937 SSL_RENEGOTIATE_TRANSITIONAL); | 923 SSL_RENEGOTIATE_TRANSITIONAL); |
938 if (rv != SECSuccess) { | 924 if (rv != SECSuccess) { |
939 LogFailedNSSFunction( | 925 LogFailedNSSFunction( |
940 net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION"); | 926 net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION"); |
941 } | 927 } |
942 #endif // SSL_ENABLE_RENEGOTIATION | 928 #endif // SSL_ENABLE_RENEGOTIATION |
943 | 929 |
944 if (!ssl_config_.next_protos.empty()) { | 930 if (!ssl_config_.next_protos.empty()) { |
945 rv = SSL_SetNextProtoCallback( | 931 rv = SSL_SetNextProtoCallback( |
946 nss_fd_, SSLClientSocketNSS::NextProtoCallback, this); | 932 nss_fd_, SSLClientSocketNSS::NextProtoCallback, this); |
947 if (rv != SECSuccess) | 933 if (rv != SECSuccess) |
948 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoCallback", ""); | 934 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoCallback", ""); |
949 } | 935 } |
950 | 936 |
951 #ifdef SSL_CBC_RANDOM_IV | 937 #ifdef SSL_CBC_RANDOM_IV |
952 rv = SSL_OptionSet(nss_fd_, SSL_CBC_RANDOM_IV, false_start_enabled); | 938 rv = SSL_OptionSet(nss_fd_, SSL_CBC_RANDOM_IV, |
939 ssl_config_.false_start_enabled); | |
Ryan Sleevi
2012/04/09 22:42:56
Did you mean to make this unconditionally true? Or
agl
2012/04/09 23:05:31
|false_start_enabled| now means that we *can* do F
| |
953 if (rv != SECSuccess) | 940 if (rv != SECSuccess) |
954 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_CBC_RANDOM_IV"); | 941 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_CBC_RANDOM_IV"); |
955 #endif | 942 #endif |
956 | 943 |
957 #ifdef SSL_ENABLE_OCSP_STAPLING | 944 #ifdef SSL_ENABLE_OCSP_STAPLING |
958 if (IsOCSPStaplingSupported()) { | 945 if (IsOCSPStaplingSupported()) { |
959 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); | 946 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); |
960 if (rv != SECSuccess) { | 947 if (rv != SECSuccess) { |
961 LogFailedNSSFunction(net_log_, "SSL_OptionSet", | 948 LogFailedNSSFunction(net_log_, "SSL_OptionSet", |
962 "SSL_ENABLE_OCSP_STAPLING"); | 949 "SSL_ENABLE_OCSP_STAPLING"); |
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1958 return; | 1945 return; |
1959 | 1946 |
1960 state->certs.push_back(std::string( | 1947 state->certs.push_back(std::string( |
1961 reinterpret_cast<char*>(certs[i]->derCert.data), | 1948 reinterpret_cast<char*>(certs[i]->derCert.data), |
1962 certs[i]->derCert.len)); | 1949 certs[i]->derCert.len)); |
1963 } | 1950 } |
1964 | 1951 |
1965 ssl_host_info_->Persist(); | 1952 ssl_host_info_->Persist(); |
1966 } | 1953 } |
1967 | 1954 |
1968 void SSLClientSocketNSS::UncorkAfterTimeout() { | |
1969 corked_ = false; | |
1970 int nsent; | |
1971 do { | |
1972 nsent = BufferSend(); | |
1973 } while (nsent > 0); | |
1974 } | |
1975 | |
1976 // Do as much network I/O as possible between the buffer and the | 1955 // Do as much network I/O as possible between the buffer and the |
1977 // transport socket. Return true if some I/O performed, false | 1956 // transport socket. Return true if some I/O performed, false |
1978 // otherwise (error or ERR_IO_PENDING). | 1957 // otherwise (error or ERR_IO_PENDING). |
1979 bool SSLClientSocketNSS::DoTransportIO() { | 1958 bool SSLClientSocketNSS::DoTransportIO() { |
1980 EnterFunction(""); | 1959 EnterFunction(""); |
1981 bool network_moved = false; | 1960 bool network_moved = false; |
1982 if (nss_bufs_ != NULL) { | 1961 if (nss_bufs_ != NULL) { |
1983 int rv; | 1962 int rv; |
1984 // Read and write as much data as we can. The loop is neccessary | 1963 // Read and write as much data as we can. The loop is neccessary |
1985 // because Write() may return synchronously. | 1964 // because Write() may return synchronously. |
(...skipping 16 matching lines...) Expand all Loading... | |
2002 if (transport_send_busy_) | 1981 if (transport_send_busy_) |
2003 return ERR_IO_PENDING; | 1982 return ERR_IO_PENDING; |
2004 | 1983 |
2005 EnterFunction(""); | 1984 EnterFunction(""); |
2006 const char* buf1; | 1985 const char* buf1; |
2007 const char* buf2; | 1986 const char* buf2; |
2008 unsigned int len1, len2; | 1987 unsigned int len1, len2; |
2009 memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2); | 1988 memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2); |
2010 const unsigned int len = len1 + len2; | 1989 const unsigned int len = len1 + len2; |
2011 | 1990 |
2012 if (corked_ && len < kRecvBufferSize / 2) | |
2013 return 0; | |
2014 | |
2015 int rv = 0; | 1991 int rv = 0; |
2016 if (len) { | 1992 if (len) { |
2017 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len)); | 1993 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len)); |
2018 memcpy(send_buffer->data(), buf1, len1); | 1994 memcpy(send_buffer->data(), buf1, len1); |
2019 memcpy(send_buffer->data() + len1, buf2, len2); | 1995 memcpy(send_buffer->data() + len1, buf2, len2); |
2020 rv = transport_->socket()->Write( | 1996 rv = transport_->socket()->Write( |
2021 send_buffer, len, | 1997 send_buffer, len, |
2022 base::Bind(&SSLClientSocketNSS::BufferSendComplete, | 1998 base::Bind(&SSLClientSocketNSS::BufferSendComplete, |
2023 base::Unretained(this))); | 1999 base::Unretained(this))); |
2024 if (rv == ERR_IO_PENDING) { | 2000 if (rv == ERR_IO_PENDING) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2118 // static | 2094 // static |
2119 // NSS calls this if an incoming certificate needs to be verified. | 2095 // NSS calls this if an incoming certificate needs to be verified. |
2120 // Do nothing but return SECSuccess. | 2096 // Do nothing but return SECSuccess. |
2121 // This is called only in full handshake mode. | 2097 // This is called only in full handshake mode. |
2122 // Peer certificate is retrieved in HandshakeCallback() later, which is called | 2098 // Peer certificate is retrieved in HandshakeCallback() later, which is called |
2123 // in full handshake mode or in resumption handshake mode. | 2099 // in full handshake mode or in resumption handshake mode. |
2124 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, | 2100 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, |
2125 PRFileDesc* socket, | 2101 PRFileDesc* socket, |
2126 PRBool checksig, | 2102 PRBool checksig, |
2127 PRBool is_server) { | 2103 PRBool is_server) { |
2128 #ifdef SSL_ENABLE_FALSE_START | |
2129 // In the event that we are False Starting this connection, we wish to send | |
2130 // out the Finished message and first application data record in the same | |
2131 // packet. This prevents non-determinism when talking to False Start | |
2132 // intolerant servers which, otherwise, might see the two messages in | |
2133 // different reads or not, depending on network conditions. | |
2134 PRBool false_start = 0; | |
2135 SECStatus rv = SSL_OptionGet(socket, SSL_ENABLE_FALSE_START, &false_start); | |
2136 DCHECK_EQ(SECSuccess, rv); | |
2137 | |
2138 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | |
2139 CERTCertificate* cert = SSL_PeerCertificate(that->nss_fd_); | |
2140 if (cert) { | |
2141 char* common_name = CERT_GetCommonName(&cert->issuer); | |
2142 if (common_name) { | |
2143 if (false_start && strcmp(common_name, "ESET_RootSslCert") == 0) { | |
2144 // ESET anti-virus is capable of intercepting HTTPS connections on | |
2145 // Windows. However, it is False Start intolerant and causes the | |
2146 // connections to hang forever. We detect ESET by the issuer of the | |
2147 // leaf certificate and set a flag to return a specific error, giving | |
2148 // the user instructions for reconfiguring ESET. | |
2149 that->eset_mitm_detected_ = true; | |
2150 } | |
2151 if (false_start && | |
2152 strcmp(common_name, "ContentWatch Root Certificate Authority") == 0) { | |
2153 // This is NetNanny. NetNanny are updating their product so we | |
2154 // silently disable False Start for now. | |
2155 rv = SSL_OptionSet(socket, SSL_ENABLE_FALSE_START, PR_FALSE); | |
2156 DCHECK_EQ(SECSuccess, rv); | |
2157 false_start = 0; | |
2158 } | |
2159 PORT_Free(common_name); | |
2160 } | |
2161 CERT_DestroyCertificate(cert); | |
2162 } | |
2163 | |
2164 if (false_start && !that->handshake_callback_called_) { | |
2165 that->corked_ = true; | |
2166 that->uncork_timer_.Start(FROM_HERE, | |
2167 base::TimeDelta::FromMilliseconds(kCorkTimeoutMs), | |
2168 that, &SSLClientSocketNSS::UncorkAfterTimeout); | |
2169 } | |
2170 #endif | |
2171 | |
2172 // Tell NSS to not verify the certificate. | 2104 // Tell NSS to not verify the certificate. |
2173 return SECSuccess; | 2105 return SECSuccess; |
2174 } | 2106 } |
2175 | 2107 |
2176 // static | 2108 // static |
2177 bool SSLClientSocketNSS::DomainBoundCertNegotiated(PRFileDesc* socket) { | 2109 bool SSLClientSocketNSS::DomainBoundCertNegotiated(PRFileDesc* socket) { |
2178 PRBool xtn_negotiated = PR_FALSE; | 2110 PRBool xtn_negotiated = PR_FALSE; |
2179 SECStatus rv = SSL_HandshakeNegotiatedExtension( | 2111 SECStatus rv = SSL_HandshakeNegotiatedExtension( |
2180 socket, ssl_ob_cert_xtn, &xtn_negotiated); | 2112 socket, ssl_ob_cert_xtn, &xtn_negotiated); |
2181 DCHECK_EQ(SECSuccess, rv); | 2113 DCHECK_EQ(SECSuccess, rv); |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2710 EnsureThreadIdAssigned(); | 2642 EnsureThreadIdAssigned(); |
2711 base::AutoLock auto_lock(lock_); | 2643 base::AutoLock auto_lock(lock_); |
2712 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 2644 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
2713 } | 2645 } |
2714 | 2646 |
2715 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { | 2647 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { |
2716 return server_bound_cert_service_; | 2648 return server_bound_cert_service_; |
2717 } | 2649 } |
2718 | 2650 |
2719 } // namespace net | 2651 } // namespace net |
OLD | NEW |