bug 1427273 - don't require importing the server certificate for overrides to succeed r?jcj draft
authorDavid Keeler <dkeeler@mozilla.com>
Thu, 04 Jan 2018 11:31:22 -0800
changeset 716472 4ee4a434f23bf5b394a3099a17e28167f5964ac9
parent 716325 81362f7306fe413b19fdba27cd0e9a5525d902e1
child 745052 161b96d740792f51fc5eb3e752a098eed7fe84db
push id94456
push userbmo:dkeeler@mozilla.com
push dateFri, 05 Jan 2018 22:13:41 +0000
reviewersjcj
bugs1427273
milestone59.0a1
bug 1427273 - don't require importing the server certificate for overrides to succeed r?jcj Previously, adding a permanent certificate error override would depend on successfully importing the server's certificate into the user's certificate database. Consequently, if the user's database were in read-only mode (or if the database couldn't be created due to code page issues on Windows), this would prevent adding new certificate error overrides. It turns out this isn't even necessary, because the implementation relies on the stored hash of the certificate rather than the certificate itself. The stored certificate is only for display purposes (and there's a fallback if the certificate can't be stored). There are remaining issues with non-ASCII characters in 8.3 paths on Windows when the code page isn't western, but this is a larger issue that must be addressed in other layers (i.e. NSS/NSPR). MozReview-Commit-ID: KEzjxtAoeb4
security/manager/ssl/nsCertOverrideService.cpp
security/manager/ssl/tests/unit/head_psm.js
security/manager/ssl/tests/unit/test_cert_overrides_read_only.js
security/manager/ssl/tests/unit/test_cert_overrides_read_only/cert9.db
security/manager/ssl/tests/unit/test_cert_overrides_read_only/key4.db
security/manager/ssl/tests/unit/xpcshell.ini
--- a/security/manager/ssl/nsCertOverrideService.cpp
+++ b/security/manager/ssl/nsCertOverrideService.cpp
@@ -6,16 +6,17 @@
 
 #include "nsCertOverrideService.h"
 
 #include "NSSCertDBTrustDomain.h"
 #include "ScopedNSSTypes.h"
 #include "SharedSSLState.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Telemetry.h"
+#include "mozilla/Unused.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsCRT.h"
 #include "nsILineInputStream.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIOutputStream.h"
 #include "nsISafeOutputStream.h"
 #include "nsIX509Cert.h"
@@ -373,21 +374,23 @@ nsCertOverrideService::RememberValidityO
   nsAutoCString nickname;
   nsresult rv = DefaultServerNicknameForCert(nsscert.get(), nickname);
   if (!aTemporary && NS_SUCCEEDED(rv)) {
     UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
     if (!slot) {
       return NS_ERROR_FAILURE;
     }
 
-    SECStatus srv = PK11_ImportCert(slot.get(), nsscert.get(), CK_INVALID_HANDLE,
-                                    nickname.get(), false);
-    if (srv != SECSuccess) {
-      return NS_ERROR_FAILURE;
-    }
+    // This can fail (for example, if we're in read-only mode). Luckily, we
+    // don't even need it to succeed - we always match on the stored hash of the
+    // certificate rather than the full certificate. It makes the display a bit
+    // less informative (since we won't have a certificate to display), but it's
+    // better than failing the entire operation.
+    Unused << PK11_ImportCert(slot.get(), nsscert.get(), CK_INVALID_HANDLE,
+                              nickname.get(), false);
   }
 
   nsAutoCString fpStr;
   rv = GetCertFingerprintByOidTag(nsscert.get(), mOidTagForStoringNewHashes,
                                   fpStr);
   if (NS_FAILED(rv))
     return rv;
 
--- a/security/manager/ssl/tests/unit/head_psm.js
+++ b/security/manager/ssl/tests/unit/head_psm.js
@@ -334,19 +334,19 @@ function run_test() {
                       function(aTransport) { ... });
   [...]
   add_connection_test("<test-name-n>.example.com", PRErrorCodeSuccess);
 
   run_next_test();
 }
 */
 
-function add_tls_server_setup(serverBinName, certsPath) {
+function add_tls_server_setup(serverBinName, certsPath, addDefaultRoot = true) {
   add_test(function() {
-    _setupTLSServerTest(serverBinName, certsPath);
+    _setupTLSServerTest(serverBinName, certsPath, addDefaultRoot);
   });
 }
 
 /**
  * Add a TLS connection test case.
  *
  * @param {String} aHost
  *   The hostname to pass in the SNI TLS extension; this should unambiguously
@@ -486,21 +486,23 @@ function _getBinaryUtil(binaryUtilName) 
     utilBin.initWithPath("/data/local/xpcb/");
     utilBin.append(binaryUtilName);
   }
   Assert.ok(utilBin.exists(), `Binary util ${binaryUtilName} should exist`);
   return utilBin;
 }
 
 // Do not call this directly; use add_tls_server_setup
-function _setupTLSServerTest(serverBinName, certsPath) {
+function _setupTLSServerTest(serverBinName, certsPath, addDefaultRoot) {
   let certdb = Cc["@mozilla.org/security/x509certdb;1"]
                   .getService(Ci.nsIX509CertDB);
   // The trusted CA that is typically used for "good" certificates.
-  addCertFromFile(certdb, `${certsPath}/test-ca.pem`, "CTu,u,u");
+  if (addDefaultRoot) {
+    addCertFromFile(certdb, `${certsPath}/test-ca.pem`, "CTu,u,u");
+  }
 
   const CALLBACK_PORT = 8444;
 
   let envSvc = Cc["@mozilla.org/process/environment;1"]
                  .getService(Ci.nsIEnvironment);
   let greBinDir = Services.dirsvc.get("GreBinD", Ci.nsIFile);
   envSvc.set("DYLD_LIBRARY_PATH", greBinDir.path);
   // TODO(bug 1107794): Android libraries are in /data/local/xpcb, but "GreBinD"
copy from security/manager/ssl/tests/unit/test_cert_overrides.js
copy to security/manager/ssl/tests/unit/test_cert_overrides_read_only.js
--- a/security/manager/ssl/tests/unit/test_cert_overrides.js
+++ b/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js
@@ -1,352 +1,93 @@
 // -*- indent-tabs-mode: nil; js-indent-level: 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/.
 "use strict";
 
-// Tests the certificate overrides we allow.
-// add_cert_override_test will queue a test that does the following:
-// 1. Attempt to connect to the given host. This should fail with the
-//    given error and override bits.
-// 2. Add an override for that host/port/certificate/override bits.
-// 3. Connect again. This should succeed.
-
-do_get_profile();
+// Tests that permanent certificate error overrides can be added even if the
+// certificate/key databases are in read-only mode.
 
-function check_telemetry() {
-  let histogram = Services.telemetry
-                    .getHistogramById("SSL_CERT_ERROR_OVERRIDES")
-                    .snapshot();
-  equal(histogram.counts[0], 0, "Should have 0 unclassified counts");
-  equal(histogram.counts[2], 9,
-        "Actual and expected SEC_ERROR_UNKNOWN_ISSUER counts should match");
-  equal(histogram.counts[3], 1,
-        "Actual and expected SEC_ERROR_CA_CERT_INVALID counts should match");
-  equal(histogram.counts[4], 0,
-        "Actual and expected SEC_ERROR_UNTRUSTED_ISSUER counts should match");
-  equal(histogram.counts[5], 1,
-        "Actual and expected SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE counts should match");
-  equal(histogram.counts[6], 0,
-        "Actual and expected SEC_ERROR_UNTRUSTED_CERT counts should match");
-  equal(histogram.counts[7], 0,
-        "Actual and expected SEC_ERROR_INADEQUATE_KEY_USAGE counts should match");
-  equal(histogram.counts[8], 2,
-        "Actual and expected SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED counts should match");
-  equal(histogram.counts[9], 13,
-        "Actual and expected SSL_ERROR_BAD_CERT_DOMAIN counts should match");
-  equal(histogram.counts[10], 5,
-        "Actual and expected SEC_ERROR_EXPIRED_CERTIFICATE counts should match");
-  equal(histogram.counts[11], 2,
-        "Actual and expected MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY counts should match");
-  equal(histogram.counts[12], 1,
-        "Actual and expected MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA counts should match");
-  equal(histogram.counts[13], 1,
-        "Actual and expected MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE counts should match");
-  equal(histogram.counts[14], 2,
-        "Actual and expected MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE counts should match");
-  equal(histogram.counts[15], 1,
-        "Actual and expected MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE counts should match");
-  equal(histogram.counts[16], 2,
-        "Actual and expected SEC_ERROR_INVALID_TIME counts should match");
-  equal(histogram.counts[17], 1,
-        "Actual and expected MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME counts should match");
+// Helper function for add_read_only_cert_override_test. Probably doesn't need
+// to be called directly.
+function add_read_only_cert_override(aHost, aExpectedBits, aSecurityInfo) {
+  let sslstatus = aSecurityInfo.QueryInterface(Ci.nsISSLStatusProvider)
+                               .SSLStatus;
+  let bits =
+    (sslstatus.isUntrusted ? Ci.nsICertOverrideService.ERROR_UNTRUSTED : 0) |
+    (sslstatus.isDomainMismatch ? Ci.nsICertOverrideService.ERROR_MISMATCH : 0) |
+    (sslstatus.isNotValidAtThisTime ? Ci.nsICertOverrideService.ERROR_TIME : 0);
 
-  let keySizeHistogram = Services.telemetry
-                           .getHistogramById("CERT_CHAIN_KEY_SIZE_STATUS")
-                           .snapshot();
-  equal(keySizeHistogram.counts[0], 0,
-        "Actual and expected unchecked key size counts should match");
-  equal(keySizeHistogram.counts[1], 16,
-        "Actual and expected successful verifications of 2048-bit keys should match");
-  equal(keySizeHistogram.counts[2], 0,
-        "Actual and expected successful verifications of 1024-bit keys should match");
-  equal(keySizeHistogram.counts[3], 60,
-        "Actual and expected verification failures unrelated to key size should match");
-
-  run_next_test();
+  Assert.equal(bits, aExpectedBits,
+               "Actual and expected override bits should match");
+  let cert = sslstatus.serverCert;
+  let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
+                              .getService(Ci.nsICertOverrideService);
+  // Setting the last argument to false here ensures that we attempt to store a
+  // permanent override (which is what was failing in bug 1427273).
+  certOverrideService.rememberValidityOverride(aHost, 8443, cert, aExpectedBits,
+                                               false);
 }
 
-// Internally, specifying "port" -1 is the same as port 443. This tests that.
-function run_port_equivalency_test(inPort, outPort) {
-  Assert.ok((inPort == 443 && outPort == -1) || (inPort == -1 && outPort == 443),
-            "The two specified ports must be -1 and 443 (in any order)");
-  let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
-                              .getService(Ci.nsICertOverrideService);
-  let cert = constructCertFromFile("bad_certs/default-ee.pem");
-  let expectedBits = Ci.nsICertOverrideService.ERROR_UNTRUSTED;
-  let expectedTemporary = true;
-  certOverrideService.rememberValidityOverride("example.com", inPort, cert,
-                                               expectedBits, expectedTemporary);
-  let actualBits = {};
-  let actualTemporary = {};
-  Assert.ok(certOverrideService.hasMatchingOverride("example.com", outPort,
-                                                    cert, actualBits,
-                                                    actualTemporary),
-            `override set on port ${inPort} should match port ${outPort}`);
-  equal(actualBits.value, expectedBits,
-        "input override bits should match output bits");
-  equal(actualTemporary.value, expectedTemporary,
-        "input override temporary value should match output temporary value");
-  Assert.ok(!certOverrideService.hasMatchingOverride("example.com", 563,
-                                                     cert, {}, {}),
-            `override set on port ${inPort} should not match port 563`);
-  certOverrideService.clearValidityOverride("example.com", inPort);
-  Assert.ok(!certOverrideService.hasMatchingOverride("example.com", outPort,
-                                                     cert, actualBits, {}),
-            `override cleared on port ${inPort} should match port ${outPort}`);
-  equal(actualBits.value, 0, "should have no bits set if there is no override");
+// Given a host, expected error bits (see nsICertOverrideService.idl), and an
+// expected error code, tests that an initial connection to the host fails with
+// the expected errors and that adding an override results in a subsequent
+// connection succeeding.
+function add_read_only_cert_override_test(aHost, aExpectedBits, aExpectedError) {
+  add_connection_test(aHost, aExpectedError, null,
+                      add_read_only_cert_override.bind(this, aHost, aExpectedBits));
+  add_connection_test(aHost, PRErrorCodeSuccess, null, aSecurityInfo => {
+    Assert.ok(aSecurityInfo.securityState &
+              Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN,
+              "Cert override flag should be set on the security state");
+  });
 }
 
 function run_test() {
-  run_port_equivalency_test(-1, 443);
-  run_port_equivalency_test(443, -1);
+  let profile = do_get_profile();
+  const KEY_DB_NAME = "key4.db";
+  const CERT_DB_NAME = "cert9.db";
+  let srcKeyDBFile = do_get_file(`test_cert_overrides_read_only/${KEY_DB_NAME}`);
+  srcKeyDBFile.copyTo(profile, KEY_DB_NAME);
+  let srcCertDBFile = do_get_file(`test_cert_overrides_read_only/${CERT_DB_NAME}`);
+  srcCertDBFile.copyTo(profile, CERT_DB_NAME);
+
+  // set the databases to read-only
+  let keyDBFile = do_get_profile();
+  keyDBFile.append(KEY_DB_NAME);
+  keyDBFile.permissions = 0o400;
+  let certDBFile = do_get_profile();
+  certDBFile.append(CERT_DB_NAME);
+  certDBFile.permissions = 0o400;
 
   Services.prefs.setIntPref("security.OCSP.enabled", 1);
-  add_tls_server_setup("BadCertServer", "bad_certs");
+  // Specifying false as the last argument means we don't try to add the default
+  // test root CA (which would fail).
+  add_tls_server_setup("BadCertServer", "bad_certs", false);
 
   let fakeOCSPResponder = new HttpServer();
   fakeOCSPResponder.registerPrefixHandler("/", function (request, response) {
     response.setStatusLine(request.httpVersion, 500, "Internal Server Error");
   });
   fakeOCSPResponder.start(8888);
 
-  add_simple_tests();
-  add_localhost_tests();
-  add_combo_tests();
-  add_distrust_tests();
+  // Since we can't add the root CA to the (read-only) trust db, all of these
+  // will result in an "unknown issuer error" and need the "untrusted" error bit
+  // set in addition to whatever other specific error bits are necessary.
+  add_read_only_cert_override_test("expired.example.com",
+                         Ci.nsICertOverrideService.ERROR_TIME |
+                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
+                         SEC_ERROR_UNKNOWN_ISSUER);
+  add_read_only_cert_override_test("selfsigned.example.com",
+                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
+                         SEC_ERROR_UNKNOWN_ISSUER);
+  add_read_only_cert_override_test("mismatch.example.com",
+                         Ci.nsICertOverrideService.ERROR_MISMATCH |
+                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
+                         SEC_ERROR_UNKNOWN_ISSUER);
 
   add_test(function () {
-    fakeOCSPResponder.stop(check_telemetry);
+    fakeOCSPResponder.stop(run_next_test);
   });
 
   run_next_test();
 }
-
-function add_simple_tests() {
-  add_cert_override_test("expired.example.com",
-                         Ci.nsICertOverrideService.ERROR_TIME,
-                         SEC_ERROR_EXPIRED_CERTIFICATE);
-  add_cert_override_test("notyetvalid.example.com",
-                         Ci.nsICertOverrideService.ERROR_TIME,
-                         MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE);
-  add_cert_override_test("before-epoch.example.com",
-                         Ci.nsICertOverrideService.ERROR_TIME,
-                         SEC_ERROR_INVALID_TIME);
-  add_cert_override_test("selfsigned.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         SEC_ERROR_UNKNOWN_ISSUER);
-  add_cert_override_test("unknownissuer.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         SEC_ERROR_UNKNOWN_ISSUER);
-  add_cert_override_test("expiredissuer.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE);
-  add_cert_override_test("notyetvalidissuer.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE);
-  add_cert_override_test("before-epoch-issuer.example.com",
-                         Ci.nsICertOverrideService.ERROR_TIME,
-                         SEC_ERROR_INVALID_TIME);
-  add_cert_override_test("md5signature.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
-  add_cert_override_test("emptyissuername.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME);
-  // This has name information in the subject alternative names extension,
-  // but not the subject common name.
-  add_cert_override_test("mismatch.example.com",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH,
-                         SSL_ERROR_BAD_CERT_DOMAIN,
-                         /The certificate is only valid for the following names:\s*doesntmatch\.example\.com, \*\.alsodoesntmatch\.example\.com/);
-  // This has name information in the subject common name but not the subject
-  // alternative names extension.
-  add_cert_override_test("mismatch-CN.example.com",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH,
-                         SSL_ERROR_BAD_CERT_DOMAIN,
-                         /The certificate is not valid for the name mismatch-CN\.example\.com/);
-
-  // A Microsoft IIS utility generates self-signed certificates with
-  // properties similar to the one this "host" will present.
-  add_cert_override_test("selfsigned-inadequateEKU.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         SEC_ERROR_UNKNOWN_ISSUER);
-
-  add_prevented_cert_override_test("inadequatekeyusage.example.com",
-                                   Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                                   SEC_ERROR_INADEQUATE_KEY_USAGE);
-
-  // This is intended to test the case where a verification has failed for one
-  // overridable reason (e.g. unknown issuer) but then, in the process of
-  // reporting that error, a non-overridable error is encountered. The
-  // non-overridable error should be prioritized.
-  add_test(function() {
-    let rootCert = constructCertFromFile("bad_certs/test-ca.pem");
-    setCertTrust(rootCert, ",,");
-    run_next_test();
-  });
-  add_prevented_cert_override_test("nsCertTypeCritical.example.com",
-                                   Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                                   SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
-  add_test(function() {
-    let rootCert = constructCertFromFile("bad_certs/test-ca.pem");
-    setCertTrust(rootCert, "CTu,,");
-    run_next_test();
-  });
-
-  // Bug 990603: Apache documentation has recommended generating a self-signed
-  // test certificate with basic constraints: CA:true. For compatibility, this
-  // is a scenario in which an override is allowed.
-  add_cert_override_test("self-signed-end-entity-with-cA-true.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         SEC_ERROR_UNKNOWN_ISSUER);
-
-  add_cert_override_test("ca-used-as-end-entity.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY);
-
-  // If an X.509 version 1 certificate is not a trust anchor, we will
-  // encounter an overridable error.
-  add_cert_override_test("end-entity-issued-by-v1-cert.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA);
-  // If we make that certificate a trust anchor, the connection will succeed.
-  add_test(function() {
-    let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
-                                .getService(Ci.nsICertOverrideService);
-    certOverrideService.clearValidityOverride("end-entity-issued-by-v1-cert.example.com", 8443);
-    let v1Cert = constructCertFromFile("bad_certs/v1Cert.pem");
-    setCertTrust(v1Cert, "CTu,,");
-    clearSessionCache();
-    run_next_test();
-  });
-  add_connection_test("end-entity-issued-by-v1-cert.example.com",
-                      PRErrorCodeSuccess);
-  // Reset the trust for that certificate.
-  add_test(function() {
-    let v1Cert = constructCertFromFile("bad_certs/v1Cert.pem");
-    setCertTrust(v1Cert, ",,");
-    clearSessionCache();
-    run_next_test();
-  });
-
-  // Due to compatibility issues, we allow overrides for certificates issued by
-  // certificates that are not valid CAs.
-  add_cert_override_test("end-entity-issued-by-non-CA.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         SEC_ERROR_CA_CERT_INVALID);
-
-  // This host presents a 1016-bit RSA key.
-  add_cert_override_test("inadequate-key-size-ee.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE);
-
-  add_cert_override_test("ipAddressAsDNSNameInSAN.example.com",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH,
-                         SSL_ERROR_BAD_CERT_DOMAIN);
-  add_cert_override_test("noValidNames.example.com",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH,
-                         SSL_ERROR_BAD_CERT_DOMAIN,
-                         /The certificate is not valid for the name noValidNames\.example\.com/);
-  add_cert_override_test("badSubjectAltNames.example.com",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH,
-                         SSL_ERROR_BAD_CERT_DOMAIN);
-
-  add_cert_override_test("bug413909.xn--hxajbheg2az3al.xn--jxalpdlp",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         SEC_ERROR_UNKNOWN_ISSUER);
-  add_test(function() {
-    // At this point, the override for bug413909.xn--hxajbheg2az3al.xn--jxalpdlp
-    // is still valid. Do some additional tests relating to IDN handling.
-    let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
-                                .getService(Ci.nsICertOverrideService);
-    let uri = Services.io.newURI("https://bug413909.xn--hxajbheg2az3al.xn--jxalpdlp");
-    let cert = constructCertFromFile("bad_certs/idn-certificate.pem");
-    Assert.ok(certOverrideService.hasMatchingOverride(uri.asciiHost, 8443, cert, {}, {}),
-              "IDN certificate should have matching override using ascii host");
-    Assert.ok(!certOverrideService.hasMatchingOverride(uri.displayHost, 8443, cert, {}, {}),
-              "IDN certificate should not have matching override using (non-ascii) host");
-    run_next_test();
-  });
-}
-
-function add_localhost_tests() {
-  add_cert_override_test("localhost",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH |
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         SEC_ERROR_UNKNOWN_ISSUER);
-  add_cert_override_test("127.0.0.1",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH,
-                         SSL_ERROR_BAD_CERT_DOMAIN);
-  add_cert_override_test("::1",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH,
-                         SSL_ERROR_BAD_CERT_DOMAIN);
-}
-
-function add_combo_tests() {
-  add_cert_override_test("mismatch-expired.example.com",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH |
-                         Ci.nsICertOverrideService.ERROR_TIME,
-                         SSL_ERROR_BAD_CERT_DOMAIN,
-                         /The certificate is only valid for <a id="cert_domain_link" title="doesntmatch\.example\.com">doesntmatch\.example\.com<\/a>/);
-  add_cert_override_test("mismatch-notYetValid.example.com",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH |
-                         Ci.nsICertOverrideService.ERROR_TIME,
-                         SSL_ERROR_BAD_CERT_DOMAIN);
-  add_cert_override_test("mismatch-untrusted.example.com",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH |
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         SEC_ERROR_UNKNOWN_ISSUER);
-  add_cert_override_test("untrusted-expired.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED |
-                         Ci.nsICertOverrideService.ERROR_TIME,
-                         SEC_ERROR_UNKNOWN_ISSUER);
-  add_cert_override_test("mismatch-untrusted-expired.example.com",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH |
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED |
-                         Ci.nsICertOverrideService.ERROR_TIME,
-                         SEC_ERROR_UNKNOWN_ISSUER);
-
-  add_cert_override_test("md5signature-expired.example.com",
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED |
-                         Ci.nsICertOverrideService.ERROR_TIME,
-                         SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
-
-  add_cert_override_test("ca-used-as-end-entity-name-mismatch.example.com",
-                         Ci.nsICertOverrideService.ERROR_MISMATCH |
-                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                         MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY);
-}
-
-function add_distrust_tests() {
-  // Before we specifically distrust this certificate, it should be trusted.
-  add_connection_test("untrusted.example.com", PRErrorCodeSuccess);
-
-  add_distrust_test("bad_certs/default-ee.pem", "untrusted.example.com",
-                    SEC_ERROR_UNTRUSTED_CERT);
-
-  add_distrust_test("bad_certs/other-test-ca.pem",
-                    "untrustedissuer.example.com", SEC_ERROR_UNTRUSTED_ISSUER);
-
-  add_distrust_test("bad_certs/test-ca.pem",
-                    "ca-used-as-end-entity.example.com",
-                    SEC_ERROR_UNTRUSTED_ISSUER);
-}
-
-function add_distrust_test(certFileName, hostName, expectedResult) {
-  let certToDistrust = constructCertFromFile(certFileName);
-
-  add_test(function () {
-    // Add an entry to the NSS certDB that says to distrust the cert
-    setCertTrust(certToDistrust, "pu,,");
-    clearSessionCache();
-    run_next_test();
-  });
-  add_prevented_cert_override_test(hostName,
-                                   Ci.nsICertOverrideService.ERROR_UNTRUSTED,
-                                   expectedResult);
-  add_test(function () {
-    setCertTrust(certToDistrust, "u,,");
-    run_next_test();
-  });
-}
new file mode 100644
index 0000000000000000000000000000000000000000..3d452f335c286da96cd47711ed7bcbb92ed9f841
GIT binary patch
literal 28672
zc%1FmQA^uU6bJA`YdY46J`Bp(L-V-87|FfKZTd2-TA|EU?JCTNAxRsdTc^ynuurhP
z?OW|_Ut-^4kIVgE%~ki{lMKrL2RWSN-g9z{8pyk&{mDG{&n_-Mr*mIAn~v)`TfXl&
zj$0g6$670n%8hf^xu5I2dir~P<B#LjD$bLQji0q&wQse(TIK#yA|fIpqKC2NdG&h3
zJ(--3^RJ^%>12F9n;kB)>10&h8FV|tuHWnLcHjG0^AGxdx$eJ6!$34&uc5;+I!x0n
zpO!nkTOF`=w}Wi%R=oQ2hWi2avqknXAI-}hYqvUFt^PYj*zBx&^=H>V$7D8J<d@}^
z%B?15@otYKY<`z+wccpBKjL|sP4jZKOjfS?3_IKV-J8|LgE<`Z-gX8j{+sTJf86gK
z9e4E|b`JV``@Nl^-`PGG3}5<bP#j@#h~khs#|3>Q)Rz){n&{I6r+P~g=@9FnbZF_2
z=+M?7)gdcF8?6Ep(J>H+<~|W(jHnP>hzVjFF-6P}M;OeEXXZmLOpeY1odr4zbQb6=
z&{?3fM3qF9M3qF9M3us-!m7fm!m2W>=&8`Ng`J6sc!KyzMPPDWD==*o6a+@TO7X0*
zTVl7w?kF(3%|>%YB1VWYqP};8yGFQcgx^by+8DKQV6N!eQ69@k#-UAxO>b<7Y#Q5C
z*|cTTq)e49Q?^XmGG)uub(yl`C_9d_<0w0hvg0T_j<Vw@J5G_dZJOFNv+2mDW1HqS
zJu6fEA(%9?<79fAahwL@3{N}>z&>BqZiXvfz1wgd^ZNKQExzba)5ZJ(=cnaA>1kM|
ztHo>Yk$(5B>#+G>U%x~|L_|bHMD)NO>%i}SA|fIpA|j%t#_xY3A|fIpBBJHT?|&j9
hA|fIpqUFc$e<C6xA|fK9<;U-TA|fIpA|j&Y_ZNs~P}%?h
new file mode 100644
index 0000000000000000000000000000000000000000..44d0cb172812d17b8f8de88bce066142d1c0cf2f
GIT binary patch
literal 36864
zc%1Fr&u`mg7zc1WKio7~)gC6Ifim9Q8rZ<`k2j9kVQK0?MAvqq6P;j+?8K7-={g!0
zxNz7G+XZol3rGG9rU`_`PUFOlX-5u#HZ-`+@8f1qs|{_JX(IZ56hC?F_kEu{wcE6A
zrM`D&Wf(`|!uHNq5DQyd&~#lpDTJnJnPi*Qn2~I`efzrhbQ$f9!*}N9|IrG?P3=%|
z{zmDC(if$-iVupL#UGzxJpcdz0Q^skW@gHjihlX^I0#44Rul)zK^#n;3+=Ao+VI6j
zYiY$7lcQpBI1uaI&goY7oOstiC(f>R&Ybnd+Nx-;t)5!xv^PZ8Utejp{bM5esdcNK
zK3TOl3r4wJ(Y4{lLG=0flTmWC7wpE{wBMW5@6{*S?2=)W%T@gYn$Z6^7!EFu$Ll-8
zPlGs`*=w$|y6kTX8dNRt1hE*@O{;b?Pc`1B8lxbLMm)thP=f{^t6|qp<&5$xRlS$C
zy&HZM^<$orKTu<D_z9iVYwfI2J~H`ehU4*Ww8L|92g;<Qk5%#NwQEwJDOaodR}H#k
zJj_|<z-8NC;OQ5xwY1jVI3@x!*^=uPSjlFqoDQfXb#=&7yPn$hXje_~92Hy@qzVlc
zJQbQM1S*6{Xi_ONja1RJD5kIDP;@CuiVcb$#U{moVo0%1jiv3S{ZVeEIaRi(vPG3G
zs%%kZiz-`G*``%Ct+HvAO{;8LC23UBsH9OzqcR<(nv!ZZXr`A&I)n6)T4tK7wH9^j
zm<fwo-b?9R(`=h&+ceuT)7k07^oUK-q3BXnukFyQI`pazT^E<uy0q3c(<5qaKXPry
zcI%v4obH?8aO!d@Ic;$2JxV1nle|pwGRe#2WSQi4B)22E9m(xTZbx!ElG~BoPLeh`
z4LA)s?Q=TdG~)Eaqm(`o(lq3DLe<W|4a`AEXWTOhpI_Om*%_n!cJ;sB{P?T1SLZyN
zyhRt(`}CX&3orCr1poj500000JZD7}aQ_bg0000005H{X{|^8F00000F#T}<4*&oF
z0000m{c!&e00000001!kaQ_bg0000005JX3|NqzLztxfl000000002I7(G2-aV{4w
z1>^B&+dG4Aelj%wrB^@v`{weW-@W|rm9Nj=KX0Be7md<uSKqn%U`{`j*R$r4+~J>p
z`Q!NQqnB=7zm>fmHitJ)-?^91=z4D9MrZfh_i^LI-7oL`_Um7Fe^-D1*XQqR$pZiY
S000000H#POTbZ5wM&TjL;kpt4
--- a/security/manager/ssl/tests/unit/xpcshell.ini
+++ b/security/manager/ssl/tests/unit/xpcshell.ini
@@ -5,16 +5,17 @@ support-files =
   bad_certs/**
   ocsp_certs/**
   test_baseline_requirements/**
   test_broken_fips/**
   test_cert_eku/**
   test_cert_embedded_null/**
   test_cert_isBuiltInRoot_reload/**
   test_cert_keyUsage/**
+  test_cert_overrides_read_only/**
   test_cert_sha1/**
   test_cert_signatures/**
   test_cert_trust/**
   test_cert_version/**
   test_certDB_import/**
   test_certviewer_invalid_oids/**
   test_content_signing/**
   test_ct/**
@@ -52,16 +53,18 @@ run-sequentially = hardcoded ports
 [test_cert_dbKey.js]
 [test_cert_eku.js]
 [test_cert_embedded_null.js]
 [test_cert_keyUsage.js]
 [test_cert_isBuiltInRoot.js]
 [test_cert_isBuiltInRoot_reload.js]
 [test_cert_overrides.js]
 run-sequentially = hardcoded ports
+[test_cert_overrides_read_only.js]
+run-sequentially = hardcoded ports
 [test_cert_override_bits_mismatches.js]
 run-sequentially = hardcoded ports
 [test_cert_sha1.js]
 [test_cert_signatures.js]
 [test_cert_trust.js]
 [test_cert_version.js]
 [test_certDB_import.js]
 [test_certDB_import_pkcs12.js]