Chromium Code Reviews| Index: net/socket/ssl_client_socket_nss.cc |
| diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc |
| index 9d12c011547b319c801cfebd27cbde1053ea9f8c..a54aeb18972aae2cb531eb291b5bcf5dea7e8b8b 100644 |
| --- a/net/socket/ssl_client_socket_nss.cc |
| +++ b/net/socket/ssl_client_socket_nss.cc |
| @@ -60,12 +60,17 @@ |
| #include <sslerr.h> |
| #include <sslproto.h> |
| +#if defined(OS_LINUX) |
| +#include <dlfcn.h> |
| +#endif |
| + |
| #include <limits> |
| #include "base/compiler_specific.h" |
| -#include "base/metrics/histogram.h" |
| #include "base/logging.h" |
| +#include "base/metrics/histogram.h" |
| #include "base/nss_util.h" |
| +#include "base/singleton.h" |
| #include "base/string_number_conversions.h" |
| #include "base/string_util.h" |
| #include "base/stringprintf.h" |
| @@ -115,23 +120,50 @@ static const int kCorkTimeoutMs = 200; |
| #if defined(OS_LINUX) |
| // On Linux, we dynamically link against the system version of libnss3.so. In |
| // order to continue working on systems without up-to-date versions of NSS we |
| -// declare CERT_CacheOCSPResponseFromSideChannel to be a weak symbol. If, at |
| -// run time, we find that the symbol didn't resolve then we can avoid calling |
| -// the function. |
| -extern SECStatus |
| -CERT_CacheOCSPResponseFromSideChannel( |
| +// lookup CERT_CacheOCSPResponseFromSideChannel with dlsym. |
| +typedef SECStatus |
| +(*CacheOCSPResponseFromSideChannelFunction)( |
| CERTCertDBHandle *handle, CERTCertificate *cert, PRTime time, |
| - SECItem *encodedResponse, void *pwArg) __attribute__((weak)); |
| + SECItem *encodedResponse, void *pwArg); |
| + |
| +// RuntimeLibNSSFunctionPointers is a singleton which caches the results of any |
| +// runtime symbol resolution that we need. |
| +class RuntimeLibNSSFunctionPointers { |
| + public: |
| + CacheOCSPResponseFromSideChannelFunction |
| + GetCacheOCSPResponseFromSideChannelFunction() { |
| + return cache_ocsp_response_from_side_channel_; |
| + } |
| -static bool HaveCacheOCSPResponseFromSideChannelFunction() { |
| - return CERT_CacheOCSPResponseFromSideChannel != NULL; |
| + static RuntimeLibNSSFunctionPointers* GetInstance() { |
| + return Singleton<RuntimeLibNSSFunctionPointers>::get(); |
| + } |
| + |
| + private: |
| + friend struct DefaultSingletonTraits<RuntimeLibNSSFunctionPointers>; |
| + |
| + RuntimeLibNSSFunctionPointers() { |
| + cache_ocsp_response_from_side_channel_ = |
| + (CacheOCSPResponseFromSideChannelFunction) |
| + dlsym(RTLD_DEFAULT, "CERT_CacheOCSPResponseFromSideChannel"); |
| + } |
| + |
| + CacheOCSPResponseFromSideChannelFunction |
| + cache_ocsp_response_from_side_channel_; |
| +}; |
| + |
| +static CacheOCSPResponseFromSideChannelFunction |
| +GetCacheOCSPResponseFromSideChannelFunction() { |
| + return RuntimeLibNSSFunctionPointers::GetInstance() |
| + ->GetCacheOCSPResponseFromSideChannelFunction(); |
| } |
| #else |
| // On other platforms we use the system's certificate validation functions. |
| // Thus we need, in the future, to plumb the OCSP response into those system |
| // functions. Until then, we act as if we didn't support OCSP stapling. |
| -static bool HaveCacheOCSPResponseFromSideChannelFunction() { |
| - return false; |
| +static CacheOCSPResponseFromSideChannelFunction |
| +GetCacheOCSPResponseFromSideChannelFunction() { |
| + return NULL; |
| } |
| #endif |
| @@ -659,7 +691,7 @@ int SSLClientSocketNSS::InitializeSSLOptions() { |
| #endif |
| #ifdef SSL_ENABLE_OCSP_STAPLING |
| - if (HaveCacheOCSPResponseFromSideChannelFunction() && |
| + if (GetCacheOCSPResponseFromSideChannelFunction() && |
| !ssl_config_.snap_start_enabled) { |
| rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); |
| if (rv != SECSuccess) |
| @@ -1990,11 +2022,12 @@ int SSLClientSocketNSS::DoHandshake() { |
| } |
| #if defined(SSL_ENABLE_OCSP_STAPLING) |
| + const CacheOCSPResponseFromSideChannelFunction cache_ocsp_response = |
| + GetCacheOCSPResponseFromSideChannelFunction(); |
| // TODO: we need to be able to plumb an OCSP response into the system |
| - // libraries. When we do, HaveCacheOCSPResponseFromSideChannelFunction |
| + // libraries. When we do, GetOCSPResponseFromSideChannelFunction |
| // needs to be updated for those platforms. |
| - if (!predicted_cert_chain_correct_ && |
| - HaveCacheOCSPResponseFromSideChannelFunction()) { |
| + if (!predicted_cert_chain_correct_ && cache_ocsp_response) { |
|
wtc
2011/01/18 20:43:48
I assume predicted_cert_chain_correct_ is likely t
|
| unsigned int len = 0; |
| SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len); |
| if (len) { |
| @@ -2008,7 +2041,7 @@ int SSLClientSocketNSS::DoHandshake() { |
| ocsp_response_item.data = ocsp_response.get(); |
| ocsp_response_item.len = len; |
| - CERT_CacheOCSPResponseFromSideChannel( |
| + cache_ocsp_response( |
| CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(), |
| &ocsp_response_item, NULL); |
| } |