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..969f3a8eee42f5c2092632298154e1ad8afe0b18 100644 |
--- a/net/socket/ssl_client_socket_nss.cc |
+++ b/net/socket/ssl_client_socket_nss.cc |
@@ -48,6 +48,7 @@ |
#include "net/socket/ssl_client_socket_nss.h" |
#include <certdb.h> |
+#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.
|
#include <hasht.h> |
#include <keyhi.h> |
#include <nspr.h> |
@@ -63,9 +64,10 @@ |
#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 +117,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 |
wtc
2011/01/18 19:57:01
Nit: LIBNSS => LibNSS
agl
2011/01/18 20:29:45
Done.
|
+// runtime symbol resolution that we need. |
+class RuntimeLIBNSSFunctionPointers { |
+ public: |
+ CacheOCSPResponseFromSideChannelFunction |
+ GetCacheOCSPResponseFromSideChannelFunction() { |
+ return cache_ocsp_response_from_side_channel_; |
+ } |
+ |
+ static RuntimeLIBNSSFunctionPointers* GetInstance() { |
+ return Singleton<RuntimeLIBNSSFunctionPointers>::get(); |
+ } |
-static bool HaveCacheOCSPResponseFromSideChannelFunction() { |
- return CERT_CacheOCSPResponseFromSideChannel != NULL; |
+ 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 +688,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) |
@@ -1991,10 +2020,10 @@ int SSLClientSocketNSS::DoHandshake() { |
#if defined(SSL_ENABLE_OCSP_STAPLING) |
// 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()) { |
+ 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.
|
unsigned int len = 0; |
SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len); |
if (len) { |
@@ -2008,7 +2037,7 @@ int SSLClientSocketNSS::DoHandshake() { |
ocsp_response_item.data = ocsp_response.get(); |
ocsp_response_item.len = len; |
- CERT_CacheOCSPResponseFromSideChannel( |
+ GetCacheOCSPResponseFromSideChannelFunction()( |
CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(), |
&ocsp_response_item, NULL); |
} |