1 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
2 // Any copyright is dedicated to the Public Domain.
3 // http://creativecommons.org/publicdomain/zero/1.0/
6 // Checks that RSA certs with key sizes below 2048 bits when verifying for EV
9 do_get_profile(); // Must be called before getting nsIX509CertDB
10 const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
14 const SERVER_PORT = 8888;
16 function getOCSPResponder(expectedCertNames) {
17 let expectedPaths = expectedCertNames.slice();
18 return startOCSPResponder(
27 function loadCert(certName, trustString) {
28 let certFilename = "test_keysize_ev/" + certName + ".pem";
29 addCertFromFile(certDB, certFilename, trustString);
30 return constructCertFromFile(certFilename);
34 * Asynchronously runs a single EV key size test.
36 * @param {Array} expectedNamesForOCSP
37 * An array of nicknames of the certs to be responded to.
38 * @param {string} rootCertFileName
39 * The file name of the root cert. Can begin with ".." to reference
40 * certs in folders other than "test_keysize_ev/".
41 * @param {Array} intCertFileNames
42 * An array of file names of any intermediate certificates.
43 * @param {string} endEntityCertFileName
44 * The file name of the end entity cert.
45 * @param {boolean} expectedResult
46 * Whether the chain is expected to validate as EV.
48 async function keySizeTestForEV(
52 endEntityCertFileName,
56 let ocspResponder = getOCSPResponder(expectedNamesForOCSP);
58 loadCert(rootCertFileName, "CTu,CTu,CTu");
59 for (let intCertFileName of intCertFileNames) {
60 loadCert(intCertFileName, ",,");
64 constructCertFromFile(`test_keysize_ev/${endEntityCertFileName}.pem`),
65 certificateUsageSSLServer,
69 await stopOCSPResponder(ocspResponder);
73 * For debug builds which have the test EV roots compiled in, checks RSA chains
74 * which contain certs with key sizes adequate for EV are validated as such,
75 * while chains that contain any cert with an inadequate key size fail EV and
77 * For opt builds which don't have the test EV roots compiled in, checks that
78 * none of the chains validate as EV.
80 * Note: This function assumes that the key size requirements for EV are greater
81 * than the requirements for DV.
83 * @param {number} inadequateKeySize
84 * The inadequate key size of the generated certs.
85 * @param {number} adequateKeySize
86 * The adequate key size of the generated certs.
88 async function checkRSAChains(inadequateKeySize, adequateKeySize) {
89 // Reuse the existing test RSA EV root
90 let rootOKCertFileName = "../test_ev_certs/evroot";
91 let rootOKName = "evroot";
92 let rootNotOKName = "ev_root_rsa_" + inadequateKeySize;
93 let intOKName = "ev_int_rsa_" + adequateKeySize;
94 let intNotOKName = "ev_int_rsa_" + inadequateKeySize;
95 let eeOKName = "ev_ee_rsa_" + adequateKeySize;
96 let eeNotOKName = "ev_ee_rsa_" + inadequateKeySize;
98 // Chain with certs that have adequate sizes for EV and DV
99 // In opt builds, this chain is only validated for DV. Hence, an OCSP fetch
100 // will for example not be done for the "ev_int_rsa_2048-evroot" intermediate
102 let intFullName = intOKName + "-" + rootOKName;
103 let eeFullName = eeOKName + "-" + intOKName + "-" + rootOKName;
104 let expectedNamesForOCSP = [eeFullName];
105 await keySizeTestForEV(
106 expectedNamesForOCSP,
113 // Chain with a root cert that has an inadequate size for EV, but
114 // adequate size for DV
115 intFullName = intOKName + "-" + rootNotOKName;
116 eeFullName = eeOKName + "-" + intOKName + "-" + rootNotOKName;
117 expectedNamesForOCSP = [eeFullName];
118 await keySizeTestForEV(
119 expectedNamesForOCSP,
126 // Chain with an intermediate cert that has an inadequate size for EV, but
127 // adequate size for DV
128 intFullName = intNotOKName + "-" + rootOKName;
129 eeFullName = eeOKName + "-" + intNotOKName + "-" + rootOKName;
130 expectedNamesForOCSP = [eeFullName];
131 await keySizeTestForEV(
132 expectedNamesForOCSP,
139 // Chain with an end entity cert that has an inadequate size for EV, but
140 // adequate size for DV
141 intFullName = intOKName + "-" + rootOKName;
142 eeFullName = eeNotOKName + "-" + intOKName + "-" + rootOKName;
143 expectedNamesForOCSP = [eeFullName];
144 await keySizeTestForEV(
145 expectedNamesForOCSP,
153 add_task(async function () {
154 Services.prefs.setCharPref("network.dns.localDomains", "www.example.com");
155 Services.prefs.setIntPref("security.OCSP.enabled", 1);
157 let smallKeyEVRoot = constructCertFromFile(
158 "test_keysize_ev/ev_root_rsa_2040.pem"
161 smallKeyEVRoot.sha256Fingerprint,
162 "40:AB:5D:A5:89:15:A9:4B:82:87:B8:A6:9A:84:B1:DB:" +
163 "7A:9D:DB:B8:4E:E1:23:E3:C6:64:E7:50:DC:35:8C:68",
164 "test sanity check: the small-key EV root must have the same " +
165 "fingerprint as the corresponding entry in ExtendedValidation.cpp"
168 await checkRSAChains(2040, 2048);