diff options
Diffstat (limited to 'security/manager/ssl/tests/unit/test_cert_sha1.js')
-rw-r--r-- | security/manager/ssl/tests/unit/test_cert_sha1.js | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/security/manager/ssl/tests/unit/test_cert_sha1.js b/security/manager/ssl/tests/unit/test_cert_sha1.js new file mode 100644 index 000000000..f0d7c570a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1.js @@ -0,0 +1,142 @@ +// -*- 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) { + checkCertErrorGenericAtTime(certdb, cert, expectedResult, + certificateUsageSSLServer, VALIDATION_TIME); +} + +function run_test() { + 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); + checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess); + checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess); + + // SHA-1 forbidden + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 1); + checkEndEntity(certFromFile("ee-pre_int-pre"), SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); + checkEndEntity(certFromFile("ee-post_int-pre"), SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); + 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); + checkEndEntity(certFromFile("ee-pre_int-pre"), SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); + checkEndEntity(certFromFile("ee-post_int-pre"), SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); + 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); + checkEndEntity(certFromFile("ee-pre_int-pre"), SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); + checkEndEntity(certFromFile("ee-post_int-pre"), SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); + 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. + checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess); + 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); + checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + checkEndEntity(certFromFile("ee-post_int-pre"), SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED); + 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. + checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess); + checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess); +} |