|
|
ae11a9 |
diff --git a/security/manager/ssl/nsNSSComponent.cpp b/security/manager/ssl/nsNSSComponent.cpp
|
|
|
ae11a9 |
--- a/security/manager/ssl/nsNSSComponent.cpp
|
|
|
ae11a9 |
+++ b/security/manager/ssl/nsNSSComponent.cpp
|
|
|
ae11a9 |
@@ -1654,6 +1654,51 @@
|
|
|
ae11a9 |
}
|
|
|
ae11a9 |
return AttemptToRenamePKCS11ModuleDB(profilePath, sqlModuleDBFilename);
|
|
|
ae11a9 |
}
|
|
|
ae11a9 |
+
|
|
|
ae11a9 |
+// When we changed from the old dbm database format to the newer sqlite
|
|
|
ae11a9 |
+// implementation, the upgrade process left behind the existing files. Suppose a
|
|
|
ae11a9 |
+// user had not set a password for the old key3.db (which is about 99% of
|
|
|
ae11a9 |
+// users). After upgrading, both the old database and the new database are
|
|
|
ae11a9 |
+// unprotected. If the user then sets a password for the new database, the old
|
|
|
ae11a9 |
+// one will not be protected. In this scenario, we should probably just remove
|
|
|
ae11a9 |
+// the old database (it would only be relevant if the user downgraded to a
|
|
|
ae11a9 |
+// version of Firefox before 58, but we have to trade this off against the
|
|
|
ae11a9 |
+// user's old private keys being unexpectedly unprotected after setting a
|
|
|
ae11a9 |
+// password).
|
|
|
ae11a9 |
+// This was never an issue on Android because we always used the new
|
|
|
ae11a9 |
+// implementation.
|
|
|
ae11a9 |
+static void
|
|
|
ae11a9 |
+MaybeCleanUpOldNSSFiles(const nsACString& profilePath)
|
|
|
ae11a9 |
+{
|
|
|
ae11a9 |
+ UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
|
|
|
ae11a9 |
+ if (!slot) {
|
|
|
ae11a9 |
+ return;
|
|
|
ae11a9 |
+ }
|
|
|
ae11a9 |
+ // Unfortunately we can't now tell the difference between "there already was a
|
|
|
ae11a9 |
+ // password when the upgrade happened" and "there was not a password but then
|
|
|
ae11a9 |
+ // the user added one after upgrading".
|
|
|
ae11a9 |
+ bool hasPassword = PK11_NeedLogin(slot.get()) &&
|
|
|
ae11a9 |
+ !PK11_NeedUserInit(slot.get());
|
|
|
ae11a9 |
+ if (!hasPassword) {
|
|
|
ae11a9 |
+ return;
|
|
|
ae11a9 |
+ }
|
|
|
ae11a9 |
+ nsCOMPtr<nsIFile> dbFile = do_CreateInstance("@mozilla.org/file/local;1");
|
|
|
ae11a9 |
+ if (!dbFile) {
|
|
|
ae11a9 |
+ return;
|
|
|
ae11a9 |
+ }
|
|
|
ae11a9 |
+ nsresult rv = dbFile->InitWithNativePath(profilePath);
|
|
|
ae11a9 |
+ if (NS_FAILED(rv)) {
|
|
|
ae11a9 |
+ return;
|
|
|
ae11a9 |
+ }
|
|
|
ae11a9 |
+ NS_NAMED_LITERAL_CSTRING(keyDBFilename, "key3.db");
|
|
|
ae11a9 |
+ rv = dbFile->AppendNative(keyDBFilename);
|
|
|
ae11a9 |
+ if (NS_FAILED(rv)) {
|
|
|
ae11a9 |
+ return;
|
|
|
ae11a9 |
+ }
|
|
|
ae11a9 |
+ // Since this isn't a directory, the `recursive` argument to `Remove` is
|
|
|
ae11a9 |
+ // irrelevant.
|
|
|
ae11a9 |
+ Unused << dbFile->Remove(false);
|
|
|
ae11a9 |
+}
|
|
|
ae11a9 |
#endif // ifndef ANDROID
|
|
|
ae11a9 |
|
|
|
ae11a9 |
// Given a profile directory, attempt to initialize NSS. If nocertdb is true,
|
|
|
ae11a9 |
@@ -1685,6 +1730,9 @@
|
|
|
ae11a9 |
SECStatus srv = ::mozilla::psm::InitializeNSS(profilePath, false, !safeMode);
|
|
|
ae11a9 |
if (srv == SECSuccess) {
|
|
|
ae11a9 |
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized NSS in r/w mode"));
|
|
|
ae11a9 |
+#ifndef ANDROID
|
|
|
ae11a9 |
+ MaybeCleanUpOldNSSFiles(profilePath);
|
|
|
ae11a9 |
+#endif // ifndef ANDROID
|
|
|
ae11a9 |
return NS_OK;
|
|
|
ae11a9 |
}
|
|
|
ae11a9 |
#ifndef ANDROID
|
|
|
ae11a9 |
|