bug 1465976 - remove all find*ByName APIs from PSM PKCS#11 module/slot/token interfaces r?jcj,fkiefer draft
authorDavid Keeler <dkeeler@mozilla.com>
Thu, 31 May 2018 14:46:06 -0700
changeset 803760 b4c7d1e7d2654221cf1d39a159bc4dc8ee7b3d10
parent 803479 fa5724780fe76d6ccbbd08d978342a1db6a43d49
push id112171
push userbmo:dkeeler@mozilla.com
push dateMon, 04 Jun 2018 19:39:55 +0000
reviewersjcj, fkiefer
bugs1465976
milestone62.0a1
bug 1465976 - remove all find*ByName APIs from PSM PKCS#11 module/slot/token interfaces r?jcj,fkiefer Before this patch, we exposed a few interfaces that revolved around mapping a name to a specific PKCS#11 module, slot, or token. These APIs were all either problematic and/or unnecessary. In theory there could be two tokens in different modules with the same name, so nsIPK11TokenDB.findTokenByName wasn't guaranteed to return what the consumer expected it to. In general, these APIs were used by front-end code to go from a handle on the specific object in question to a string identifier and then back to a handle on the object. This was unnecessary - we can just retain the original handle. MozReview-Commit-ID: IbqLbV4wceA
security/manager/pki/nsNSSDialogs.cpp
security/manager/pki/resources/content/changepassword.js
security/manager/pki/resources/content/device_manager.js
security/manager/ssl/PKCS11ModuleDB.cpp
security/manager/ssl/SecretDecoderRing.cpp
security/manager/ssl/nsIPK11TokenDB.idl
security/manager/ssl/nsIPKCS11Module.idl
security/manager/ssl/nsIPKCS11ModuleDB.idl
security/manager/ssl/nsITokenPasswordDialogs.idl
security/manager/ssl/nsNSSComponent.cpp
security/manager/ssl/nsPK11TokenDB.cpp
security/manager/ssl/nsPKCS11Slot.cpp
security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js
security/manager/ssl/tests/unit/test_pkcs11_module.js
security/manager/ssl/tests/unit/test_pkcs11_moduleDB.js
security/manager/ssl/tests/unit/test_pkcs11_slot.js
security/manager/ssl/tests/unit/test_pkcs11_tokenDB.js
--- a/security/manager/pki/nsNSSDialogs.cpp
+++ b/security/manager/pki/nsNSSDialogs.cpp
@@ -13,16 +13,17 @@
 #include "mozIDOMWindow.h"
 #include "nsArray.h"
 #include "nsEmbedCID.h"
 #include "nsHashPropertyBag.h"
 #include "nsIDialogParamBlock.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIKeygenThread.h"
+#include "nsIPK11Token.h"
 #include "nsIPromptService.h"
 #include "nsIProtectedAuthThread.h"
 #include "nsIWindowWatcher.h"
 #include "nsIX509CertDB.h"
 #include "nsIX509Cert.h"
 #include "nsNSSDialogHelper.h"
 #include "nsPromiseFlatString.h"
 #include "nsString.h"
@@ -55,33 +56,43 @@ nsNSSDialogs::Init()
 
   rv = service->CreateBundle(PIPSTRING_BUNDLE_URL,
                              getter_AddRefs(mPIPStringBundle));
   return rv;
 }
 
 NS_IMETHODIMP
 nsNSSDialogs::SetPassword(nsIInterfaceRequestor* ctx,
-                          const nsAString& tokenName,
+                          nsIPK11Token* token,
                   /*out*/ bool* canceled)
 {
   // |ctx| is allowed to be null.
   NS_ENSURE_ARG(canceled);
 
   *canceled = false;
 
   // Get the parent window for the dialog
   nsCOMPtr<mozIDOMWindowProxy> parent = do_GetInterface(ctx);
 
   nsCOMPtr<nsIDialogParamBlock> block =
            do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
   if (!block) return NS_ERROR_FAILURE;
 
-  nsresult rv = block->SetString(1, PromiseFlatString(tokenName).get());
-  if (NS_FAILED(rv)) return rv;
+  nsCOMPtr<nsIMutableArray> objects = nsArrayBase::Create();
+  if (!objects) {
+    return NS_ERROR_FAILURE;
+  }
+  nsresult rv = objects->AppendElement(token);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = block->SetObjects(objects);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
 
   rv = nsNSSDialogHelper::openDialog(parent,
                                 "chrome://pippki/content/changepassword.xul",
                                 block);
 
   if (NS_FAILED(rv)) return rv;
 
   int32_t status;
--- a/security/manager/pki/resources/content/changepassword.js
+++ b/security/manager/pki/resources/content/changepassword.js
@@ -7,92 +7,69 @@ const { Services } = ChromeUtils.import(
 
 const nsIPK11TokenDB = Ci.nsIPK11TokenDB;
 const nsPKCS11ModuleDB = "@mozilla.org/security/pkcs11moduledb;1";
 const nsIPKCS11ModuleDB = Ci.nsIPKCS11ModuleDB;
 const nsIPKCS11Slot = Ci.nsIPKCS11Slot;
 const nsIPK11Token = Ci.nsIPK11Token;
 
 var params;
-var tokenName = "";
+var token;
 var pw1;
 
 function doPrompt(msg) {
   Services.prompt.alert(window, null, msg);
 }
 
 function onLoad() {
   document.documentElement.getButton("accept").disabled = true;
 
   pw1 = document.getElementById("pw1");
   params = window.arguments[0].QueryInterface(Ci.nsIDialogParamBlock);
-  tokenName = params.GetString(1);
+  token = params.objects.GetElementAt(0).QueryInterface(Ci.nsIPK11Token);
 
-  document.getElementById("tokenName").setAttribute("value", tokenName);
+  document.getElementById("tokenName").setAttribute("value", token.name);
 
   process();
 }
 
 function process() {
   let bundle = document.getElementById("pippki_bundle");
-
+  let oldpwbox = document.getElementById("oldpw");
+  let msgBox = document.getElementById("message");
   // If the token is unitialized, don't use the old password box.
   // Otherwise, do.
+  if ((token.needsLogin() && token.needsUserInit) || !token.needsLogin()) {
+    oldpwbox.setAttribute("hidden", "true");
+    msgBox.setAttribute("value", bundle.getString("password_not_set"));
+    msgBox.setAttribute("hidden", "false");
 
-  let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"]
-                  .getService(Ci.nsIPK11TokenDB);
-  let token;
-  if (tokenName.length > 0) {
-    token = tokenDB.findTokenByName(tokenName);
+    if (!token.needsLogin()) {
+      oldpwbox.setAttribute("inited", "empty");
+    } else {
+      oldpwbox.setAttribute("inited", "true");
+    }
+
+    // Select first password field
+    document.getElementById("pw1").focus();
   } 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");
-
-      if (!token.needsLogin()) {
-        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 old password field
+    oldpwbox.setAttribute("hidden", "false");
+    msgBox.setAttribute("hidden", "true");
+    oldpwbox.setAttribute("inited", "false");
+    oldpwbox.focus();
   }
 
-  if (params) {
-    // Return value 0 means "canceled"
-    params.SetInt(1, 0);
-  }
+  // Return value 0 means "canceled"
+  params.SetInt(1, 0);
 
   checkPasswords();
 }
 
 function setPassword() {
-  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");
   var bundle = document.getElementById("pippki_bundle");
 
   var success = false;
 
   if (initpw == "false" || initpw == "empty") {
     try {
--- a/security/manager/pki/resources/content/device_manager.js
+++ b/security/manager/pki/resources/content/device_manager.js
@@ -1,14 +1,15 @@
 /* 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";
 
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
+const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", {});
 
 const nsIPKCS11Slot = Ci.nsIPKCS11Slot;
 const nsIPKCS11Module = Ci.nsIPKCS11Module;
 const nsPKCS11ModuleDB = "@mozilla.org/security/pkcs11moduledb;1";
 const nsIPKCS11ModuleDB = Ci.nsIPKCS11ModuleDB;
 const nsIPK11Token = Ci.nsIPK11Token;
 const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1";
 const nsIPK11TokenDB = Ci.nsIPK11TokenDB;
@@ -35,26 +36,20 @@ function doPrompt(msg) {
 }
 
 function doConfirm(msg) {
   return Services.prompt.confirm(window, null, msg);
 }
 
 function RefreshDeviceList() {
   let modules = secmoddb.listModules();
-  while (modules.hasMoreElements()) {
-    let module = modules.getNext().QueryInterface(nsIPKCS11Module);
-    let slotnames = [];
+  for (let module of XPCOMUtils.IterSimpleEnumerator(modules,
+                                                     Ci.nsIPKCS11Module)) {
     let slots = module.listSlots();
-    while (slots.hasMoreElements()) {
-      let slot = slots.getNext().QueryInterface(nsIPKCS11Slot);
-      // Token names are preferred because NSS prefers lookup by token name.
-      slotnames.push(slot.tokenName ? slot.tokenName : slot.name);
-    }
-    AddModule(module.name, slotnames);
+    AddModule(module, slots);
   }
 
   // Set the text on the FIPS button.
   SetFIPSButton();
 }
 
 function SetFIPSButton() {
   var fipsButton = document.getElementById("fipsbutton");
@@ -77,64 +72,58 @@ function SetFIPSButton() {
 /* Add a module to the tree.  slots is the array of slots in the module,
  * to be represented as children.
  */
 function AddModule(module, slots) {
   var tree = document.getElementById("device_list");
   var item  = document.createElement("treeitem");
   var row  = document.createElement("treerow");
   var cell = document.createElement("treecell");
-  cell.setAttribute("label", module);
+  cell.setAttribute("label", module.name);
   row.appendChild(cell);
   item.appendChild(row);
   var parent = document.createElement("treechildren");
-  for (let slot of slots) {
+  for (let slot of XPCOMUtils.IterSimpleEnumerator(slots, Ci.nsIPKCS11Slot)) {
     var child_item = document.createElement("treeitem");
     var child_row = document.createElement("treerow");
     var child_cell = document.createElement("treecell");
-    child_cell.setAttribute("label", slot);
+    child_cell.setAttribute("label", slot.name);
     child_row.appendChild(child_cell);
     child_item.appendChild(child_row);
     child_item.setAttribute("pk11kind", "slot");
+    // 'slot' is an attribute on any HTML element, hence 'slotObject' instead.
+    child_item.slotObject = slot;
     parent.appendChild(child_item);
   }
   item.appendChild(parent);
   item.setAttribute("pk11kind", "module");
+  item.module = module;
   item.setAttribute("open", "true");
   item.setAttribute("container", "true");
   tree.appendChild(item);
 }
 
 var selected_slot;
 var selected_module;
 
 /* get the slot selected by the user (can only be one-at-a-time) */
 function getSelectedItem() {
-  var tree = document.getElementById("device_tree");
-  if (tree.currentIndex < 0) return;
-  var item = tree.contentView.getItemAtIndex(tree.currentIndex);
+  let tree = document.getElementById("device_tree");
+  if (tree.currentIndex < 0) {
+    return;
+  }
+  let item = tree.contentView.getItemAtIndex(tree.currentIndex);
   selected_slot = null;
   selected_module = null;
   if (item) {
-    var kind = item.getAttribute("pk11kind");
-    var module_name;
+    let kind = item.getAttribute("pk11kind");
     if (kind == "slot") {
-      // get the module cell for this slot cell
-      var cell = item.parentNode.parentNode.firstChild.firstChild;
-      module_name = cell.getAttribute("label");
-      var module = secmoddb.findModuleByName(module_name);
-      // get the cell for the selected row (the slot to display)
-      cell = item.firstChild.firstChild;
-      var slot_name = cell.getAttribute("label");
-      selected_slot = module.findSlotByName(slot_name);
+      selected_slot = item.slotObject;
     } else { // (kind == "module")
-      // get the cell for the selected row (the module to display)
-      cell = item.firstChild.firstChild;
-      module_name = cell.getAttribute("label");
-      selected_module = secmoddb.findModuleByName(module_name);
+      selected_module = item.module;
     }
   }
 }
 
 function enableButtons() {
   if (skip_enable_buttons) {
     return;
   }
@@ -355,17 +344,19 @@ function doUnload() {
     RefreshDeviceList();
   }
 }
 
 function changePassword() {
   getSelectedItem();
   let params = Cc[nsDialogParamBlock]
                  .createInstance(nsIDialogParamBlock);
-  params.SetString(1, selected_slot.tokenName);
+  let objects = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
+  objects.appendElement(selected_slot.getToken());
+  params.objects = objects;
   window.openDialog("changepassword.xul", "", "chrome,centerscreen,modal",
                     params);
   showSlotInfo();
   enableButtons();
 }
 
 // -------------------------------------   Old code
 
--- a/security/manager/ssl/PKCS11ModuleDB.cpp
+++ b/security/manager/ssl/PKCS11ModuleDB.cpp
@@ -152,42 +152,16 @@ PKCS11ModuleDB::AddModule(const nsAStrin
   if (scalarKey.Length() > 0) {
     Telemetry::ScalarSet(Telemetry::ScalarID::SECURITY_PKCS11_MODULES_LOADED,
                          scalarKey, true);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-PKCS11ModuleDB::FindModuleByName(const nsAString& name,
-                         /*out*/ nsIPKCS11Module** _retval)
-{
-  NS_ENSURE_ARG_POINTER(_retval);
-
-  nsresult rv = BlockUntilLoadableRootsLoaded();
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  nsAutoCString moduleNameNormalized;
-  rv = NormalizeModuleNameIn(name, moduleNameNormalized);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  UniqueSECMODModule mod(SECMOD_FindModule(moduleNameNormalized.get()));
-  if (!mod) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(mod.get());
-  module.forget(_retval);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 PKCS11ModuleDB::ListModules(nsISimpleEnumerator** _retval)
 {
   NS_ENSURE_ARG_POINTER(_retval);
 
   nsresult rv = BlockUntilLoadableRootsLoaded();
   if (NS_FAILED(rv)) {
     return rv;
   }
--- a/security/manager/ssl/SecretDecoderRing.cpp
+++ b/security/manager/ssl/SecretDecoderRing.cpp
@@ -15,16 +15,17 @@
 #include "nsCOMPtr.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIObserverService.h"
 #include "nsIServiceManager.h"
 #include "nsITokenPasswordDialogs.h"
 #include "nsNSSComponent.h"
 #include "nsNSSHelper.h"
+#include "nsPK11TokenDB.h"
 #include "pk11func.h"
 #include "pk11sdr.h" // For PK11SDR_Encrypt, PK11SDR_Decrypt
 #include "ssl.h" // For SSL_ClearSessionCache
 
 using namespace mozilla;
 using dom::Promise;
 
 NS_IMPL_ISUPPORTS(SecretDecoderRing, nsISecretDecoderRing)
@@ -207,29 +208,31 @@ SecretDecoderRing::DecryptString(const n
 NS_IMETHODIMP
 SecretDecoderRing::ChangePassword()
 {
   UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
   if (!slot) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  NS_ConvertUTF8toUTF16 tokenName(PK11_GetTokenName(slot.get()));
+  // nsPK11Token::nsPK11Token takes its own reference to slot, so we pass a
+  // non-owning pointer here.
+  nsCOMPtr<nsIPK11Token> token = new nsPK11Token(slot.get());
 
   nsCOMPtr<nsITokenPasswordDialogs> dialogs;
   nsresult rv = getNSSDialogs(getter_AddRefs(dialogs),
                               NS_GET_IID(nsITokenPasswordDialogs),
                               NS_TOKENPASSWORDSDIALOG_CONTRACTID);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
   bool canceled; // Ignored
-  return dialogs->SetPassword(ctx, tokenName, &canceled);
+  return dialogs->SetPassword(ctx, token, &canceled);
 }
 
 NS_IMETHODIMP
 SecretDecoderRing::Logout()
 {
   PK11_LogoutAll();
   SSL_ClearSessionCache();
   return NS_OK;
--- a/security/manager/ssl/nsIPK11TokenDB.idl
+++ b/security/manager/ssl/nsIPK11TokenDB.idl
@@ -23,19 +23,9 @@ interface nsIPK11Token;
  */
 [scriptable, uuid(4ee28c82-1dd2-11b2-aabf-bb4017abe395)]
 interface nsIPK11TokenDB : nsISupports
 {
   /*
    * Get the internal key database token
    */
   nsIPK11Token getInternalKeyToken();
-
-  /*
-   * Find a token by name. Throws NS_ERROR_FAILURE if no token with the given
-   * name can be found.
-   * @param tokenName a string identifying the name of the token. Must be
-   *                  non-empty.
-   * @return a token with the given name
-   */
-  [must_use]
-  nsIPK11Token findTokenByName(in AUTF8String tokenName);
 };
--- a/security/manager/ssl/nsIPKCS11Module.idl
+++ b/security/manager/ssl/nsIPKCS11Module.idl
@@ -11,15 +11,11 @@ interface nsISimpleEnumerator;
 
 [scriptable, uuid(8a44bdf9-d1a5-4734-bd5a-34ed7fe564c2)]
 interface nsIPKCS11Module : nsISupports
 {
   [must_use]
   readonly attribute AUTF8String name;
   [must_use]
   readonly attribute AUTF8String libName;
-
-  [must_use]
-  nsIPKCS11Slot findSlotByName(in AUTF8String name);
-
   [must_use]
   nsISimpleEnumerator listSlots();
 };
--- a/security/manager/ssl/nsIPKCS11ModuleDB.idl
+++ b/security/manager/ssl/nsIPKCS11ModuleDB.idl
@@ -22,19 +22,16 @@ interface nsIPKCS11ModuleDB : nsISupport
 
   [must_use]
   void addModule(in AString moduleName,
                  in AString libraryFullPath,
                  in long cryptoMechanismFlags,
                  in long cipherFlags);
 
   [must_use]
-  nsIPKCS11Module findModuleByName(in AString name);
-
-  [must_use]
   nsISimpleEnumerator listModules();
 
   [must_use]
   readonly attribute boolean canToggleFIPS;
 
   [must_use]
   void toggleFIPSMode();
 
--- a/security/manager/ssl/nsITokenPasswordDialogs.idl
+++ b/security/manager/ssl/nsITokenPasswordDialogs.idl
@@ -1,29 +1,30 @@
 /* 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 "nsISupports.idl"
 
 interface nsIInterfaceRequestor;
+interface nsIPK11Token;
 
 /**
  *  This is the interface for setting and changing password
  *  on a PKCS11 token.
  */
 [scriptable, uuid(87dbd64a-4466-474e-95f5-1ad1cee5702c)]
 interface nsITokenPasswordDialogs : nsISupports
 {
   /**
    * Brings up a dialog to set the password on a token.
    *
    * @param ctx A user interface context.
-   * @param tokenName Name of the token.
+   * @param token {nsIPK11Token} The token.
    * @return true if the user canceled the dialog, false otherwise.
    */
   [must_use]
-  boolean setPassword(in nsIInterfaceRequestor ctx, in AString tokenName);
+  boolean setPassword(in nsIInterfaceRequestor ctx, in nsIPK11Token token);
 };
 
 %{C++
 #define NS_TOKENPASSWORDSDIALOG_CONTRACTID "@mozilla.org/nsTokenPasswordDialogs;1"
 %}
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -2553,18 +2553,18 @@ setPassword(PK11SlotInfo* slot, nsIInter
     nsresult rv = getNSSDialogs(getter_AddRefs(dialogs),
                                 NS_GET_IID(nsITokenPasswordDialogs),
                                 NS_TOKENPASSWORDSDIALOG_CONTRACTID);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     bool canceled;
-    NS_ConvertUTF8toUTF16 tokenName(PK11_GetTokenName(slot));
-    rv = dialogs->SetPassword(ctx, tokenName, &canceled);
+    nsCOMPtr<nsIPK11Token> token = new nsPK11Token(slot);
+    rv = dialogs->SetPassword(ctx, token, &canceled);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     if (canceled) {
       return NS_ERROR_NOT_AVAILABLE;
     }
   }
--- a/security/manager/ssl/nsPK11TokenDB.cpp
+++ b/security/manager/ssl/nsPK11TokenDB.cpp
@@ -287,34 +287,8 @@ nsPK11TokenDB::GetInternalKeyToken(nsIPK
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIPK11Token> token = new nsPK11Token(slot.get());
   token.forget(_retval);
 
   return NS_OK;
 }
-
-NS_IMETHODIMP
-nsPK11TokenDB::FindTokenByName(const nsACString& tokenName,
-                       /*out*/ nsIPK11Token** _retval)
-{
-  NS_ENSURE_ARG_POINTER(_retval);
-  nsresult rv = BlockUntilLoadableRootsLoaded();
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  if (tokenName.IsEmpty()) {
-    return NS_ERROR_ILLEGAL_VALUE;
-  }
-
-  UniquePK11SlotInfo slot(
-    PK11_FindSlotByName(PromiseFlatCString(tokenName).get()));
-  if (!slot) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<nsIPK11Token> token = new nsPK11Token(slot.get());
-  token.forget(_retval);
-
-  return NS_OK;
-}
--- a/security/manager/ssl/nsPKCS11Slot.cpp
+++ b/security/manager/ssl/nsPKCS11Slot.cpp
@@ -222,52 +222,16 @@ nsPKCS11Module::GetLibName(/*out*/ nsACS
     libName = mModule->dllName;
   } else {
     libName.SetIsVoid(true);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsPKCS11Module::FindSlotByName(const nsACString& name,
-                       /*out*/ nsIPKCS11Slot** _retval)
-{
-  NS_ENSURE_ARG_POINTER(_retval);
-
-  const nsCString& flatName = PromiseFlatCString(name);
-  MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Getting \"%s\"", flatName.get()));
-  UniquePK11SlotInfo slotInfo;
-  UniquePK11SlotList slotList(PK11_FindSlotsByNames(mModule->dllName,
-                                                    flatName.get() /*slotName*/,
-                                                    nullptr /*tokenName*/,
-                                                    false));
-  if (!slotList) {
-    /* name must be the token name */
-    slotList.reset(PK11_FindSlotsByNames(mModule->dllName, nullptr /*slotName*/,
-                                         flatName.get() /*tokenName*/, false));
-  }
-  if (slotList && slotList->head && slotList->head->slot) {
-    slotInfo.reset(PK11_ReferenceSlot(slotList->head->slot));
-  }
-  if (!slotInfo) {
-    // workaround - the builtin module has no name
-    if (!flatName.EqualsLiteral("Root Certificates")) {
-      // Give up.
-      return NS_ERROR_FAILURE;
-    }
-
-    slotInfo.reset(PK11_ReferenceSlot(mModule->slots[0]));
-  }
-
-  nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotInfo.get());
-  slot.forget(_retval);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsPKCS11Module::ListSlots(nsISimpleEnumerator** _retval)
 {
   NS_ENSURE_ARG_POINTER(_retval);
 
   nsresult rv = CheckForSmartCardChanges();
   if (NS_FAILED(rv)) {
     return rv;
   }
--- a/security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js
+++ b/security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js
@@ -37,24 +37,16 @@ const gMockPKCS11ModuleDB = {
   getInternal() {
     throw new Error("not expecting getInternal() to be called");
   },
 
   getInternalFIPS() {
     throw new Error("not expecting getInternalFIPS() to be called");
   },
 
-  findModuleByName() {
-    throw new Error("not expecting findModuleByName() to be called");
-  },
-
-  findSlotByName() {
-    throw new Error("not expecting findSlotByName() to be called");
-  },
-
   listModules() {
     throw new Error("not expecting listModules() to be called");
   },
 
   get canToggleFIPS() {
     throw new Error("not expecting get canToggleFIPS() to be called");
   },
 
--- a/security/manager/ssl/tests/unit/test_pkcs11_module.js
+++ b/security/manager/ssl/tests/unit/test_pkcs11_module.js
@@ -18,19 +18,16 @@ function checkTestModuleNotPresent() {
      "One or more modules should be present with test module not present");
   while (modules.hasMoreElements()) {
     let module = modules.getNext().QueryInterface(Ci.nsIPKCS11Module);
     notEqual(module.name, "PKCS11 Test Module",
              "Non-test module name shouldn't equal 'PKCS11 Test Module'");
     ok(!(module.libName && module.libName.includes("pkcs11testmodule")),
        "Non-test module lib name should not include 'pkcs11testmodule'");
   }
-
-  throws(() => gModuleDB.findModuleByName("PKCS11 Test Module"),
-         /NS_ERROR_FAILURE/, "Test module should not be findable by name");
 }
 
 /**
  * Checks that the test module exists in the module list.
  * Also checks various attributes of the test module for correctness.
  *
  * @returns {nsIPKCS11Module}
  *          The test module.
@@ -47,19 +44,16 @@ function checkTestModuleExists() {
       break;
     }
   }
   notEqual(testModule, null, "Test module should have been found");
   notEqual(testModule.libName, null, "Test module lib name should not be null");
   ok(testModule.libName.includes(ctypes.libraryName("pkcs11testmodule")),
      "Test module lib name should include lib name of 'pkcs11testmodule'");
 
-  notEqual(gModuleDB.findModuleByName("PKCS11 Test Module"), null,
-           "Test module should be findable by name");
-
   return testModule;
 }
 
 function checkModuleTelemetry(additionalExpectedModule = undefined) {
   let expectedModules = [
     "NSS Internal PKCS #11 Module",
   ];
   if (additionalExpectedModule) {
@@ -102,23 +96,16 @@ function run_test() {
     let slot = slots.getNext().QueryInterface(Ci.nsIPKCS11Slot);
     testModuleSlotNames.push(slot.name);
   }
   testModuleSlotNames.sort();
   const expectedSlotNames = ["Empty PKCS11 Slot", "Test PKCS11 Slot", "Test PKCS11 Slot 二"];
   deepEqual(testModuleSlotNames, expectedSlotNames,
             "Actual and expected slot names should be equal");
 
-  // Check that finding the test slot by name is possible, and that trying to
-  // find a non-present slot fails.
-  notEqual(testModule.findSlotByName("Test PKCS11 Slot"), null,
-           "Test slot should be findable by name");
-  throws(() => testModule.findSlotByName("Not Present"), /NS_ERROR_FAILURE/,
-         "Non-present slot should not be findable by name");
-
   // Check that deleting the test module makes it disappear from the module list.
   let pkcs11ModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]
                          .getService(Ci.nsIPKCS11ModuleDB);
   pkcs11ModuleDB.deleteModule("PKCS11 Test Module");
   checkTestModuleNotPresent();
 
   // Check miscellaneous module DB methods and attributes.
   ok(!gModuleDB.canToggleFIPS, "It should NOT be possible to toggle FIPS");
--- a/security/manager/ssl/tests/unit/test_pkcs11_moduleDB.js
+++ b/security/manager/ssl/tests/unit/test_pkcs11_moduleDB.js
@@ -12,26 +12,31 @@ const gModuleDB = Cc["@mozilla.org/secur
                     .getService(Ci.nsIPKCS11ModuleDB);
 
 function run_test() {
   let libraryFile = Services.dirsvc.get("CurWorkD", Ci.nsIFile);
   libraryFile.append("pkcs11testmodule");
   libraryFile.append(ctypes.libraryName("pkcs11testmodule"));
   ok(libraryFile.exists(), "The pkcs11testmodule file should exist");
 
-  let pkcs11ModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]
+  let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]
                          .getService(Ci.nsIPKCS11ModuleDB);
-  throws(() => pkcs11ModuleDB.addModule("Root Certs", libraryFile.path, 0, 0),
+  throws(() => moduleDB.addModule("Root Certs", libraryFile.path, 0, 0),
          /NS_ERROR_ILLEGAL_VALUE/,
          "Adding a module named 'Root Certs' should fail.");
-  throws(() => pkcs11ModuleDB.addModule("", libraryFile.path, 0, 0),
+  throws(() => moduleDB.addModule("", libraryFile.path, 0, 0),
          /NS_ERROR_ILLEGAL_VALUE/,
          "Adding a module with an empty name should fail.");
 
   let bundle =
     Services.strings.createBundle("chrome://pipnss/locale/pipnss.properties");
   let rootsModuleName = bundle.GetStringFromName("RootCertModuleName");
-  let rootsModule = pkcs11ModuleDB.findModuleByName(rootsModuleName);
-  notEqual(rootsModule, null,
-           "Should be able to find builtin roots module by localized name.");
-  equal(rootsModule.name, rootsModuleName,
-        "Builtin roots module should have correct localized name.");
+  let foundRootsModule = false;
+  for (let module of XPCOMUtils.IterSimpleEnumerator(moduleDB.listModules(),
+                                                     Ci.nsIPKCS11Module)) {
+    if (module.name == rootsModuleName) {
+      foundRootsModule = true;
+      break;
+    }
+  }
+  ok(foundRootsModule,
+     "Should be able to find builtin roots module by localized name.");
 }
--- a/security/manager/ssl/tests/unit/test_pkcs11_slot.js
+++ b/security/manager/ssl/tests/unit/test_pkcs11_slot.js
@@ -3,23 +3,41 @@
 // http://creativecommons.org/publicdomain/zero/1.0/
 "use strict";
 
 // Tests the methods and attributes for interfacing with a PKCS #11 slot.
 
 // Ensure that the appropriate initialization has happened.
 do_get_profile();
 
+function find_slot_by_name(module, name) {
+  for (let slot of XPCOMUtils.IterSimpleEnumerator(module.listSlots(),
+                                                   Ci.nsIPKCS11Slot)) {
+    if (slot.name == name) {
+      return slot;
+    }
+  }
+  return null;
+}
+
 function run_test() {
   loadPKCS11TestModule(false);
 
   let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]
                    .getService(Ci.nsIPKCS11ModuleDB);
-  let testModule = moduleDB.findModuleByName("PKCS11 Test Module");
-  let testSlot = testModule.findSlotByName("Test PKCS11 Slot 二");
+  let testModule;
+  for (let module of XPCOMUtils.IterSimpleEnumerator(moduleDB.listModules(),
+                                                     Ci.nsIPKCS11Module)) {
+    if (module.name == "PKCS11 Test Module") {
+      testModule = module;
+      break;
+    }
+  }
+  let testSlot = find_slot_by_name(testModule, "Test PKCS11 Slot 二");
+  notEqual(testSlot, null, "should be able to find 'Test PKCS11 Slot 二'");
 
   equal(testSlot.name, "Test PKCS11 Slot 二",
         "Actual and expected name should match");
   equal(testSlot.desc, "Test PKCS11 Slot 二",
         "Actual and expected description should match");
   equal(testSlot.manID, "Test PKCS11 Manufacturer ID",
         "Actual and expected manufacturer ID should match");
   equal(testSlot.HWVersion, "0.0",
@@ -32,13 +50,14 @@ function run_test() {
         "Actual and expected token name should match");
 
   let testToken = testSlot.getToken();
   notEqual(testToken, null, "getToken() should succeed");
   equal(testToken.tokenLabel, "Test PKCS11 Tokeñ 2 Label",
         "Spot check: the actual and expected test token labels should be equal");
   ok(!testToken.isInternalKeyToken, "This token is not the internal key token");
 
-  testSlot = testModule.findSlotByName("Empty PKCS11 Slot");
+  testSlot = find_slot_by_name(testModule, "Empty PKCS11 Slot");
+  notEqual(testSlot, null, "should be able to find 'Empty PKCS11 Slot'");
   equal(testSlot.tokenName, null, "Empty slot is empty");
   equal(testSlot.status, Ci.nsIPKCS11Slot.SLOT_NOT_PRESENT,
         "Actual and expected status should match");
 }
--- a/security/manager/ssl/tests/unit/test_pkcs11_tokenDB.js
+++ b/security/manager/ssl/tests/unit/test_pkcs11_tokenDB.js
@@ -8,26 +8,9 @@
 do_get_profile();
 
 function run_test() {
   let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"]
                   .getService(Ci.nsIPK11TokenDB);
 
   notEqual(tokenDB.getInternalKeyToken(), null,
            "The internal token should be non-null");
-
-  throws(() => tokenDB.findTokenByName("Test PKCS11 Tokeñ Label"),
-         /NS_ERROR_FAILURE/,
-         "Non-present test token 1 should not be findable by name");
-  throws(() => tokenDB.findTokenByName("Test PKCS11 Tokeñ 2 Label"),
-         /NS_ERROR_FAILURE/,
-         "Non-present test token 2 should not be findable by name");
-
-  loadPKCS11TestModule(false);
-
-  // Test Token 1 is simulated to insert and remove itself in a tight loop, so
-  // we don't bother testing that it's present.
-  notEqual(tokenDB.findTokenByName("Test PKCS11 Tokeñ 2 Label"), null,
-           "Test token 2 should be findable by name after loading test module");
-
-  throws(() => tokenDB.findTokenByName(""), /NS_ERROR_ILLEGAL_VALUE/,
-         "nsIPK11TokenDB.findTokenByName should throw given an empty name");
 }