forked from mirrors/gecko-dev
208 lines
7.2 KiB
JavaScript
208 lines
7.2 KiB
JavaScript
// -*- 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();
|
|
}
|