Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

// -*- 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";
do_get_profile(); // must be called before getting nsIX509CertDB
registerCleanupFunction(() => {
Services.prefs.clearUserPref("security.pki.certificate_transparency.mode");
Services.prefs.clearUserPref("security.test.built_in_root_hash");
let cert = constructCertFromFile("test_ct/ct-valid.example.com.pem");
setCertTrust(cert, ",,");
});
function add_tests_in_mode(mode) {
add_test(function set_mode() {
info(`setting CT to mode ${mode}`);
Services.prefs.setIntPref(
"security.pki.certificate_transparency.mode",
mode
);
run_next_test();
});
// Test that certificate transparency is not checked for certificates issued
// by roots that are not built-in.
add_ct_test(
"ct-unknown-log.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE,
true
);
add_test(function set_test_root_as_built_in() {
// Make the test root appear to be a built-in root, so that certificate
// transparency is checked.
let rootCert = constructCertFromFile("test_ct/test-ca.pem");
Services.prefs.setCharPref(
"security.test.built_in_root_hash",
rootCert.sha256Fingerprint
);
run_next_test();
});
// These certificates have a validity period of 800 days, which is greater
// than 180 days. Our policy requires 3 embedded SCTs for certificates with a
// validity period greater than 180 days.
add_ct_test(
"ct-valid.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT,
true
);
// This certificate has only 2 embedded SCTs, and so is not policy-compliant.
add_ct_test(
"ct-insufficient-scts.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
mode == CT_MODE_COLLECT_TELEMETRY
);
// Test that SCTs with timestamps from the future are not valid.
add_ct_test(
"ct-future-timestamp.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
mode == CT_MODE_COLLECT_TELEMETRY
);
// Test that additional SCTs from the same log do not contribute to meeting
// the requirements.
add_ct_test(
"ct-multiple-from-same-log.example.com",
Ci.nsITransportSecurityInfo
.CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS,
mode == CT_MODE_COLLECT_TELEMETRY
);
// Test that SCTs from an unknown log do not contribute to meeting the
// requirements.
add_ct_test(
"ct-unknown-log.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
mode == CT_MODE_COLLECT_TELEMETRY
);
add_ct_test(
"no-ct.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
mode == CT_MODE_COLLECT_TELEMETRY
);
add_test(function set_disable_ct_for_hosts_pref() {
// Disable CT enforcement for exactly 'ct-unknown-log.example.com' as well
// as 'sub.example.com' and all subdomains under 'sub.example.com'.
// CT will still be checked, and the security info of the connection will say
// the information is insufficient, but the connection will still succeed
// (essentially, it behaves like telemetry-only mode).
Services.prefs.setCharPref(
"security.pki.certificate_transparency.disable_for_hosts",
".ct-unknown-log.example.com,no-ct.example.com"
);
clearSessionCache();
run_next_test();
});
add_ct_test(
"ct-unknown-log.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
true
);
add_ct_test(
"sub.ct-unknown-log.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
mode == CT_MODE_COLLECT_TELEMETRY
);
add_ct_test(
"no-ct.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
true
);
add_ct_test(
"sub.no-ct.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
true
);
add_ct_test(
"ct-insufficient-scts.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
mode == CT_MODE_COLLECT_TELEMETRY
);
add_test(function reset_disable_ct_for_hosts_pref() {
Services.prefs.clearUserPref(
"security.pki.certificate_transparency.disable_for_hosts"
);
clearSessionCache();
run_next_test();
});
add_test(function set_disable_ct_for_spki_hashes_pref_nonexistent_keys() {
// Disable CT enforcement for two SPKIs we don't actually have the private
// key for.
Services.prefs.setCharPref(
"security.pki.certificate_transparency.disable_for_spki_hashes",
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=,BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB="
);
clearSessionCache();
run_next_test();
});
add_ct_test(
"ct-insufficient-scts.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
mode == CT_MODE_COLLECT_TELEMETRY
);
add_test(function set_disable_ct_for_spki_hashes_pref() {
// Disable CT enforcement for the default test key's SPKI.
// Again, the behavior will be that of telemetry-only mode.
Services.prefs.setCharPref(
"security.pki.certificate_transparency.disable_for_spki_hashes",
"CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC=,VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8="
);
clearSessionCache();
run_next_test();
});
add_ct_test(
"ct-insufficient-scts.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
true
);
add_test(function set_disable_ct_for_spki_hashes_pref_alternate() {
// Disable CT enforcement for the alternate test key's SPKI.
Services.prefs.setCharPref(
"security.pki.certificate_transparency.disable_for_spki_hashes",
"MQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJI=,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD="
);
clearSessionCache();
run_next_test();
});
add_ct_test(
"no-ct.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
true
);
add_test(function reset_disable_ct_for_spki_hashes_pref() {
Services.prefs.clearUserPref(
"security.pki.certificate_transparency.disable_for_spki_hashes"
);
clearSessionCache();
run_next_test();
});
// Test that if an end-entity is marked as a trust anchor, CT verification
// returns a "not enough SCTs" result.
add_test(function set_up_end_entity_trust_anchor_test() {
let cert = constructCertFromFile("test_ct/ct-valid.example.com.pem");
Services.prefs.setCharPref(
"security.test.built_in_root_hash",
cert.sha256Fingerprint
);
setCertTrust(cert, "CTu,,");
clearSessionCache();
run_next_test();
});
add_ct_test(
"ct-valid.example.com",
Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS,
mode == CT_MODE_COLLECT_TELEMETRY
);
add_test(function reset_for_next_test_mode() {
Services.prefs.clearUserPref("security.test.built_in_root_hash");
let cert = constructCertFromFile("test_ct/ct-valid.example.com.pem");
setCertTrust(cert, "u,,");
clearSessionCache();
run_next_test();
});
}
function run_test() {
add_tls_server_setup("BadCertAndPinningServer", "test_ct");
add_tests_in_mode(CT_MODE_COLLECT_TELEMETRY);
add_tests_in_mode(CT_MODE_ENFORCE);
run_next_test();
}