Bug 1252722 - Use smart pointers for NSS resources. r=keeler draft
authorCykesiopka <cykesiopka.bmo@gmail.com>
Thu, 31 Mar 2016 17:31:55 -0700
changeset 346418 5fac97fadafffe95e5d43cbe82e424d946ad4289
parent 346417 5527e3e2418503acfac99a9e7487e9f673ff79ac
child 346419 d0767bf26004e311155faca0d0ce0d3a30719624
push id14371
push usercykesiopka.bmo@gmail.com
push dateFri, 01 Apr 2016 01:15:04 +0000
reviewerskeeler
bugs1252722
milestone48.0a1
Bug 1252722 - Use smart pointers for NSS resources. r=keeler MozReview-Commit-ID: Gg3DNjGiNIQ
security/manager/ssl/nsPKCS11Slot.cpp
security/manager/ssl/nsPKCS11Slot.h
--- a/security/manager/ssl/nsPKCS11Slot.cpp
+++ b/security/manager/ssl/nsPKCS11Slot.cpp
@@ -18,52 +18,56 @@ extern mozilla::LazyLogModule gPIPNSSLog
 NS_IMPL_ISUPPORTS(nsPKCS11Slot, nsIPKCS11Slot)
 
 nsPKCS11Slot::nsPKCS11Slot(PK11SlotInfo *slot)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return;
 
-  PK11_ReferenceSlot(slot);
-  mSlot = slot;
+  mSlot.reset(PK11_ReferenceSlot(slot));
   mSeries = PK11_GetSlotSeries(slot);
   refreshSlotInfo(locker);
 }
 
 void
 nsPKCS11Slot::refreshSlotInfo(const nsNSSShutDownPreventionLock& /*proofOfLock*/)
 {
-  CK_SLOT_INFO slot_info;
-  if (PK11_GetSlotInfo(mSlot, &slot_info) == SECSuccess) {
-    // Set the Description field
-    const char *ccDesc = (const char*)slot_info.slotDescription;
-    const nsACString &cDesc = Substring(
-      ccDesc, 
-      ccDesc+PL_strnlen(ccDesc, sizeof(slot_info.slotDescription)));
-    mSlotDesc = NS_ConvertUTF8toUTF16(cDesc);
-    mSlotDesc.Trim(" ", false, true);
-    // Set the Manufacturer field
-    const char *ccManID = (const char*)slot_info.manufacturerID;
-    const nsACString &cManID = Substring(
-      ccManID, 
-      ccManID+PL_strnlen(ccManID, sizeof(slot_info.manufacturerID)));
-    mSlotManID = NS_ConvertUTF8toUTF16(cManID);
-    mSlotManID.Trim(" ", false, true);
-    // Set the Hardware Version field
-    mSlotHWVersion = EmptyString();
-    mSlotHWVersion.AppendInt(slot_info.hardwareVersion.major);
-    mSlotHWVersion.Append('.');
-    mSlotHWVersion.AppendInt(slot_info.hardwareVersion.minor);
-    // Set the Firmware Version field
-    mSlotFWVersion = EmptyString();
-    mSlotFWVersion.AppendInt(slot_info.firmwareVersion.major);
-    mSlotFWVersion.Append('.');
-    mSlotFWVersion.AppendInt(slot_info.firmwareVersion.minor);
+  CK_SLOT_INFO slotInfo;
+  if (PK11_GetSlotInfo(mSlot.get(), &slotInfo) != SECSuccess) {
+    return;
   }
+
+  // Set the Description field
+  const char* ccDesc = reinterpret_cast<const char*>(slotInfo.slotDescription);
+  const nsACString& cDesc = Substring(
+    ccDesc,
+    ccDesc + PL_strnlen(ccDesc, sizeof(slotInfo.slotDescription)));
+  mSlotDesc = NS_ConvertUTF8toUTF16(cDesc);
+  mSlotDesc.Trim(" ", false, true);
+
+  // Set the Manufacturer field
+  const char* ccManID = reinterpret_cast<const char*>(slotInfo.manufacturerID);
+  const nsACString& cManID = Substring(
+    ccManID,
+    ccManID + PL_strnlen(ccManID, sizeof(slotInfo.manufacturerID)));
+  mSlotManID = NS_ConvertUTF8toUTF16(cManID);
+  mSlotManID.Trim(" ", false, true);
+
+  // Set the Hardware Version field
+  mSlotHWVersion = EmptyString();
+  mSlotHWVersion.AppendInt(slotInfo.hardwareVersion.major);
+  mSlotHWVersion.Append('.');
+  mSlotHWVersion.AppendInt(slotInfo.hardwareVersion.minor);
+
+  // Set the Firmware Version field
+  mSlotFWVersion = EmptyString();
+  mSlotFWVersion.AppendInt(slotInfo.firmwareVersion.major);
+  mSlotFWVersion.Append('.');
+  mSlotFWVersion.AppendInt(slotInfo.firmwareVersion.minor);
 }
 
 nsPKCS11Slot::~nsPKCS11Slot()
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return;
   }
@@ -73,33 +77,31 @@ nsPKCS11Slot::~nsPKCS11Slot()
 
 void nsPKCS11Slot::virtualDestroyNSSReference()
 {
   destructorSafeDestroyNSSReference();
 }
 
 void nsPKCS11Slot::destructorSafeDestroyNSSReference()
 {
-  if (mSlot) {
-    PK11_FreeSlot(mSlot);
-    mSlot = nullptr;
-  }
+  mSlot = nullptr;
 }
 
 NS_IMETHODIMP 
 nsPKCS11Slot::GetName(char16_t **aName)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
 
-  char *csn = PK11_GetSlotName(mSlot);
+  // |csn| is non-owning.
+  char* csn = PK11_GetSlotName(mSlot.get());
   if (*csn) {
     *aName = ToNewUnicode(NS_ConvertUTF8toUTF16(csn));
-  } else if (PK11_HasRootCerts(mSlot)) {
+  } else if (PK11_HasRootCerts(mSlot.get())) {
     // This is a workaround to an Root Module bug - the root certs module has
     // no slot name.  Not bothering to localize, because this is a workaround
     // and for now all the slot names returned by NSS are char * anyway.
     *aName = ToNewUnicode(NS_LITERAL_STRING("Root Certificates"));
   } else {
     // same as above, this is a catch-all
     *aName = ToNewUnicode(NS_LITERAL_STRING("Unnamed Slot"));
   }
@@ -109,139 +111,139 @@ nsPKCS11Slot::GetName(char16_t **aName)
 
 NS_IMETHODIMP 
 nsPKCS11Slot::GetDesc(char16_t **aDesc)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
 
-  if (mSeries != PK11_GetSlotSeries(mSlot)) {
+  if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
     refreshSlotInfo(locker);
   }
 
   *aDesc = ToNewUnicode(mSlotDesc);
   if (!*aDesc) return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11Slot::GetManID(char16_t **aManID)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  if (mSeries != PK11_GetSlotSeries(mSlot)) {
+  if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
     refreshSlotInfo(locker);
   }
   *aManID = ToNewUnicode(mSlotManID);
   if (!*aManID) return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11Slot::GetHWVersion(char16_t **aHWVersion)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  if (mSeries != PK11_GetSlotSeries(mSlot)) {
+  if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
     refreshSlotInfo(locker);
   }
   *aHWVersion = ToNewUnicode(mSlotHWVersion);
   if (!*aHWVersion) return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11Slot::GetFWVersion(char16_t **aFWVersion)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  if (mSeries != PK11_GetSlotSeries(mSlot)) {
+  if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
     refreshSlotInfo(locker);
   }
   *aFWVersion = ToNewUnicode(mSlotFWVersion);
   if (!*aFWVersion) return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11Slot::GetToken(nsIPK11Token **_retval)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
 
-  nsCOMPtr<nsIPK11Token> token = new nsPK11Token(mSlot);
+  nsCOMPtr<nsIPK11Token> token = new nsPK11Token(mSlot.get());
   token.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11Slot::GetTokenName(char16_t **aName)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
 
-  if (!PK11_IsPresent(mSlot)) {
+  if (!PK11_IsPresent(mSlot.get())) {
     *aName = nullptr;
     return NS_OK;
   }
 
-  if (mSeries != PK11_GetSlotSeries(mSlot)) {
+  if (PK11_GetSlotSeries(mSlot.get()) != mSeries) {
     refreshSlotInfo(locker);
   }
 
-
-  *aName = ToNewUnicode(NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot)));
+  *aName = ToNewUnicode(NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot.get())));
   if (!*aName) return NS_ERROR_OUT_OF_MEMORY;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPKCS11Slot::GetStatus(uint32_t *_retval)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
 
-  if (PK11_IsDisabled(mSlot))
+  if (PK11_IsDisabled(mSlot.get())) {
     *_retval = SLOT_DISABLED;
-  else if (!PK11_IsPresent(mSlot))
+  } else if (!PK11_IsPresent(mSlot.get())) {
     *_retval = SLOT_NOT_PRESENT;
-  else if (PK11_NeedLogin(mSlot) && PK11_NeedUserInit(mSlot))
+  } else if (PK11_NeedLogin(mSlot.get()) && PK11_NeedUserInit(mSlot.get())) {
     *_retval = SLOT_UNINITIALIZED;
-  else if (PK11_NeedLogin(mSlot) && !PK11_IsLoggedIn(mSlot, nullptr))
+  } else if (PK11_NeedLogin(mSlot.get()) &&
+             !PK11_IsLoggedIn(mSlot.get(), nullptr)) {
     *_retval = SLOT_NOT_LOGGED_IN;
-  else if (PK11_NeedLogin(mSlot))
+  } else if (PK11_NeedLogin(mSlot.get())) {
     *_retval = SLOT_LOGGED_IN;
-  else
+  } else {
     *_retval = SLOT_READY;
+  }
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS(nsPKCS11Module, nsIPKCS11Module)
 
 nsPKCS11Module::nsPKCS11Module(SECMODModule *module)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return;
 
-  SECMOD_ReferenceModule(module);
-  mModule = module;
+  mModule.reset(SECMOD_ReferenceModule(module));
 }
 
 nsPKCS11Module::~nsPKCS11Module()
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return;
   }
@@ -251,20 +253,17 @@ nsPKCS11Module::~nsPKCS11Module()
 
 void nsPKCS11Module::virtualDestroyNSSReference()
 {
   destructorSafeDestroyNSSReference();
 }
 
 void nsPKCS11Module::destructorSafeDestroyNSSReference()
 {
-  if (mModule) {
-    SECMOD_DestroyModule(mModule);
-    mModule = nullptr;
-  }
+  mModule = nullptr;
 }
 
 NS_IMETHODIMP 
 nsPKCS11Module::GetName(char16_t **aName)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
@@ -291,48 +290,42 @@ nsPKCS11Module::GetLibName(char16_t **aN
 NS_IMETHODIMP 
 nsPKCS11Module::FindSlotByName(const char16_t *aName,
                                nsIPKCS11Slot **_retval)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
 
-  char *asciiname = ToNewUTF8String(nsDependentString(aName));
-  MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Getting \"%s\"\n", asciiname));
-  PK11SlotInfo *slotinfo = nullptr;
-  PK11SlotList *slotList = PK11_FindSlotsByNames(mModule->dllName, 
-        asciiname /* slotName */, nullptr /* token Name */, false);
+  NS_ConvertUTF16toUTF8 asciiname(aName);
+  MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Getting \"%s\"\n", asciiname.get()));
+  UniquePK11SlotInfo slotInfo;
+  UniquePK11SlotList slotList(PK11_FindSlotsByNames(mModule->dllName,
+                                                    asciiname.get() /*slotName*/,
+                                                    nullptr /*tokenName*/,
+                                                    false));
   if (!slotList) {
     /* name must be the token name */
-    slotList = PK11_FindSlotsByNames(mModule->dllName, 
-        nullptr /*slot Name */, asciiname /* token Name */, false);
-  }
-  if (slotList) {
-    /* should only be one */
-    if (slotList->head && slotList->head->slot) {
-      slotinfo =  PK11_ReferenceSlot(slotList->head->slot);
-    }
-    PK11_FreeSlotList(slotList);
+    slotList.reset(PK11_FindSlotsByNames(mModule->dllName, nullptr /*slotName*/,
+                                         asciiname.get() /*tokenName*/, false));
   }
-  if (!slotinfo) {
+  if (slotList && slotList->head && slotList->head->slot) {
+    slotInfo.reset(PK11_ReferenceSlot(slotList->head->slot));
+  }
+  if (!slotInfo) {
     // workaround - the builtin module has no name
-    if (!asciiname) {
-      return NS_ERROR_FAILURE;
-    } else if (nsCRT::strcmp(asciiname, "Root Certificates") == 0) {
-      slotinfo = PK11_ReferenceSlot(mModule->slots[0]);
-    } else {
-      // give up
-      free(asciiname);
+    if (!asciiname.EqualsLiteral("Root Certificates")) {
+      // Give up.
       return NS_ERROR_FAILURE;
     }
-  } 
-  free(asciiname);
-  nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotinfo);
-  PK11_FreeSlot(slotinfo);
+
+    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)
 {
   nsNSSShutDownPreventionLock locker;
@@ -382,79 +375,86 @@ nsPKCS11ModuleDB::~nsPKCS11ModuleDB()
 NS_IMETHODIMP 
 nsPKCS11ModuleDB::GetInternal(nsIPKCS11Module **_retval)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  SECMODModule *nssMod = 
-    SECMOD_CreateModule(nullptr, SECMOD_INT_NAME, nullptr, SECMOD_INT_FLAGS);
-  nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(nssMod);
-  SECMOD_DestroyModule(nssMod);
+  UniqueSECMODModule nssMod(
+    SECMOD_CreateModule(nullptr, SECMOD_INT_NAME, nullptr, SECMOD_INT_FLAGS));
+  if (!nssMod) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(nssMod.get());
   module.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11ModuleDB::GetInternalFIPS(nsIPKCS11Module **_retval)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  SECMODModule *nssMod = 
-    SECMOD_CreateModule(nullptr, SECMOD_FIPS_NAME, nullptr, SECMOD_FIPS_FLAGS);
-  nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(nssMod);
-  SECMOD_DestroyModule(nssMod);
+  UniqueSECMODModule nssMod(
+    SECMOD_CreateModule(nullptr, SECMOD_FIPS_NAME, nullptr, SECMOD_FIPS_FLAGS));
+  if (!nssMod) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(nssMod.get());
   module.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsPKCS11ModuleDB::FindModuleByName(const char16_t *aName,
                                    nsIPKCS11Module **_retval)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  NS_ConvertUTF16toUTF8 aUtf8Name(aName);
-  SECMODModule *mod =
-    SECMOD_FindModule(const_cast<char *>(aUtf8Name.get()));
-  if (!mod)
+  NS_ConvertUTF16toUTF8 utf8Name(aName);
+  UniqueSECMODModule mod(SECMOD_FindModule(const_cast<char*>(utf8Name.get())));
+  if (!mod) {
     return NS_ERROR_FAILURE;
-  nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(mod);
-  SECMOD_DestroyModule(mod);
+  }
+
+  nsCOMPtr<nsIPKCS11Module> module = new nsPKCS11Module(mod.get());
   module.forget(_retval);
   return NS_OK;
 }
 
 /* This is essentially the same as nsIPK11Token::findTokenByName, except
  * that it returns an nsIPKCS11Slot, which may be desired.
  */
 NS_IMETHODIMP 
 nsPKCS11ModuleDB::FindSlotByName(const char16_t *aName,
                                  nsIPKCS11Slot **_retval)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  NS_ConvertUTF16toUTF8 aUtf8Name(aName);
-  PK11SlotInfo *slotinfo =
-   PK11_FindSlotByName(const_cast<char*>(aUtf8Name.get()));
-  if (!slotinfo)
+  NS_ConvertUTF16toUTF8 utf8Name(aName);
+  UniquePK11SlotInfo slotInfo(
+    PK11_FindSlotByName(const_cast<char*>(utf8Name.get())));
+  if (!slotInfo) {
     return NS_ERROR_FAILURE;
-  nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotinfo);
-  PK11_FreeSlot(slotinfo);
+  }
+
+  nsCOMPtr<nsIPKCS11Slot> slot = new nsPKCS11Slot(slotInfo.get());
   slot.forget(_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPKCS11ModuleDB::ListModules(nsISimpleEnumerator** _retval)
 {
   nsNSSShutDownPreventionLock locker;
--- a/security/manager/ssl/nsPKCS11Slot.h
+++ b/security/manager/ssl/nsPKCS11Slot.h
@@ -2,16 +2,17 @@
  *
  * 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 nsPKCS11Slot_h
 #define nsPKCS11Slot_h
 
+#include "ScopedNSSTypes.h"
 #include "nsICryptoFIPSInfo.h"
 #include "nsIPKCS11Module.h"
 #include "nsIPKCS11ModuleDB.h"
 #include "nsIPKCS11Slot.h"
 #include "nsISupports.h"
 #include "nsNSSShutDown.h"
 #include "nsString.h"
 #include "pk11func.h"
@@ -24,17 +25,17 @@ public:
   NS_DECL_NSIPKCS11SLOT
 
   explicit nsPKCS11Slot(PK11SlotInfo *slot);
 
 protected:
   virtual ~nsPKCS11Slot();
 
 private:
-  PK11SlotInfo *mSlot;
+  mozilla::UniquePK11SlotInfo mSlot;
   nsString mSlotDesc, mSlotManID, mSlotHWVersion, mSlotFWVersion;
   int mSeries;
 
   virtual void virtualDestroyNSSReference() override;
   void destructorSafeDestroyNSSReference();
   void refreshSlotInfo(const nsNSSShutDownPreventionLock& proofOfLock);
 };
 
@@ -46,17 +47,17 @@ public:
   NS_DECL_NSIPKCS11MODULE
 
   explicit nsPKCS11Module(SECMODModule *module);
 
 protected:
   virtual ~nsPKCS11Module();
 
 private:
-  SECMODModule *mModule;
+  mozilla::UniqueSECMODModule mModule;
 
   virtual void virtualDestroyNSSReference() override;
   void destructorSafeDestroyNSSReference();
 };
 
 class nsPKCS11ModuleDB : public nsIPKCS11ModuleDB
                        , public nsICryptoFIPSInfo
                        , public nsNSSShutDownObject