no bug - Import translations from android-l10n r=release a=l10n CLOSED TREE
[gecko.git] / security / manager / ssl / tests / unit / test_keysize_ev.js
blob8e0edd7851f5c7639bb2c0f366824da4ac5d0beb
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/
4 "use strict";
6 // Checks that RSA certs with key sizes below 2048 bits when verifying for EV
7 // are rejected.
9 do_get_profile(); // Must be called before getting nsIX509CertDB
10 const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
11   Ci.nsIX509CertDB
14 const SERVER_PORT = 8888;
16 function getOCSPResponder(expectedCertNames) {
17   let expectedPaths = expectedCertNames.slice();
18   return startOCSPResponder(
19     SERVER_PORT,
20     "www.example.com",
21     "test_keysize_ev/",
22     expectedCertNames,
23     expectedPaths
24   );
27 function loadCert(certName, trustString) {
28   let certFilename = "test_keysize_ev/" + certName + ".pem";
29   addCertFromFile(certDB, certFilename, trustString);
30   return constructCertFromFile(certFilename);
33 /**
34  * Asynchronously runs a single EV key size test.
35  *
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.
47  */
48 async function keySizeTestForEV(
49   expectedNamesForOCSP,
50   rootCertFileName,
51   intCertFileNames,
52   endEntityCertFileName,
53   expectedResult
54 ) {
55   clearOCSPCache();
56   let ocspResponder = getOCSPResponder(expectedNamesForOCSP);
58   loadCert(rootCertFileName, "CTu,CTu,CTu");
59   for (let intCertFileName of intCertFileNames) {
60     loadCert(intCertFileName, ",,");
61   }
62   await checkEVStatus(
63     certDB,
64     constructCertFromFile(`test_keysize_ev/${endEntityCertFileName}.pem`),
65     certificateUsageSSLServer,
66     expectedResult
67   );
69   await stopOCSPResponder(ocspResponder);
72 /**
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
76  * validate as DV.
77  * For opt builds which don't have the test EV roots compiled in, checks that
78  * none of the chains validate as EV.
79  *
80  * Note: This function assumes that the key size requirements for EV are greater
81  * than the requirements for DV.
82  *
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.
87  */
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
101   // in such a build.
102   let intFullName = intOKName + "-" + rootOKName;
103   let eeFullName = eeOKName + "-" + intOKName + "-" + rootOKName;
104   let expectedNamesForOCSP = [eeFullName];
105   await keySizeTestForEV(
106     expectedNamesForOCSP,
107     rootOKCertFileName,
108     [intFullName],
109     eeFullName,
110     gEVExpected
111   );
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,
120     rootNotOKName,
121     [intFullName],
122     eeFullName,
123     false
124   );
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,
133     rootOKCertFileName,
134     [intFullName],
135     eeFullName,
136     false
137   );
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,
146     rootOKCertFileName,
147     [intFullName],
148     eeFullName,
149     false
150   );
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"
159   );
160   equal(
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"
166   );
168   await checkRSAChains(2040, 2048);