Bug 1260643 - Convert most uses of ScopedCERTCertificate in PSM to UniqueCERTCertificate. r=keeler draft
authorCykesiopka <cykesiopka.bmo@gmail.com>
Wed, 20 Apr 2016 01:14:22 -0700
changeset 354196 9978b6f50997e660b63c3cc2d57674270c2d961b
parent 354192 1687a256328b8f3b3476b1fa5053e1f946134ca7
child 518922 3c427f749dbd63349232ad7f457201fba624b18d
push id15989
push usercykesiopka.bmo@gmail.com
push dateWed, 20 Apr 2016 08:49:00 +0000
reviewerskeeler
bugs1260643
milestone48.0a1
Bug 1260643 - Convert most uses of ScopedCERTCertificate in PSM to UniqueCERTCertificate. r=keeler MozReview-Commit-ID: JnjoUd7d2M0
security/apps/AppTrustDomain.cpp
security/apps/AppTrustDomain.h
security/certverifier/CertVerifier.cpp
security/certverifier/CertVerifier.h
security/certverifier/NSSCertDBTrustDomain.cpp
security/manager/ssl/SSLServerCertVerification.cpp
security/manager/ssl/TransportSecurityInfo.cpp
security/manager/ssl/nsCertOverrideService.cpp
security/manager/ssl/nsCertTree.cpp
security/manager/ssl/nsNSSCallbacks.cpp
security/manager/ssl/nsNSSCertificate.cpp
security/manager/ssl/nsNSSCertificate.h
security/manager/ssl/nsNSSCertificateDB.cpp
security/manager/ssl/nsNSSComponent.cpp
security/manager/ssl/nsNSSIOLayer.cpp
security/manager/ssl/nsPKCS12Blob.cpp
security/manager/ssl/nsSiteSecurityService.cpp
security/manager/ssl/tests/compiled/TestIsCertBuiltInRoot.cpp
security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp
security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp
security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp
security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h
security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp
security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h
--- a/security/apps/AppTrustDomain.cpp
+++ b/security/apps/AppTrustDomain.cpp
@@ -160,18 +160,18 @@ AppTrustDomain::SetTrustedRoot(AppTruste
       break;
     }
 
     default:
       PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
       return SECFailure;
   }
 
-  mTrustedRoot = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
-                                         &trustedDER, nullptr, false, true);
+  mTrustedRoot.reset(CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+                                             &trustedDER, nullptr, false, true));
   if (!mTrustedRoot) {
     return SECFailure;
   }
 
   return SECSuccess;
 }
 
 Result
@@ -239,17 +239,17 @@ AppTrustDomain::GetCertTrust(EndEntityOr
 
   // Handle active distrust of the certificate.
 
   // XXX: This would be cleaner and more efficient if we could get the trust
   // information without constructing a CERTCertificate here, but NSS doesn't
   // expose it in any other easy-to-use fashion.
   SECItem candidateCertDERSECItem =
     UnsafeMapInputToSECItem(candidateCertDER);
-  ScopedCERTCertificate candidateCert(
+  UniqueCERTCertificate candidateCert(
     CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &candidateCertDERSECItem,
                             nullptr, false, true));
   if (!candidateCert) {
     return MapPRErrorCodeToResult(PR_GetError());
   }
 
   CERTCertTrust trust;
   if (CERT_GetCertTrust(candidateCert.get(), &trust) == SECSuccess) {
--- a/security/apps/AppTrustDomain.h
+++ b/security/apps/AppTrustDomain.h
@@ -64,17 +64,17 @@ public:
   virtual Result DigestBuf(mozilla::pkix::Input item,
                            mozilla::pkix::DigestAlgorithm digestAlg,
                            /*out*/ uint8_t* digestBuf,
                            size_t digestBufLen) override;
 
 private:
   /*out*/ ScopedCERTCertList& mCertChain;
   void* mPinArg; // non-owning!
-  ScopedCERTCertificate mTrustedRoot;
+  UniqueCERTCertificate mTrustedRoot;
   unsigned int mMinRSABits;
 
   static StaticMutex sMutex;
   static UniquePtr<unsigned char[]> sDevImportedDERData;
   static unsigned int sDevImportedDERLen;
 };
 
 } } // namespace mozilla::psm
--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -640,17 +640,17 @@ CertVerifier::VerifyCert(CERTCertificate
     PR_SetError(MapResultToPRErrorCode(rv), 0);
     return SECFailure;
   }
 
   return SECSuccess;
 }
 
 SECStatus
-CertVerifier::VerifySSLServerCert(CERTCertificate* peerCert,
+CertVerifier::VerifySSLServerCert(const UniqueCERTCertificate& peerCert,
                      /*optional*/ const SECItem* stapledOCSPResponse,
                                   Time time,
                      /*optional*/ void* pinarg,
                                   const char* hostname,
                           /*out*/ ScopedCERTCertList& builtChain,
                      /*optional*/ bool saveIntermediatesInPermanentDatabase,
                      /*optional*/ Flags flags,
                  /*optional out*/ SECOidTag* evOidPolicy,
@@ -670,19 +670,20 @@ CertVerifier::VerifySSLServerCert(CERTCe
 
   if (!hostname || !hostname[0]) {
     PR_SetError(SSL_ERROR_BAD_CERT_DOMAIN, 0);
     return SECFailure;
   }
 
   // CreateCertErrorRunnable assumes that CheckCertHostname is only called
   // if VerifyCert succeeded.
-  SECStatus rv = VerifyCert(peerCert, certificateUsageSSLServer, time, pinarg,
-                            hostname, builtChain, flags, stapledOCSPResponse,
-                            evOidPolicy, ocspStaplingStatus, keySizeStatus,
+  SECStatus rv = VerifyCert(peerCert.get(), certificateUsageSSLServer, time,
+                            pinarg, hostname, builtChain, flags,
+                            stapledOCSPResponse, evOidPolicy,
+                            ocspStaplingStatus, keySizeStatus,
                             sha1ModeResult, pinningTelemetryInfo);
   if (rv != SECSuccess) {
     return rv;
   }
 
   Input peerCertInput;
   Result result = peerCertInput.Init(peerCert->derCert.data,
                                      peerCert->derCert.len);
--- a/security/certverifier/CertVerifier.h
+++ b/security/certverifier/CertVerifier.h
@@ -79,17 +79,17 @@ public:
        /*optional in*/ const SECItem* stapledOCSPResponse = nullptr,
       /*optional out*/ SECOidTag* evOidPolicy = nullptr,
       /*optional out*/ OCSPStaplingStatus* ocspStaplingStatus = nullptr,
       /*optional out*/ KeySizeStatus* keySizeStatus = nullptr,
       /*optional out*/ SHA1ModeResult* sha1ModeResult = nullptr,
       /*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr);
 
   SECStatus VerifySSLServerCert(
-                    CERTCertificate* peerCert,
+                    const UniqueCERTCertificate& peerCert,
        /*optional*/ const SECItem* stapledOCSPResponse,
                     mozilla::pkix::Time time,
        /*optional*/ void* pinarg,
                     const char* hostname,
             /*out*/ ScopedCERTCertList& builtChain,
        /*optional*/ bool saveIntermediatesInPermanentDatabase = false,
        /*optional*/ Flags flags = 0,
    /*optional out*/ SECOidTag* evOidPolicy = nullptr,
--- a/security/certverifier/NSSCertDBTrustDomain.cpp
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
@@ -174,17 +174,17 @@ NSSCertDBTrustDomain::GetCertTrust(EndEn
 
   // XXX: This would be cleaner and more efficient if we could get the trust
   // information without constructing a CERTCertificate here, but NSS doesn't
   // expose it in any other easy-to-use fashion. The use of
   // CERT_NewTempCertificate to get a CERTCertificate shouldn't be a
   // performance problem because NSS will just find the existing
   // CERTCertificate in its in-memory cache and return it.
   SECItem candidateCertDERSECItem = UnsafeMapInputToSECItem(candidateCertDER);
-  ScopedCERTCertificate candidateCert(
+  UniqueCERTCertificate candidateCert(
     CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &candidateCertDERSECItem,
                             nullptr, false, true));
   if (!candidateCert) {
     return MapPRErrorCodeToResult(PR_GetError());
   }
 
   // Check the certificate against the OneCRL cert blocklist
   if (!mCertBlocklist) {
--- a/security/manager/ssl/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/SSLServerCertVerification.cpp
@@ -343,17 +343,18 @@ MapCertErrorToProbeValue(PRErrorCode err
   if (probeValue & FATAL_ERROR_FLAG) {
     probeValue ^= FATAL_ERROR_FLAG;
     probeValue += 90;
   }
   return probeValue;
 }
 
 SECStatus
-DetermineCertOverrideErrors(CERTCertificate* cert, const char* hostName,
+DetermineCertOverrideErrors(const UniqueCERTCertificate& cert,
+                            const char* hostName,
                             PRTime now, PRErrorCode defaultErrorCodeToReport,
                             /*out*/ uint32_t& collectedErrors,
                             /*out*/ PRErrorCode& errorCodeTrust,
                             /*out*/ PRErrorCode& errorCodeMismatch,
                             /*out*/ PRErrorCode& errorCodeTime)
 {
   MOZ_ASSERT(cert);
   MOZ_ASSERT(hostName);
@@ -373,17 +374,18 @@ DetermineCertOverrideErrors(CERTCertific
     case mozilla::pkix::MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE:
     {
       collectedErrors = nsICertOverrideService::ERROR_UNTRUSTED;
       errorCodeTrust = defaultErrorCodeToReport;
 
-      SECCertTimeValidity validity = CERT_CheckCertValidTimes(cert, now, false);
+      SECCertTimeValidity validity = CERT_CheckCertValidTimes(cert.get(), now,
+                                                              false);
       if (validity == secCertTimeUndetermined) {
         // This only happens if cert is null. CERT_CheckCertValidTimes will
         // have set the error code to SEC_ERROR_INVALID_ARGS. We should really
         // be using mozilla::pkix here anyway.
         MOZ_ASSERT(PR_GetError() == SEC_ERROR_INVALID_ARGS);
         return SECFailure;
       }
       if (validity == secCertTimeExpired) {
@@ -633,17 +635,17 @@ CertErrorRunnable::RunOnTargetThread()
 }
 
 // Returns null with the error code (PR_GetError()) set if it does not create
 // the CertErrorRunnable.
 CertErrorRunnable*
 CreateCertErrorRunnable(CertVerifier& certVerifier,
                         PRErrorCode defaultErrorCodeToReport,
                         nsNSSSocketInfo* infoObject,
-                        CERTCertificate* cert,
+                        const UniqueCERTCertificate& cert,
                         const void* fdForLogging,
                         uint32_t providerFlags,
                         PRTime now)
 {
   MOZ_ASSERT(infoObject);
   MOZ_ASSERT(cert);
 
   uint32_t probeValue = MapCertErrorToProbeValue(defaultErrorCodeToReport);
@@ -662,17 +664,17 @@ CreateCertErrorRunnable(CertVerifier& ce
     // return from CreateCertErrorRunnable without calling
     // infoObject->SetStatusErrorBits, we won't have the required information
     // to actually add a certificate error override. This results in a broken
     // UI which is annoying but not a security disaster.
     MOZ_ASSERT(!ErrorIsOverridable(PR_GetError()));
     return nullptr;
   }
 
-  RefPtr<nsNSSCertificate> nssCert(nsNSSCertificate::Create(cert));
+  RefPtr<nsNSSCertificate> nssCert(nsNSSCertificate::Create(cert.get()));
   if (!nssCert) {
     NS_ERROR("nsNSSCertificate::Create failed");
     PR_SetError(SEC_ERROR_NO_MEMORY, 0);
     return nullptr;
   }
 
   if (!collected_errors) {
     // This will happen when CERT_*Verify* only returned error(s) that are
@@ -726,56 +728,56 @@ private:
 
 class SSLServerCertVerificationJob : public nsRunnable
 {
 public:
   // Must be called only on the socket transport thread
   static SECStatus Dispatch(const RefPtr<SharedCertVerifier>& certVerifier,
                             const void* fdForLogging,
                             nsNSSSocketInfo* infoObject,
-                            CERTCertificate* serverCert,
+                            const UniqueCERTCertificate& serverCert,
                             ScopedCERTCertList& peerCertChain,
                             SECItem* stapledOCSPResponse,
                             uint32_t providerFlags,
                             Time time,
                             PRTime prtime);
 private:
   NS_DECL_NSIRUNNABLE
 
   // Must be called only on the socket transport thread
   SSLServerCertVerificationJob(const RefPtr<SharedCertVerifier>& certVerifier,
                                const void* fdForLogging,
                                nsNSSSocketInfo* infoObject,
-                               CERTCertificate* cert,
+                               const UniqueCERTCertificate& cert,
                                CERTCertList* peerCertChain,
                                SECItem* stapledOCSPResponse,
                                uint32_t providerFlags,
                                Time time,
                                PRTime prtime);
   const RefPtr<SharedCertVerifier> mCertVerifier;
   const void* const mFdForLogging;
   const RefPtr<nsNSSSocketInfo> mInfoObject;
-  const ScopedCERTCertificate mCert;
+  const UniqueCERTCertificate mCert;
   ScopedCERTCertList mPeerCertChain;
   const uint32_t mProviderFlags;
   const Time mTime;
   const PRTime mPRTime;
   const TimeStamp mJobStartTime;
   const ScopedSECItem mStapledOCSPResponse;
 };
 
 SSLServerCertVerificationJob::SSLServerCertVerificationJob(
     const RefPtr<SharedCertVerifier>& certVerifier, const void* fdForLogging,
-    nsNSSSocketInfo* infoObject, CERTCertificate* cert,
+    nsNSSSocketInfo* infoObject, const UniqueCERTCertificate& cert,
     CERTCertList* peerCertChain, SECItem* stapledOCSPResponse,
     uint32_t providerFlags, Time time, PRTime prtime)
   : mCertVerifier(certVerifier)
   , mFdForLogging(fdForLogging)
   , mInfoObject(infoObject)
-  , mCert(CERT_DupCertificate(cert))
+  , mCert(CERT_DupCertificate(cert.get()))
   , mPeerCertChain(peerCertChain)
   , mProviderFlags(providerFlags)
   , mTime(time)
   , mPRTime(prtime)
   , mJobStartTime(TimeStamp::Now())
   , mStapledOCSPResponse(SECITEM_DupItem(stapledOCSPResponse))
 {
 }
@@ -788,17 +790,17 @@ SSLServerCertVerificationJob::SSLServerC
 // Returns SECSuccess on the initial handshake of all connections, on
 // renegotiations for any connections where we did not negotiate SPDY, or on any
 // SPDY connection where the server's certificate did not change.
 //
 // Prohibit changing the server cert only if we negotiated SPDY,
 // in order to support SPDY's cross-origin connection pooling.
 static SECStatus
 BlockServerCertChangeForSpdy(nsNSSSocketInfo* infoObject,
-                             CERTCertificate* serverCert)
+                             const UniqueCERTCertificate& serverCert)
 {
   // Get the existing cert. If there isn't one, then there is
   // no cert change to worry about.
   nsCOMPtr<nsIX509Cert> cert;
 
   RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
   if (!status) {
     // If we didn't have a status, then this is the
@@ -828,19 +830,19 @@ BlockServerCertChangeForSpdy(nsNSSSocket
   // If GetNegotiatedNPN() failed we will assume spdy for safety's safe
   if (NS_FAILED(rv)) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
            ("BlockServerCertChangeForSpdy failed GetNegotiatedNPN() call."
             " Assuming spdy.\n"));
   }
 
   // Check to see if the cert has actually changed
-  ScopedCERTCertificate c(cert->GetCert());
+  UniqueCERTCertificate c(cert->GetCert());
   NS_ASSERTION(c, "very bad and hopefully impossible state");
-  bool sameCert = CERT_CompareCerts(c, serverCert);
+  bool sameCert = CERT_CompareCerts(c.get(), serverCert.get());
   if (sameCert) {
     return SECSuccess;
   }
 
   // Report an error - changed cert is confirmed
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
          ("SPDY Refused to allow new cert during renegotiation\n"));
   PR_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, 0);
@@ -1210,17 +1212,17 @@ GatherSuccessfulValidationTelemetry(cons
   GatherEKUTelemetry(certList);
   GatherRootCATelemetry(certList);
   GatherEndEntityTelemetry(certList);
 }
 
 SECStatus
 AuthCertificate(CertVerifier& certVerifier,
                 nsNSSSocketInfo* infoObject,
-                CERTCertificate* cert,
+                const UniqueCERTCertificate& cert,
                 ScopedCERTCertList& peerCertChain,
                 SECItem* stapledOCSPResponse,
                 uint32_t providerFlags,
                 Time time)
 {
   MOZ_ASSERT(infoObject);
   MOZ_ASSERT(cert);
 
@@ -1288,20 +1290,20 @@ AuthCertificate(CertVerifier& certVerifi
   // complete chain at any time it might need it.
   // But we keep only those CA certs in the temp db, that we didn't already know.
 
   RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
   RefPtr<nsNSSCertificate> nsc;
 
   if (!status || !status->HasServerCert()) {
     if( rv == SECSuccess ){
-      nsc = nsNSSCertificate::Create(cert, &evOidPolicy);
+      nsc = nsNSSCertificate::Create(cert.get(), &evOidPolicy);
     }
     else {
-      nsc = nsNSSCertificate::Create(cert);
+      nsc = nsNSSCertificate::Create(cert.get());
     }
   }
 
   if (rv == SECSuccess) {
     GatherSuccessfulValidationTelemetry(certList);
 
     // The connection may get terminated, for example, if the server requires
     // a client cert. Let's provide a minimal SSLStatus
@@ -1348,17 +1350,17 @@ AuthCertificate(CertVerifier& certVerifi
   return rv;
 }
 
 /*static*/ SECStatus
 SSLServerCertVerificationJob::Dispatch(
   const RefPtr<SharedCertVerifier>& certVerifier,
   const void* fdForLogging,
   nsNSSSocketInfo* infoObject,
-  CERTCertificate* serverCert,
+  const UniqueCERTCertificate& serverCert,
   ScopedCERTCertList& peerCertChain,
   SECItem* stapledOCSPResponse,
   uint32_t providerFlags,
   Time time,
   PRTime prtime)
 {
   // Runs on the socket transport thread
   if (!certVerifier || !infoObject || !serverCert) {
@@ -1422,17 +1424,17 @@ SSLServerCertVerificationJob::Run()
     Telemetry::ID successTelemetry
       = Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_MOZILLAPKIX;
     Telemetry::ID failureTelemetry
       = Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_MOZILLAPKIX;
 
     // Reset the error code here so we can detect if AuthCertificate fails to
     // set the error code if/when it fails.
     PR_SetError(0, 0);
-    SECStatus rv = AuthCertificate(*mCertVerifier, mInfoObject, mCert.get(),
+    SECStatus rv = AuthCertificate(*mCertVerifier, mInfoObject, mCert,
                                    mPeerCertChain, mStapledOCSPResponse,
                                    mProviderFlags, mTime);
     if (rv == SECSuccess) {
       uint32_t interval = (uint32_t) ((TimeStamp::Now() - mJobStartTime).ToMilliseconds());
       RefPtr<SSLServerCertVerificationResult> restart(
         new SSLServerCertVerificationResult(mInfoObject, 0,
                                             successTelemetry, interval));
       restart->Dispatch();
@@ -1445,19 +1447,18 @@ SSLServerCertVerificationJob::Run()
     error = PR_GetError();
     {
       TimeStamp now = TimeStamp::Now();
       MutexAutoLock telemetryMutex(*gSSLVerificationTelemetryMutex);
       Telemetry::AccumulateTimeDelta(failureTelemetry, mJobStartTime, now);
     }
     if (error != 0) {
       RefPtr<CertErrorRunnable> runnable(
-          CreateCertErrorRunnable(*mCertVerifier, error, mInfoObject,
-                                  mCert.get(), mFdForLogging, mProviderFlags,
-                                  mPRTime));
+          CreateCertErrorRunnable(*mCertVerifier, error, mInfoObject, mCert,
+                                  mFdForLogging, mProviderFlags, mPRTime));
       if (!runnable) {
         // CreateCertErrorRunnable set a new error code
         error = PR_GetError();
       } else {
         // We must block the the socket transport service thread while the
         // main thread executes the CertErrorRunnable. The CertErrorRunnable
         // will dispatch the result asynchronously, so we don't have to block
         // this thread waiting for it.
@@ -1518,17 +1519,17 @@ AuthCertificateHook(void* arg, PRFileDes
   NS_ASSERTION(checkSig, "AuthCertificateHook: checkSig unexpectedly false");
 
   // PSM never causes libssl to call this function with PR_TRUE for isServer,
   // and many things in PSM assume that we are a client.
   NS_ASSERTION(!isServer, "AuthCertificateHook: isServer unexpectedly true");
 
   nsNSSSocketInfo* socketInfo = static_cast<nsNSSSocketInfo*>(arg);
 
-  ScopedCERTCertificate serverCert(SSL_PeerCertificate(fd));
+  UniqueCERTCertificate serverCert(SSL_PeerCertificate(fd));
 
   if (!checkSig || isServer || !socketInfo || !serverCert) {
       PR_SetError(PR_INVALID_STATE_ERROR, 0);
       return SECFailure;
   }
 
   // Get the peer certificate chain for error reporting
   ScopedCERTCertList peerCertChain(SSL_PeerCertificateChain(fd));
--- a/security/manager/ssl/TransportSecurityInfo.cpp
+++ b/security/manager/ssl/TransportSecurityInfo.cpp
@@ -714,17 +714,17 @@ AppendErrorTextMismatch(const nsString& 
   params[0] = host.get();
   nsresult rv = component->PIPBundleFormatStringFromName(
     "certErrorMismatch", params, 1, notValidForHostnameString);
   if (NS_FAILED(rv)) {
     return rv;
   }
   notValidForHostnameString.Append('\n');
 
-  ScopedCERTCertificate nssCert(ix509->GetCert());
+  UniqueCERTCertificate nssCert(ix509->GetCert());
   if (!nssCert) {
     returnedMessage.Append(notValidForHostnameString);
     return NS_OK;
   }
 
   nsAutoString allNames;
   uint32_t nameCount = GetSubjectAltNames(nssCert.get(), allNames);
   if (nameCount == 0) {
--- a/security/manager/ssl/nsCertOverrideService.cpp
+++ b/security/manager/ssl/nsCertOverrideService.cpp
@@ -343,18 +343,17 @@ nsCertOverrideService::Write()
   return NS_OK;
 }
 
 static nsresult
 GetCertFingerprintByOidTag(nsIX509Cert *aCert,
                            SECOidTag aOidTag, 
                            nsCString &fp)
 {
-
-  ScopedCERTCertificate nsscert(aCert->GetCert());
+  UniqueCERTCertificate nsscert(aCert->GetCert());
   if (!nsscert) {
     return NS_ERROR_FAILURE;
   }
   return GetCertFingerprintByOidTag(nsscert.get(), aOidTag, fp);
 }
 
 NS_IMETHODIMP
 nsCertOverrideService::RememberValidityOverride(const nsACString& aHostName,
@@ -364,17 +363,17 @@ nsCertOverrideService::RememberValidityO
                                                 bool aTemporary)
 {
   NS_ENSURE_ARG_POINTER(aCert);
   if (aHostName.IsEmpty())
     return NS_ERROR_INVALID_ARG;
   if (aPort < -1)
     return NS_ERROR_INVALID_ARG;
 
-  ScopedCERTCertificate nsscert(aCert->GetCert());
+  UniqueCERTCertificate nsscert(aCert->GetCert());
   if (!nsscert) {
     return NS_ERROR_FAILURE;
   }
 
   char* nickname = DefaultServerNicknameForCert(nsscert.get());
   if (!aTemporary && nickname && *nickname)
   {
     ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
--- a/security/manager/ssl/nsCertTree.cpp
+++ b/security/manager/ssl/nsCertTree.cpp
@@ -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/. */
 
 #include "nsCertTree.h"
 
+#include "ScopedNSSTypes.h"
 #include "mozilla/Logging.h"
 #include "nsArray.h"
 #include "nsArrayUtils.h"
 #include "nsHashKeys.h"
 #include "nsISupportsPrimitives.h"
 #include "nsITreeColumns.h"
 #include "nsIX509CertDB.h"
 #include "nsIX509Cert.h"
@@ -786,22 +787,22 @@ nsCertTree::DeleteEntryObject(uint32_t i
           } 
         }
         else {
           if (addonInfo && addonInfo->mUsageCount > 1) {
             // user is trying to delete a perm trusted cert,
             // although there are still overrides stored,
             // so, we keep the cert, but remove the trust
 
-            ScopedCERTCertificate nsscert(cert->GetCert());
+            UniqueCERTCertificate nsscert(cert->GetCert());
 
             if (nsscert) {
               CERTCertTrust trust;
               memset((void*)&trust, 0, sizeof(trust));
-            
+
               SECStatus srv = CERT_DecodeTrustString(&trust, ""); // no override 
               if (srv == SECSuccess) {
                 CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert.get(),
                                      &trust);
               }
             }
           }
           else {
--- a/security/manager/ssl/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/nsNSSCallbacks.cpp
@@ -18,16 +18,17 @@
 #include "nsIWebProgressListener.h"
 #include "nsNetUtil.h"
 #include "nsNSSComponent.h"
 #include "nsNSSIOLayer.h"
 #include "nsProtectedAuthThread.h"
 #include "nsProxyRelease.h"
 #include "pkix/pkixtypes.h"
 #include "PSMRunnable.h"
+#include "ScopedNSSTypes.h"
 #include "SharedSSLState.h"
 #include "ssl.h"
 #include "sslproto.h"
 
 using namespace mozilla;
 using namespace mozilla::psm;
 
 extern LazyLogModule gPIPNSSLog;
@@ -1224,17 +1225,17 @@ void HandshakeCallback(PRFileDesc* fd, v
                                                 infoObject->GetPort());
     }
   }
 
   if (status->HasServerCert()) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
            ("HandshakeCallback KEEPING existing cert\n"));
   } else {
-    ScopedCERTCertificate serverCert(SSL_PeerCertificate(fd));
+    UniqueCERTCertificate serverCert(SSL_PeerCertificate(fd));
     RefPtr<nsNSSCertificate> nssc(nsNSSCertificate::Create(serverCert.get()));
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
            ("HandshakeCallback using NEW cert %p\n", nssc.get()));
     status->SetServerCert(nssc, nsNSSCertificate::ev_status_unknown);
   }
 
   nsCOMPtr<nsICertOverrideService> overrideService =
       do_GetService(NS_CERTOVERRIDE_CONTRACTID);
--- a/security/manager/ssl/nsNSSCertificate.cpp
+++ b/security/manager/ssl/nsNSSCertificate.cpp
@@ -113,17 +113,17 @@ nsNSSCertificate::InitFromDER(char* cert
   if (!aCert)
     return false;
 
   if (!aCert->dbhandle)
   {
     aCert->dbhandle = CERT_GetDefaultCertDB();
   }
 
-  mCert = aCert;
+  mCert.reset(aCert);
   return true;
 }
 
 nsNSSCertificate::nsNSSCertificate(CERTCertificate* cert,
                                    SECOidTag* evOidPolicy)
   : mCert(nullptr)
   , mPermDelete(false)
   , mCertType(CERT_TYPE_NOT_YET_INITIALIZED)
@@ -134,17 +134,17 @@ nsNSSCertificate::nsNSSCertificate(CERTC
     NS_ERROR("Trying to initialize nsNSSCertificate in a non-chrome process!");
 #endif
 
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return;
 
   if (cert) {
-    mCert = CERT_DupCertificate(cert);
+    mCert.reset(CERT_DupCertificate(cert));
     if (evOidPolicy) {
       if (*evOidPolicy == SEC_OID_UNKNOWN) {
         mCachedEVStatus =  ev_status_invalid;
       }
       else {
         mCachedEVStatus = ev_status_valid;
       }
       mCachedEVOidTag = *evOidPolicy;
@@ -222,17 +222,17 @@ NS_IMETHODIMP
 nsNSSCertificate::GetIsBuiltInRoot(bool* aIsBuiltInRoot)
 {
   NS_ENSURE_ARG(aIsBuiltInRoot);
 
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
-  pkix::Result rv = IsCertBuiltInRoot(mCert, *aIsBuiltInRoot);
+  pkix::Result rv = IsCertBuiltInRoot(mCert.get(), *aIsBuiltInRoot);
   if (rv != pkix::Result::Success) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 nsresult
 nsNSSCertificate::MarkForPermDeletion()
@@ -510,17 +510,17 @@ nsNSSCertificate::GetDbKey(nsACString& a
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   return GetDbKey(mCert, aDbKey);
 }
 
 nsresult
-nsNSSCertificate::GetDbKey(CERTCertificate* cert, nsACString& aDbKey)
+nsNSSCertificate::GetDbKey(const UniqueCERTCertificate& cert, nsACString& aDbKey)
 {
   static_assert(sizeof(uint64_t) == 8, "type size sanity check");
   static_assert(sizeof(uint32_t) == 4, "type size sanity check");
   // The format of the key is the base64 encoding of the following:
   // 4 bytes: {0, 0, 0, 0} (this was intended to be the module ID, but it was
   //                        never implemented)
   // 4 bytes: {0, 0, 0, 0} (this was intended to be the slot ID, but it was
   //                        never implemented)
@@ -1171,41 +1171,41 @@ nsNSSCertificate::ExportAsCMS(uint32_t c
 
   // Calling NSS_CMSSignedData_CreateCertsOnly() will not allow us
   // to specify the inclusion of the root, but CERT_CertChainFromCert() does.
   // Since CERT_CertChainFromCert() also includes the certificate itself,
   // we have to start at the issuing cert (to avoid duplicate certs
   // in the SignedData).
   if (chainMode == nsIX509Cert::CMS_CHAIN_MODE_CertChain ||
       chainMode == nsIX509Cert::CMS_CHAIN_MODE_CertChainWithRoot) {
-    ScopedCERTCertificate issuerCert(
-        CERT_FindCertIssuer(mCert.get(), PR_Now(), certUsageAnyCA));
+    UniqueCERTCertificate issuerCert(
+      CERT_FindCertIssuer(mCert.get(), PR_Now(), certUsageAnyCA));
     // the issuerCert of a self signed root is the cert itself,
     // so make sure we're not adding duplicates, again
-    if (issuerCert && issuerCert != mCert.get()) {
+    if (issuerCert && issuerCert != mCert) {
       bool includeRoot =
         (chainMode == nsIX509Cert::CMS_CHAIN_MODE_CertChainWithRoot);
       UniqueCERTCertificateList certChain(
-          CERT_CertChainFromCert(issuerCert, certUsageAnyCA, includeRoot));
+        CERT_CertChainFromCert(issuerCert.get(), certUsageAnyCA, includeRoot));
       if (certChain) {
         if (NSS_CMSSignedData_AddCertList(sigd.get(), certChain.get())
               == SECSuccess) {
           Unused << certChain.release();
         }
         else {
           MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
                  ("nsNSSCertificate::ExportAsCMS - can't add chain\n"));
           return NS_ERROR_FAILURE;
         }
       }
       else {
         // try to add the issuerCert, at least
-        if (NSS_CMSSignedData_AddCertificate(sigd.get(), issuerCert)
-            == SECSuccess) {
-          issuerCert.forget();
+        if (NSS_CMSSignedData_AddCertificate(sigd.get(), issuerCert.get())
+              == SECSuccess) {
+          Unused << issuerCert.release();
         }
         else {
           MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
                  ("nsNSSCertificate::ExportAsCMS - can't add issuer cert\n"));
           return NS_ERROR_FAILURE;
         }
       }
     }
@@ -1375,17 +1375,17 @@ nsNSSCertificate::Equals(nsIX509Cert* ot
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown())
     return NS_ERROR_NOT_AVAILABLE;
 
   NS_ENSURE_ARG(other);
   NS_ENSURE_ARG(result);
 
-  ScopedCERTCertificate cert(other->GetCert());
+  UniqueCERTCertificate cert(other->GetCert());
   *result = (mCert.get() == cert.get());
   return NS_OK;
 }
 
 #ifndef MOZ_NO_EV_CERTS
 
 nsresult
 nsNSSCertificate::hasValidEVOidTag(SECOidTag& resultOidTag, bool& validEV)
@@ -1485,27 +1485,27 @@ ConstructCERTCertListFromReversedDERArra
     return SECFailure;
   }
 
   CERTCertDBHandle* certDB(CERT_GetDefaultCertDB()); // non-owning
 
   size_t numCerts = certArray.GetLength();
   for (size_t i = 0; i < numCerts; ++i) {
     SECItem certDER(UnsafeMapInputToSECItem(*certArray.GetDER(i)));
-    ScopedCERTCertificate cert(CERT_NewTempCertificate(certDB, &certDER,
+    UniqueCERTCertificate cert(CERT_NewTempCertificate(certDB, &certDER,
                                                        nullptr, false, true));
     if (!cert) {
       return SECFailure;
     }
     // certArray is ordered with the root first, but we want the resulting
     // certList to have the root last.
-    if (CERT_AddCertToListHead(certList, cert) != SECSuccess) {
+    if (CERT_AddCertToListHead(certList.get(), cert.get()) != SECSuccess) {
       return SECFailure;
     }
-    cert.forget(); // cert is now owned by certList.
+    Unused << cert.release(); // cert is now owned by certList.
   }
 
   return SECSuccess;
 }
 
 } // namespace mozilla
 
 NS_IMPL_CLASSINFO(nsNSSCertList,
--- a/security/manager/ssl/nsNSSCertificate.h
+++ b/security/manager/ssl/nsNSSCertificate.h
@@ -50,22 +50,23 @@ public:
   enum EVStatus {
     ev_status_invalid = 0,
     ev_status_valid = 1,
     ev_status_unknown = 2
   };
 
   // This is a separate static method so nsNSSComponent can use it during NSS
   // initialization. Other code should probably not use it.
-  static nsresult GetDbKey(CERTCertificate* cert, nsACString& aDbKey);
+  static nsresult GetDbKey(const mozilla::UniqueCERTCertificate& cert,
+                           nsACString& aDbKey);
 
 private:
   virtual ~nsNSSCertificate();
 
-  mozilla::ScopedCERTCertificate mCert;
+  mozilla::UniqueCERTCertificate mCert;
   bool             mPermDelete;
   uint32_t         mCertType;
   nsresult CreateASN1Struct(nsIASN1Object** aRetVal);
   nsresult CreateTBSCertificateASN1Struct(nsIASN1Sequence** retSequence,
                                           nsINSSComponent* nssComponent);
   nsresult GetSortableDate(PRTime aTime, nsAString& _aSortableDate);
   virtual void virtualDestroyNSSReference() override;
   void destructorSafeDestroyNSSReference();
--- a/security/manager/ssl/nsNSSCertificateDB.cpp
+++ b/security/manager/ssl/nsNSSCertificateDB.cpp
@@ -97,24 +97,23 @@ nsNSSCertificateDB::FindCertByNickname(c
 {
   NS_ENSURE_ARG_POINTER(_rvCert);
   *_rvCert = nullptr;
 
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
-  ScopedCERTCertificate cert;
   char *asciiname = nullptr;
   NS_ConvertUTF16toUTF8 aUtf8Nickname(nickname);
   asciiname = const_cast<char*>(aUtf8Nickname.get());
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Getting \"%s\"\n", asciiname));
-  cert = PK11_FindCertFromNickname(asciiname, nullptr);
+  UniqueCERTCertificate cert(PK11_FindCertFromNickname(asciiname, nullptr));
   if (!cert) {
-    cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), asciiname);
+    cert.reset(CERT_FindCertByNickname(CERT_GetDefaultCertDB(), asciiname));
   }
   if (cert) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("got it\n"));
     nsCOMPtr<nsIX509Cert> pCert = nsNSSCertificate::Create(cert.get());
     if (pCert) {
       pCert.forget(_rvCert);
       return NS_OK;
     }
@@ -339,25 +338,24 @@ nsNSSCertificateDB::handleCACertDownload
   SECItem der;
   rv=certToShow->GetRawDER(&der.len, (uint8_t **)&der.data);
 
   if (NS_FAILED(rv))
     return rv;
 
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Creating temp cert\n"));
   CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
-  ScopedCERTCertificate tmpCert(CERT_FindCertByDERCert(certdb, &der));
+  UniqueCERTCertificate tmpCert(CERT_FindCertByDERCert(certdb, &der));
   if (!tmpCert) {
-    tmpCert = CERT_NewTempCertificate(certdb, &der,
-                                      nullptr, false, true);
+    tmpCert.reset(CERT_NewTempCertificate(certdb, &der, nullptr, false, true));
   }
   free(der.data);
   der.data = nullptr;
   der.len = 0;
-  
+
   if (!tmpCert) {
     NS_ERROR("Couldn't create cert from DER blob");
     return NS_ERROR_FAILURE;
   }
 
   if (!CERT_IsCACert(tmpCert.get(), nullptr)) {
     DisplayCertificateAlert(ctx, "NotACACert", certToShow, proofOfLock);
     return NS_ERROR_FAILURE;
@@ -814,17 +812,17 @@ nsNSSCertificateDB::ImportUserCertificat
 NS_IMETHODIMP 
 nsNSSCertificateDB::DeleteCertificate(nsIX509Cert *aCert)
 {
   NS_ENSURE_ARG_POINTER(aCert);
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
-  ScopedCERTCertificate cert(aCert->GetCert());
+  UniqueCERTCertificate cert(aCert->GetCert());
   if (!cert) {
     return NS_ERROR_FAILURE;
   }
   SECStatus srv = SECSuccess;
 
   uint32_t certType;
   aCert->GetCertType(&certType);
   if (NS_FAILED(aCert->MarkForPermDeletion()))
@@ -855,17 +853,17 @@ nsNSSCertificateDB::SetCertTrust(nsIX509
 {
   NS_ENSURE_ARG_POINTER(cert);
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   nsNSSCertTrust trust;
   nsresult rv;
-  ScopedCERTCertificate nsscert(cert->GetCert());
+  UniqueCERTCertificate nsscert(cert->GetCert());
 
   rv = attemptToLogInWithDefaultPassword();
   if (NS_WARN_IF(rv != NS_OK)) {
     return rv;
   }
 
   SECStatus srv;
   if (type == nsIX509Cert::CA_CERT) {
@@ -907,17 +905,17 @@ nsNSSCertificateDB::IsCertTrusted(nsIX50
   NS_ENSURE_ARG_POINTER(_isTrusted);
   *_isTrusted = false;
 
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   SECStatus srv;
-  ScopedCERTCertificate nsscert(cert->GetCert());
+  UniqueCERTCertificate nsscert(cert->GetCert());
   CERTCertTrust nsstrust;
   srv = CERT_GetCertTrust(nsscert.get(), &nsstrust);
   if (srv != SECSuccess)
     return NS_ERROR_FAILURE;
 
   nsNSSCertTrust trust(&nsstrust);
   if (certType == nsIX509Cert::CA_CERT) {
     if (trustType & nsIX509CertDB::TRUSTED_SSL) {
@@ -1074,17 +1072,17 @@ nsNSSCertificateDB::FindEmailEncryptionC
   }
 
   nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
   char *asciiname = nullptr;
   NS_ConvertUTF16toUTF8 aUtf8Nickname(aNickname);
   asciiname = const_cast<char*>(aUtf8Nickname.get());
 
   /* Find a good cert in the user's database */
-  ScopedCERTCertificate cert(CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
+  UniqueCERTCertificate cert(CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
                                                       asciiname,
                                                       certUsageEmailRecipient,
                                                       true, ctx));
   if (!cert) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIX509Cert> nssCert = nsNSSCertificate::Create(cert.get());
@@ -1111,17 +1109,17 @@ nsNSSCertificateDB::FindEmailSigningCert
   }
 
   nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
   char *asciiname = nullptr;
   NS_ConvertUTF16toUTF8 aUtf8Nickname(aNickname);
   asciiname = const_cast<char*>(aUtf8Nickname.get());
 
   /* Find a good cert in the user's database */
-  ScopedCERTCertificate cert(CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
+  UniqueCERTCertificate cert(CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
                                                       asciiname,
                                                       certUsageEmailSigner,
                                                       true, ctx));
   if (!cert) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIX509Cert> nssCert = nsNSSCertificate::Create(cert.get());
@@ -1238,17 +1236,17 @@ nsNSSCertificateDB::ConstructX509(const 
     return NS_ERROR_INVALID_POINTER;
   }
 
   SECItem secitem_cert;
   secitem_cert.type = siDERCertBuffer;
   secitem_cert.data = (unsigned char*)certDER;
   secitem_cert.len = lengthDER;
 
-  ScopedCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+  UniqueCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                                      &secitem_cert, nullptr,
                                                      false, true));
   if (!cert)
     return (PORT_GetError() == SEC_ERROR_NO_MEMORY)
       ? NS_ERROR_OUT_OF_MEMORY : NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIX509Cert> nssCert = nsNSSCertificate::Create(cert.get());
   if (!nssCert) {
@@ -1332,28 +1330,27 @@ nsNSSCertificateDB::get_default_nickname
       if (!tmp) {
         nickname.Truncate();
         return;
       }
       nickname = tmp;
       PR_smprintf_free(tmp);
     }
 
-    ScopedCERTCertificate dummycert;
+    UniqueCERTCertificate dummycert;
 
     if (PK11_IsInternal(slot)) {
       /* look up the nickname to make sure it isn't in use already */
-      dummycert = CERT_FindCertByNickname(defaultcertdb, nickname.get());
-
+      dummycert.reset(CERT_FindCertByNickname(defaultcertdb, nickname.get()));
     } else {
       /*
        * Check the cert against others that already live on the smart 
        * card.
        */
-      dummycert = PK11_FindCertFromNickname(nickname.get(), ctx);
+      dummycert.reset(PK11_FindCertFromNickname(nickname.get(), ctx));
       if (dummycert) {
 	/*
 	 * Make sure the subject names are different.
 	 */ 
 	if (CERT_CompareName(&cert->subject, &dummycert->subject) == SECEqual)
 	{
 	  /*
 	   * There is another certificate with the same nickname and
@@ -1395,20 +1392,20 @@ NS_IMETHODIMP nsNSSCertificateDB::AddCer
   NS_ENSURE_SUCCESS(rv, rv);
 
   SECItem der;
   rv = newCert->GetRawDER(&der.len, (uint8_t **)&der.data);
   NS_ENSURE_SUCCESS(rv, rv);
 
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Creating temp cert\n"));
   CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
-  ScopedCERTCertificate tmpCert(CERT_FindCertByDERCert(certdb, &der));
-  if (!tmpCert)
-    tmpCert = CERT_NewTempCertificate(certdb, &der,
-                                      nullptr, false, true);
+  UniqueCERTCertificate tmpCert(CERT_FindCertByDERCert(certdb, &der));
+  if (!tmpCert) {
+    tmpCert.reset(CERT_NewTempCertificate(certdb, &der, nullptr, false, true));
+  }
   free(der.data);
   der.data = nullptr;
   der.len = 0;
 
   if (!tmpCert) {
     NS_ERROR("Couldn't create cert from DER blob");
     return MapSECStatus(SECFailure);
   }
@@ -1452,17 +1449,17 @@ nsNSSCertificateDB::SetCertTrustFromStri
   CERTCertTrust trust;
 
   // need to calculate the trust bits from the aTrust string.
   SECStatus srv = CERT_DecodeTrustString(&trust,
                                          const_cast<char *>(trustString));
   if (srv != SECSuccess) {
     return MapSECStatus(SECFailure);
   }
-  ScopedCERTCertificate nssCert(cert->GetCert());
+  UniqueCERTCertificate nssCert(cert->GetCert());
 
   nsresult rv = attemptToLogInWithDefaultPassword();
   if (NS_WARN_IF(rv != NS_OK)) {
     return rv;
   }
 
   srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nssCert.get(), &trust);
   return MapSECStatus(srv);
@@ -1507,17 +1504,17 @@ VerifyCertAtTime(nsIX509Cert* aCert,
   *aVerifiedChain = nullptr;
   *aHasEVPolicy = false;
   *_retval = PR_UNKNOWN_ERROR;
 
 #ifndef MOZ_NO_EV_CERTS
   EnsureIdentityInfoLoaded();
 #endif
 
-  ScopedCERTCertificate nssCert(aCert->GetCert());
+  UniqueCERTCertificate nssCert(aCert->GetCert());
   if (!nssCert) {
     return NS_ERROR_INVALID_ARG;
   }
 
   RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
   NS_ENSURE_TRUE(certVerifier, NS_ERROR_FAILURE);
 
   ScopedCERTCertList resultChain;
@@ -1530,17 +1527,17 @@ VerifyCertAtTime(nsIX509Cert* aCert,
                                             aTime,
                                             nullptr, // Assume no context
                                             aHostname,
                                             resultChain,
                                             false, // don't save intermediates
                                             aFlags,
                                             &evOidPolicy);
   } else {
-    srv = certVerifier->VerifyCert(nssCert, aUsage, aTime,
+    srv = certVerifier->VerifyCert(nssCert.get(), aUsage, aTime,
                                    nullptr, // Assume no context
                                    aHostname,
                                    resultChain,
                                    aFlags,
                                    nullptr, // stapledOCSPResponse
                                    &evOidPolicy);
   }
 
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -695,17 +695,17 @@ MaybeImportFamilySafetyRoot(PCCERT_CONTE
     SECStatus srv = __CERT_AddTempCertToPerm(
       nssCertificate.get(), "Microsoft Family Safety", &trust);
     if (srv != SECSuccess) {
       MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
               ("couldn't permanently add certificate"));
       return NS_ERROR_FAILURE;
     }
     nsAutoCString dbKey;
-    nsresult rv = nsNSSCertificate::GetDbKey(nssCertificate.get(), dbKey);
+    nsresult rv = nsNSSCertificate::GetDbKey(nssCertificate, dbKey);
     if (NS_FAILED(rv)) {
       MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("GetDbKey failed"));
       return rv;
     }
     Preferences::SetCString(kImportedFamilySafetyRootPref, dbKey);
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("added Family Safety root"));
   }
   return NS_OK;
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -13,16 +13,17 @@
 #include "PSMRunnable.h"
 #include "SSLServerCertVerification.h"
 #include "ScopedNSSTypes.h"
 #include "SharedSSLState.h"
 #include "keyhi.h"
 #include "mozilla/Casting.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Logging.h"
+#include "mozilla/Move.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsClientAuthRemember.h"
 #include "nsContentUtils.h"
 #include "nsIClientAuthDialogs.h"
 #include "nsIConsoleService.h"
 #include "nsIPrefService.h"
@@ -331,24 +332,24 @@ nsNSSSocketInfo::IsAcceptableForHost(con
   // because the user decides on whether to send client certs to hosts on a
   // per-domain basis.
   if (mSentClientCert)
     return NS_OK;
 
   // Ensure that the server certificate covers the hostname that would
   // like to join this connection
 
-  ScopedCERTCertificate nssCert;
+  UniqueCERTCertificate nssCert;
 
   nsCOMPtr<nsIX509Cert> cert;
   if (NS_FAILED(SSLStatus()->GetServerCert(getter_AddRefs(cert)))) {
     return NS_OK;
   }
   if (cert) {
-    nssCert = cert->GetCert();
+    nssCert.reset(cert->GetCert());
   }
 
   if (!nssCert) {
     return NS_OK;
   }
 
   // Attempt to verify the joinee's certificate using the joining hostname.
   // This ensures that any hostname-specific verification logic (e.g. key
@@ -1985,24 +1986,24 @@ hasExplicitKeyUsageNonRepudiation(CERTCe
 
 class ClientAuthDataRunnable : public SyncRunnableBase
 {
 public:
   ClientAuthDataRunnable(CERTDistNames* caNames,
                          CERTCertificate** pRetCert,
                          SECKEYPrivateKey** pRetKey,
                          nsNSSSocketInfo* info,
-                         CERTCertificate* serverCert)
+                         const UniqueCERTCertificate& serverCert)
     : mRV(SECFailure)
     , mErrorCodeToReport(SEC_ERROR_NO_MEMORY)
     , mPRetCert(pRetCert)
     , mPRetKey(pRetKey)
     , mCANames(caNames)
     , mSocketInfo(info)
-    , mServerCert(serverCert)
+    , mServerCert(serverCert.get())
   {
   }
 
   SECStatus mRV;                        // out
   PRErrorCode mErrorCodeToReport;       // out
   CERTCertificate** const mPRetCert;    // in/out
   SECKEYPrivateKey** const mPRetKey;    // in/out
 protected:
@@ -2033,17 +2034,17 @@ nsNSS_SSLGetClientAuthData(void* arg, PR
   if (!socket || !caNames || !pRetCert || !pRetKey) {
     PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
     return SECFailure;
   }
 
   RefPtr<nsNSSSocketInfo> info(
     reinterpret_cast<nsNSSSocketInfo*>(socket->higher->secret));
 
-  ScopedCERTCertificate serverCert(SSL_PeerCertificate(socket));
+  UniqueCERTCertificate serverCert(SSL_PeerCertificate(socket));
   if (!serverCert) {
     NS_NOTREACHED("Missing server certificate should have been detected during "
                   "server cert authentication.");
     PR_SetError(SSL_ERROR_NO_CERTIFICATE, 0);
     return SECFailure;
   }
 
   if (info->GetJoined()) {
@@ -2081,44 +2082,44 @@ void
 ClientAuthDataRunnable::RunOnTargetThread()
 {
   // We check the value of a pref in this runnable, so this runnable should only
   // be run on the main thread.
   MOZ_ASSERT(NS_IsMainThread());
 
   UniquePLArenaPool arena;
   char** caNameStrings;
-  ScopedCERTCertificate cert;
+  UniqueCERTCertificate cert;
   UniqueSECKEYPrivateKey privKey;
   ScopedCERTCertList certList;
   CERTCertListNode* node;
   UniqueCERTCertNicknames nicknames;
   int keyError = 0; // used for private key retrieval error
   int32_t NumberOfCerts = 0;
   void* wincx = mSocketInfo;
   nsresult rv;
 
   nsCOMPtr<nsIX509Cert> socketClientCert;
   mSocketInfo->GetClientCert(getter_AddRefs(socketClientCert));
 
   // If a client cert preference was set on the socket info, use that and skip
   // the client cert UI and/or search of the user's past cert decisions.
   if (socketClientCert) {
-    cert = socketClientCert->GetCert();
+    cert.reset(socketClientCert->GetCert());
     if (!cert) {
       goto loser;
     }
 
     // Get the private key
     privKey.reset(PK11_FindKeyByAnyCert(cert.get(), wincx));
     if (!privKey) {
       goto loser;
     }
 
-    *mPRetCert = cert.forget();
+    *mPRetCert = cert.release();
     *mPRetKey = privKey.release();
     mRV = SECSuccess;
     return;
   }
 
   // create caNameStrings
   arena.reset(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
   if (!arena) {
@@ -2156,47 +2157,47 @@ ClientAuthDataRunnable::RunOnTargetThrea
     }
 
     // make sure the list is not empty
     node = CERT_LIST_HEAD(certList);
     if (CERT_LIST_END(node, certList)) {
       goto noCert;
     }
 
-    ScopedCERTCertificate low_prio_nonrep_cert;
+    UniqueCERTCertificate lowPrioNonrepCert;
 
     // loop through the list until we find a cert with a key
     while (!CERT_LIST_END(node, certList)) {
       // if the certificate has restriction and we do not satisfy it we do not
       // use it
       privKey.reset(PK11_FindKeyByAnyCert(node->cert, wincx));
       if (privKey) {
         if (hasExplicitKeyUsageNonRepudiation(node->cert)) {
           privKey = nullptr;
-          // Not a prefered cert
-          if (!low_prio_nonrep_cert) { // did not yet find a low prio cert
-            low_prio_nonrep_cert = CERT_DupCertificate(node->cert);
+          // Not a preferred cert
+          if (!lowPrioNonrepCert) { // did not yet find a low prio cert
+            lowPrioNonrepCert.reset(CERT_DupCertificate(node->cert));
           }
         } else {
           // this is a good cert to present
-          cert = CERT_DupCertificate(node->cert);
+          cert.reset(CERT_DupCertificate(node->cert));
           break;
         }
       }
       keyError = PR_GetError();
       if (keyError == SEC_ERROR_BAD_PASSWORD) {
         // problem with password: bail
         goto loser;
       }
 
       node = CERT_LIST_NEXT(node);
     }
 
-    if (!cert && low_prio_nonrep_cert) {
-      cert = low_prio_nonrep_cert.forget();
+    if (!cert && lowPrioNonrepCert) {
+      cert = Move(lowPrioNonrepCert);
       privKey.reset(PK11_FindKeyByAnyCert(cert.get(), wincx));
     }
 
     if (!cert) {
       goto noCert;
     }
   } else { // Not Auto => ask
     // Get the SSL Certificate
@@ -2230,17 +2231,17 @@ ClientAuthDataRunnable::RunOnTargetThrea
           nsCOMPtr<nsIX509Cert> found_cert;
           nsresult find_rv =
             certdb->FindCertByDBKey(rememberedDBKey.get(),
             getter_AddRefs(found_cert));
           if (NS_SUCCEEDED(find_rv) && found_cert) {
             nsNSSCertificate* obj_cert =
               reinterpret_cast<nsNSSCertificate*>(found_cert.get());
             if (obj_cert) {
-              cert = obj_cert->GetCert();
+              cert.reset(obj_cert->GetCert());
             }
           }
 
           if (!cert) {
             hasRemembered = false;
           }
         }
       }
@@ -2390,17 +2391,17 @@ ClientAuthDataRunnable::RunOnTargetThrea
 
       int i;
       if (!canceled)
       for (i = 0, node = CERT_LIST_HEAD(certList);
         !CERT_LIST_END(node, certList);
         ++i, node = CERT_LIST_NEXT(node)) {
 
         if (i == selectedIndex) {
-          cert = CERT_DupCertificate(node->cert);
+          cert.reset(CERT_DupCertificate(node->cert));
           break;
         }
       }
 
       if (cars && wantRemember) {
         cars->RememberDecision(hostname, mServerCert,
           canceled ? nullptr : cert.get());
       }
@@ -2429,17 +2430,17 @@ ClientAuthDataRunnable::RunOnTargetThrea
 noCert:
 loser:
   if (mRV == SECSuccess) {
     mRV = SECFailure;
   }
 done:
   int error = PR_GetError();
 
-  *mPRetCert = cert.forget();
+  *mPRetCert = cert.release();
   *mPRetKey = privKey.release();
 
   if (mRV == SECFailure) {
     mErrorCodeToReport = error;
   }
 }
 
 static PRFileDesc*
--- a/security/manager/ssl/nsPKCS12Blob.cpp
+++ b/security/manager/ssl/nsPKCS12Blob.cpp
@@ -1,40 +1,35 @@
 /* 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/. */
-/* $Id: nsPKCS12Blob.cpp,v 1.49 2007/09/05 07:13:46 jwalden%mit.edu Exp $ */
 
 #include "nsPKCS12Blob.h"
 
-#include "pkix/pkixtypes.h"
-
-#include "prmem.h"
-#include "prprf.h"
-
+#include "ScopedNSSTypes.h"
+#include "nsCRT.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsICertificateDialogs.h"
+#include "nsIDirectoryService.h"
 #include "nsIFile.h"
-#include "nsNetUtil.h"
 #include "nsIInputStream.h"
-#include "nsIDirectoryService.h"
-#include "nsThreadUtils.h"
-
+#include "nsKeygenHandler.h" // For GetSlotWithMechanism
+#include "nsNSSCertificate.h"
 #include "nsNSSComponent.h"
 #include "nsNSSHelper.h"
-#include "nsString.h"
+#include "nsNSSHelper.h"
+#include "nsNSSShutDown.h"
+#include "nsNetUtil.h"
+#include "nsPK11TokenDB.h"
 #include "nsReadableUtils.h"
-#include "nsXPIDLString.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsNSSHelper.h"
-#include "nsNSSCertificate.h"
-#include "nsKeygenHandler.h" //For GetSlotWithMechanism
-#include "nsPK11TokenDB.h"
-#include "nsICertificateDialogs.h"
-#include "nsNSSShutDown.h"
-#include "nsCRT.h"
-
+#include "nsString.h"
+#include "nsThreadUtils.h"
+#include "pkix/pkixtypes.h"
+#include "prmem.h"
+#include "prprf.h"
 #include "secerr.h"
 
 using namespace mozilla;
 extern LazyLogModule gPIPNSSLog;
 
 #define PIP_PKCS12_TMPFILENAME   NS_LITERAL_CSTRING(".pip_p12tmp")
 #define PIP_PKCS12_BUFFER_SIZE   2048
 #define PIP_PKCS12_RESTORE_OK          1
@@ -310,17 +305,17 @@ nsPKCS12Blob::ExportToFile(nsIFile *file
     goto finish;
   }
   // add password integrity
   srv = SEC_PKCS12AddPasswordIntegrity(ecx, &unicodePw, SEC_OID_SHA1);
   if (srv) goto finish;
   for (i=0; i<numCerts; i++) {
     nsNSSCertificate *cert = (nsNSSCertificate *)certs[i];
     // get it as a CERTCertificate XXX
-    ScopedCERTCertificate nssCert(cert->GetCert());
+    UniqueCERTCertificate nssCert(cert->GetCert());
     if (!nssCert) {
       rv = NS_ERROR_FAILURE;
       goto finish;
     }
     // We can only successfully export certs that are on 
     // internal token.  Most, if not all, smart card vendors
     // won't let you extract the private key (in any way
     // shape or form) from the card.  So let's punt if 
--- a/security/manager/ssl/nsSiteSecurityService.cpp
+++ b/security/manager/ssl/nsSiteSecurityService.cpp
@@ -690,17 +690,17 @@ nsSiteSecurityService::ProcessPKPHeader(
   // 2. use this chain to check if things would have broken!
   nsAutoCString host;
   nsresult rv = GetHost(aSourceURI, host);
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIX509Cert> cert;
   rv = aSSLStatus->GetServerCert(getter_AddRefs(cert));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(cert, NS_ERROR_FAILURE);
-  ScopedCERTCertificate nssCert(cert->GetCert());
+  UniqueCERTCertificate nssCert(cert->GetCert());
   NS_ENSURE_TRUE(nssCert, NS_ERROR_FAILURE);
 
   mozilla::pkix::Time now(mozilla::pkix::Now());
   ScopedCERTCertList certList;
   RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
   NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
   if (certVerifier->VerifySSLServerCert(nssCert, nullptr, // stapled ocsp
                                         now, nullptr, // pinarg
--- a/security/manager/ssl/tests/compiled/TestIsCertBuiltInRoot.cpp
+++ b/security/manager/ssl/tests/compiled/TestIsCertBuiltInRoot.cpp
@@ -123,29 +123,29 @@ AddCertificate(char* pem, char* nickname
     return false;
   }
 
   if (!sCertDER) {
     fail("sCertDER didn't get set as expected");
     return false;
   }
 
-  mozilla::ScopedCERTCertificate cert(
+  mozilla::UniqueCERTCertificate cert(
     CERT_NewTempCertificate(CERT_GetDefaultCertDB(), sCertDER, nickname, false,
                             true));
   if (!cert) {
     fail("CERT_NewTempCertificate failed");
     return false;
   }
 
   CERTCertTrust trust;
   trust.sslFlags = 0;
   trust.emailFlags = 0;
   trust.objectSigningFlags = 0;
-  if (CERT_AddTempCertToPerm(cert, nickname, &trust) != SECSuccess) {
+  if (CERT_AddTempCertToPerm(cert.get(), nickname, &trust) != SECSuccess) {
     fail("CERT_AddTempCertToPerm failed");
     return false;
   }
   passed("AddCertificate succeeded");
   return true;
 }
 
 bool
--- a/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp
@@ -112,17 +112,17 @@ DoSNISocketConfig(PRFileDesc* aFd, const
     // a certificate with a matching subject CN.
     return DoSNISocketConfigBySubjectCN(aFd, aSrvNameArr, aSrvNameArrSize);
   }
 
   if (gDebugLevel >= DEBUG_VERBOSE) {
     fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName);
   }
 
-  ScopedCERTCertificate cert;
+  UniqueCERTCertificate cert;
   SSLKEAType certKEA;
   if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, host->mCertName,
                                                     &cert, &certKEA)) {
     return SSL_SNI_SEND_ALERT;
   }
 
   return 0;
 }
--- a/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp
@@ -140,17 +140,17 @@ main(int argc, char* argv[])
 
     OCSPResponseType ORT;
     if (!StringToOCSPResponseType(ocspTypeText, &ORT)) {
       PR_fprintf(PR_STDERR, "Cannot generate OCSP response of type %s\n",
                  ocspTypeText);
       exit(EXIT_FAILURE);
     }
 
-    ScopedCERTCertificate cert(PK11_FindCertFromNickname(certNick, nullptr));
+    UniqueCERTCertificate cert(PK11_FindCertFromNickname(certNick, nullptr));
     if (!cert) {
       PrintPRError("PK11_FindCertFromNickname failed");
       PR_fprintf(PR_STDERR, "Failed to find certificate with nick '%s'\n",
                  certNick);
       exit(EXIT_FAILURE);
     }
 
     SECItemArray* response = GetOCSPResponseForType(ORT, cert, arena,
--- a/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp
@@ -77,17 +77,17 @@ DoSNISocketConfig(PRFileDesc *aFd, const
 
   if (gDebugLevel >= DEBUG_VERBOSE) {
     fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName);
   }
 
   const char *certNickname = host->mServerCertName ? host->mServerCertName
                                                    : DEFAULT_CERT_NICKNAME;
 
-  ScopedCERTCertificate cert;
+  UniqueCERTCertificate cert;
   SSLKEAType certKEA;
   if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, certNickname,
                                                     &cert, &certKEA)) {
     return SSL_SNI_SEND_ALERT;
   }
 
   // If the OCSP response type is "none", don't staple a response.
   if (host->mORT == ORTNone) {
--- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
@@ -22,35 +22,35 @@ TestKeyPair* CreateTestKeyPair(const Tes
 } } } // namespace mozilla::pkix::test
 
 using namespace mozilla;
 using namespace mozilla::pkix;
 using namespace mozilla::pkix::test;
 using namespace mozilla::test;
 
 static TestKeyPair*
-CreateTestKeyPairFromCert(CERTCertificate& cert)
+CreateTestKeyPairFromCert(const UniqueCERTCertificate& cert)
 {
-  UniqueSECKEYPrivateKey privateKey(PK11_FindKeyByAnyCert(&cert, nullptr));
+  UniqueSECKEYPrivateKey privateKey(PK11_FindKeyByAnyCert(cert.get(), nullptr));
   if (!privateKey) {
     return nullptr;
   }
-  ScopedSECKEYPublicKey publicKey(CERT_ExtractPublicKey(&cert));
+  ScopedSECKEYPublicKey publicKey(CERT_ExtractPublicKey(cert.get()));
   if (!publicKey) {
     return nullptr;
   }
   return CreateTestKeyPair(RSA_PKCS1(), *publicKey, privateKey.release());
 }
 
 SECItemArray*
-GetOCSPResponseForType(OCSPResponseType aORT, CERTCertificate* aCert,
+GetOCSPResponseForType(OCSPResponseType aORT, const UniqueCERTCertificate& aCert,
                        const UniquePLArenaPool& aArena,
                        const char* aAdditionalCertName)
 {
-  MOZ_ASSERT(aArena.get());
+  MOZ_ASSERT(aArena);
   MOZ_ASSERT(aCert);
   // Note: |aAdditionalCertName| may or may not need to be non-null depending
   //       on the |aORT| value given.
 
   if (aORT == ORTNone) {
     if (gDebugLevel >= DEBUG_WARNINGS) {
       fprintf(stderr, "GetOCSPResponseForType called with type ORTNone, "
                       "which makes no sense.\n");
@@ -63,28 +63,28 @@ GetOCSPResponseForType(OCSPResponseType 
     arr->items[0].data = nullptr;
     arr->items[0].len = 0;
     return arr;
   }
 
   time_t now = time(nullptr);
   time_t oldNow = now - (8 * Time::ONE_DAY_IN_SECONDS);
 
-  mozilla::ScopedCERTCertificate cert(CERT_DupCertificate(aCert));
+  mozilla::UniqueCERTCertificate cert(CERT_DupCertificate(aCert.get()));
 
   if (aORT == ORTGoodOtherCert) {
-    cert = PK11_FindCertFromNickname(aAdditionalCertName, nullptr);
+    cert.reset(PK11_FindCertFromNickname(aAdditionalCertName, nullptr));
     if (!cert) {
       PrintPRError("PK11_FindCertFromNickname failed");
       return nullptr;
     }
   }
   // XXX CERT_FindCertIssuer uses the old, deprecated path-building logic
-  mozilla::ScopedCERTCertificate
-    issuerCert(CERT_FindCertIssuer(aCert, PR_Now(), certUsageSSLCA));
+  mozilla::UniqueCERTCertificate
+    issuerCert(CERT_FindCertIssuer(aCert.get(), PR_Now(), certUsageSSLCA));
   if (!issuerCert) {
     PrintPRError("CERT_FindCertIssuer failed");
     return nullptr;
   }
   Input issuer;
   if (issuer.Init(cert->derIssuer.data, cert->derIssuer.len) != Success) {
     return nullptr;
   }
@@ -96,21 +96,21 @@ GetOCSPResponseForType(OCSPResponseType 
   Input serialNumber;
   if (serialNumber.Init(cert->serialNumber.data,
                         cert->serialNumber.len) != Success) {
     return nullptr;
   }
   CertID certID(issuer, issuerPublicKey, serialNumber);
   OCSPResponseContext context(certID, now);
 
-  mozilla::ScopedCERTCertificate signerCert;
+  mozilla::UniqueCERTCertificate signerCert;
   if (aORT == ORTGoodOtherCA || aORT == ORTDelegatedIncluded ||
       aORT == ORTDelegatedIncludedLast || aORT == ORTDelegatedMissing ||
       aORT == ORTDelegatedMissingMultiple) {
-    signerCert = PK11_FindCertFromNickname(aAdditionalCertName, nullptr);
+    signerCert.reset(PK11_FindCertFromNickname(aAdditionalCertName, nullptr));
     if (!signerCert) {
       PrintPRError("PK11_FindCertFromNickname failed");
       return nullptr;
     }
   }
 
   ByteString certs[5];
 
@@ -187,19 +187,19 @@ GetOCSPResponseForType(OCSPResponseType 
     extension.next = nullptr;
     context.extensions = &extension;
   }
   if (aORT == ORTEmptyExtensions) {
     context.includeEmptyExtensions = true;
   }
 
   if (!signerCert) {
-    signerCert = CERT_DupCertificate(issuerCert.get());
+    signerCert.reset(CERT_DupCertificate(issuerCert.get()));
   }
-  context.signerKeyPair.reset(CreateTestKeyPairFromCert(*signerCert));
+  context.signerKeyPair.reset(CreateTestKeyPairFromCert(signerCert));
   if (!context.signerKeyPair) {
     PrintPRError("PK11_FindKeyByAnyCert failed");
     return nullptr;
   }
 
   ByteString response(CreateEncodedOCSPResponse(context));
   if (ENCODING_FAILED(response)) {
     PrintPRError("CreateEncodedOCSPResponse failed");
--- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h
@@ -48,13 +48,14 @@ struct OCSPHost
 {
   const char *mHostName;
   OCSPResponseType mORT;
   const char *mAdditionalCertName; // useful for ORTGoodOtherCert, etc.
   const char *mServerCertName;
 };
 
 SECItemArray*
-GetOCSPResponseForType(OCSPResponseType aORT, CERTCertificate* aCert,
+GetOCSPResponseForType(OCSPResponseType aORT,
+                       const mozilla::UniqueCERTCertificate& aCert,
                        const mozilla::UniquePLArenaPool& aArena,
                        const char* aAdditionalCertName);
 
 #endif // OCSPCommon_h
--- a/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp
@@ -5,16 +5,17 @@
 #include "TLSServer.h"
 
 #include <stdio.h>
 #include <string>
 #include <vector>
 
 #include "ScopedNSSTypes.h"
 #include "base64.h"
+#include "mozilla/Move.h"
 #include "mozilla/Snprintf.h"
 #include "nspr.h"
 #include "nss.h"
 #include "plarenas.h"
 #include "prenv.h"
 #include "prerror.h"
 #include "prnetdb.h"
 #include "prtime.h"
@@ -184,32 +185,33 @@ AddCertificateFromFile(const char* baseP
     return rv;
   }
   SECItem certDER;
   rv = CERT_DecodeCertPackage(buf, strlen(buf), DecodeCertCallback, &certDER);
   if (rv != SECSuccess) {
     PrintPRError("CERT_DecodeCertPackage failed");
     return rv;
   }
-  ScopedCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+  UniqueCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                                      &certDER, nullptr, false,
                                                      true));
   PORT_Free(certDER.data);
   if (!cert) {
     PrintPRError("CERT_NewTempCertificate failed");
     return SECFailure;
   }
   ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
   if (!slot) {
     PrintPRError("PK11_GetInternalKeySlot failed");
     return SECFailure;
   }
   // The nickname is the filename without '.pem'.
   std::string nickname(filename, strlen(filename) - 4);
-  rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, nickname.c_str(), false);
+  rv = PK11_ImportCert(slot.get(), cert.get(), CK_INVALID_HANDLE,
+                       nickname.c_str(), false);
   if (rv != SECSuccess) {
     PrintPRError("PK11_ImportCert failed");
     return rv;
   }
   return SECSuccess;
 }
 
 SECStatus
@@ -405,31 +407,31 @@ DoCallback()
     fprintf(stderr, "PR_Recv eof 1\n");
     return 1;
   }
   fprintf(stderr, "%s\n", buf);
   return 0;
 }
 
 SECStatus
-ConfigSecureServerWithNamedCert(PRFileDesc *fd, const char *certName,
-                                /*optional*/ ScopedCERTCertificate *certOut,
-                                /*optional*/ SSLKEAType *keaOut)
+ConfigSecureServerWithNamedCert(PRFileDesc* fd, const char* certName,
+                                /*optional*/ UniqueCERTCertificate* certOut,
+                                /*optional*/ SSLKEAType* keaOut)
 {
-  ScopedCERTCertificate cert(PK11_FindCertFromNickname(certName, nullptr));
+  UniqueCERTCertificate cert(PK11_FindCertFromNickname(certName, nullptr));
   if (!cert) {
     PrintPRError("PK11_FindCertFromNickname failed");
     return SECFailure;
   }
   // If an intermediate certificate issued the server certificate (rather than
   // directly by a trust anchor), we want to send it along in the handshake so
   // we don't encounter unknown issuer errors when that's not what we're
   // testing.
   UniqueCERTCertificateList certList;
-  ScopedCERTCertificate issuerCert(
+  UniqueCERTCertificate issuerCert(
     CERT_FindCertByName(CERT_GetDefaultCertDB(), &cert->derIssuer));
   // If we can't find the issuer cert, continue without it.
   if (issuerCert) {
     // Sadly, CERTCertificateList does not have a CERT_NewCertificateList
     // utility function, so we must create it ourselves. This consists
     // of creating an arena, allocating space for the CERTCertificateList,
     // and then transferring ownership of the arena to that list.
     UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
@@ -464,26 +466,26 @@ ConfigSecureServerWithNamedCert(PRFileDe
   ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
   UniqueSECKEYPrivateKey key(
     PK11_FindKeyByDERCert(slot.get(), cert.get(), nullptr));
   if (!key) {
     PrintPRError("PK11_FindKeyByDERCert failed");
     return SECFailure;
   }
 
-  SSLKEAType certKEA = NSS_FindCertKEAType(cert);
+  SSLKEAType certKEA = NSS_FindCertKEAType(cert.get());
 
   if (SSL_ConfigSecureServerWithCertChain(fd, cert.get(), certList.get(),
                                           key.get(), certKEA) != SECSuccess) {
     PrintPRError("SSL_ConfigSecureServer failed");
     return SECFailure;
   }
 
   if (certOut) {
-    *certOut = cert.forget();
+    *certOut = Move(cert);
   }
 
   if (keaOut) {
     *keaOut = certKEA;
   }
 
   return SECSuccess;
 }
--- a/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h
@@ -39,19 +39,19 @@ extern DebugLevel gDebugLevel;
 void PrintPRError(const char *aPrefix);
 
 // The default certificate is trusted for localhost and *.example.com
 extern const char DEFAULT_CERT_NICKNAME[];
 
 // Pass DEFAULT_CERT_NICKNAME as certName unless you need a specific
 // certificate.
 SECStatus
-ConfigSecureServerWithNamedCert(PRFileDesc *fd, const char *certName,
-                                /*optional*/ ScopedCERTCertificate *cert,
-                                /*optional*/ SSLKEAType *kea);
+ConfigSecureServerWithNamedCert(PRFileDesc* fd, const char* certName,
+                                /*optional*/ UniqueCERTCertificate* cert,
+                                /*optional*/ SSLKEAType* kea);
 
 SECStatus
 InitializeNSS(const char* nssCertDBDir);
 
 int
 StartServer(const char *nssCertDBDir, SSLSNISocketConfig sniSocketConfig,
             void *sniSocketConfigArg);