summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/nss_util.cc41
-rw-r--r--net/socket/ssl_client_socket_nss.cc62
2 files changed, 61 insertions, 42 deletions
diff --git a/base/nss_util.cc b/base/nss_util.cc
index 2f7ff7f..f440f70 100644
--- a/base/nss_util.cc
+++ b/base/nss_util.cc
@@ -4,7 +4,6 @@
#include "base/nss_util.h"
-#include <dlfcn.h>
#include <nss.h>
#include <plarena.h>
#include <prerror.h>
@@ -12,7 +11,6 @@
#include <prtime.h>
#include <pk11pub.h>
#include <secmod.h>
-#include <ssl.h>
#include "base/file_util.h"
#include "base/logging.h"
@@ -41,7 +39,7 @@ SECMODModule *InitDefaultRootCerts() {
const char* kModulePath = "libnssckbi.so";
char modparams[1024];
snprintf(modparams, sizeof(modparams),
- "name=\"Root Certs\" library=\"%s\"", kModulePath);
+ "name=\"Root Certs\" library=\"%s\"", kModulePath);
SECMODModule *root = SECMOD_LoadUserModule(modparams, NULL, PR_FALSE);
if (root)
return root;
@@ -61,6 +59,7 @@ class NSPRInitSingleton {
}
~NSPRInitSingleton() {
+ PL_ArenaFinish();
PRStatus prstatus = PR_Cleanup();
if (prstatus != PR_SUCCESS) {
LOG(ERROR) << "PR_Cleanup failed; was NSPR initialized on wrong thread?";
@@ -118,37 +117,6 @@ class NSSInitSingleton {
}
root_ = InitDefaultRootCerts();
-
- NSS_SetDomesticPolicy();
-
-#if defined(USE_SYSTEM_SSL)
- // Use late binding to avoid scary but benign warning
- // "Symbol `SSL_ImplementedCiphers' has different size in shared object,
- // consider re-linking"
- const PRUint16* pSSL_ImplementedCiphers = static_cast<const PRUint16*>(
- dlsym(RTLD_DEFAULT, "SSL_ImplementedCiphers"));
- if (pSSL_ImplementedCiphers == NULL) {
- NOTREACHED() << "Can't get list of supported ciphers";
- return;
- }
-#else
-#define pSSL_ImplementedCiphers SSL_ImplementedCiphers
-#endif
-
- // Explicitly enable exactly those ciphers with keys of at least 80 bits
- for (int i = 0; i < SSL_NumImplementedCiphers; i++) {
- SSLCipherSuiteInfo info;
- if (SSL_GetCipherSuiteInfo(pSSL_ImplementedCiphers[i], &info,
- sizeof(info)) == SECSuccess) {
- SSL_CipherPrefSetDefault(pSSL_ImplementedCiphers[i],
- (info.effectiveKeyBits >= 80));
- }
- }
-
- // Enable SSL
- SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);
-
- // All other SSL options are set per-session by SSLClientSocket.
}
~NSSInitSingleton() {
@@ -158,9 +126,6 @@ class NSSInitSingleton {
root_ = NULL;
}
- // Have to clear the cache, or NSS_Shutdown fails with SEC_ERROR_BUSY
- SSL_ClearSessionCache();
-
SECStatus status = NSS_Shutdown();
if (status != SECSuccess) {
// We LOG(INFO) because this failure is relatively harmless
@@ -168,8 +133,6 @@ class NSSInitSingleton {
LOG(INFO) << "NSS_Shutdown failed; see "
"http://code.google.com/p/chromium/issues/detail?id=4609";
}
-
- PL_ArenaFinish();
}
private:
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index 350a4c9..29af7f0 100644
--- a/net/socket/ssl_client_socket_nss.cc
+++ b/net/socket/ssl_client_socket_nss.cc
@@ -47,6 +47,9 @@
#include "net/socket/ssl_client_socket_nss.h"
+#if defined(USE_SYSTEM_SSL)
+#include <dlfcn.h>
+#endif
#include <certdb.h>
#include <keyhi.h>
#include <nspr.h>
@@ -59,6 +62,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/nss_util.h"
+#include "base/singleton.h"
#include "base/string_util.h"
#include "net/base/cert_verifier.h"
#include "net/base/io_buffer.h"
@@ -96,6 +100,57 @@ namespace net {
namespace {
+class NSSSSLInitSingleton {
+ public:
+ NSSSSLInitSingleton() {
+ base::EnsureNSSInit();
+
+ NSS_SetDomesticPolicy();
+
+#if defined(USE_SYSTEM_SSL)
+ // Use late binding to avoid scary but benign warning
+ // "Symbol `SSL_ImplementedCiphers' has different size in shared object,
+ // consider re-linking"
+ const PRUint16* pSSL_ImplementedCiphers = static_cast<const PRUint16*>(
+ dlsym(RTLD_DEFAULT, "SSL_ImplementedCiphers"));
+ if (pSSL_ImplementedCiphers == NULL) {
+ NOTREACHED() << "Can't get list of supported ciphers";
+ return;
+ }
+#else
+#define pSSL_ImplementedCiphers SSL_ImplementedCiphers
+#endif
+
+ // Explicitly enable exactly those ciphers with keys of at least 80 bits
+ for (int i = 0; i < SSL_NumImplementedCiphers; i++) {
+ SSLCipherSuiteInfo info;
+ if (SSL_GetCipherSuiteInfo(pSSL_ImplementedCiphers[i], &info,
+ sizeof(info)) == SECSuccess) {
+ SSL_CipherPrefSetDefault(pSSL_ImplementedCiphers[i],
+ (info.effectiveKeyBits >= 80));
+ }
+ }
+
+ // Enable SSL.
+ SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);
+
+ // All other SSL options are set per-session by SSLClientSocket.
+ }
+
+ ~NSSSSLInitSingleton() {
+ // Have to clear the cache, or NSS_Shutdown fails with SEC_ERROR_BUSY.
+ SSL_ClearSessionCache();
+ }
+};
+
+// Initialize the NSS SSL library if it isn't already initialized. This must
+// be called before any other NSS SSL functions. This function is
+// thread-safe, and the NSS SSL library will only ever be initialized once.
+// The NSS SSL library will be properly shut down on program exit.
+void EnsureNSSSSLInit() {
+ Singleton<NSSSSLInitSingleton>::get();
+}
+
// The default error mapping function.
// Maps an NSPR error code to a network error code.
int MapNSPRError(PRErrorCode err) {
@@ -193,8 +248,9 @@ SSLClientSocketNSS::~SSLClientSocketNSS() {
int SSLClientSocketNSS::Init() {
EnterFunction("");
- // Initialize NSS in a threadsafe way.
- base::EnsureNSSInit();
+ // Initialize the NSS SSL library in a threadsafe way. This also
+ // initializes the NSS base library.
+ EnsureNSSSSLInit();
// We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop
// by MessageLoopForIO::current().
// X509Certificate::Verify() runs on a worker thread of CertVerifier.
@@ -576,7 +632,7 @@ SSLClientSocketNSS::GetNextProto(std::string* proto) {
}
// We don't check for truncation because sizeof(buf) is large enough to hold
// the maximum protocol size.
- switch(state) {
+ switch (state) {
case SSL_NEXT_PROTO_NO_SUPPORT:
proto->clear();
return kNextProtoUnsupported;