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
|
"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(function* () {
let ee_usages = [ certificateUsageSSLClient, certificateUsageSSLServer,
certificateUsageEmailSigner, certificateUsageEmailRecipient,
certificateUsageObjectSigner ];
let ca_usages = [ certificateUsageSSLCA, certificateUsageVerifyCA ];
let eku_usages = [ certificateUsageSSLClient, certificateUsageSSLServer ];
// Load the ca into mem
let ca_name = "ca";
load_cert(ca_name, "CTu,CTu,CTu");
yield test_cert_for_usages([ca_name], ca_usages);
// A certificate with no basicConstraints extension is considered an EE.
yield 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.
yield test_cert_for_usages(["ee-int-no-extensions", "int-no-extensions"], []);
// a certificate with basicConstraints.cA==false is considered an EE.
yield 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.
yield 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).
yield test_cert_for_usages(["int-cA-FALSE-asserts-keyCertSign"], ee_usages);
yield 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.
yield 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.
yield 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)
//
yield test_cert_for_usages(["int-limited-depth-invalid", "int-limited-depth"],
[]);
yield test_cert_for_usages(["ee-int-limited-depth-invalid",
"int-limited-depth-invalid", "int-limited-depth"],
[]);
// int-valid-ku-no-eku has keyCertSign
yield test_cert_for_usages(["int-valid-ku-no-eku"], ca_usages);
yield 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.
yield test_cert_for_usages(["int-bad-ku-no-eku"], []);
yield 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".
yield test_cert_for_usages(["int-no-ku-no-eku"], ca_usages);
yield 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}.
yield test_cert_for_usages(["int-valid-ku-server-eku"], ca_usages);
yield 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}.
yield test_cert_for_usages(["int-bad-ku-server-eku"], []);
yield 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}.
yield test_cert_for_usages(["int-no-ku-server-eku"], ca_usages);
yield test_cert_for_usages(["ee-int-no-ku-server-eku",
"int-no-ku-server-eku"], eku_usages);
});
|