no bug - Import translations from android-l10n r=release a=l10n CLOSED TREE
[gecko.git] / security / manager / ssl / tests / unit / test_self_signed_certs.js
blob2500ea38a5d09645af987f50eedc0a3f69157a5c
1 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
2 // This Source Code Form is subject to the terms of the Mozilla Public
3 // License, v. 2.0. If a copy of the MPL was not distributed with this
4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 "use strict";
7 // This test uses a specially-crafted NSS cert DB containing 12 self-signed certificates that all
8 // have the same subject and issuer distinguished name. Since they all have different keys and none
9 // of them are trust anchors, there are a large number of potential trust paths that could be
10 // explored. If our trust domain were naive enough to allow mozilla::pkix to explore them all, it
11 // would take a long time to perform (mozilla::pkix does have the concept of a path-building budget,
12 // but even on a fast computer, it takes an unacceptable amount of time to exhaust). To prevent the
13 // full exploration of this space, NSSCertDBTrustDomain skips searching through self-signed
14 // certificates that aren't trust anchors, since those would never otherwise be essential to
15 // complete a path (note that this is only true as long as the extensions we support are restrictive
16 // rather than additive).
17 // When we try to verify one of these certificates in this test, we should finish relatively
18 // quickly, even on slow hardware.
19 // Should these certificates ever need regenerating, they were produced with the following commands:
20 // certutil -N -d . --empty-password
21 // for num in 00 01 02 03 04 05 06 07 08 09 10 11; do
22 //   echo -ne "5\n6\n9\ny\ny\n\ny\n" | certutil -d . -S -s "CN=self-signed cert" -t ,, \
23 //   -q secp256r1 -x -k ec -z <(date +%s) -1 -2 -n cert$num; sleep 2;
24 // done
26 add_task(async function test_no_overlong_path_building() {
27   let profile = do_get_profile();
28   const CERT_DB_NAME = "cert9.db";
29   let srcCertDBFile = do_get_file(`test_self_signed_certs/${CERT_DB_NAME}`);
30   srcCertDBFile.copyTo(profile, CERT_DB_NAME);
32   let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
33     Ci.nsIX509CertDB
34   );
35   let certToVerify = null;
36   for (let cert of certDB.getCerts()) {
37     if (cert.subjectName == "CN=self-signed cert") {
38       certToVerify = cert;
39       break;
40     }
41   }
42   notEqual(
43     certToVerify,
44     null,
45     "should have found one of the preloaded self-signed certs"
46   );
47   let timeBefore = Date.now();
48   // As mentioned above, mozilla::pkix limits how much it will search for a trusted path, even if a
49   // trust domain keeps providing potential issuers. So, if we only tried to verify a certificate
50   // once, this test could potentially pass on a fast computer even if we weren't properly skipping
51   // unnecessary paths. If we were to try and lower our time limit (the comparison with
52   // secondsElapsed, below), this test would intermittently fail on slow hardware. By trying to
53   // verify the certificate 10 times, we hopefully end up with a meaningful test (it should still
54   // fail on fast hardware if we don't properly skip unproductive paths) that won't intermittently
55   // time out on slow hardware.
56   for (let i = 0; i < 10; i++) {
57     let date = new Date("2019-05-15T00:00:00.000Z");
58     await checkCertErrorGenericAtTime(
59       certDB,
60       certToVerify,
61       SEC_ERROR_UNKNOWN_ISSUER,
62       certificateUsageSSLCA,
63       date.getTime() / 1000
64     );
65   }
66   let timeAfter = Date.now();
67   let secondsElapsed = (timeAfter - timeBefore) / 1000;
68   Assert.less(secondsElapsed, 120, "verifications shouldn't take too long");
69 });
71 add_task(async function test_no_bad_signature() {
72   // If there are two self-signed CA certificates with the same subject and
73   // issuer but different keys, where one is trusted, test that using the other
74   // one as a server certificate doesn't result in a non-overridable "bad
75   // signature" error but rather a "self-signed cert" error.
76   let selfSignedCert = constructCertFromFile("test_self_signed_certs/ca1.pem");
77   let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
78     Ci.nsIX509CertDB
79   );
80   addCertFromFile(certDB, "test_self_signed_certs/ca2.pem", "CTu,,");
81   await checkCertErrorGeneric(
82     certDB,
83     selfSignedCert,
84     MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT,
85     certificateUsageSSLServer,
86     false,
87     "example.com"
88   );
89 });
91 add_task(async function test_no_inadequate_key_usage() {
92   // If there are two different non-CA, self-signed certificates with the same
93   // subject and issuer but different keys, test that using one of them as a
94   // server certificate doesn't result in a non-overridable "inadequate key
95   // usage" error but rather a "self-signed cert" error.
96   let selfSignedCert = constructCertFromFile("test_self_signed_certs/ee1.pem");
97   let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
98     Ci.nsIX509CertDB
99   );
100   addCertFromFile(certDB, "test_self_signed_certs/ee2.pem", ",,");
101   await checkCertErrorGeneric(
102     certDB,
103     selfSignedCert,
104     MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT,
105     certificateUsageSSLServer,
106     false,
107     "example.com"
108   );