bug 1324071 - add nsIPK11Token.hasPassword to replace unnecessary uses of nsIPKCS11Slot.status r=Cykesiopka,gps,MattN,sebastian

MozReview-Commit-ID: C2jwQHPEDC0

--HG--
extra : rebase_source : 16271e70ef32da8657cdc4f8df41b7822430e3bf
This commit is contained in:
David Keeler 2016-12-02 15:09:35 -08:00
parent 682555bbc4
commit 104c38c723
14 changed files with 144 additions and 160 deletions

View File

@ -1430,12 +1430,10 @@ var gBrowserInit = {
if (window.closed) {
return;
}
let secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]
.getService(Ci.nsIPKCS11ModuleDB);
let slot = secmodDB.findSlotByName("");
let mpEnabled = slot &&
slot.status != Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED &&
slot.status != Ci.nsIPKCS11Slot.SLOT_READY;
let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"]
.getService(Ci.nsIPK11TokenDB);
let token = tokenDB.getInternalKeyToken();
let mpEnabled = token.hasPassword;
if (mpEnabled) {
Services.telemetry.getHistogramById("MASTER_PASSWORD_ENABLED").add(mpEnabled);
}

View File

@ -7,12 +7,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Snackbars", "resource://gre/modules/Sna
var MasterPassword = {
pref: "privacy.masterpassword.enabled",
_tokenName: "",
get _secModuleDB() {
delete this._secModuleDB;
return this._secModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService(Ci.nsIPKCS11ModuleDB);
},
get _pk11DB() {
delete this._pk11DB;
@ -20,29 +14,21 @@ var MasterPassword = {
},
get enabled() {
let slot = this._secModuleDB.findSlotByName(this._tokenName);
if (slot) {
let status = slot.status;
return status != Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED && status != Ci.nsIPKCS11Slot.SLOT_READY;
let token = this._pk11DB.getInternalKeyToken();
if (token) {
return token.hasPassword;
}
return false;
},
setPassword: function setPassword(aPassword) {
try {
let status;
let slot = this._secModuleDB.findSlotByName(this._tokenName);
if (slot)
status = slot.status;
else
return false;
let token = this._pk11DB.findTokenByName(this._tokenName);
if (status == Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED)
let token = this._pk11DB.getInternalKeyToken();
if (token.needsUserInit) {
token.initPassword(aPassword);
else if (status == Ci.nsIPKCS11Slot.SLOT_READY)
} else if (!token.needsLogin()) {
token.changePassword("", aPassword);
}
return true;
} catch(e) {

View File

@ -3,6 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1";
const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB;
const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
@ -81,40 +83,43 @@ function onMenuChange()
function process()
{
var secmoddb = Components.classes[nsPKCS11ModuleDB].getService(nsIPKCS11ModuleDB);
var bundle = document.getElementById("pippki_bundle");
let bundle = document.getElementById("pippki_bundle");
// If the token is unitialized, don't use the old password box.
// Otherwise, do.
// If the token is unitialized, don't use the old password box.
// Otherwise, do.
var slot = secmoddb.findSlotByName(tokenName);
if (slot) {
var oldpwbox = document.getElementById("oldpw");
var msgBox = document.getElementById("message");
var status = slot.status;
if (status == nsIPKCS11Slot.SLOT_UNINITIALIZED
|| status == nsIPKCS11Slot.SLOT_READY) {
let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"]
.getService(Ci.nsIPK11TokenDB);
let token;
if (tokenName.length > 0) {
token = tokenDB.findTokenByName(tokenName);
} else {
token = tokenDB.getInternalKeyToken();
}
if (token) {
let oldpwbox = document.getElementById("oldpw");
let msgBox = document.getElementById("message");
if ((token.needsLogin() && token.needsUserInit) || !token.needsLogin()) {
oldpwbox.setAttribute("hidden", "true");
msgBox.setAttribute("value", bundle.getString("password_not_set"));
msgBox.setAttribute("hidden", "false");
oldpwbox.setAttribute("hidden", "true");
msgBox.setAttribute("value", bundle.getString("password_not_set"));
msgBox.setAttribute("hidden", "false");
if (!token.needsLogin()) {
oldpwbox.setAttribute("inited", "empty");
} else {
oldpwbox.setAttribute("inited", "true");
}
if (status == nsIPKCS11Slot.SLOT_READY) {
oldpwbox.setAttribute("inited", "empty");
} else {
oldpwbox.setAttribute("inited", "true");
}
// Select first password field
document.getElementById("pw1").focus();
} else {
// Select old password field
oldpwbox.setAttribute("hidden", "false");
msgBox.setAttribute("hidden", "true");
oldpwbox.setAttribute("inited", "false");
oldpwbox.focus();
}
}
// Select first password field
document.getElementById("pw1").focus();
} else {
// Select old password field
oldpwbox.setAttribute("hidden", "false");
msgBox.setAttribute("hidden", "true");
oldpwbox.setAttribute("inited", "false");
oldpwbox.focus();
}
}
if (params) {
// Return value 0 means "canceled"
@ -126,8 +131,14 @@ function process()
function setPassword()
{
var pk11db = Components.classes[nsPK11TokenDB].getService(nsIPK11TokenDB);
var token = pk11db.findTokenByName(tokenName);
let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"]
.getService(Ci.nsIPK11TokenDB);
let token;
if (tokenName.length > 0) {
token = tokenDB.findTokenByName(tokenName);
} else {
token = tokenDB.getInternalKeyToken();
}
var oldpwbox = document.getElementById("oldpw");
var initpw = oldpwbox.getAttribute("inited");

View File

@ -480,13 +480,10 @@ function toggleFIPS()
var tokendb = Components.classes[nsPK11TokenDB].getService(nsIPK11TokenDB);
var internal_token = tokendb.getInternalKeyToken(); // nsIPK11Token
var slot = secmoddb.findSlotByName(internal_token.tokenName);
switch (slot.status) {
case nsIPKCS11Slot.SLOT_UNINITIALIZED:
case nsIPKCS11Slot.SLOT_READY:
// Token has either no or an empty password.
doPrompt(bundle.getString("fips_nonempty_password_required"));
return;
if (!internal_token.hasPassword) {
// Token has either no or an empty password.
doPrompt(bundle.getString("fips_nonempty_password_required"));
return;
}
}

View File

@ -64,6 +64,14 @@ interface nsIPK11Token : nsISupports
long getAskPasswordTimeout();
void setAskPasswordDefaults([const] in long askTimes, [const] in long timeout);
/*
* True if a password has been configured for this token, and false otherwise.
* (Whether or not the user is currently logged in makes no difference.)
* In particular, this can be used to determine if a user has set a master
* password (if this is the internal key token).
*/
readonly attribute boolean hasPassword;
/*
* Other attributes
*/

View File

@ -358,6 +358,23 @@ nsPK11Token::ChangePassword(const nsACString& oldPassword,
newPassword.IsVoid() ? nullptr : PromiseFlatCString(newPassword).get()));
}
NS_IMETHODIMP
nsPK11Token::GetHasPassword(bool* hasPassword)
{
NS_ENSURE_ARG_POINTER(hasPassword);
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
// PK11_NeedLogin returns true if the token is currently configured to require
// the user to log in (whether or not the user is actually logged in makes no
// difference).
*hasPassword = PK11_NeedLogin(mSlot.get()) && !PK11_NeedUserInit(mSlot.get());
return NS_OK;
}
NS_IMETHODIMP
nsPK11Token::IsHardwareToken(bool* _retval)
{

View File

@ -453,6 +453,10 @@ nsPKCS11ModuleDB::FindSlotByName(const nsACString& name,
return NS_ERROR_NOT_AVAILABLE;
}
if (name.IsEmpty()) {
return NS_ERROR_ILLEGAL_VALUE;
}
UniquePK11SlotInfo slotInfo(
PK11_FindSlotByName(PromiseFlatCString(name).get()));
if (!slotInfo) {

View File

@ -105,6 +105,8 @@ function run_test() {
"Spot check: actual and expected internal 'slot' names should be equal");
throws(() => gModuleDB.findSlotByName("Not Present"), /NS_ERROR_FAILURE/,
"Non-present 'slot' should not be findable by name via the module DB");
throws(() => gModuleDB.findSlotByName(""), /NS_ERROR_ILLEGAL_VALUE/,
"nsIPKCS11ModuleDB.findSlotByName should throw given an empty name");
// Check that deleting the test module makes it disappear from the module list.
let pkcs11 = Cc["@mozilla.org/security/pkcs11;1"].getService(Ci.nsIPKCS11);

View File

@ -51,6 +51,8 @@ function checkBasicAttributes(token) {
function checkPasswordFeaturesAndResetPassword(token, initialPW) {
ok(!token.needsUserInit,
"Token should not need user init after setting a password");
ok(token.hasPassword,
"Token should have a password after setting a password");
equal(token.minimumPasswordLength, 0,
"Actual and expected min password length should match");
@ -76,8 +78,8 @@ function checkPasswordFeaturesAndResetPassword(token, initialPW) {
"password was given");
token.reset();
ok(token.needsUserInit,
"Token should need password init after reset");
ok(token.needsUserInit, "Token should need password init after reset");
ok(!token.hasPassword, "Token should not have a password after reset");
ok(!token.isLoggedIn(), "Token should be logged out of after reset");
}
@ -94,6 +96,8 @@ function run_test() {
// does not result in an error.
token.logoutSimple();
ok(!token.isLoggedIn(), "Token should still not be logged into");
ok(!token.hasPassword,
"Token should not have a password before it has been set");
let initialPW = "foo 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/? 一二三";
token.initPassword(initialPW);

View File

@ -602,34 +602,20 @@ this.Utils = {
* Is there a master password configured, regardless of current lock state?
*/
mpEnabled: function mpEnabled() {
let modules = Cc["@mozilla.org/security/pkcs11moduledb;1"]
.getService(Ci.nsIPKCS11ModuleDB);
let sdrSlot = modules.findSlotByName("");
let status = sdrSlot.status;
let slots = Ci.nsIPKCS11Slot;
return status != slots.SLOT_UNINITIALIZED && status != slots.SLOT_READY;
let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"]
.getService(Ci.nsIPK11TokenDB);
let token = tokenDB.getInternalKeyToken();
return token.hasPassword;
},
/**
* Is there a master password configured and currently locked?
*/
mpLocked: function mpLocked() {
let modules = Cc["@mozilla.org/security/pkcs11moduledb;1"]
.getService(Ci.nsIPKCS11ModuleDB);
let sdrSlot = modules.findSlotByName("");
let status = sdrSlot.status;
let slots = Ci.nsIPKCS11Slot;
if (status == slots.SLOT_READY || status == slots.SLOT_LOGGED_IN
|| status == slots.SLOT_UNINITIALIZED)
return false;
if (status == slots.SLOT_NOT_LOGGED_IN)
return true;
// something wacky happened, pretend MP is locked
return true;
let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"]
.getService(Ci.nsIPK11TokenDB);
let token = tokenDB.getInternalKeyToken();
return token.hasPassword && !token.isLoggedIn();
},
// If Master Password is enabled and locked, present a dialog to unlock it.

View File

@ -687,15 +687,10 @@ this.LoginHelper = {
* Returns true if the user has a master password set and false otherwise.
*/
isMasterPasswordSet() {
let secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].
getService(Ci.nsIPKCS11ModuleDB);
let slot = secmodDB.findSlotByName("");
if (!slot) {
return false;
}
let hasMP = slot.status != Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED &&
slot.status != Ci.nsIPKCS11Slot.SLOT_READY;
return hasMP;
let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"]
.getService(Ci.nsIPK11TokenDB);
let token = tokenDB.getInternalKeyToken();
return token.hasPassword;
},
/**

View File

@ -19,16 +19,6 @@ LoginManagerCrypto_SDR.prototype = {
classID : Components.ID("{dc6c2976-0f73-4f1f-b9ff-3d72b4e28309}"),
QueryInterface : XPCOMUtils.generateQI([Ci.nsILoginManagerCrypto]),
__sdrSlot : null, // PKCS#11 slot being used by the SDR.
get _sdrSlot() {
if (!this.__sdrSlot) {
let modules = Cc["@mozilla.org/security/pkcs11moduledb;1"].
getService(Ci.nsIPKCS11ModuleDB);
this.__sdrSlot = modules.findSlotByName("");
}
return this.__sdrSlot;
},
__decoderRing : null, // nsSecretDecoderRing service
get _decoderRing() {
if (!this.__decoderRing)
@ -170,14 +160,10 @@ LoginManagerCrypto_SDR.prototype = {
* isLoggedIn
*/
get isLoggedIn() {
let status = this._sdrSlot.status;
this.log("SDR slot status is " + status);
if (status == Ci.nsIPKCS11Slot.SLOT_READY ||
status == Ci.nsIPKCS11Slot.SLOT_LOGGED_IN)
return true;
if (status == Ci.nsIPKCS11Slot.SLOT_NOT_LOGGED_IN)
return false;
throw Components.Exception("unexpected slot status: " + status, Cr.NS_ERROR_FAILURE);
let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].
getService(Ci.nsIPK11TokenDB);
let token = tokenDB.getInternalKeyToken();
return !token.hasPassword || token.isLoggedIn();
},

View File

@ -263,19 +263,12 @@ this.LoginTestUtils.masterPassword = {
newPW = "";
}
let secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]
.getService(Ci.nsIPKCS11ModuleDB);
let slot = secmodDB.findSlotByName("");
if (!slot) {
throw new Error("Can't find slot");
}
// Set master password. Note that this does not log you in, so the next
// invocation of pwmgr can trigger a MP prompt.
let pk11db = Cc["@mozilla.org/security/pk11tokendb;1"]
.getService(Ci.nsIPK11TokenDB);
let token = pk11db.findTokenByName("");
if (slot.status == Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED) {
let token = pk11db.getInternalKeyToken();
if (token.needsUserInit) {
dump("MP initialized to " + newPW + "\n");
token.initPassword(newPW);
} else {

View File

@ -4,6 +4,8 @@
* 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/. */
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1";
const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB;
const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
@ -14,7 +16,6 @@ const nsIPK11Token = Components.interfaces.nsIPK11Token;
var params;
var tokenName = "";
var pw1;
function init()
@ -27,41 +28,38 @@ function init()
function process()
{
var secmoddb = Components.classes[nsPKCS11ModuleDB].getService(nsIPKCS11ModuleDB);
var bundle = document.getElementById("bundlePreferences");
let bundle = document.getElementById("bundlePreferences");
// If the token is unitialized, don't use the old password box.
// Otherwise, do.
// If the token is unitialized, don't use the old password box.
// Otherwise, do.
var slot = secmoddb.findSlotByName(tokenName);
if (slot) {
var oldpwbox = document.getElementById("oldpw");
var msgBox = document.getElementById("message");
var status = slot.status;
if (status == nsIPKCS11Slot.SLOT_UNINITIALIZED
|| status == nsIPKCS11Slot.SLOT_READY) {
let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"]
.getService(Ci.nsIPK11TokenDB);
let token = tokenDB.getInternalKeyToken();
if (token) {
let oldpwbox = document.getElementById("oldpw");
let msgBox = document.getElementById("message");
if ((token.needsLogin() && token.needsUserInit) || !token.needsLogin()) {
oldpwbox.setAttribute("hidden", "true");
msgBox.setAttribute("value", bundle.getString("password_not_set"));
msgBox.setAttribute("hidden", "false");
oldpwbox.setAttribute("hidden", "true");
msgBox.setAttribute("value", bundle.getString("password_not_set"));
msgBox.setAttribute("hidden", "false");
if (!token.needsLogin()) {
oldpwbox.setAttribute("inited", "empty");
} else {
oldpwbox.setAttribute("inited", "true");
}
if (status == nsIPKCS11Slot.SLOT_READY) {
oldpwbox.setAttribute("inited", "empty");
} else {
oldpwbox.setAttribute("inited", "true");
}
// Select first password field
document.getElementById('pw1').focus();
} else {
// Select old password field
oldpwbox.setAttribute("hidden", "false");
msgBox.setAttribute("hidden", "true");
oldpwbox.setAttribute("inited", "false");
oldpwbox.focus();
}
}
// Select first password field
document.getElementById('pw1').focus();
} else {
// Select old password field
oldpwbox.setAttribute("hidden", "false");
msgBox.setAttribute("hidden", "true");
oldpwbox.setAttribute("inited", "false");
oldpwbox.focus();
}
}
if (params) {
// Return value 0 means "canceled"
@ -76,8 +74,7 @@ function setPassword()
var pk11db = Components.classes[nsPK11TokenDB].getService(nsIPK11TokenDB);
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
var token = pk11db.findTokenByName(tokenName);
dump("*** TOKEN!!!! (name = |" + token + "|\n");
var token = pk11db.getInternalKeyToken();
var oldpwbox = document.getElementById("oldpw");
var initpw = oldpwbox.getAttribute("inited");