summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/tests/unit/test_crlite_preexisting.js
diff options
context:
space:
mode:
Diffstat (limited to 'security/manager/ssl/tests/unit/test_crlite_preexisting.js')
-rw-r--r--security/manager/ssl/tests/unit/test_crlite_preexisting.js208
1 files changed, 208 insertions, 0 deletions
diff --git a/security/manager/ssl/tests/unit/test_crlite_preexisting.js b/security/manager/ssl/tests/unit/test_crlite_preexisting.js
new file mode 100644
index 0000000000..c788a11b54
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_crlite_preexisting.js
@@ -0,0 +1,208 @@
+// -*- 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/.
+
+// Tests that starting a profile with a preexisting CRLite filter and stash
+// works correctly.
+
+"use strict";
+
+add_task(async function test_preexisting_crlite_data() {
+ Services.prefs.setIntPref(
+ "security.pki.crlite_mode",
+ CRLiteModeEnforcePrefValue
+ );
+
+ let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService(
+ Ci.nsICertStorage
+ );
+
+ let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
+ Ci.nsIX509CertDB
+ );
+ // These need to be available to be able to find them during path building
+ // for certificate verification.
+ let issuerCert = constructCertFromFile("test_crlite_filters/issuer.pem");
+ ok(issuerCert, "issuer certificate should decode successfully");
+ let noSCTCertIssuer = constructCertFromFile(
+ "test_crlite_filters/no-sct-issuer.pem"
+ );
+ ok(
+ noSCTCertIssuer,
+ "issuer certificate for certificate without SCTs should decode successfully"
+ );
+
+ let validCert = constructCertFromFile("test_crlite_filters/valid.pem");
+ let revokedCert = constructCertFromFile("test_crlite_filters/revoked.pem");
+
+ // We didn't load a data.bin file, so the filter is not considered fresh and
+ // we should get a "no filter" result. We later test that CRLite considers
+ // this cert to be revoked. So success here shows that CRLite is not
+ // consulted when the filter is stale.
+ await checkCertErrorGenericAtTime(
+ certdb,
+ revokedCert,
+ PRErrorCodeSuccess,
+ certificateUsageSSLServer,
+ new Date("2020-10-20T00:00:00Z").getTime() / 1000,
+ false,
+ "us-datarecovery.com",
+ Ci.nsIX509CertDB.FLAG_LOCAL_ONLY
+ );
+
+ // Add an empty stash to ensure the filter is considered to be fresh.
+ await new Promise(resolve => {
+ certStorage.addCRLiteStash(new Uint8Array([]), (rv, _) => {
+ Assert.equal(rv, Cr.NS_OK, "marked filter as fresh");
+ resolve();
+ });
+ });
+
+ // NB: by not specifying Ci.nsIX509CertDB.FLAG_LOCAL_ONLY, this tests that
+ // the implementation does not fall back to OCSP fetching, because if it
+ // did, the implementation would attempt to connect to a server outside the
+ // test infrastructure, which would result in a crash in the test
+ // environment, which would be treated as a test failure.
+ await checkCertErrorGenericAtTime(
+ certdb,
+ validCert,
+ PRErrorCodeSuccess,
+ certificateUsageSSLServer,
+ new Date("2020-10-20T00:00:00Z").getTime() / 1000,
+ false,
+ "vpn.worldofspeed.org",
+ 0
+ );
+
+ // NB: by not specifying Ci.nsIX509CertDB.FLAG_LOCAL_ONLY, this tests that
+ // the implementation does not fall back to OCSP fetching, because if it
+ // did, the implementation would attempt to connect to a server outside the
+ // test infrastructure, which would result in a crash in the test
+ // environment, which would be treated as a test failure.
+ await checkCertErrorGenericAtTime(
+ certdb,
+ validCert,
+ PRErrorCodeSuccess,
+ certificateUsageSSLServer,
+ new Date("2020-10-20T00:00:00Z").getTime() / 1000,
+ false,
+ "vpn.worldofspeed.org",
+ 0
+ );
+
+ await checkCertErrorGenericAtTime(
+ certdb,
+ revokedCert,
+ SEC_ERROR_REVOKED_CERTIFICATE,
+ certificateUsageSSLServer,
+ new Date("2020-10-20T00:00:00Z").getTime() / 1000,
+ false,
+ "us-datarecovery.com",
+ 0
+ );
+
+ let revokedInStashCert = constructCertFromFile(
+ "test_crlite_filters/revoked-in-stash.pem"
+ );
+ // The stash may not have loaded yet, so await a task that ensures the stash
+ // loading task has completed.
+ await new Promise(resolve => {
+ certStorage.hasPriorData(
+ Ci.nsICertStorage.DATA_TYPE_CRLITE_FILTER_INCREMENTAL,
+ (rv, _) => {
+ Assert.equal(rv, Cr.NS_OK, "hasPriorData should succeed");
+ resolve();
+ }
+ );
+ });
+ await checkCertErrorGenericAtTime(
+ certdb,
+ revokedInStashCert,
+ SEC_ERROR_REVOKED_CERTIFICATE,
+ certificateUsageSSLServer,
+ new Date("2020-10-20T00:00:00Z").getTime() / 1000,
+ false,
+ "stokedmoto.com",
+ 0
+ );
+
+ let revokedInStash2Cert = constructCertFromFile(
+ "test_crlite_filters/revoked-in-stash-2.pem"
+ );
+ await checkCertErrorGenericAtTime(
+ certdb,
+ revokedInStash2Cert,
+ SEC_ERROR_REVOKED_CERTIFICATE,
+ certificateUsageSSLServer,
+ new Date("2020-10-20T00:00:00Z").getTime() / 1000,
+ false,
+ "icsreps.com",
+ 0
+ );
+
+ // This certificate has no embedded SCTs, so it is not guaranteed to be in
+ // CT, so CRLite can't be guaranteed to give the correct answer, so it is
+ // not consulted, and the implementation falls back to OCSP. Since the real
+ // OCSP responder can't be reached, this results in a
+ // SEC_ERROR_OCSP_SERVER_ERROR.
+ let noSCTCert = constructCertFromFile("test_crlite_filters/no-sct.pem");
+ // NB: this will cause an OCSP request to be sent to localhost:80, but
+ // since an OCSP responder shouldn't be running on that port, this should
+ // fail safely.
+ Services.prefs.setCharPref("network.dns.localDomains", "ocsp.digicert.com");
+ Services.prefs.setBoolPref("security.OCSP.require", true);
+ Services.prefs.setIntPref("security.OCSP.enabled", 1);
+ await checkCertErrorGenericAtTime(
+ certdb,
+ noSCTCert,
+ SEC_ERROR_OCSP_SERVER_ERROR,
+ certificateUsageSSLServer,
+ new Date("2020-10-20T00:00:00Z").getTime() / 1000,
+ false,
+ "mail233.messagelabs.com",
+ 0
+ );
+ Services.prefs.clearUserPref("network.dns.localDomains");
+ Services.prefs.clearUserPref("security.OCSP.require");
+ Services.prefs.clearUserPref("security.OCSP.enabled");
+
+ let notCoveredCert = constructCertFromFile(
+ "test_crlite_filters/notcovered.pem"
+ );
+ await checkCertErrorGenericAtTime(
+ certdb,
+ notCoveredCert,
+ PRErrorCodeSuccess,
+ certificateUsageSSLServer,
+ new Date("2022-01-07T00:00:00Z").getTime() / 1000,
+ false,
+ "peekaboophonics.com",
+ Ci.nsIX509CertDB.FLAG_LOCAL_ONLY
+ );
+});
+
+function run_test() {
+ let securityStateDirectory = do_get_profile();
+ securityStateDirectory.append("security_state");
+ // For simplicity, re-use the filter from test_crlite_filters.js.
+ let crilteFile = do_get_file("test_crlite_filters/20201017-0-filter");
+ crilteFile.copyTo(securityStateDirectory, "crlite.filter");
+ // This stash file and the following cert storage file were obtained by
+ // running just the task `test_crlite_filters_and_check_revocation` in
+ // test_crlite_filters.js, causing it to hang (by adding something like
+ // `add_test(() => {});`), and then copying the files from the temporary
+ // profile directory.
+ let stashFile = do_get_file("test_crlite_preexisting/crlite.stash");
+ stashFile.copyTo(securityStateDirectory, "crlite.stash");
+ let coverageFile = do_get_file("test_crlite_preexisting/crlite.coverage");
+ coverageFile.copyTo(securityStateDirectory, "crlite.coverage");
+ let enrollmentFile = do_get_file("test_crlite_preexisting/crlite.enrollment");
+ enrollmentFile.copyTo(securityStateDirectory, "crlite.enrollment");
+ let certStorageFile = do_get_file(
+ "test_crlite_preexisting/crlite.enrollment"
+ );
+ certStorageFile.copyTo(securityStateDirectory, "crlite.enrollment");
+
+ run_next_test();
+}