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 30 matching lines...) Expand all Loading... | |
41 * decision by deleting the provisions above and replace them with the notice | 41 * decision by deleting the provisions above and replace them with the notice |
42 * and other provisions required by the GPL or the LGPL. If you do not delete | 42 * and other provisions required by the GPL or the LGPL. If you do not delete |
43 * the provisions above, a recipient may use your version of this file under | 43 * the provisions above, a recipient may use your version of this file under |
44 * the terms of any one of the MPL, the GPL or the LGPL. | 44 * the terms of any one of the MPL, the GPL or the LGPL. |
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 <dlfcn.h> | |
wtc
2011/01/18 19:57:01
BUG: this #include needs to be protected with an i
agl
2011/01/18 20:29:45
Done, thanks.
| |
51 #include <hasht.h> | 52 #include <hasht.h> |
52 #include <keyhi.h> | 53 #include <keyhi.h> |
53 #include <nspr.h> | 54 #include <nspr.h> |
54 #include <nss.h> | 55 #include <nss.h> |
55 #include <ocsp.h> | 56 #include <ocsp.h> |
56 #include <pk11pub.h> | 57 #include <pk11pub.h> |
57 #include <secerr.h> | 58 #include <secerr.h> |
58 #include <sechash.h> | 59 #include <sechash.h> |
59 #include <ssl.h> | 60 #include <ssl.h> |
60 #include <sslerr.h> | 61 #include <sslerr.h> |
61 #include <sslproto.h> | 62 #include <sslproto.h> |
62 | 63 |
63 #include <limits> | 64 #include <limits> |
64 | 65 |
65 #include "base/compiler_specific.h" | 66 #include "base/compiler_specific.h" |
67 #include "base/logging.h" | |
66 #include "base/metrics/histogram.h" | 68 #include "base/metrics/histogram.h" |
67 #include "base/logging.h" | |
68 #include "base/nss_util.h" | 69 #include "base/nss_util.h" |
70 #include "base/singleton.h" | |
69 #include "base/string_number_conversions.h" | 71 #include "base/string_number_conversions.h" |
70 #include "base/string_util.h" | 72 #include "base/string_util.h" |
71 #include "base/stringprintf.h" | 73 #include "base/stringprintf.h" |
72 #include "base/threading/thread_restrictions.h" | 74 #include "base/threading/thread_restrictions.h" |
73 #include "base/values.h" | 75 #include "base/values.h" |
74 #include "net/base/address_list.h" | 76 #include "net/base/address_list.h" |
75 #include "net/base/cert_status_flags.h" | 77 #include "net/base/cert_status_flags.h" |
76 #include "net/base/cert_verifier.h" | 78 #include "net/base/cert_verifier.h" |
77 #include "net/base/connection_type_histograms.h" | 79 #include "net/base/connection_type_histograms.h" |
78 #include "net/base/dns_util.h" | 80 #include "net/base/dns_util.h" |
(...skipping 29 matching lines...) Expand all Loading... | |
108 | 110 |
109 // kCorkTimeoutMs is the number of milliseconds for which we'll wait for a | 111 // kCorkTimeoutMs is the number of milliseconds for which we'll wait for a |
110 // Write to an SSL socket which we're False Starting. Since corking stops the | 112 // Write to an SSL socket which we're False Starting. Since corking stops the |
111 // Finished message from being sent, the server sees an incomplete handshake | 113 // Finished message from being sent, the server sees an incomplete handshake |
112 // and some will time out such sockets quite aggressively. | 114 // and some will time out such sockets quite aggressively. |
113 static const int kCorkTimeoutMs = 200; | 115 static const int kCorkTimeoutMs = 200; |
114 | 116 |
115 #if defined(OS_LINUX) | 117 #if defined(OS_LINUX) |
116 // On Linux, we dynamically link against the system version of libnss3.so. In | 118 // 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 | 119 // 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 | 120 // lookup CERT_CacheOCSPResponseFromSideChannel with dlsym. |
119 // run time, we find that the symbol didn't resolve then we can avoid calling | 121 typedef SECStatus |
120 // the function. | 122 (*CacheOCSPResponseFromSideChannelFunction)( |
121 extern SECStatus | |
122 CERT_CacheOCSPResponseFromSideChannel( | |
123 CERTCertDBHandle *handle, CERTCertificate *cert, PRTime time, | 123 CERTCertDBHandle *handle, CERTCertificate *cert, PRTime time, |
124 SECItem *encodedResponse, void *pwArg) __attribute__((weak)); | 124 SECItem *encodedResponse, void *pwArg); |
125 | 125 |
126 static bool HaveCacheOCSPResponseFromSideChannelFunction() { | 126 // RuntimeLIBNSSFunctionPointers is a singleton which caches the results of any |
wtc
2011/01/18 19:57:01
Nit: LIBNSS => LibNSS
agl
2011/01/18 20:29:45
Done.
| |
127 return CERT_CacheOCSPResponseFromSideChannel != NULL; | 127 // runtime symbol resolution that we need. |
128 class RuntimeLIBNSSFunctionPointers { | |
129 public: | |
130 CacheOCSPResponseFromSideChannelFunction | |
131 GetCacheOCSPResponseFromSideChannelFunction() { | |
132 return cache_ocsp_response_from_side_channel_; | |
133 } | |
134 | |
135 static RuntimeLIBNSSFunctionPointers* GetInstance() { | |
136 return Singleton<RuntimeLIBNSSFunctionPointers>::get(); | |
137 } | |
138 | |
139 private: | |
140 friend struct DefaultSingletonTraits<RuntimeLIBNSSFunctionPointers>; | |
141 | |
142 RuntimeLIBNSSFunctionPointers() { | |
143 cache_ocsp_response_from_side_channel_ = | |
144 (CacheOCSPResponseFromSideChannelFunction) | |
145 dlsym(RTLD_DEFAULT, "CERT_CacheOCSPResponseFromSideChannel"); | |
146 } | |
147 | |
148 CacheOCSPResponseFromSideChannelFunction | |
149 cache_ocsp_response_from_side_channel_; | |
150 }; | |
151 | |
152 static CacheOCSPResponseFromSideChannelFunction | |
153 GetCacheOCSPResponseFromSideChannelFunction() { | |
154 return RuntimeLIBNSSFunctionPointers::GetInstance() | |
155 ->GetCacheOCSPResponseFromSideChannelFunction(); | |
128 } | 156 } |
129 #else | 157 #else |
130 // On other platforms we use the system's certificate validation functions. | 158 // 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 | 159 // 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. | 160 // functions. Until then, we act as if we didn't support OCSP stapling. |
133 static bool HaveCacheOCSPResponseFromSideChannelFunction() { | 161 static CacheOCSPResponseFromSideChannelFunction |
134 return false; | 162 GetCacheOCSPResponseFromSideChannelFunction() { |
163 return NULL; | |
135 } | 164 } |
136 #endif | 165 #endif |
137 | 166 |
138 namespace net { | 167 namespace net { |
139 | 168 |
140 // State machines are easier to debug if you log state transitions. | 169 // State machines are easier to debug if you log state transitions. |
141 // Enable these if you want to see what's going on. | 170 // Enable these if you want to see what's going on. |
142 #if 1 | 171 #if 1 |
143 #define EnterFunction(x) | 172 #define EnterFunction(x) |
144 #define LeaveFunction(x) | 173 #define LeaveFunction(x) |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
652 rv = SSL_SetNextProtoNego( | 681 rv = SSL_SetNextProtoNego( |
653 nss_fd_, | 682 nss_fd_, |
654 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()), | 683 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()), |
655 ssl_config_.next_protos.size()); | 684 ssl_config_.next_protos.size()); |
656 if (rv != SECSuccess) | 685 if (rv != SECSuccess) |
657 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", ""); | 686 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", ""); |
658 } | 687 } |
659 #endif | 688 #endif |
660 | 689 |
661 #ifdef SSL_ENABLE_OCSP_STAPLING | 690 #ifdef SSL_ENABLE_OCSP_STAPLING |
662 if (HaveCacheOCSPResponseFromSideChannelFunction() && | 691 if (GetCacheOCSPResponseFromSideChannelFunction() && |
663 !ssl_config_.snap_start_enabled) { | 692 !ssl_config_.snap_start_enabled) { |
664 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); | 693 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); |
665 if (rv != SECSuccess) | 694 if (rv != SECSuccess) |
666 LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", ""); | 695 LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", ""); |
667 } | 696 } |
668 #endif | 697 #endif |
669 | 698 |
670 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | 699 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); |
671 if (rv != SECSuccess) { | 700 if (rv != SECSuccess) { |
672 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); | 701 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); |
(...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1984 certs[i]->derCert.len) != 0) { | 2013 certs[i]->derCert.len) != 0) { |
1985 predicted_cert_chain_correct_ = false; | 2014 predicted_cert_chain_correct_ = false; |
1986 break; | 2015 break; |
1987 } | 2016 } |
1988 } | 2017 } |
1989 } | 2018 } |
1990 } | 2019 } |
1991 | 2020 |
1992 #if defined(SSL_ENABLE_OCSP_STAPLING) | 2021 #if defined(SSL_ENABLE_OCSP_STAPLING) |
1993 // TODO: we need to be able to plumb an OCSP response into the system | 2022 // TODO: we need to be able to plumb an OCSP response into the system |
1994 // libraries. When we do, HaveCacheOCSPResponseFromSideChannelFunction | 2023 // libraries. When we do, GetOCSPResponseFromSideChannelFunction |
1995 // needs to be updated for those platforms. | 2024 // needs to be updated for those platforms. |
1996 if (!predicted_cert_chain_correct_ && | 2025 if (!predicted_cert_chain_correct_ && |
1997 HaveCacheOCSPResponseFromSideChannelFunction()) { | 2026 GetCacheOCSPResponseFromSideChannelFunction()) { |
wtc
2011/01/18 19:57:01
Nit: it would be nice to save the return value of
agl
2011/01/18 20:29:45
Done.
| |
1998 unsigned int len = 0; | 2027 unsigned int len = 0; |
1999 SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len); | 2028 SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len); |
2000 if (len) { | 2029 if (len) { |
2001 const unsigned int orig_len = len; | 2030 const unsigned int orig_len = len; |
2002 scoped_array<uint8> ocsp_response(new uint8[orig_len]); | 2031 scoped_array<uint8> ocsp_response(new uint8[orig_len]); |
2003 SSL_GetStapledOCSPResponse(nss_fd_, ocsp_response.get(), &len); | 2032 SSL_GetStapledOCSPResponse(nss_fd_, ocsp_response.get(), &len); |
2004 DCHECK_EQ(orig_len, len); | 2033 DCHECK_EQ(orig_len, len); |
2005 | 2034 |
2006 SECItem ocsp_response_item; | 2035 SECItem ocsp_response_item; |
2007 ocsp_response_item.type = siBuffer; | 2036 ocsp_response_item.type = siBuffer; |
2008 ocsp_response_item.data = ocsp_response.get(); | 2037 ocsp_response_item.data = ocsp_response.get(); |
2009 ocsp_response_item.len = len; | 2038 ocsp_response_item.len = len; |
2010 | 2039 |
2011 CERT_CacheOCSPResponseFromSideChannel( | 2040 GetCacheOCSPResponseFromSideChannelFunction()( |
2012 CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(), | 2041 CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(), |
2013 &ocsp_response_item, NULL); | 2042 &ocsp_response_item, NULL); |
2014 } | 2043 } |
2015 } | 2044 } |
2016 #endif | 2045 #endif |
2017 | 2046 |
2018 SaveSnapStartInfo(); | 2047 SaveSnapStartInfo(); |
2019 // SSL handshake is completed. It's possible that we mispredicted the | 2048 // SSL handshake is completed. It's possible that we mispredicted the |
2020 // NPN agreed protocol. In this case, we've just sent a request in the | 2049 // NPN agreed protocol. In this case, we've just sent a request in the |
2021 // wrong protocol! The higher levels of this network stack aren't | 2050 // wrong protocol! The higher levels of this network stack aren't |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2485 case SSL_CONNECTION_VERSION_TLS1_1: | 2514 case SSL_CONNECTION_VERSION_TLS1_1: |
2486 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1); | 2515 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1); |
2487 break; | 2516 break; |
2488 case SSL_CONNECTION_VERSION_TLS1_2: | 2517 case SSL_CONNECTION_VERSION_TLS1_2: |
2489 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2); | 2518 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2); |
2490 break; | 2519 break; |
2491 }; | 2520 }; |
2492 } | 2521 } |
2493 | 2522 |
2494 } // namespace net | 2523 } // namespace net |
OLD | NEW |