forked from mirrors/gecko-dev
# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D35928 --HG-- extra : source : 4e926f91b17c2b13cdaf13e017629286275dbc00
187 lines
7.1 KiB
JavaScript
187 lines
7.1 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 the rejection of SHA-1 certificates based on the preference
|
|
// security.pki.sha1_enforcement_level.
|
|
|
|
"use strict";
|
|
|
|
do_get_profile(); // must be called before getting nsIX509CertDB
|
|
const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
|
|
Ci.nsIX509CertDB
|
|
);
|
|
|
|
// We need to test as if we are at a fixed time, so that we are testing the
|
|
// 2016 checks on SHA-1, not the notBefore checks.
|
|
//
|
|
// (new Date("2016-03-01")).getTime() / 1000
|
|
const VALIDATION_TIME = 1456790400;
|
|
|
|
function certFromFile(certName) {
|
|
return constructCertFromFile("test_cert_sha1/" + certName + ".pem");
|
|
}
|
|
|
|
function loadCertWithTrust(certName, trustString) {
|
|
addCertFromFile(certdb, "test_cert_sha1/" + certName + ".pem", trustString);
|
|
}
|
|
|
|
function checkEndEntity(cert, expectedResult) {
|
|
return checkCertErrorGenericAtTime(
|
|
certdb,
|
|
cert,
|
|
expectedResult,
|
|
certificateUsageSSLServer,
|
|
VALIDATION_TIME
|
|
);
|
|
}
|
|
|
|
add_task(async function() {
|
|
loadCertWithTrust("ca", "CTu,,");
|
|
loadCertWithTrust("int-pre", ",,");
|
|
loadCertWithTrust("int-post", ",,");
|
|
|
|
// Test cases per pref setting
|
|
//
|
|
// root intermed. end entity
|
|
// ===========================
|
|
// root
|
|
// |
|
|
// +--- pre-2016
|
|
// | |
|
|
// | +----- pre-2016 <--- (a)
|
|
// | +----- post-2016 <--- (b)
|
|
// |
|
|
// +--- post-2016
|
|
// |
|
|
// +----- post-2016 <--- (c)
|
|
//
|
|
// Expected outcomes (accept / reject):
|
|
//
|
|
// a b c
|
|
// Allowed (0) Accept Accept Accept
|
|
// Forbidden (1) Reject Reject Reject
|
|
// (2) is no longer available and is treated as Forbidden (1) internally.
|
|
// ImportedRoot (3) Reject Reject Reject (for built-in roots)
|
|
// ImportedRoot Accept Accept Accept (for non-built-in roots)
|
|
// ImportedRootOrBefore2016 (4) Accept Reject Reject (for built-in roots)
|
|
// ImportedRootOrBefore2016 Accept Accept Accept (for non-built-in roots)
|
|
//
|
|
// The pref setting of ImportedRoot accepts usage of SHA-1 only for
|
|
// certificates issued by non-built-in roots. By default, the testing
|
|
// certificates are all considered issued by a non-built-in root. However, we
|
|
// have the ability to treat a given non-built-in root as built-in. We test
|
|
// both of these situations below.
|
|
//
|
|
// As a historical note, a policy option (Before2016) was previously available
|
|
// that only allowed SHA-1 for certificates with a notBefore before 2016.
|
|
// However, to enable the policy of only allowing SHA-1 from non-built-in
|
|
// roots in the most straightforward way (while still having a time-based
|
|
// policy that users could enable if this new policy were problematic),
|
|
// Before2016 was shifted to also allow SHA-1 from non-built-in roots, hence
|
|
// ImportedRootOrBefore2016.
|
|
//
|
|
// A note about intermediate certificates: the certificate verifier has the
|
|
// ability to directly verify a given certificate for the purpose of issuing
|
|
// TLS web server certificates. However, when asked to do so, the certificate
|
|
// verifier does not take into account the currently configured SHA-1 policy.
|
|
// This is in part due to implementation complexity and because this isn't
|
|
// actually how TLS web server certificates are verified in the TLS handshake
|
|
// (which makes a full implementation that supports heeding the SHA-1 policy
|
|
// unnecessary).
|
|
|
|
// SHA-1 allowed
|
|
Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 0);
|
|
await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess);
|
|
await checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess);
|
|
await checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess);
|
|
|
|
// SHA-1 forbidden
|
|
Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 1);
|
|
await checkEndEntity(
|
|
certFromFile("ee-pre_int-pre"),
|
|
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
|
);
|
|
await checkEndEntity(
|
|
certFromFile("ee-post_int-pre"),
|
|
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
|
);
|
|
await checkEndEntity(
|
|
certFromFile("ee-post_int-post"),
|
|
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
|
);
|
|
|
|
// SHA-1 forbidden (test the case where the pref has been set to 2)
|
|
Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 2);
|
|
await checkEndEntity(
|
|
certFromFile("ee-pre_int-pre"),
|
|
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
|
);
|
|
await checkEndEntity(
|
|
certFromFile("ee-post_int-pre"),
|
|
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
|
);
|
|
await checkEndEntity(
|
|
certFromFile("ee-post_int-post"),
|
|
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
|
);
|
|
|
|
// SHA-1 allowed only when issued by an imported root. First test with the
|
|
// test root considered a built-in (on debug only - this functionality is
|
|
// disabled on non-debug builds).
|
|
Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 3);
|
|
if (isDebugBuild) {
|
|
let root = certFromFile("ca");
|
|
Services.prefs.setCharPref(
|
|
"security.test.built_in_root_hash",
|
|
root.sha256Fingerprint
|
|
);
|
|
await checkEndEntity(
|
|
certFromFile("ee-pre_int-pre"),
|
|
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
|
);
|
|
await checkEndEntity(
|
|
certFromFile("ee-post_int-pre"),
|
|
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
|
);
|
|
await checkEndEntity(
|
|
certFromFile("ee-post_int-post"),
|
|
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
|
);
|
|
Services.prefs.clearUserPref("security.test.built_in_root_hash");
|
|
}
|
|
|
|
// SHA-1 still allowed only when issued by an imported root.
|
|
// Now test with the test root considered a non-built-in.
|
|
await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess);
|
|
await checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess);
|
|
await checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess);
|
|
|
|
// SHA-1 allowed before 2016 or when issued by an imported root. First test
|
|
// with the test root considered a built-in.
|
|
Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 4);
|
|
if (isDebugBuild) {
|
|
let root = certFromFile("ca");
|
|
Services.prefs.setCharPref(
|
|
"security.test.built_in_root_hash",
|
|
root.sha256Fingerprint
|
|
);
|
|
await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess);
|
|
await checkEndEntity(
|
|
certFromFile("ee-post_int-pre"),
|
|
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
|
);
|
|
await checkEndEntity(
|
|
certFromFile("ee-post_int-post"),
|
|
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
|
);
|
|
Services.prefs.clearUserPref("security.test.built_in_root_hash");
|
|
}
|
|
|
|
// SHA-1 still only allowed before 2016 or when issued by an imported root.
|
|
// Now test with the test root considered a non-built-in.
|
|
await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess);
|
|
await checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess);
|
|
await checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess);
|
|
});
|