Bug 891066, Part 3: Move more initialization of NSS to security/certverifier, r=keeler
--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CertVerifier.h"
#include "ExtendedValidation.h"
#include "ScopedNSSTypes.h"
#include "cert.h"
--- a/security/certverifier/CertVerifier.h
+++ b/security/certverifier/CertVerifier.h
@@ -1,8 +1,10 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_psm__CertVerifier_h
#define mozilla_psm__CertVerifier_h
#include "certt.h"
new file mode 100644
--- /dev/null
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "NSSCertDBTrustDomain.h"
+
+#include <stdint.h>
+
+#include "insanity/ScopedPtr.h"
+#include "cert.h"
+#include "nss.h"
+#include "ocsp.h"
+#include "prerror.h"
+#include "prprf.h"
+#include "secerr.h"
+#include "secmod.h"
+
+using namespace insanity::pkix;
+
+namespace mozilla { namespace psm {
+
+const char BUILTIN_ROOTS_MODULE_DEFAULT_NAME[] = "Builtin Roots Module";
+
+namespace {
+
+inline void PORT_Free_string(char* str) { PORT_Free(str); }
+
+typedef ScopedPtr<SECMODModule, SECMOD_DestroyModule> ScopedSECMODModule;
+
+static char*
+nss_addEscape(const char* string, char quote)
+{
+ char* newString = 0;
+ int escapes = 0, size = 0;
+ const char* src;
+ char* dest;
+
+ for (src=string; *src ; src++) {
+ if ((*src == quote) || (*src == '\\')) {
+ escapes++;
+ }
+ size++;
+ }
+
+ newString = (char*)PORT_ZAlloc(escapes+size+1);
+ if (!newString) {
+ return nullptr;
+ }
+
+ for (src=string, dest=newString; *src; src++,dest++) {
+ if ((*src == quote) || (*src == '\\')) {
+ *dest++ = '\\';
+ }
+ *dest = *src;
+ }
+
+ return newString;
+}
+
+} // unnamed namespace
+
+SECStatus
+InitializeNSS(const char* dir, bool readOnly)
+{
+ // The NSS_INIT_NOROOTINIT flag turns off the loading of the root certs
+ // module by NSS_Initialize because we will load it in InstallLoadableRoots
+ // later. It also allows us to work around a bug in the system NSS in
+ // Ubuntu 8.04, which loads any nonexistent "<configdir>/libnssckbi.so" as
+ // "/usr/lib/nss/libnssckbi.so".
+ uint32_t flags = NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE;
+ if (readOnly) {
+ flags |= NSS_INIT_READONLY;
+ }
+ return ::NSS_Initialize(dir, "", "", SECMOD_DB, flags);
+}
+
+SECStatus
+LoadLoadableRoots(/*optional*/ const char* dir, const char* modNameUTF8)
+{
+ PR_ASSERT(modNameUTF8);
+
+ if (!modNameUTF8) {
+ PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
+ return SECFailure;
+ }
+
+ ScopedPtr<char, PR_FreeLibraryName> fullLibraryPath(
+ PR_GetLibraryName(dir, "nssckbi"));
+ if (!fullLibraryPath) {
+ return SECFailure;
+ }
+
+ ScopedPtr<char, PORT_Free_string> escaped_fullLibraryPath(
+ nss_addEscape(fullLibraryPath.get(), '\"'));
+ if (!escaped_fullLibraryPath) {
+ return SECFailure;
+ }
+
+ // If a module exists with the same name, delete it.
+ int modType;
+ SECMOD_DeleteModule(modNameUTF8, &modType);
+
+ ScopedPtr<char, PR_smprintf_free> pkcs11ModuleSpec(
+ PR_smprintf("name=\"%s\" library=\"%s\"", modNameUTF8,
+ escaped_fullLibraryPath.get()));
+ if (!pkcs11ModuleSpec) {
+ return SECFailure;
+ }
+
+ ScopedSECMODModule rootsModule(SECMOD_LoadUserModule(pkcs11ModuleSpec.get(),
+ nullptr, false));
+ if (!rootsModule) {
+ return SECFailure;
+ }
+
+ if (!rootsModule->loaded) {
+ PR_SetError(PR_INVALID_STATE_ERROR, 0);
+ return SECFailure;
+ }
+
+ return SECSuccess;
+}
+
+void
+UnloadLoadableRoots(const char* modNameUTF8)
+{
+ PR_ASSERT(modNameUTF8);
+ ScopedSECMODModule rootsModule(SECMOD_FindModule(modNameUTF8));
+
+ if (rootsModule) {
+ SECMOD_UnloadUserModule(rootsModule.get());
+ }
+}
+
+void
+SetClassicOCSPBehavior(CertVerifier::ocsp_download_config enabled,
+ CertVerifier::ocsp_strict_config strict,
+ CertVerifier::ocsp_get_config get)
+{
+ CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB());
+ if (enabled == CertVerifier::ocsp_off) {
+ CERT_DisableOCSPChecking(CERT_GetDefaultCertDB());
+ } else {
+ CERT_EnableOCSPChecking(CERT_GetDefaultCertDB());
+ }
+
+ SEC_OcspFailureMode failureMode = strict == CertVerifier::ocsp_strict
+ ? ocspMode_FailureIsVerificationFailure
+ : ocspMode_FailureIsNotAVerificationFailure;
+ (void) CERT_SetOCSPFailureMode(failureMode);
+
+ CERT_ForcePostMethodForOCSP(get != CertVerifier::ocsp_get_enabled);
+
+ int OCSPTimeoutSeconds = 3;
+ if (strict == CertVerifier::ocsp_strict) {
+ OCSPTimeoutSeconds = 10;
+ }
+ CERT_SetOCSPTimeout(OCSPTimeoutSeconds);
+}
+
+} } // namespace mozilla::psm
new file mode 100644
--- /dev/null
+++ b/security/certverifier/NSSCertDBTrustDomain.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_psm__NSSCertDBTrustDomain_h
+#define mozilla_psm__NSSCertDBTrustDomain_h
+
+#include "secmodt.h"
+#include "CertVerifier.h"
+
+namespace mozilla { namespace psm {
+
+SECStatus InitializeNSS(const char* dir, bool readOnly);
+
+extern const char BUILTIN_ROOTS_MODULE_DEFAULT_NAME[];
+
+// The dir parameter is the path to the directory containing the NSS builtin
+// roots module. Usually this is the same as the path to the other NSS shared
+// libraries. If it is null then the (library) path will be searched.
+//
+// The modNameUTF8 parameter should usually be
+// BUILTIN_ROOTS_MODULE_DEFAULT_NAME.
+SECStatus LoadLoadableRoots(/*optional*/ const char* dir,
+ const char* modNameUTF8);
+
+void UnloadLoadableRoots(const char* modNameUTF8);
+
+void
+SetClassicOCSPBehavior(CertVerifier::ocsp_download_config enabled,
+ CertVerifier::ocsp_strict_config strict,
+ CertVerifier::ocsp_get_config get);
+
+} } // namespace mozilla::psm
+
+#endif // mozilla_psm__NSSCertDBTrustDomain_h
--- a/security/certverifier/moz.build
+++ b/security/certverifier/moz.build
@@ -1,16 +1,17 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES += [
'CertVerifier.cpp',
+ 'NSSCertDBTrustDomain.cpp',
]
if not CONFIG['NSS_NO_LIBPKIX']:
UNIFIED_SOURCES += [
'ExtendedValidation.cpp',
]
LOCAL_INCLUDES += [
--- a/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/security/manager/ssl/src/nsNSSComponent.cpp
@@ -6,16 +6,17 @@
#ifdef MOZ_LOGGING
#define FORCE_PR_LOG 1
#endif
#include "nsNSSComponent.h"
#include "ExtendedValidation.h"
+#include "NSSCertDBTrustDomain.h"
#include "mozilla/Telemetry.h"
#include "nsCertVerificationThread.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsComponentManagerUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsICertOverrideService.h"
#include "mozilla/Preferences.h"
#include "nsThreadUtils.h"
@@ -201,16 +202,46 @@ bool EnsureNSSInitialized(EnsureNSSOpera
}
default:
NS_ASSERTION(false, "Bad operator to EnsureNSSInitialized");
return false;
}
}
+static void
+SetClassicOCSPBehaviorFromPrefs(/*out*/ CertVerifier::ocsp_download_config* odc,
+ /*out*/ CertVerifier::ocsp_strict_config* osc,
+ /*out*/ CertVerifier::ocsp_get_config* ogc,
+ const MutexAutoLock& /*proofOfLock*/)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(odc);
+ MOZ_ASSERT(osc);
+ MOZ_ASSERT(ogc);
+
+ // 0 = disabled, otherwise enabled
+ *odc = Preferences::GetInt("security.OCSP.enabled", 1)
+ ? CertVerifier::ocsp_on
+ : CertVerifier::ocsp_off;
+
+ *osc = Preferences::GetBool("security.OCSP.require", false)
+ ? CertVerifier::ocsp_strict
+ : CertVerifier::ocsp_relaxed;
+
+ // XXX: Always use POST for OCSP; see bug 871954 for undoing this.
+ *ogc = Preferences::GetBool("security.OCSP.GET.enabled", false)
+ ? CertVerifier::ocsp_get_enabled
+ : CertVerifier::ocsp_get_disabled;
+
+ SetClassicOCSPBehavior(*odc, *osc, *ogc);
+
+ SSL_ClearSessionCache();
+}
+
nsNSSComponent::nsNSSComponent()
:mutex("nsNSSComponent.mutex"),
mNSSInitialized(false),
#ifndef MOZ_DISABLE_CRYPTOLEGACY
mThreadList(nullptr),
#endif
mCertVerificationThread(nullptr)
{
@@ -527,48 +558,18 @@ nsNSSComponent::ShutdownSmartCardThread(
void
nsNSSComponent::ShutdownSmartCardThreads()
{
delete mThreadList;
mThreadList = nullptr;
}
#endif // MOZ_DISABLE_CRYPTOLEGACY
-static char*
-nss_addEscape(const char* string, char quote)
-{
- char* newString = 0;
- int escapes = 0, size = 0;
- const char* src;
- char* dest;
-
- for (src=string; *src ; src++) {
- if ((*src == quote) || (*src == '\\')) {
- escapes++;
- }
- size++;
- }
-
- newString = (char*)PORT_ZAlloc(escapes+size+1);
- if (!newString) {
- return nullptr;
- }
-
- for (src=string, dest=newString; *src; src++,dest++) {
- if ((*src == quote) || (*src == '\\')) {
- *dest++ = '\\';
- }
- *dest = *src;
- }
-
- return newString;
-}
-
void
-nsNSSComponent::InstallLoadableRoots()
+nsNSSComponent::LoadLoadableRoots()
{
nsNSSShutDownPreventionLock locker;
SECMODModule* RootsModule = nullptr;
// In the past we used SECMOD_AddNewModule to load our module containing
// root CA certificates. This caused problems, refer to bug 176501.
// On startup, we fix our database and clean any stored module reference,
// and will use SECMOD_LoadUserModule to temporarily load it
@@ -633,25 +634,20 @@ nsNSSComponent::InstallLoadableRoots()
NS_XPCOM_CURRENT_PROCESS_DIR,
NS_GRE_DIR,
0 // This special value means:
// search for ckbi in the directories on the shared
// library/DLL search path
};
for (size_t il = 0; il < sizeof(possible_ckbi_locations)/sizeof(const char*); ++il) {
- nsCOMPtr<nsIFile> mozFile;
- char* fullLibraryPath = nullptr;
+ nsAutoCString libDir;
- if (!possible_ckbi_locations[il])
- {
- fullLibraryPath = PR_GetLibraryName(nullptr, "nssckbi");
- }
- else
- {
+ if (possible_ckbi_locations[il]) {
+ nsCOMPtr<nsIFile> mozFile;
if (possible_ckbi_locations[il] == nss_lib) {
// Get the location of the nss3 library.
char* nss_path = PR_GetLibraryFilePathname(DLL_PREFIX "nss3" DLL_SUFFIX,
(PRFuncPtr) NSS_Initialize);
if (!nss_path) {
continue;
}
// Get the directory containing the nss3 library.
@@ -671,79 +667,40 @@ nsNSSComponent::InstallLoadableRoots()
NS_GET_IID(nsIFile),
getter_AddRefs(mozFile));
}
if (!mozFile) {
continue;
}
- nsAutoCString processDir;
- mozFile->GetNativePath(processDir);
- fullLibraryPath = PR_GetLibraryName(processDir.get(), "nssckbi");
- }
-
- if (!fullLibraryPath) {
- continue;
- }
-
- char* escaped_fullLibraryPath = nss_addEscape(fullLibraryPath, '\"');
- if (!escaped_fullLibraryPath) {
- PR_FreeLibraryName(fullLibraryPath); // allocated by NSPR
- continue;
+ if (NS_FAILED(mozFile->GetNativePath(libDir))) {
+ continue;
+ }
}
- // If a module exists with the same name, delete it.
NS_ConvertUTF16toUTF8 modNameUTF8(modName);
- int modType;
- SECMOD_DeleteModule(const_cast<char*>(modNameUTF8.get()), &modType);
-
- nsCString pkcs11moduleSpec;
- pkcs11moduleSpec.Append(NS_LITERAL_CSTRING("name=\""));
- pkcs11moduleSpec.Append(modNameUTF8.get());
- pkcs11moduleSpec.Append(NS_LITERAL_CSTRING("\" library=\""));
- pkcs11moduleSpec.Append(escaped_fullLibraryPath);
- pkcs11moduleSpec.Append(NS_LITERAL_CSTRING("\""));
-
- PR_FreeLibraryName(fullLibraryPath); // allocated by NSPR
- PORT_Free(escaped_fullLibraryPath);
-
- RootsModule =
- SECMOD_LoadUserModule(const_cast<char*>(pkcs11moduleSpec.get()),
- nullptr, // no parent
- false); // do not recurse
-
- if (RootsModule) {
- bool found = (RootsModule->loaded);
-
- SECMOD_DestroyModule(RootsModule);
- RootsModule = nullptr;
-
- if (found) {
- break;
- }
+ if (mozilla::psm::LoadLoadableRoots(
+ libDir.Length() > 0 ? libDir.get() : nullptr,
+ modNameUTF8.get()) == SECSuccess) {
+ break;
}
}
}
void
nsNSSComponent::UnloadLoadableRoots()
{
nsresult rv;
nsAutoString modName;
rv = GetPIPNSSBundleString("RootCertModuleName", modName);
if (NS_FAILED(rv)) return;
NS_ConvertUTF16toUTF8 modNameUTF8(modName);
- SECMODModule* RootsModule = SECMOD_FindModule(modNameUTF8.get());
-
- if (RootsModule) {
- SECMOD_UnloadUserModule(RootsModule);
- SECMOD_DestroyModule(RootsModule);
- }
+ ::mozilla::psm::UnloadLoadableRoots(modNameUTF8.get());
}
nsresult
nsNSSComponent::ConfigureInternalPKCS11Token()
{
nsNSSShutDownPreventionLock locker;
nsAutoString manufacturerID;
nsAutoString libraryDescription;
@@ -889,29 +846,16 @@ static const CipherPref sCipherPrefs[] =
{ "security.ssl3.dhe_dss_camellia_128_sha",
TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, false },
{ "security.ssl3.rsa_seed_sha",
TLS_RSA_WITH_SEED_CBC_SHA, false },
{ nullptr, 0 } // end marker
};
-static void
-setNonPkixOcspEnabled(int32_t ocspEnabled)
-{
- // Note: this preference is numeric vs boolean because previously we
- // supported more than two options.
- CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB());
- if (!ocspEnabled) {
- CERT_DisableOCSPChecking(CERT_GetDefaultCertDB());
- } else {
- CERT_EnableOCSPChecking(CERT_GetDefaultCertDB());
- }
-}
-
static const int32_t OCSP_ENABLED_DEFAULT = 1;
static const bool REQUIRE_SAFE_NEGOTIATION_DEFAULT = false;
static const bool ALLOW_UNRESTRICTED_RENEGO_DEFAULT = false;
static const bool FALSE_START_ENABLED_DEFAULT = true;
static const bool NPN_ENABLED_DEFAULT = true;
static const bool ALPN_ENABLED_DEFAULT = false;
namespace {
@@ -988,20 +932,19 @@ CipherSuiteChangeObserver::Observe(nsISu
}
}
return NS_OK;
}
} // anonymous namespace
// Caller must hold a lock on nsNSSComponent::mutex when calling this function
-void nsNSSComponent::setValidationOptions(bool isInitialSetting)
+void nsNSSComponent::setValidationOptions(bool isInitialSetting,
+ const MutexAutoLock& lock)
{
- nsNSSShutDownPreventionLock locker;
-
bool crlDownloading = Preferences::GetBool("security.CRL_download.enabled",
false);
// This preference controls whether we do OCSP fetching and does not affect
// OCSP stapling.
// 0 = disabled, 1 = enabled
int32_t ocspEnabled = Preferences::GetInt("security.OCSP.enabled",
OCSP_ENABLED_DEFAULT);
@@ -1019,53 +962,38 @@ void nsNSSComponent::setValidationOption
bool aiaDownloadEnabled = Preferences::GetBool("security.missing_cert_download.enabled",
false);
bool ocspStaplingEnabled = Preferences::GetBool("security.ssl.enable_ocsp_stapling",
true);
PublicSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
PrivateSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
- setNonPkixOcspEnabled(ocspEnabled);
-
- CERT_SetOCSPFailureMode( ocspRequired ?
- ocspMode_FailureIsVerificationFailure
- : ocspMode_FailureIsNotAVerificationFailure);
-
- int OCSPTimeoutSeconds = 3;
- if (ocspRequired) {
- OCSPTimeoutSeconds = 10;
- }
- CERT_SetOCSPTimeout(OCSPTimeoutSeconds);
-
- // XXX: Always use POST for OCSP; see bug 871954 for undoing this.
- bool ocspGetEnabled = Preferences::GetBool("security.OCSP.GET.enabled", false);
- CERT_ForcePostMethodForOCSP(!ocspGetEnabled);
-
CertVerifier::implementation_config certVerifierImplementation
= CertVerifier::classic;
#ifndef NSS_NO_LIBPKIX
if (Preferences::GetBool("security.use_libpkix_verification", false)) {
certVerifierImplementation = CertVerifier::libpkix;
}
#endif
+ CertVerifier::ocsp_download_config odc;
+ CertVerifier::ocsp_strict_config osc;
+ CertVerifier::ocsp_get_config ogc;
+
+ SetClassicOCSPBehaviorFromPrefs(&odc, &osc, &ogc, lock);
mDefaultCertVerifier = new SharedCertVerifier(
certVerifierImplementation,
aiaDownloadEnabled ?
CertVerifier::missing_cert_download_on : CertVerifier::missing_cert_download_off,
crlDownloading ?
CertVerifier::crl_download_allowed : CertVerifier::crl_local_only,
- ocspEnabled ?
- CertVerifier::ocsp_on : CertVerifier::ocsp_off,
- ocspRequired ?
- CertVerifier::ocsp_strict : CertVerifier::ocsp_relaxed,
- ocspGetEnabled ?
- CertVerifier::ocsp_get_enabled : CertVerifier::ocsp_get_disabled);
+ odc, osc, ogc);
+
}
// Enable the TLS versions given in the prefs, defaulting to SSL 3.0 (min
// version) and TLS 1.2 (max version) when the prefs aren't set or set to
// invalid values.
nsresult
nsNSSComponent::setEnabledTLSVersions()
{
@@ -1106,25 +1034,25 @@ nsNSSComponent::SkipOcsp()
SECStatus rv = CERT_DisableOCSPChecking(certdb);
return (rv == SECSuccess) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsNSSComponent::SkipOcspOff()
{
- nsNSSShutDownPreventionLock locker;
- // 0 = disabled, 1 = enabled
- int32_t ocspEnabled = Preferences::GetInt("security.OCSP.enabled",
- OCSP_ENABLED_DEFAULT);
+ MutexAutoLock lock(mutex);
+ MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(mNSSInitialized);
+ NS_ENSURE_TRUE(mNSSInitialized, NS_ERROR_NOT_INITIALIZED);
- setNonPkixOcspEnabled(ocspEnabled);
-
- if (ocspEnabled)
- SSL_ClearSessionCache();
+ CertVerifier::ocsp_download_config odc; // ignored
+ CertVerifier::ocsp_strict_config osc; // ignored
+ CertVerifier::ocsp_get_config ogc; // ignored
+ SetClassicOCSPBehaviorFromPrefs(&odc, &osc, &ogc, lock);
return NS_OK;
}
nsresult
nsNSSComponent::InitializeNSS()
{
// Can be called both during init and profile change.
@@ -1195,33 +1123,22 @@ nsNSSComponent::InitializeNSS()
// The call to ConfigureInternalPKCS11Token needs to be done before NSS is initialized,
// but affects only static data.
// If we could assume i18n will not change between profiles, one call per application
// run were sufficient. As I can't predict what happens in the future, let's repeat
// this call for every re-init of NSS.
ConfigureInternalPKCS11Token();
- // The NSS_INIT_NOROOTINIT flag turns off the loading of the root certs
- // module by NSS_Initialize because we will load it in InstallLoadableRoots
- // later. It also allows us to work around a bug in the system NSS in
- // Ubuntu 8.04, which loads any nonexistent "<configdir>/libnssckbi.so" as
- // "/usr/lib/nss/libnssckbi.so".
- uint32_t init_flags = NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE;
- SECStatus init_rv = ::NSS_Initialize(profileStr.get(), "", "",
- SECMOD_DB, init_flags);
-
+ SECStatus init_rv = ::mozilla::psm::InitializeNSS(profileStr.get(), false);
if (init_rv != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can not init NSS r/w in %s\n", profileStr.get()));
// try to init r/o
- init_flags |= NSS_INIT_READONLY;
- init_rv = ::NSS_Initialize(profileStr.get(), "", "",
- SECMOD_DB, init_flags);
-
+ init_rv = ::mozilla::psm::InitializeNSS(profileStr.get(), true);
if (init_rv != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can not init in r/o either\n"));
init_rv = NSS_NoDB_Init(profileStr.get());
if (init_rv != SECSuccess) {
nsPSMInitPanic::SetPanic();
return NS_ERROR_NOT_AVAILABLE;
}
@@ -1245,16 +1162,17 @@ nsNSSComponent::InitializeNSS()
rv = setEnabledTLSVersions();
if (NS_FAILED(rv)) {
nsPSMInitPanic::SetPanic();
return NS_ERROR_UNEXPECTED;
}
DisableMD5();
+ LoadLoadableRoots();
SSL_OptionSetDefault(SSL_ENABLE_SESSION_TICKETS, true);
bool requireSafeNegotiation =
Preferences::GetBool("security.ssl.require_safe_negotiation",
REQUIRE_SAFE_NEGOTIATION_DEFAULT);
SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, requireSafeNegotiation);
@@ -1282,23 +1200,21 @@ nsNSSComponent::InitializeNSS()
ALPN_ENABLED_DEFAULT));
if (NS_FAILED(InitializeCipherSuite())) {
PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("Unable to initialize cipher suite settings\n"));
return NS_ERROR_FAILURE;
}
// dynamic options from prefs
- setValidationOptions(true);
+ setValidationOptions(true, lock);
mHttpForNSS.initTable();
mHttpForNSS.registerHttpClient();
- InstallLoadableRoots();
-
#ifndef MOZ_DISABLE_CRYPTOLEGACY
LaunchSmartCardThreads();
#endif
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("NSS Initialization done\n"));
}
return NS_OK;
}
@@ -1688,17 +1604,17 @@ nsNSSComponent::Observe(nsISupports* aSu
} else if (prefName.Equals("security.OCSP.enabled")
|| prefName.Equals("security.CRL_download.enabled")
|| prefName.Equals("security.fresh_revocation_info.require")
|| prefName.Equals("security.missing_cert_download.enabled")
|| prefName.Equals("security.OCSP.require")
|| prefName.Equals("security.OCSP.GET.enabled")
|| prefName.Equals("security.ssl.enable_ocsp_stapling")) {
MutexAutoLock lock(mutex);
- setValidationOptions(false);
+ setValidationOptions(false, lock);
} else if (prefName.Equals("network.ntlm.send-lm-response")) {
bool sendLM = Preferences::GetBool("network.ntlm.send-lm-response",
SEND_LM_DEFAULT);
nsNTLMAuthModule::SetSendLM(sendLM);
clearSessionCache = false;
} else {
clearSessionCache = false;
}
--- a/security/manager/ssl/src/nsNSSComponent.h
+++ b/security/manager/ssl/src/nsNSSComponent.h
@@ -175,19 +175,20 @@ public:
::mozilla::TemporaryRef<mozilla::psm::SharedCertVerifier>
GetDefaultCertVerifier() MOZ_OVERRIDE;
private:
nsresult InitializeNSS();
void ShutdownNSS();
- void InstallLoadableRoots();
+ void LoadLoadableRoots();
void UnloadLoadableRoots();
- void setValidationOptions(bool isInitialSetting);
+ void setValidationOptions(bool isInitialSetting,
+ const mozilla::MutexAutoLock& lock);
nsresult setEnabledTLSVersions();
nsresult InitializePIPNSSBundle();
nsresult ConfigureInternalPKCS11Token();
nsresult RegisterObservers();
nsresult DeregisterObservers();
// Methods that we use to handle the profile change notifications (and to
// synthesize a full profile change when we're just doing a profile startup):