bug 1311077 - fix builtin root module loading so it works in Android Cpp unit tests r?Cykesiopka draft
authorDavid Keeler <dkeeler@mozilla.com>
Wed, 19 Oct 2016 15:14:23 -0700
changeset 427198 21952c3a9fb8a8b30172ede06f57929ef0f5c8b1
parent 426483 01ab78dd98805e150b0311cce2351d5b408f3001
child 534409 6b479e8662031a150b2b038ff5283b2a33cd1749
push id32954
push userdkeeler@mozilla.com
push dateThu, 20 Oct 2016 00:03:07 +0000
reviewersCykesiopka
bugs1311077
milestone52.0a1
bug 1311077 - fix builtin root module loading so it works in Android Cpp unit tests r?Cykesiopka Also updates the relevant test (TestCertDB) to ensure that we actually are loading builtin root certificates. MozReview-Commit-ID: LXA4TqTzy8T
security/manager/ssl/nsNSSComponent.cpp
security/manager/ssl/tests/compiled/TestCertDB.cpp
security/manager/ssl/tests/compiled/TestIsCertBuiltInRoot.cpp
testing/cppunittest.ini
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -1132,20 +1132,28 @@ nsNSSComponent::LoadLoadableRoots()
     SECMOD_DestroyModule(RootsModule);
     RootsModule = nullptr;
   }
 
   // Find the best Roots module for our purposes.
   // Prefer the application's installation directory,
   // but also ensure the library is at least the version we expect.
 
-  nsresult rv;
   nsAutoString modName;
-  rv = GetPIPNSSBundleString("RootCertModuleName", modName);
-  if (NS_FAILED(rv)) return;
+  nsresult rv = GetPIPNSSBundleString("RootCertModuleName", modName);
+  if (NS_FAILED(rv)) {
+    // When running Cpp unit tests on Android, this will fail because string
+    // bundles aren't available (see bug 1311077, bug 1228175 comment 12, and
+    // bug 929655). Because the module name is really only for display purposes,
+    // we can just hard-code the value here. Furthermore, if we want to be able
+    // to stop using string bundles in PSM in this way, we'll have to hard-code
+    // the string and only use the localized version when displaying it to the
+    // user, so this is a step in that direction anyway.
+    modName.AssignLiteral("Builtin Roots Module");
+  }
 
   nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
   if (!directoryService)
     return;
 
   static const char nss_lib[] = "nss3";
   const char* possible_ckbi_locations[] = {
     nss_lib, // This special value means: search for ckbi in the directory
--- a/security/manager/ssl/tests/compiled/TestCertDB.cpp
+++ b/security/manager/ssl/tests/compiled/TestCertDB.cpp
@@ -1,34 +1,83 @@
 /* -*- 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 "TestHarness.h"
 #include "nsCOMPtr.h"
 #include "nsIPrefService.h"
+#include "nsISimpleEnumerator.h"
+#include "nsIX509Cert.h"
 #include "nsIX509CertDB.h"
+#include "nsIX509CertList.h"
 #include "nsServiceManagerUtils.h"
-#include "TestHarness.h"
 
 int
 main(int argc, char* argv[])
 {
   ScopedXPCOM xpcom("TestCertDB");
+  if (xpcom.failed()) {
+    fail("couldn't initialize XPCOM");
+    return 1;
+  }
   {
     nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
     if (!prefs) {
-      return -1;
+      fail("couldn't get nsIPrefBranch");
+      return 1;
     }
-    // When NSS initializes, it attempts to get some localized strings.
+    // When PSM initializes, it attempts to get some localized strings.
     // As a result, Android flips out if this isn't set.
     nsresult rv = prefs->SetBoolPref("intl.locale.matchOS", true);
     if (NS_FAILED(rv)) {
-      return -1;
+      fail("couldn't set pref 'intl.locale.matchOS'");
+      return 1;
     }
     nsCOMPtr<nsIX509CertDB> certdb(do_GetService(NS_X509CERTDB_CONTRACTID));
     if (!certdb) {
-      return -1;
+      fail("couldn't get certdb");
+      return 1;
+    }
+    nsCOMPtr<nsIX509CertList> certList;
+    rv = certdb->GetCerts(getter_AddRefs(certList));
+    if (NS_FAILED(rv)) {
+      fail("couldn't get list of certificates");
+      return 1;
+    }
+    nsCOMPtr<nsISimpleEnumerator> enumerator;
+    rv = certList->GetEnumerator(getter_AddRefs(enumerator));
+    if (NS_FAILED(rv)) {
+      fail("couldn't enumerate certificate list");
+      return 1;
+    }
+    bool foundBuiltIn = false;
+    bool hasMore = false;
+    while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
+      nsCOMPtr<nsISupports> supports;
+      if (NS_FAILED(enumerator->GetNext(getter_AddRefs(supports)))) {
+        fail("couldn't get next certificate");
+        return 1;
+      }
+      nsCOMPtr<nsIX509Cert> cert(do_QueryInterface(supports));
+      if (!cert) {
+        fail("couldn't QI to nsIX509Cert");
+        return 1;
+      }
+      if (NS_FAILED(cert->GetIsBuiltInRoot(&foundBuiltIn))) {
+        fail("GetIsBuiltInRoot failed");
+        return 1;
+      }
+      if (foundBuiltIn) {
+        break;
+      }
+    }
+    if (foundBuiltIn) {
+      passed("successfully loaded at least one built-in certificate");
+    } else {
+      fail("didn't load any built-in certificates");
+      return 1;
     }
   } // this scopes the nsCOMPtrs
   // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
   return 0;
 }
--- a/security/manager/ssl/tests/compiled/TestIsCertBuiltInRoot.cpp
+++ b/security/manager/ssl/tests/compiled/TestIsCertBuiltInRoot.cpp
@@ -3,16 +3,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/. */
 
 #include "ScopedNSSTypes.h"
 #include "TestHarness.h"
 #include "cert.h"
 #include "certdb.h"
+#include "nsIPrefService.h"
 #include "nsISimpleEnumerator.h"
 #include "nsIX509Cert.h"
 #include "nsIX509CertDB.h"
 #include "nsIX509CertList.h"
 #include "nsServiceManagerUtils.h"
 #include "nss.h"
 #include "prerror.h"
 #include "secerr.h"
@@ -213,16 +214,28 @@ TestIsCertBuiltIn(const char* certDBKey,
 int
 main(int argc, char* argv[])
 {
   ScopedXPCOM xpcom("TestIsCertBuiltInRoot");
   if (xpcom.failed()) {
     fail("couldn't initialize XPCOM");
     return 1;
   }
+  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
+  if (!prefs) {
+    fail("couldn't get nsIPrefBranch");
+    return 1;
+  }
+  // When PSM initializes, it attempts to get some localized strings.
+  // As a result, Android flips out if this isn't set.
+  nsresult rv = prefs->SetBoolPref("intl.locale.matchOS", true);
+  if (NS_FAILED(rv)) {
+    fail("couldn't set pref 'intl.locale.matchOS'");
+    return 1;
+  }
   nsCOMPtr<nsIFile> profileDirectory(xpcom.GetProfileDirectory());
   if (!profileDirectory) {
     fail("couldn't get profile directory");
     return 1;
   }
   nsAutoCString profilePath;
   if (NS_FAILED(profileDirectory->GetNativePath(profilePath))) {
     fail("couldn't get profile path");
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -40,17 +40,16 @@ skip-if = os != 'win'
 [TestFunction]
 [TestGetURL]
 [TestHashtables]
 [TestID]
 [TestInitializerList]
 [TestIntegerPrintfMacros]
 [TestIntegerRange]
 [TestIsCertBuiltInRoot]
-skip-if = os == 'android' # bug 1228175, bug 929655
 [TestJSONWriter]
 [TestJemalloc]
 [TestLineBreak]
 [TestLinkedList]
 [TestMacroArgs]
 [TestMacroForEach]
 [TestMathAlgorithms]
 [TestMaybe]