Thu, 22 Jan 2015 13:21:57 +0100
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 | } |