security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial