diff --git a/security/manager/ssl/public/nsIX509CertList.idl b/security/manager/ssl/public/nsIX509CertList.idl
index c2b4eb607ebaac0382ffaf940830a5d5e385b65d..d51b7b31ebfb026bce215e9eb7033d1939e0f8f1 100644
--- a/security/manager/ssl/public/nsIX509CertList.idl
+++ b/security/manager/ssl/public/nsIX509CertList.idl
@@ -13,6 +13,9 @@ interface nsIX509CertList : nsISupports {
    void deleteCert(in nsIX509Cert cert);
    nsISimpleEnumerator getEnumerator();
 
+   /* getRawCertList MUST be called only from functions where
+    * the nssShutdownPreventionLock has been adquired.
+    */
    [notxpcom, noscript] voidPtr getRawCertList();
 
 };
diff --git a/security/manager/ssl/src/nsNSSCertCache.cpp b/security/manager/ssl/src/nsNSSCertCache.cpp
index de9f053711d89f4a3cbbfe213db6af5c7cc8e8dd..9f0ebb406b9a7fbe013407bd844a256083fb7bfd 100644
--- a/security/manager/ssl/src/nsNSSCertCache.cpp
+++ b/security/manager/ssl/src/nsNSSCertCache.cpp
@@ -52,7 +52,7 @@ nsNSSCertCache::CacheAllCerts()
 
   if (newList) {
     MutexAutoLock lock(mutex);
-    mCertList = new nsNSSCertList(newList, true); // adopt
+    mCertList = new nsNSSCertList(newList, locker);
   }
   
   return NS_OK;
diff --git a/security/manager/ssl/src/nsNSSCertificate.cpp b/security/manager/ssl/src/nsNSSCertificate.cpp
index 5b839ff7097d453846eff91a3aa1505e018072fa..e1670edc4925715664e77e84783836760e9d08ea 100644
--- a/security/manager/ssl/src/nsNSSCertificate.cpp
+++ b/security/manager/ssl/src/nsNSSCertificate.cpp
@@ -1475,23 +1475,46 @@ char* nsNSSCertificate::defaultServerNickname(CERTCertificate* cert)
 
 NS_IMPL_ISUPPORTS1(nsNSSCertList, nsIX509CertList)
 
-nsNSSCertList::nsNSSCertList(CERTCertList *certList, bool adopt)
+nsNSSCertList::nsNSSCertList(CERTCertList *certList,
+                             const nsNSSShutDownPreventionLock &proofOfLock)
 {
   if (certList) {
-    if (adopt) {
-      mCertList = certList;
-    } else {
-      mCertList = DupCertList(certList);
-    }
+    mCertList = certList;
   } else {
     mCertList = CERT_NewCertList();
   }
 }
 
+nsNSSCertList::~nsNSSCertList()
+{
+  nsNSSShutDownPreventionLock locker;
+  destructorSafeDestroyNSSReference();
+  shutdown(calledFromObject);
+}
+
+void nsNSSCertList::virtualDestroyNSSReference()
+{
+  destructorSafeDestroyNSSReference();
+}
+
+void nsNSSCertList::destructorSafeDestroyNSSReference()
+{
+  if (isAlreadyShutDown()) {
+    return;
+  }
+  if (mCertList) {
+    mCertList = nullptr;
+  }
+}
+
 /* void addCert (in nsIX509Cert cert); */
 NS_IMETHODIMP
 nsNSSCertList::AddCert(nsIX509Cert *aCert) 
 {
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
   /* This should be a query interface, but currently this his how the
    * rest of PSM is working */
   nsCOMPtr<nsIX509Cert2> nssCert = do_QueryInterface(aCert);
@@ -1515,6 +1538,10 @@ nsNSSCertList::AddCert(nsIX509Cert *aCert)
 NS_IMETHODIMP
 nsNSSCertList::DeleteCert(nsIX509Cert *aCert)
 {
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
   /* This should be a query interface, but currently this his how the
    * rest of PSM is working */
   nsCOMPtr<nsIX509Cert2> nssCert = do_QueryInterface(aCert);
@@ -1542,7 +1569,8 @@ nsNSSCertList::DeleteCert(nsIX509Cert *aCert)
 }
 
 CERTCertList *
-nsNSSCertList::DupCertList(CERTCertList *aCertList)
+nsNSSCertList::DupCertList(CERTCertList *aCertList,
+                           const nsNSSShutDownPreventionLock &/*proofOfLock*/)
 {
   if (!aCertList)
     return nullptr;
@@ -1565,6 +1593,8 @@ nsNSSCertList::DupCertList(CERTCertList *aCertList)
 void *
 nsNSSCertList::GetRawCertList()
 {
+  // This function should only be called after adquiring a
+  // nsNSSShutDownPreventionLock
   return mCertList;
 }
 
@@ -1572,7 +1602,12 @@ nsNSSCertList::GetRawCertList()
 NS_IMETHODIMP
 nsNSSCertList::GetEnumerator(nsISimpleEnumerator **_retval) 
 {
-  nsCOMPtr<nsISimpleEnumerator> enumerator = new nsNSSCertListEnumerator(mCertList);
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+  nsCOMPtr<nsISimpleEnumerator> enumerator =
+    new nsNSSCertListEnumerator(mCertList, locker);
 
   *_retval = enumerator;
   NS_ADDREF(*_retval);
@@ -1581,15 +1616,43 @@ nsNSSCertList::GetEnumerator(nsISimpleEnumerator **_retval)
 
 NS_IMPL_ISUPPORTS1(nsNSSCertListEnumerator, nsISimpleEnumerator)
 
-nsNSSCertListEnumerator::nsNSSCertListEnumerator(CERTCertList *certList)
+nsNSSCertListEnumerator::nsNSSCertListEnumerator(CERTCertList *certList,
+                                                 const nsNSSShutDownPreventionLock &proofOfLock)
+{
+  mCertList = nsNSSCertList::DupCertList(certList, proofOfLock);
+}
+
+nsNSSCertListEnumerator::~nsNSSCertListEnumerator()
 {
-  mCertList = nsNSSCertList::DupCertList(certList);
+  nsNSSShutDownPreventionLock locker;
+  destructorSafeDestroyNSSReference();
+  shutdown(calledFromObject);
+}
+
+void nsNSSCertListEnumerator::virtualDestroyNSSReference()
+{
+  destructorSafeDestroyNSSReference();
+}
+
+void nsNSSCertListEnumerator::destructorSafeDestroyNSSReference()
+{
+  if (isAlreadyShutDown()) {
+    return;
+  }
+  if (mCertList) {
+    mCertList = nullptr;
+  }
 }
 
 /* boolean hasMoreElements (); */
 NS_IMETHODIMP
 nsNSSCertListEnumerator::HasMoreElements(bool *_retval)
 { 
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   NS_ENSURE_TRUE(mCertList, NS_ERROR_FAILURE);
 
   *_retval = !CERT_LIST_EMPTY(mCertList);
@@ -1600,6 +1663,11 @@ nsNSSCertListEnumerator::HasMoreElements(bool *_retval)
 NS_IMETHODIMP
 nsNSSCertListEnumerator::GetNext(nsISupports **_retval) 
 {
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   NS_ENSURE_TRUE(mCertList, NS_ERROR_FAILURE);
 
   CERTCertListNode *node = CERT_LIST_HEAD(mCertList);
diff --git a/security/manager/ssl/src/nsNSSCertificate.h b/security/manager/ssl/src/nsNSSCertificate.h
index e4e3f3430e80f4a035cb5a6d2cb18ef58c2883aa..b0b0acdb8787e7a6dae8663a834057fb4103a340 100644
--- a/security/manager/ssl/src/nsNSSCertificate.h
+++ b/security/manager/ssl/src/nsNSSCertificate.h
@@ -76,17 +76,22 @@ private:
   nsresult getValidEVOidTag(SECOidTag &resultOidTag, bool &validEV);
 };
 
-class nsNSSCertList: public nsIX509CertList
+class nsNSSCertList: public nsIX509CertList,
+                     public nsNSSShutDownObject
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIX509CERTLIST
 
-  nsNSSCertList(CERTCertList *certList = nullptr, bool adopt = false);
+  nsNSSCertList(CERTCertList *certList,
+                const nsNSSShutDownPreventionLock &proofOfLock);
 
-  static CERTCertList *DupCertList(CERTCertList *aCertList);
+  static CERTCertList *DupCertList(CERTCertList *aCertList,
+                                   const nsNSSShutDownPreventionLock &proofOfLock);
 private:
-   virtual ~nsNSSCertList() { }
+   virtual ~nsNSSCertList();
+   virtual void virtualDestroyNSSReference();
+   void destructorSafeDestroyNSSReference();
 
    mozilla::ScopedCERTCertList mCertList;
 
@@ -94,15 +99,19 @@ private:
    void operator=(const nsNSSCertList &) MOZ_DELETE;
 };
 
-class nsNSSCertListEnumerator: public nsISimpleEnumerator
+class nsNSSCertListEnumerator: public nsISimpleEnumerator,
+                               public nsNSSShutDownObject
 {
 public:
    NS_DECL_THREADSAFE_ISUPPORTS
    NS_DECL_NSISIMPLEENUMERATOR
 
-   nsNSSCertListEnumerator(CERTCertList *certList);
+   nsNSSCertListEnumerator(CERTCertList *certList,
+                           const nsNSSShutDownPreventionLock &proofOfLock);
 private:
-   virtual ~nsNSSCertListEnumerator() { }
+   virtual ~nsNSSCertListEnumerator();
+   virtual void virtualDestroyNSSReference();
+   void destructorSafeDestroyNSSReference();
 
    mozilla::ScopedCERTCertList mCertList;
 
diff --git a/security/manager/ssl/src/nsNSSCertificateDB.cpp b/security/manager/ssl/src/nsNSSCertificateDB.cpp
index 5b3ca96413e55ba8a3f78c8af79dbd6791e43354..b2ec08d60b48fbcafd16913094fac18ade3decbc 100644
--- a/security/manager/ssl/src/nsNSSCertificateDB.cpp
+++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp
@@ -1639,7 +1639,7 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval)
 
   // nsNSSCertList 1) adopts certList, and 2) handles the nullptr case fine.
   // (returns an empty list) 
-  nssCertList = new nsNSSCertList(certList, true);
+  nssCertList = new nsNSSCertList(certList, locker);
 
   *_retval = nssCertList;
   NS_ADDREF(*_retval);