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

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,139 @@
     1.4 +"use strict";
     1.5 +/* To regenerate the certificates for this test:
     1.6 + *
     1.7 + *      cd security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints
     1.8 + *      ./generate.py
     1.9 + *      cd ../../../../../..
    1.10 + *      make -C $OBJDIR/security/manager/ssl/tests
    1.11 + *
    1.12 + * Check in the generated files. These steps are not done as part of the build
    1.13 + * because we do not want to add a build-time dependency on the OpenSSL or NSS
    1.14 + * tools or libraries built for the host platform.
    1.15 + */
    1.16 +
    1.17 +do_get_profile(); // must be called before getting nsIX509CertDB
    1.18 +const certdb = Cc["@mozilla.org/security/x509certdb;1"]
    1.19 +                 .getService(Ci.nsIX509CertDB);
    1.20 +
    1.21 +function load_cert(name, trust) {
    1.22 +  let filename = "test_intermediate_basic_usage_constraints/" + name + ".der";
    1.23 +  addCertFromFile(certdb, filename, trust);
    1.24 +}
    1.25 +
    1.26 +function test_cert_for_usages(certChainNicks, expected_usages_string) {
    1.27 +  let certs = [];
    1.28 +  for (let i in certChainNicks) {
    1.29 +    let certNick = certChainNicks[i];
    1.30 +    let certDER = readFile(do_get_file(
    1.31 +                             "test_intermediate_basic_usage_constraints/"
    1.32 +                                + certNick + ".der"), false);
    1.33 +    certs.push(certdb.constructX509(certDER, certDER.length));
    1.34 +  }
    1.35 +
    1.36 +  let cert = certs[0];
    1.37 +  let verified = {};
    1.38 +  let usages = {};
    1.39 +  cert.getUsagesString(true, verified, usages);
    1.40 +  do_print("usages.value = " + usages.value);
    1.41 +  do_check_eq(expected_usages_string, usages.value);
    1.42 +}
    1.43 +
    1.44 +function run_test_in_mode(useMozillaPKIX) {
    1.45 +  Services.prefs.setBoolPref("security.use_mozillapkix_verification", useMozillaPKIX);
    1.46 +
    1.47 +  // mozilla::pkix doesn't support the obsolete Netscape object signing
    1.48 +  // extension, but NSS does.
    1.49 +  let ee_usage1 = useMozillaPKIX
    1.50 +                ? 'Client,Server,Sign,Encrypt,Object Signer'
    1.51 +                : 'Client,Server,Sign,Encrypt'
    1.52 +
    1.53 +  // mozilla::pkix doesn't validate CA certificates for non-CA uses, but
    1.54 +  // NSS does.
    1.55 +  let ca_usage1 = useMozillaPKIX
    1.56 +                ? "SSL CA"
    1.57 +                : 'Client,Server,Sign,Encrypt,SSL CA,Status Responder';
    1.58 +
    1.59 +  // Load the ca into mem
    1.60 +  let ca_name = "ca";
    1.61 +  load_cert(ca_name, "CTu,CTu,CTu");
    1.62 +  do_print("ca_name = " + ca_name);
    1.63 +  test_cert_for_usages([ca_name], ca_usage1);
    1.64 +
    1.65 +  // A certificate with no basicConstraints extension is considered an EE.
    1.66 +  test_cert_for_usages(["int-no-extensions"], ee_usage1);
    1.67 +
    1.68 +  // int-no-extensions is an EE (see previous case), so no certs can chain to
    1.69 +  // it.
    1.70 +  test_cert_for_usages(["ee-int-no-extensions", "int-no-extensions"], "");
    1.71 +
    1.72 +  // a certificate with bsaicConstraints.cA==false is considered an EE.
    1.73 +  test_cert_for_usages(["int-not-a-ca"], ee_usage1);
    1.74 +
    1.75 +  // int-not-a-ca is an EE (see previous case), so no certs can chain to it.
    1.76 +  test_cert_for_usages(["ee-int-not-a-ca", "int-not-a-ca"], "");
    1.77 +
    1.78 +  // int-limited-depth has cA==true and a path length constraint of zero.
    1.79 +  test_cert_for_usages(["int-limited-depth"], ca_usage1);
    1.80 +
    1.81 +  // path length constraints do not affect the ability of a non-CA cert to
    1.82 +  // chain to to the CA cert.
    1.83 +  test_cert_for_usages(["ee-int-limited-depth", "int-limited-depth"],
    1.84 +                       ee_usage1);
    1.85 +
    1.86 +  // ca
    1.87 +  //   int-limited-depth (cA==true, pathLenConstraint==0)
    1.88 +  //      int-limited-depth-invalid (cA==true)
    1.89 +  //
    1.90 +  // XXX: It seems the NSS code does not consider the path length of the
    1.91 +  // certificate we're validating, but mozilla::pkix does. mozilla::pkix's
    1.92 +  // behavior is correct.
    1.93 +  test_cert_for_usages(["int-limited-depth-invalid", "int-limited-depth"],
    1.94 +                       useMozillaPKIX ? "" : ca_usage1);
    1.95 +  test_cert_for_usages(["ee-int-limited-depth-invalid",
    1.96 +                        "int-limited-depth-invalid",
    1.97 +                        "int-limited-depth"],
    1.98 +                       "");
    1.99 +
   1.100 +  // int-valid-ku-no-eku has keyCertSign
   1.101 +  test_cert_for_usages(["int-valid-ku-no-eku"], "SSL CA");
   1.102 +  test_cert_for_usages(["ee-int-valid-ku-no-eku", "int-valid-ku-no-eku"],
   1.103 +                       ee_usage1);
   1.104 +
   1.105 +  // int-bad-ku-no-eku has basicConstraints.cA==true and has a KU extension
   1.106 +  // but the KU extension is missing keyCertSign. Note that mozilla::pkix
   1.107 +  // doesn't validate certificates with basicConstraints.Ca==true for non-CA
   1.108 +  // uses, but NSS does.
   1.109 +  test_cert_for_usages(["int-bad-ku-no-eku"],
   1.110 +                       useMozillaPKIX
   1.111 +                          ? ""
   1.112 +                          : 'Client,Server,Sign,Encrypt,Status Responder');
   1.113 +  test_cert_for_usages(["ee-int-bad-ku-no-eku", "int-bad-ku-no-eku"], "");
   1.114 +
   1.115 +  // int-no-ku-no-eku has basicConstraints.cA==true and no KU extension.
   1.116 +  // We treat a missing KU as "any key usage is OK".
   1.117 +  test_cert_for_usages(["int-no-ku-no-eku"], ca_usage1);
   1.118 +  test_cert_for_usages(["ee-int-no-ku-no-eku", "int-no-ku-no-eku"], ee_usage1);
   1.119 +
   1.120 +  // int-valid-ku-server-eku has basicConstraints.cA==true, keyCertSign in KU,
   1.121 +  // and EKU=={id-kp-serverAuth,id-kp-clientAuth}.
   1.122 +  test_cert_for_usages(["int-valid-ku-server-eku"], "SSL CA");
   1.123 +  test_cert_for_usages(["ee-int-valid-ku-server-eku",
   1.124 +                        "int-valid-ku-server-eku"], "Client,Server");
   1.125 +
   1.126 +  // int-bad-ku-server-eku has basicConstraints.cA==true, a KU without
   1.127 +  // keyCertSign, and EKU=={id-kp-serverAuth,id-kp-clientAuth}.
   1.128 +  test_cert_for_usages(["int-bad-ku-server-eku"], "");
   1.129 +  test_cert_for_usages(["ee-int-bad-ku-server-eku", "int-bad-ku-server-eku"],
   1.130 +                       "");
   1.131 +
   1.132 +  // int-bad-ku-server-eku has basicConstraints.cA==true, no KU, and
   1.133 +  // EKU=={id-kp-serverAuth,id-kp-clientAuth}.
   1.134 +  test_cert_for_usages(["int-no-ku-server-eku"], "SSL CA");
   1.135 +  test_cert_for_usages(["ee-int-no-ku-server-eku", "int-no-ku-server-eku"],
   1.136 +                       "Client,Server");
   1.137 +}
   1.138 +
   1.139 +function run_test() {
   1.140 +  run_test_in_mode(true);
   1.141 +  run_test_in_mode(false);
   1.142 +}

mercurial