summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/tests/unit/test_keysize_ev.js
diff options
context:
space:
mode:
Diffstat (limited to 'security/manager/ssl/tests/unit/test_keysize_ev.js')
-rw-r--r--security/manager/ssl/tests/unit/test_keysize_ev.js146
1 files changed, 146 insertions, 0 deletions
diff --git a/security/manager/ssl/tests/unit/test_keysize_ev.js b/security/manager/ssl/tests/unit/test_keysize_ev.js
new file mode 100644
index 000000000..b6b4ccade
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_keysize_ev.js
@@ -0,0 +1,146 @@
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+"use strict";
+
+// Checks that RSA certs with key sizes below 2048 bits when verifying for EV
+// are rejected.
+
+do_get_profile(); // Must be called before getting nsIX509CertDB
+const certDB = Cc["@mozilla.org/security/x509certdb;1"]
+ .getService(Ci.nsIX509CertDB);
+
+const SERVER_PORT = 8888;
+
+function getOCSPResponder(expectedCertNames) {
+ let expectedPaths = expectedCertNames.slice();
+ return startOCSPResponder(SERVER_PORT, "www.example.com", "test_keysize_ev/",
+ expectedCertNames, expectedPaths);
+}
+
+function loadCert(certName, trustString) {
+ let certFilename = "test_keysize_ev/" + certName + ".pem";
+ addCertFromFile(certDB, certFilename, trustString);
+ return constructCertFromFile(certFilename);
+}
+
+/**
+ * Adds a single EV key size test.
+ *
+ * @param {Array} expectedNamesForOCSP
+ * An array of nicknames of the certs to be responded to.
+ * @param {String} rootCertFileName
+ * The file name of the root cert. Can begin with ".." to reference
+ * certs in folders other than "test_keysize_ev/".
+ * @param {Array} intCertFileNames
+ * An array of file names of any intermediate certificates.
+ * @param {String} endEntityCertFileName
+ * The file name of the end entity cert.
+ * @param {Boolean} expectedResult
+ * Whether the chain is expected to validate as EV.
+ */
+function addKeySizeTestForEV(expectedNamesForOCSP,
+ rootCertFileName, intCertFileNames,
+ endEntityCertFileName, expectedResult)
+{
+ add_test(function() {
+ clearOCSPCache();
+ let ocspResponder = getOCSPResponder(expectedNamesForOCSP);
+
+ loadCert(rootCertFileName, "CTu,CTu,CTu");
+ for (let intCertFileName of intCertFileNames) {
+ loadCert(intCertFileName, ",,");
+ }
+ checkEVStatus(
+ certDB,
+ constructCertFromFile(`test_keysize_ev/${endEntityCertFileName}.pem`),
+ certificateUsageSSLServer,
+ expectedResult);
+
+ ocspResponder.stop(run_next_test);
+ });
+}
+
+/**
+ * For debug builds which have the test EV roots compiled in, checks RSA chains
+ * which contain certs with key sizes adequate for EV are validated as such,
+ * while chains that contain any cert with an inadequate key size fail EV and
+ * validate as DV.
+ * For opt builds which don't have the test EV roots compiled in, checks that
+ * none of the chains validate as EV.
+ *
+ * Note: This function assumes that the key size requirements for EV are greater
+ * than the requirements for DV.
+ *
+ * @param {Number} inadequateKeySize
+ * The inadequate key size of the generated certs.
+ * @param {Number} adequateKeySize
+ * The adequate key size of the generated certs.
+ */
+function checkRSAChains(inadequateKeySize, adequateKeySize) {
+ // Reuse the existing test RSA EV root
+ let rootOKCertFileName = "../test_ev_certs/evroot";
+ let rootOKName = "evroot";
+ let rootNotOKName = "ev_root_rsa_" + inadequateKeySize;
+ let intOKName = "ev_int_rsa_" + adequateKeySize;
+ let intNotOKName = "ev_int_rsa_" + inadequateKeySize;
+ let eeOKName = "ev_ee_rsa_" + adequateKeySize;
+ let eeNotOKName = "ev_ee_rsa_" + inadequateKeySize;
+
+ // Chain with certs that have adequate sizes for EV and DV
+ // In opt builds, this chain is only validated for DV. Hence, an OCSP fetch
+ // will for example not be done for the "ev_int_rsa_2048-evroot" intermediate
+ // in such a build.
+ let intFullName = intOKName + "-" + rootOKName;
+ let eeFullName = eeOKName + "-" + intOKName + "-" + rootOKName;
+ let expectedNamesForOCSP = gEVExpected
+ ? [ intFullName,
+ eeFullName ]
+ : [ eeFullName ];
+ addKeySizeTestForEV(expectedNamesForOCSP, rootOKCertFileName,
+ [ intFullName ], eeFullName, gEVExpected);
+
+ // Chain with a root cert that has an inadequate size for EV, but
+ // adequate size for DV
+ intFullName = intOKName + "-" + rootNotOKName;
+ eeFullName = eeOKName + "-" + intOKName + "-" + rootNotOKName;
+ expectedNamesForOCSP = [ eeFullName ];
+ addKeySizeTestForEV(expectedNamesForOCSP, rootNotOKName,
+ [ intFullName ], eeFullName, false);
+
+ // Chain with an intermediate cert that has an inadequate size for EV, but
+ // adequate size for DV
+ intFullName = intNotOKName + "-" + rootOKName;
+ eeFullName = eeOKName + "-" + intNotOKName + "-" + rootOKName;
+ expectedNamesForOCSP = [ eeFullName ];
+ addKeySizeTestForEV(expectedNamesForOCSP, rootOKCertFileName,
+ [ intFullName ], eeFullName, false);
+
+ // Chain with an end entity cert that has an inadequate size for EV, but
+ // adequate size for DV
+ intFullName = intOKName + "-" + rootOKName;
+ eeFullName = eeNotOKName + "-" + intOKName + "-" + rootOKName;
+ expectedNamesForOCSP = gEVExpected
+ ? [ intFullName,
+ eeFullName ]
+ : [ eeFullName ];
+ addKeySizeTestForEV(expectedNamesForOCSP, rootOKCertFileName,
+ [ intFullName ], eeFullName, false);
+}
+
+function run_test() {
+ Services.prefs.setCharPref("network.dns.localDomains", "www.example.com");
+ Services.prefs.setIntPref("security.OCSP.enabled", 1);
+
+ let smallKeyEVRoot =
+ constructCertFromFile("test_keysize_ev/ev_root_rsa_2040.pem");
+ equal(smallKeyEVRoot.sha256Fingerprint,
+ "49:46:10:F4:F5:B1:96:E7:FB:FA:4D:A6:34:03:D0:99:" +
+ "22:D4:77:20:3F:84:E0:DF:1C:AD:B4:C2:76:BB:63:24",
+ "test sanity check: the small-key EV root must have the same " +
+ "fingerprint as the corresponding entry in ExtendedValidation.cpp");
+
+ checkRSAChains(2040, 2048);
+
+ run_next_test();
+}