bug 1398932 - add a preference for enabling the sqlite-backed NSS databases r=Cykesiopka,jcj

In the future, bug 1377940 will make the sqlite-backed databases the default,
but until we're sure this will stick we want to be able to control this with a
Firefox-only change. The use of a preference to configure which format to use
will hopefully allow us to restore the old behavior quickly and relatively
safely if necessary. Note that doing this should be done with care; any changes
made in the sqlite databases after upgrade migration will not be reflected if
we need to go back to the old database format. Thus, user data (imported CAs,
client certificates, and keys) can be lost.

MozReview-Commit-ID: tkovdiCU9v

--HG--
extra : rebase_source : e74358bd65afb5844fa8fc5b729eba2bbc5bb2db
This commit is contained in:
David Keeler 2017-09-06 14:31:27 -07:00
Родитель 37c05393f5
Коммит 9f77404d3f
8 изменённых файлов: 91 добавлений и 11 удалений

Просмотреть файл

@ -19,11 +19,13 @@
#include "mozilla/Casting.h"
#include "mozilla/Move.h"
#include "mozilla/PodOperations.h"
#include "mozilla/Preferences.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Unused.h"
#include "nsCRTGlue.h"
#include "nsNSSCertificate.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "nss.h"
#include "pk11pub.h"
#include "pkix/Result.h"
@ -1228,8 +1230,10 @@ NSSCertDBTrustDomain::NoteAuxiliaryExtension(AuxiliaryExtension extension,
}
SECStatus
InitializeNSS(const char* dir, bool readOnly, bool loadPKCS11Modules)
InitializeNSS(const nsACString& dir, bool readOnly, bool loadPKCS11Modules)
{
MOZ_ASSERT(NS_IsMainThread());
// 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
@ -1242,9 +1246,20 @@ InitializeNSS(const char* dir, bool readOnly, bool loadPKCS11Modules)
if (!loadPKCS11Modules) {
flags |= NSS_INIT_NOMODDB;
}
bool useSQLDB = Preferences::GetBool("security.use_sqldb", false);
nsAutoCString dbTypeAndDirectory;
// Don't change any behavior if the user has specified an alternative database
// location with MOZPSM_NSSDBDIR_OVERRIDE.
const char* dbDirOverride = getenv("MOZPSM_NSSDBDIR_OVERRIDE");
if (useSQLDB && (!dbDirOverride || strlen(dbDirOverride) == 0)) {
dbTypeAndDirectory.Append("sql:");
}
dbTypeAndDirectory.Append(dir);
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("InitializeNSS(%s, %d, %d)", dir, readOnly, loadPKCS11Modules));
SECStatus srv = NSS_Initialize(dir, "", "", SECMOD_DB, flags);
("InitializeNSS(%s, %d, %d)", dbTypeAndDirectory.get(), readOnly,
loadPKCS11Modules));
SECStatus srv = NSS_Initialize(dbTypeAndDirectory.get(), "", "",
SECMOD_DB, flags);
if (srv != SECSuccess) {
return srv;
}

Просмотреть файл

@ -37,7 +37,8 @@ enum class NetscapeStepUpPolicy : uint32_t {
NeverMatch = 3,
};
SECStatus InitializeNSS(const char* dir, bool readOnly, bool loadPKCS11Modules);
SECStatus InitializeNSS(const nsACString& dir, bool readOnly,
bool loadPKCS11Modules);
void DisableMD5();

Просмотреть файл

@ -83,6 +83,11 @@ if CONFIG['_MSC_VER']:
# class copy constructor is inaccessible or deleted
'-wd4626', # assignment operator could not be generated because a base
# class assignment operator is inaccessible or deleted
'-wd4628', # digraphs not supported with -Ze (nsThreadUtils.h includes
# what would be the digraph "<:" in the expression
# "mozilla::EnableIf<::detail::...". Since we don't want it
# interpreted as a digraph anyway, we can disable the
# warning.)
'-wd4640', # construction of local static object is not thread-safe
'-wd4710', # 'function': function not inlined
'-wd4711', # function 'function' selected for inline expansion

Просмотреть файл

@ -1886,13 +1886,11 @@ InitializeNSSWithFallbacks(const nsACString& profilePath, bool nocertdb,
}
const nsCString& profilePathCStr = PromiseFlatCString(profilePath);
// Try read/write mode. If we're in safeMode, we won't load PKCS#11 modules.
#ifndef ANDROID
PRErrorCode savedPRErrorCode1;
#endif // ifndef ANDROID
SECStatus srv = ::mozilla::psm::InitializeNSS(profilePathCStr.get(), false,
!safeMode);
SECStatus srv = ::mozilla::psm::InitializeNSS(profilePath, false, !safeMode);
if (srv == SECSuccess) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized NSS in r/w mode"));
return NS_OK;
@ -1902,7 +1900,7 @@ InitializeNSSWithFallbacks(const nsACString& profilePath, bool nocertdb,
PRErrorCode savedPRErrorCode2;
#endif // ifndef ANDROID
// That failed. Try read-only mode.
srv = ::mozilla::psm::InitializeNSS(profilePathCStr.get(), true, !safeMode);
srv = ::mozilla::psm::InitializeNSS(profilePath, true, !safeMode);
if (srv == SECSuccess) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized NSS in r-o mode"));
return NS_OK;
@ -1929,7 +1927,7 @@ InitializeNSSWithFallbacks(const nsACString& profilePath, bool nocertdb,
// problem, but for some reason the combination of read-only and no-moddb
// flags causes NSS initialization to fail, so unfortunately we have to use
// read-write mode.
srv = ::mozilla::psm::InitializeNSS(profilePathCStr.get(), false, false);
srv = ::mozilla::psm::InitializeNSS(profilePath, false, false);
if (srv == SECSuccess) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("FIPS may be the problem"));
// Unload NSS so we can attempt to fix this situation for the user.
@ -1945,12 +1943,12 @@ InitializeNSSWithFallbacks(const nsACString& profilePath, bool nocertdb,
if (NS_FAILED(rv)) {
return rv;
}
srv = ::mozilla::psm::InitializeNSS(profilePathCStr.get(), false, true);
srv = ::mozilla::psm::InitializeNSS(profilePath, false, true);
if (srv == SECSuccess) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized in r/w mode"));
return NS_OK;
}
srv = ::mozilla::psm::InitializeNSS(profilePathCStr.get(), true, true);
srv = ::mozilla::psm::InitializeNSS(profilePath, true, true);
if (srv == SECSuccess) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized in r-o mode"));
return NS_OK;

Просмотреть файл

@ -43,6 +43,14 @@ pref("security.remember_cert_checkbox_default_setting", true);
pref("security.ask_for_password", 0);
pref("security.password_lifetime", 30);
// If true, use the modern sqlite-backed certificate and key databases in NSS.
// If false, use the default format. Currently the default in NSS is the old
// BerkeleyDB format, but this will change in bug 1377940.
// Changing this requires a restart to take effect.
// Note that the environment variable MOZPSM_NSSDBDIR_OVERRIDE can override both
// the behavior of this preference and the NSS default.
pref("security.use_sqldb", false);
// The supported values of this pref are:
// 0: disable detecting Family Safety mode and importing the root
// 1: only attempt to detect Family Safety mode (don't import the root)

Просмотреть файл

@ -0,0 +1,23 @@
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
// 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/.
"use strict";
// Tests that if "security.use_sqldb" is set to true when PSM initializes,
// we create the sqlite-backed certificate and key databases.
function run_test() {
let profileDir = do_get_profile();
Services.prefs.setBoolPref("security.use_sqldb", true);
let certificateDBFile = profileDir.clone();
certificateDBFile.append("cert9.db");
ok(!certificateDBFile.exists(), "cert9.db should not exist beforehand");
let keyDBFile = profileDir.clone();
keyDBFile.append("key4.db");
ok(!keyDBFile.exists(), "key4.db should not exist beforehand");
// This should start PSM.
Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports);
ok(certificateDBFile.exists(), "cert9.db should exist in the profile");
ok(keyDBFile.exists(), "key4.db should exist in the profile");
}

Просмотреть файл

@ -0,0 +1,24 @@
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
// 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/.
"use strict";
// Tests that if "security.use_sqldb" is set to false when PSM initializes,
// we create the system-default certificate and key databases, which currently
// use the old BerkeleyDB format. This will change in bug 1377940.
function run_test() {
let profileDir = do_get_profile();
Services.prefs.setBoolPref("security.use_sqldb", false);
let certificateDBFile = profileDir.clone();
certificateDBFile.append("cert8.db");
ok(!certificateDBFile.exists(), "cert8.db should not exist beforehand");
let keyDBFile = profileDir.clone();
keyDBFile.append("key3.db");
ok(!keyDBFile.exists(), "key3.db should not exist beforehand");
// This should start PSM.
Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports);
ok(certificateDBFile.exists(), "cert8.db should exist in the profile");
ok(keyDBFile.exists(), "key3.db should exist in the profile");
}

Просмотреть файл

@ -73,6 +73,12 @@ skip-if = toolkit == 'android'
skip-if = !debug
run-sequentially = hardcoded ports
[test_datasignatureverifier.js]
# Android always has and always will use the new format, so
# these two tests don't apply.
[test_db_format_pref_new.js]
skip-if = toolkit == 'android'
[test_db_format_pref_old.js]
skip-if = toolkit == 'android'
[test_der.js]
[test_enterprise_roots.js]
skip-if = os != 'win' # tests a Windows-specific feature