|
1 "use strict"; |
|
2 /* To regenerate the certificates for this test: |
|
3 * |
|
4 * cd security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints |
|
5 * ./generate.py |
|
6 * cd ../../../../../.. |
|
7 * make -C $OBJDIR/security/manager/ssl/tests |
|
8 * |
|
9 * Check in the generated files. These steps are not done as part of the build |
|
10 * because we do not want to add a build-time dependency on the OpenSSL or NSS |
|
11 * tools or libraries built for the host platform. |
|
12 */ |
|
13 |
|
14 do_get_profile(); // must be called before getting nsIX509CertDB |
|
15 const certdb = Cc["@mozilla.org/security/x509certdb;1"] |
|
16 .getService(Ci.nsIX509CertDB); |
|
17 |
|
18 function load_cert(name, trust) { |
|
19 let filename = "test_intermediate_basic_usage_constraints/" + name + ".der"; |
|
20 addCertFromFile(certdb, filename, trust); |
|
21 } |
|
22 |
|
23 function test_cert_for_usages(certChainNicks, expected_usages_string) { |
|
24 let certs = []; |
|
25 for (let i in certChainNicks) { |
|
26 let certNick = certChainNicks[i]; |
|
27 let certDER = readFile(do_get_file( |
|
28 "test_intermediate_basic_usage_constraints/" |
|
29 + certNick + ".der"), false); |
|
30 certs.push(certdb.constructX509(certDER, certDER.length)); |
|
31 } |
|
32 |
|
33 let cert = certs[0]; |
|
34 let verified = {}; |
|
35 let usages = {}; |
|
36 cert.getUsagesString(true, verified, usages); |
|
37 do_print("usages.value = " + usages.value); |
|
38 do_check_eq(expected_usages_string, usages.value); |
|
39 } |
|
40 |
|
41 function run_test_in_mode(useMozillaPKIX) { |
|
42 Services.prefs.setBoolPref("security.use_mozillapkix_verification", useMozillaPKIX); |
|
43 |
|
44 // mozilla::pkix doesn't support the obsolete Netscape object signing |
|
45 // extension, but NSS does. |
|
46 let ee_usage1 = useMozillaPKIX |
|
47 ? 'Client,Server,Sign,Encrypt,Object Signer' |
|
48 : 'Client,Server,Sign,Encrypt' |
|
49 |
|
50 // mozilla::pkix doesn't validate CA certificates for non-CA uses, but |
|
51 // NSS does. |
|
52 let ca_usage1 = useMozillaPKIX |
|
53 ? "SSL CA" |
|
54 : 'Client,Server,Sign,Encrypt,SSL CA,Status Responder'; |
|
55 |
|
56 // Load the ca into mem |
|
57 let ca_name = "ca"; |
|
58 load_cert(ca_name, "CTu,CTu,CTu"); |
|
59 do_print("ca_name = " + ca_name); |
|
60 test_cert_for_usages([ca_name], ca_usage1); |
|
61 |
|
62 // A certificate with no basicConstraints extension is considered an EE. |
|
63 test_cert_for_usages(["int-no-extensions"], ee_usage1); |
|
64 |
|
65 // int-no-extensions is an EE (see previous case), so no certs can chain to |
|
66 // it. |
|
67 test_cert_for_usages(["ee-int-no-extensions", "int-no-extensions"], ""); |
|
68 |
|
69 // a certificate with bsaicConstraints.cA==false is considered an EE. |
|
70 test_cert_for_usages(["int-not-a-ca"], ee_usage1); |
|
71 |
|
72 // int-not-a-ca is an EE (see previous case), so no certs can chain to it. |
|
73 test_cert_for_usages(["ee-int-not-a-ca", "int-not-a-ca"], ""); |
|
74 |
|
75 // int-limited-depth has cA==true and a path length constraint of zero. |
|
76 test_cert_for_usages(["int-limited-depth"], ca_usage1); |
|
77 |
|
78 // path length constraints do not affect the ability of a non-CA cert to |
|
79 // chain to to the CA cert. |
|
80 test_cert_for_usages(["ee-int-limited-depth", "int-limited-depth"], |
|
81 ee_usage1); |
|
82 |
|
83 // ca |
|
84 // int-limited-depth (cA==true, pathLenConstraint==0) |
|
85 // int-limited-depth-invalid (cA==true) |
|
86 // |
|
87 // XXX: It seems the NSS code does not consider the path length of the |
|
88 // certificate we're validating, but mozilla::pkix does. mozilla::pkix's |
|
89 // behavior is correct. |
|
90 test_cert_for_usages(["int-limited-depth-invalid", "int-limited-depth"], |
|
91 useMozillaPKIX ? "" : ca_usage1); |
|
92 test_cert_for_usages(["ee-int-limited-depth-invalid", |
|
93 "int-limited-depth-invalid", |
|
94 "int-limited-depth"], |
|
95 ""); |
|
96 |
|
97 // int-valid-ku-no-eku has keyCertSign |
|
98 test_cert_for_usages(["int-valid-ku-no-eku"], "SSL CA"); |
|
99 test_cert_for_usages(["ee-int-valid-ku-no-eku", "int-valid-ku-no-eku"], |
|
100 ee_usage1); |
|
101 |
|
102 // int-bad-ku-no-eku has basicConstraints.cA==true and has a KU extension |
|
103 // but the KU extension is missing keyCertSign. Note that mozilla::pkix |
|
104 // doesn't validate certificates with basicConstraints.Ca==true for non-CA |
|
105 // uses, but NSS does. |
|
106 test_cert_for_usages(["int-bad-ku-no-eku"], |
|
107 useMozillaPKIX |
|
108 ? "" |
|
109 : 'Client,Server,Sign,Encrypt,Status Responder'); |
|
110 test_cert_for_usages(["ee-int-bad-ku-no-eku", "int-bad-ku-no-eku"], ""); |
|
111 |
|
112 // int-no-ku-no-eku has basicConstraints.cA==true and no KU extension. |
|
113 // We treat a missing KU as "any key usage is OK". |
|
114 test_cert_for_usages(["int-no-ku-no-eku"], ca_usage1); |
|
115 test_cert_for_usages(["ee-int-no-ku-no-eku", "int-no-ku-no-eku"], ee_usage1); |
|
116 |
|
117 // int-valid-ku-server-eku has basicConstraints.cA==true, keyCertSign in KU, |
|
118 // and EKU=={id-kp-serverAuth,id-kp-clientAuth}. |
|
119 test_cert_for_usages(["int-valid-ku-server-eku"], "SSL CA"); |
|
120 test_cert_for_usages(["ee-int-valid-ku-server-eku", |
|
121 "int-valid-ku-server-eku"], "Client,Server"); |
|
122 |
|
123 // int-bad-ku-server-eku has basicConstraints.cA==true, a KU without |
|
124 // keyCertSign, and EKU=={id-kp-serverAuth,id-kp-clientAuth}. |
|
125 test_cert_for_usages(["int-bad-ku-server-eku"], ""); |
|
126 test_cert_for_usages(["ee-int-bad-ku-server-eku", "int-bad-ku-server-eku"], |
|
127 ""); |
|
128 |
|
129 // int-bad-ku-server-eku has basicConstraints.cA==true, no KU, and |
|
130 // EKU=={id-kp-serverAuth,id-kp-clientAuth}. |
|
131 test_cert_for_usages(["int-no-ku-server-eku"], "SSL CA"); |
|
132 test_cert_for_usages(["ee-int-no-ku-server-eku", "int-no-ku-server-eku"], |
|
133 "Client,Server"); |
|
134 } |
|
135 |
|
136 function run_test() { |
|
137 run_test_in_mode(true); |
|
138 run_test_in_mode(false); |
|
139 } |