OLD | NEW |
---|---|
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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 * | 45 * |
46 * ***** END LICENSE BLOCK ***** */ | 46 * ***** END LICENSE BLOCK ***** */ |
47 | 47 |
48 #include "net/socket/ssl_client_socket_nss.h" | 48 #include "net/socket/ssl_client_socket_nss.h" |
49 | 49 |
50 #include <certdb.h> | 50 #include <certdb.h> |
51 #include <hasht.h> | 51 #include <hasht.h> |
52 #include <keyhi.h> | 52 #include <keyhi.h> |
53 #include <nspr.h> | 53 #include <nspr.h> |
54 #include <nss.h> | 54 #include <nss.h> |
55 #include <ocsp.h> | |
55 #include <pk11pub.h> | 56 #include <pk11pub.h> |
56 #include <secerr.h> | 57 #include <secerr.h> |
57 #include <sechash.h> | 58 #include <sechash.h> |
58 #include <ssl.h> | 59 #include <ssl.h> |
59 #include <sslerr.h> | 60 #include <sslerr.h> |
60 #include <sslproto.h> | 61 #include <sslproto.h> |
61 | 62 |
62 #include <limits> | 63 #include <limits> |
63 | 64 |
64 #include "base/compiler_specific.h" | 65 #include "base/compiler_specific.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
104 #endif | 105 #endif |
105 | 106 |
106 static const int kRecvBufferSize = 4096; | 107 static const int kRecvBufferSize = 4096; |
107 | 108 |
108 // kCorkTimeoutMs is the number of milliseconds for which we'll wait for a | 109 // kCorkTimeoutMs is the number of milliseconds for which we'll wait for a |
109 // Write to an SSL socket which we're False Starting. Since corking stops the | 110 // Write to an SSL socket which we're False Starting. Since corking stops the |
110 // Finished message from being sent, the server sees an incomplete handshake | 111 // Finished message from being sent, the server sees an incomplete handshake |
111 // and some will time out such sockets quite aggressively. | 112 // and some will time out such sockets quite aggressively. |
112 static const int kCorkTimeoutMs = 200; | 113 static const int kCorkTimeoutMs = 200; |
113 | 114 |
115 #if defined(OS_LINUX) | |
116 // On Linux, we dynamically link against the system version of libnss3.so. In | |
117 // order to continue working on systems without up-to-date versions of NSS we | |
118 // declare CERT_CacheOCSPResponseFromSideChannel to be a weak symbol. If, at | |
119 // run time, we find that the symbol didn't resolve then we can avoid calling | |
120 // the function. | |
121 extern SECStatus | |
122 CERT_CacheOCSPResponseFromSideChannel( | |
123 CERTCertDBHandle *handle, CERTCertificate *cert, PRTime time, | |
124 SECItem *encodedResponse, void *pwArg) __attribute__((weak)); | |
125 | |
126 static bool HaveCacheOCSPResponseFromSideChannelFunction() { | |
127 return CERT_CacheOCSPResponseFromSideChannel != NULL; | |
128 } | |
129 #else | |
130 // On other platforms we use the system's certificate validation functions. | |
131 // Thus we need, in the future, to plumb the OCSP response into those system | |
132 // functions. Until then, we act as if we didn't support OCSP stapling. | |
133 static bool HaveCacheOCSPResponseFromSideChannelFunction() { | |
134 return false; | |
135 } | |
136 #endif | |
137 | |
114 namespace net { | 138 namespace net { |
115 | 139 |
116 // State machines are easier to debug if you log state transitions. | 140 // State machines are easier to debug if you log state transitions. |
117 // Enable these if you want to see what's going on. | 141 // Enable these if you want to see what's going on. |
118 #if 1 | 142 #if 1 |
119 #define EnterFunction(x) | 143 #define EnterFunction(x) |
120 #define LeaveFunction(x) | 144 #define LeaveFunction(x) |
121 #define GotoState(s) next_handshake_state_ = s | 145 #define GotoState(s) next_handshake_state_ = s |
122 #define LogData(s, len) | 146 #define LogData(s, len) |
123 #else | 147 #else |
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
794 if (!ssl_config_.next_protos.empty()) { | 818 if (!ssl_config_.next_protos.empty()) { |
795 rv = SSL_SetNextProtoNego( | 819 rv = SSL_SetNextProtoNego( |
796 nss_fd_, | 820 nss_fd_, |
797 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()), | 821 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()), |
798 ssl_config_.next_protos.size()); | 822 ssl_config_.next_protos.size()); |
799 if (rv != SECSuccess) | 823 if (rv != SECSuccess) |
800 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", ""); | 824 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", ""); |
801 } | 825 } |
802 #endif | 826 #endif |
803 | 827 |
828 #ifdef SSL_ENABLE_OCSP_STAPLING | |
829 if (HaveCacheOCSPResponseFromSideChannelFunction() && | |
830 !ssl_config_.snap_start_enabled) { | |
831 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); | |
832 if (rv != SECSuccess) | |
833 LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", ""); | |
834 } | |
835 #endif | |
836 | |
804 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | 837 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); |
805 if (rv != SECSuccess) { | 838 if (rv != SECSuccess) { |
806 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); | 839 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); |
807 return ERR_UNEXPECTED; | 840 return ERR_UNEXPECTED; |
808 } | 841 } |
809 | 842 |
810 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); | 843 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); |
811 if (rv != SECSuccess) { | 844 if (rv != SECSuccess) { |
812 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); | 845 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); |
813 return ERR_UNEXPECTED; | 846 return ERR_UNEXPECTED; |
(...skipping 1336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2150 if (certs[i]->derCert.len != state.certs[i].size() || | 2183 if (certs[i]->derCert.len != state.certs[i].size() || |
2151 memcmp(certs[i]->derCert.data, state.certs[i].data(), | 2184 memcmp(certs[i]->derCert.data, state.certs[i].data(), |
2152 certs[i]->derCert.len) != 0) { | 2185 certs[i]->derCert.len) != 0) { |
2153 predicted_cert_chain_correct_ = false; | 2186 predicted_cert_chain_correct_ = false; |
2154 break; | 2187 break; |
2155 } | 2188 } |
2156 } | 2189 } |
2157 } | 2190 } |
2158 } | 2191 } |
2159 | 2192 |
2193 #if defined(SSL_ENABLE_OCSP_STAPLING) | |
2194 // TODO: we need to be able to plumb an OCSP response into the system | |
wtc
2010/11/30 19:19:16
Nit: cpplint.py requires that a TODO comment inclu
| |
2195 // libraries. When we do, HaveCacheOCSPResponseFromSideChannelFunction | |
2196 // needs to be updated for those platforms. | |
2197 if (!predicted_cert_chain_correct_ && | |
2198 HaveCacheOCSPResponseFromSideChannelFunction()) { | |
2199 unsigned int len = 0; | |
2200 SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len); | |
2201 if (len) { | |
2202 const unsigned int orig_len = len; | |
2203 scoped_array<uint8> ocsp_response(new uint8[orig_len]); | |
2204 SSL_GetStapledOCSPResponse(nss_fd_, ocsp_response.get(), &len); | |
2205 DCHECK_EQ(orig_len, len); | |
2206 | |
2207 SECItem ocsp_response_item; | |
2208 ocsp_response_item.type = siBuffer; | |
2209 ocsp_response_item.data = ocsp_response.get(); | |
2210 ocsp_response_item.len = len; | |
2211 | |
2212 CERT_CacheOCSPResponseFromSideChannel( | |
2213 CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(), | |
2214 &ocsp_response_item, NULL); | |
2215 } | |
2216 } | |
2217 #endif | |
2218 | |
2160 SaveSnapStartInfo(); | 2219 SaveSnapStartInfo(); |
2161 // SSL handshake is completed. It's possible that we mispredicted the | 2220 // SSL handshake is completed. It's possible that we mispredicted the |
2162 // NPN agreed protocol. In this case, we've just sent a request in the | 2221 // NPN agreed protocol. In this case, we've just sent a request in the |
2163 // wrong protocol! The higher levels of this network stack aren't | 2222 // wrong protocol! The higher levels of this network stack aren't |
2164 // prepared for switching the protocol like that so we make up an error | 2223 // prepared for switching the protocol like that so we make up an error |
2165 // and rely on the fact that the request will be retried. | 2224 // and rely on the fact that the request will be retried. |
2166 if (IsNPNProtocolMispredicted()) { | 2225 if (IsNPNProtocolMispredicted()) { |
2167 LOG(WARNING) << "Mispredicted NPN protocol for " | 2226 LOG(WARNING) << "Mispredicted NPN protocol for " |
2168 << host_and_port_.ToString(); | 2227 << host_and_port_.ToString(); |
2169 net_error = ERR_SSL_SNAP_START_NPN_MISPREDICTION; | 2228 net_error = ERR_SSL_SNAP_START_NPN_MISPREDICTION; |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2612 case SSL_CONNECTION_VERSION_TLS1_1: | 2671 case SSL_CONNECTION_VERSION_TLS1_1: |
2613 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1); | 2672 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1); |
2614 break; | 2673 break; |
2615 case SSL_CONNECTION_VERSION_TLS1_2: | 2674 case SSL_CONNECTION_VERSION_TLS1_2: |
2616 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2); | 2675 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2); |
2617 break; | 2676 break; |
2618 }; | 2677 }; |
2619 } | 2678 } |
2620 | 2679 |
2621 } // namespace net | 2680 } // namespace net |
OLD | NEW |