summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js
blob: 4b09c719fce167e40ec6dd684a783b899765885b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
"use strict";

do_get_profile(); // must be called before getting nsIX509CertDB
const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
  Ci.nsIX509CertDB
);

function load_cert(name, trust) {
  let filename = "test_intermediate_basic_usage_constraints/" + name + ".pem";
  addCertFromFile(certdb, filename, trust);
}

function test_cert_for_usages(certChainNicks, expected_usages) {
  let certs = [];
  for (let i in certChainNicks) {
    let certNick = certChainNicks[i];
    let certPEM = readFile(
      do_get_file(
        "test_intermediate_basic_usage_constraints/" + certNick + ".pem"
      ),
      false
    );
    certs.push(certdb.constructX509FromBase64(pemToBase64(certPEM)));
  }

  let cert = certs[0];
  return asyncTestCertificateUsages(certdb, cert, expected_usages);
}

add_task(async function () {
  let ee_usages = [
    certificateUsageSSLClient,
    certificateUsageSSLServer,
    certificateUsageEmailSigner,
    certificateUsageEmailRecipient,
  ];
  let ca_usages = [certificateUsageSSLCA];
  let eku_usages = [certificateUsageSSLClient, certificateUsageSSLServer];

  // Load the ca into mem
  let ca_name = "ca";
  load_cert(ca_name, "CTu,CTu,CTu");
  await test_cert_for_usages([ca_name], ca_usages);

  // A certificate with no basicConstraints extension is considered an EE.
  await test_cert_for_usages(["int-no-extensions"], ee_usages);

  // int-no-extensions is an EE (see previous case), so no certs can chain to
  // it.
  await test_cert_for_usages(["ee-int-no-extensions", "int-no-extensions"], []);

  // a certificate with basicConstraints.cA==false is considered an EE.
  await test_cert_for_usages(["int-not-a-ca"], ee_usages);

  // int-not-a-ca is an EE (see previous case), so no certs can chain to it.
  await test_cert_for_usages(["ee-int-not-a-ca", "int-not-a-ca"], []);

  // a certificate with basicConstraints.cA==false but with the keyCertSign
  // key usage may not act as a CA (it can act like an end-entity).
  await test_cert_for_usages(["int-cA-FALSE-asserts-keyCertSign"], ee_usages);
  await test_cert_for_usages(
    ["ee-int-cA-FALSE-asserts-keyCertSign", "int-cA-FALSE-asserts-keyCertSign"],
    []
  );

  // int-limited-depth has cA==true and a path length constraint of zero.
  await test_cert_for_usages(["int-limited-depth"], ca_usages);

  // path length constraints do not affect the ability of a non-CA cert to
  // chain to to the CA cert.
  await test_cert_for_usages(
    ["ee-int-limited-depth", "int-limited-depth"],
    ee_usages
  );

  // ca
  //   int-limited-depth (cA==true, pathLenConstraint==0)
  //      int-limited-depth-invalid (cA==true)
  //
  await test_cert_for_usages(
    ["int-limited-depth-invalid", "int-limited-depth"],
    []
  );
  await test_cert_for_usages(
    [
      "ee-int-limited-depth-invalid",
      "int-limited-depth-invalid",
      "int-limited-depth",
    ],
    []
  );

  // int-valid-ku-no-eku has keyCertSign
  await test_cert_for_usages(["int-valid-ku-no-eku"], ca_usages);
  await test_cert_for_usages(
    ["ee-int-valid-ku-no-eku", "int-valid-ku-no-eku"],
    ee_usages
  );

  // int-bad-ku-no-eku has basicConstraints.cA==true and has a KU extension
  // but the KU extension is missing keyCertSign. Note that mozilla::pkix
  // doesn't validate certificates with basicConstraints.Ca==true for non-CA
  // uses.
  await test_cert_for_usages(["int-bad-ku-no-eku"], []);
  await test_cert_for_usages(["ee-int-bad-ku-no-eku", "int-bad-ku-no-eku"], []);

  // int-no-ku-no-eku has basicConstraints.cA==true and no KU extension.
  // We treat a missing KU as "any key usage is OK".
  await test_cert_for_usages(["int-no-ku-no-eku"], ca_usages);
  await test_cert_for_usages(
    ["ee-int-no-ku-no-eku", "int-no-ku-no-eku"],
    ee_usages
  );

  // int-valid-ku-server-eku has basicConstraints.cA==true, keyCertSign in KU,
  // and EKU=={id-kp-serverAuth,id-kp-clientAuth}.
  await test_cert_for_usages(["int-valid-ku-server-eku"], ca_usages);
  await test_cert_for_usages(
    ["ee-int-valid-ku-server-eku", "int-valid-ku-server-eku"],
    eku_usages
  );

  // int-bad-ku-server-eku has basicConstraints.cA==true, a KU without
  // keyCertSign, and EKU=={id-kp-serverAuth,id-kp-clientAuth}.
  await test_cert_for_usages(["int-bad-ku-server-eku"], []);
  await test_cert_for_usages(
    ["ee-int-bad-ku-server-eku", "int-bad-ku-server-eku"],
    []
  );

  // int-bad-ku-server-eku has basicConstraints.cA==true, no KU, and
  // EKU=={id-kp-serverAuth,id-kp-clientAuth}.
  await test_cert_for_usages(["int-no-ku-server-eku"], ca_usages);
  await test_cert_for_usages(
    ["ee-int-no-ku-server-eku", "int-no-ku-server-eku"],
    eku_usages
  );
});