bug 1085509 - fix nsCertOverrideService so its initialization doesn't depend on NSS r=mmc
authorDavid Keeler <dkeeler@mozilla.com>
Fri, 24 Oct 2014 10:46:30 -0700
changeset 213229 70af2ce2bdfcaa38c60bde30ffc3e1ae2b881ffc
parent 213228 339521504f276c1d4519bb46491ed350409e63e0
child 213230 c1d47db66068f2ffca07bba4b6a473899d797dce
push id27745
push usercbook@mozilla.com
push dateFri, 31 Oct 2014 13:09:12 +0000
treeherdermozilla-central@6bd2071b373f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmmc
bugs1085509
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1085509 - fix nsCertOverrideService so its initialization doesn't depend on NSS r=mmc
security/manager/ssl/src/nsCertOverrideService.cpp
security/manager/ssl/src/nsNSSModule.cpp
--- a/security/manager/ssl/src/nsCertOverrideService.cpp
+++ b/security/manager/ssl/src/nsCertOverrideService.cpp
@@ -1,39 +1,33 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * 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 "nsCertOverrideService.h"
 
-#include "pkix/pkixtypes.h"
-#include "nsIX509Cert.h"
 #include "NSSCertDBTrustDomain.h"
-#include "nsNSSCertificate.h"
-#include "nsNSSCertHelper.h"
+#include "ScopedNSSTypes.h"
+#include "SharedSSLState.h"
+#include "nsAppDirectoryServiceDefs.h"
 #include "nsCRT.h"
-#include "nsAppDirectoryServiceDefs.h"
-#include "nsStreamUtils.h"
-#include "nsNetUtil.h"
 #include "nsILineInputStream.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
-#include "nsISupportsPrimitives.h"
+#include "nsIX509Cert.h"
+#include "nsNSSCertHelper.h"
+#include "nsNSSCertificate.h"
+#include "nsNSSComponent.h"
+#include "nsNetUtil.h"
 #include "nsPromiseFlatString.h"
-#include "nsThreadUtils.h"
+#include "nsStreamUtils.h"
 #include "nsStringBuffer.h"
-#include "ScopedNSSTypes.h"
-#include "SharedSSLState.h"
-
-#include "nspr.h"
-#include "pk11pub.h"
-#include "certdb.h"
-#include "sechash.h"
+#include "nsThreadUtils.h"
 #include "ssl.h" // For SSL_ClearSessionCache
 
 using namespace mozilla;
 using namespace mozilla::psm;
 
 static const char kCertOverrideFileName[] = "cert_override.txt";
 
 void
@@ -101,28 +95,21 @@ nsCertOverrideService::~nsCertOverrideSe
 nsresult
 nsCertOverrideService::Init()
 {
   if (!NS_IsMainThread()) {
     NS_NOTREACHED("nsCertOverrideService initialized off main thread");
     return NS_ERROR_NOT_SAME_THREAD;
   }
 
+  // Note that the names of these variables would seem to indicate that at one
+  // point another hash algorithm was used and is still supported for backwards
+  // compatibility. This is not the case. It has always been SHA256.
   mOidTagForStoringNewHashes = SEC_OID_SHA256;
-
-  SECOidData *od = SECOID_FindOIDByTag(mOidTagForStoringNewHashes);
-  if (!od)
-    return NS_ERROR_FAILURE;
-
-  char *dotted_oid = CERT_GetOidString(&od->oid);
-  if (!dotted_oid)
-    return NS_ERROR_FAILURE;
-
-  mDottedOidForStoringNewHashes = dotted_oid;
-  PR_smprintf_free(dotted_oid);
+  mDottedOidForStoringNewHashes.Assign("OID.2.16.840.1.101.3.4.2.1");
 
   nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
 
   // If we cannot add ourselves as a profile change observer, then we will not
   // attempt to read/write any settings file. Otherwise, we would end up
   // reading/writing the wrong settings file after a profile change.
   if (observerService) {
@@ -393,52 +380,16 @@ GetCertFingerprintByOidTag(nsIX509Cert *
 
   ScopedCERTCertificate nsscert(aCert->GetCert());
   if (!nsscert) {
     return NS_ERROR_FAILURE;
   }
   return GetCertFingerprintByOidTag(nsscert.get(), aOidTag, fp);
 }
 
-static nsresult
-GetCertFingerprintByDottedOidString(CERTCertificate* nsscert,
-                                    const nsCString &dottedOid, 
-                                    nsCString &fp)
-{
-  SECItem oid;
-  oid.data = nullptr;
-  oid.len = 0;
-  SECStatus srv = SEC_StringToOID(nullptr, &oid, 
-                    dottedOid.get(), dottedOid.Length());
-  if (srv != SECSuccess)
-    return NS_ERROR_FAILURE;
-
-  SECOidTag oid_tag = SECOID_FindOIDTag(&oid);
-  SECITEM_FreeItem(&oid, false);
-
-  if (oid_tag == SEC_OID_UNKNOWN)
-    return NS_ERROR_FAILURE;
-
-  return GetCertFingerprintByOidTag(nsscert, oid_tag, fp);
-}
-
-static nsresult
-GetCertFingerprintByDottedOidString(nsIX509Cert *aCert,
-                                    const nsCString &dottedOid,
-                                    nsCString &fp)
-{
-
-  ScopedCERTCertificate nsscert(aCert->GetCert());
-  if (!nsscert) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return GetCertFingerprintByDottedOidString(nsscert.get(), dottedOid, fp);
-}
-
 NS_IMETHODIMP
 nsCertOverrideService::RememberValidityOverride(const nsACString& aHostName,
                                                 int32_t aPort,
                                                 nsIX509Cert* aCert,
                                                 uint32_t aOverrideBits,
                                                 bool aTemporary)
 {
   NS_ENSURE_ARG_POINTER(aCert);
@@ -541,24 +492,27 @@ nsCertOverrideService::HasMatchingOverri
   }
 
   *aOverrideBits = settings.mOverrideBits;
   *aIsTemporary = settings.mIsTemporary;
 
   nsAutoCString fpStr;
   nsresult rv;
 
+  // This code was originally written in a way that suggested that other hash
+  // algorithms are supported for backwards compatibility. However, this was
+  // always unnecessary, because only SHA256 has ever been used here.
   if (settings.mFingerprintAlgOID.Equals(mDottedOidForStoringNewHashes)) {
     rv = GetCertFingerprintByOidTag(aCert, mOidTagForStoringNewHashes, fpStr);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+  } else {
+    return NS_ERROR_UNEXPECTED;
   }
-  else {
-    rv = GetCertFingerprintByDottedOidString(aCert, settings.mFingerprintAlgOID, fpStr);
-  }
-  if (NS_FAILED(rv))
-    return rv;
 
   *_retval = settings.mFingerprint.Equals(fpStr);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCertOverrideService::GetValidityOverride(const nsACString & aHostName, int32_t aPort,
                                            nsACString & aHashAlg, 
@@ -644,17 +598,23 @@ nsCertOverrideService::ClearValidityOver
   }
   nsAutoCString hostPort;
   GetHostWithPort(aHostName, aPort, hostPort);
   {
     ReentrantMonitorAutoEnter lock(monitor);
     mSettingsTable.RemoveEntry(hostPort.get());
     Write();
   }
-  SSL_ClearSessionCache();
+
+  if (EnsureNSSInitialized(nssEnsure)) {
+    SSL_ClearSessionCache();
+  } else {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCertOverrideService::GetAllOverrideHostsWithPorts(uint32_t *aCount, 
                                                         char16_t ***aHostsWithPortsArray)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
@@ -733,25 +693,21 @@ FindMatchingCertCallback(nsCertOverrideE
     if ((settings.mIsTemporary && !cai->aCheckTemporaries)
         ||
         (!settings.mIsTemporary && !cai->aCheckPermanents)) {
       still_ok = false;
     }
 
     if (still_ok && matchesDBKey(cai->cert, settings.mDBKey.get())) {
       nsAutoCString cert_fingerprint;
-      nsresult rv;
+      nsresult rv = NS_ERROR_UNEXPECTED;
       if (settings.mFingerprintAlgOID.Equals(cai->mDottedOidForStoringNewHashes)) {
         rv = GetCertFingerprintByOidTag(cai->cert,
                cai->mOidTagForStoringNewHashes, cert_fingerprint);
       }
-      else {
-        rv = GetCertFingerprintByDottedOidString(cai->cert,
-               settings.mFingerprintAlgOID, cert_fingerprint);
-      }
       if (NS_SUCCEEDED(rv) &&
           settings.mFingerprint.Equals(cert_fingerprint)) {
         cai->counter++;
       }
     }
   }
 
   return PL_DHASH_NEXT;
@@ -803,25 +759,21 @@ EnumerateCertOverridesCallback(nsCertOve
     const nsCertOverride &settings = aEntry->mSettings;
 
     if (!capac->cert) {
       (*capac->enumerator)(settings, capac->userdata);
     }
     else {
       if (matchesDBKey(capac->cert, settings.mDBKey.get())) {
         nsAutoCString cert_fingerprint;
-        nsresult rv;
+        nsresult rv = NS_ERROR_UNEXPECTED;
         if (settings.mFingerprintAlgOID.Equals(capac->mDottedOidForStoringNewHashes)) {
           rv = GetCertFingerprintByOidTag(capac->cert,
                  capac->mOidTagForStoringNewHashes, cert_fingerprint);
         }
-        else {
-          rv = GetCertFingerprintByDottedOidString(capac->cert,
-                 settings.mFingerprintAlgOID, cert_fingerprint);
-        }
         if (NS_SUCCEEDED(rv) &&
             settings.mFingerprint.Equals(cert_fingerprint)) {
           (*capac->enumerator)(settings, capac->userdata);
         }
       }
     }
   }
 
@@ -855,9 +807,8 @@ nsCertOverrideService::GetHostWithPort(c
     aPort = 443;
   }
   if (!hostPort.IsEmpty()) {
     hostPort.Append(':');
     hostPort.AppendInt(aPort);
   }
   _retval.Assign(hostPort);
 }
-
--- a/security/manager/ssl/src/nsNSSModule.cpp
+++ b/security/manager/ssl/src/nsNSSModule.cpp
@@ -194,24 +194,24 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEn
 NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCertPicker)
 NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsNTLMAuthModule, InitTest)
 NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCryptoHash)
 NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsCryptoHMAC)
 NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsStreamCipher)
 NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsKeyObject)
 NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsKeyObjectFactory)
 NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsDataSignatureVerifier)
-NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsCertOverrideService, Init)
 NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsRandomGenerator)
 NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsSSLStatus)
 NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, TransportSecurityInfo)
 
 typedef mozilla::psm::NSSErrorsService NSSErrorsService;
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(NSSErrorsService, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsNSSVersion)
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCertOverrideService, Init)
 
 NS_DEFINE_NAMED_CID(NS_NSSCOMPONENT_CID);
 NS_DEFINE_NAMED_CID(NS_SSLSOCKETPROVIDER_CID);
 NS_DEFINE_NAMED_CID(NS_STARTTLSSOCKETPROVIDER_CID);
 NS_DEFINE_NAMED_CID(NS_SDR_CID);
 NS_DEFINE_NAMED_CID(NS_PK11TOKENDB_CID);
 NS_DEFINE_NAMED_CID(NS_PKCS11MODULEDB_CID);
 NS_DEFINE_NAMED_CID(NS_PSMCONTENTLISTEN_CID);