summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js
diff options
context:
space:
mode:
Diffstat (limited to 'security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js')
-rw-r--r--security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js111
1 files changed, 111 insertions, 0 deletions
diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js
new file mode 100644
index 000000000..5ebc1546b
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js
@@ -0,0 +1,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);
+});