security/manager/ssl/tests/unit/test_ev_certs.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

     1 // -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2 // This Source Code Form is subject to the terms of the Mozilla Public
     3 // License, v. 2.0. If a copy of the MPL was not distributed with this
     4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6 "use strict";
     8 // XXX: The isDebugBuild tests you see are here because the test EV root is
     9 // only enabled for EV in debug builds, as a security measure. An ugly hack.
    11 do_get_profile(); // must be called before getting nsIX509CertDB
    12 const certdb = Cc["@mozilla.org/security/x509certdb;1"]
    13                  .getService(Ci.nsIX509CertDB);
    15 const evrootnick = "XPCShell EV Testing (untrustworthy) CA - Mozilla - " +
    16                    "EV debug test CA";
    18 // This is the list of certificates needed for the test
    19 // The certificates prefixed by 'int-' are intermediates
    20 let certList = [
    21   // Test for successful EV validation
    22   'int-ev-valid',
    23   'ev-valid',
    24   'ev-valid-anypolicy-int',
    25   'int-ev-valid-anypolicy-int',
    26   'no-ocsp-url-cert', // a cert signed by the EV auth that has no OCSP url
    27                       // but that contains a valid CRLDP.
    29   // Testing a root that looks like EV but is not EV enabled
    30   'int-non-ev-root',
    31   'non-ev-root',
    32 ]
    34 function load_ca(ca_name) {
    35   var ca_filename = ca_name + ".der";
    36   addCertFromFile(certdb, "test_ev_certs/" + ca_filename, 'CTu,CTu,CTu');
    37 }
    39 const SERVER_PORT = 8888;
    41 function failingOCSPResponder() {
    42   return getFailingHttpServer(SERVER_PORT,
    43                               ["www.example.com", "crl.example.com"]);
    44 }
    46 function start_ocsp_responder(expectedCertNames) {
    47   let expectedPaths = expectedCertNames.slice();
    48   return startOCSPResponder(SERVER_PORT, "www.example.com", ["crl.example.com"],
    49                             "test_ev_certs", expectedCertNames, expectedPaths);
    50 }
    52 function check_cert_err(cert_name, expected_error) {
    53   let cert = certdb.findCertByNickname(null, cert_name);
    54   let hasEVPolicy = {};
    55   let verifiedChain = {};
    56   let error = certdb.verifyCertNow(cert, certificateUsageSSLServer,
    57                                    NO_FLAGS, verifiedChain, hasEVPolicy);
    58   do_check_eq(error,  expected_error);
    59 }
    62 function check_ee_for_ev(cert_name, expected_ev) {
    63     let cert = certdb.findCertByNickname(null, cert_name);
    64     let hasEVPolicy = {};
    65     let verifiedChain = {};
    66     let error = certdb.verifyCertNow(cert, certificateUsageSSLServer,
    67                                      NO_FLAGS, verifiedChain, hasEVPolicy);
    68     do_check_eq(hasEVPolicy.value, expected_ev);
    69     do_check_eq(0, error);
    70 }
    72 function run_test() {
    73   for (let i = 0 ; i < certList.length; i++) {
    74     let cert_filename = certList[i] + ".der";
    75     addCertFromFile(certdb, "test_ev_certs/" + cert_filename, ',,');
    76   }
    77   load_ca("evroot");
    78   load_ca("non-evroot-ca");
    80   // setup and start ocsp responder
    81   Services.prefs.setCharPref("network.dns.localDomains",
    82                              'www.example.com, crl.example.com');
    83   add_tests_in_mode(true);
    84   add_tests_in_mode(false);
    85   run_next_test();
    86 }
    88 function add_tests_in_mode(useMozillaPKIX)
    89 {
    90   add_test(function () {
    91     Services.prefs.setBoolPref("security.use_mozillapkix_verification",
    92                                useMozillaPKIX);
    93     run_next_test();
    94   });
    96   add_test(function () {
    97     clearOCSPCache();
    98     let ocspResponder = start_ocsp_responder(
    99                           isDebugBuild ? ["int-ev-valid", "ev-valid"]
   100                                        : ["ev-valid"]);
   101     check_ee_for_ev("ev-valid", isDebugBuild);
   102     ocspResponder.stop(run_next_test);
   103   });
   106   add_test(function () {
   107     clearOCSPCache();
   109     let ocspResponder = start_ocsp_responder(
   110                           isDebugBuild ? ["int-ev-valid-anypolicy-int", "ev-valid-anypolicy-int"]
   111                                        : ["ev-valid-anypolicy-int"]);
   112     check_ee_for_ev("ev-valid-anypolicy-int", isDebugBuild);
   113     ocspResponder.stop(run_next_test);
   114   });
   116   add_test(function() {
   117     clearOCSPCache();
   118     let ocspResponder = start_ocsp_responder(["non-ev-root"]);
   119     check_ee_for_ev("non-ev-root", false);
   120     ocspResponder.stop(run_next_test);
   121   });
   123   add_test(function() {
   124     clearOCSPCache();
   125     // libpkix will attempt to validate the intermediate, which does have an
   126     // OCSP URL.
   127     let ocspResponder = isDebugBuild ? start_ocsp_responder(["int-ev-valid"])
   128                                      : failingOCSPResponder();
   129     check_ee_for_ev("no-ocsp-url-cert", false);
   130     ocspResponder.stop(run_next_test);
   131   });
   133   // bug 917380: Chcek that an untrusted EV root is untrusted.
   134   const nsIX509Cert = Ci.nsIX509Cert;
   135   add_test(function() {
   136     let evRootCA = certdb.findCertByNickname(null, evrootnick);
   137     certdb.setCertTrust(evRootCA, nsIX509Cert.CA_CERT, 0);
   139     clearOCSPCache();
   140     let ocspResponder = failingOCSPResponder();
   141     check_cert_err("ev-valid",
   142                    useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER
   143                                   : SEC_ERROR_UNTRUSTED_ISSUER);
   144     ocspResponder.stop(run_next_test);
   145   });
   147   // bug 917380: Chcek that a trusted EV root is trusted after disabling and
   148   // re-enabling trust.
   149   add_test(function() {
   150     let evRootCA = certdb.findCertByNickname(null, evrootnick);
   151     certdb.setCertTrust(evRootCA, nsIX509Cert.CA_CERT,
   152                         Ci.nsIX509CertDB.TRUSTED_SSL |
   153                         Ci.nsIX509CertDB.TRUSTED_EMAIL |
   154                         Ci.nsIX509CertDB.TRUSTED_OBJSIGN);
   156     clearOCSPCache();
   157     let ocspResponder = start_ocsp_responder(
   158                           isDebugBuild ? ["int-ev-valid", "ev-valid"]
   159                                        : ["ev-valid"]);
   160     check_ee_for_ev("ev-valid", isDebugBuild);
   161     ocspResponder.stop(run_next_test);
   162   });
   164   add_test(function () {
   165     check_no_ocsp_requests("ev-valid",
   166       useMozillaPKIX ? SEC_ERROR_POLICY_VALIDATION_FAILED
   167                      : (isDebugBuild ? SEC_ERROR_REVOKED_CERTIFICATE
   168                                      : SEC_ERROR_EXTENSION_NOT_FOUND));
   169   });
   171   add_test(function () {
   172     check_no_ocsp_requests("non-ev-root",
   173       useMozillaPKIX ? SEC_ERROR_POLICY_VALIDATION_FAILED
   174                      : (isDebugBuild ? SEC_ERROR_UNTRUSTED_ISSUER
   175                                      : SEC_ERROR_EXTENSION_NOT_FOUND));
   176   });
   178   add_test(function () {
   179     check_no_ocsp_requests("no-ocsp-url-cert",
   180       useMozillaPKIX ? SEC_ERROR_POLICY_VALIDATION_FAILED
   181                      : (isDebugBuild ? SEC_ERROR_REVOKED_CERTIFICATE
   182                                      : SEC_ERROR_EXTENSION_NOT_FOUND));
   183   });
   186   // Test the EV continues to work with flags after successful EV verification
   187   add_test(function () {
   188     clearOCSPCache();
   189     let ocspResponder = start_ocsp_responder(
   190                           isDebugBuild ? ["int-ev-valid", "ev-valid"]
   191                                        : ["ev-valid"]);
   192     check_ee_for_ev("ev-valid", isDebugBuild);
   193     ocspResponder.stop(function () {
   194       // without net it must be able to EV verify
   195       let failingOcspResponder = failingOCSPResponder();
   196       let cert = certdb.findCertByNickname(null, "ev-valid");
   197       let hasEVPolicy = {};
   198       let verifiedChain = {};
   199       let flags = Ci.nsIX509CertDB.FLAG_LOCAL_ONLY |
   200                   Ci.nsIX509CertDB.FLAG_MUST_BE_EV;
   202       let error = certdb.verifyCertNow(cert, certificateUsageSSLServer,
   203                                        flags, verifiedChain, hasEVPolicy);
   204       do_check_eq(hasEVPolicy.value, isDebugBuild);
   205       do_check_eq(error,
   206                   isDebugBuild ? 0
   207                                : (useMozillaPKIX ? SEC_ERROR_POLICY_VALIDATION_FAILED
   208                                                  : SEC_ERROR_EXTENSION_NOT_FOUND));
   209       failingOcspResponder.stop(run_next_test);
   210     });
   211   });
   213   // Bug 991815 old but valid intermediates are OK
   214   add_test(function () {
   215     clearOCSPCache();
   216     let ocspResponder = startOCSPResponder(SERVER_PORT, "www.example.com", [],
   217                           "test_ev_certs",
   218                           isDebugBuild ? ["int-ev-valid", "ev-valid"]
   219                                        : ["ev-valid"],
   220                           [], [],
   221                           isDebugBuild ? ["longvalidityalmostold", "good"]
   222                                        : ["good"]);
   223     check_ee_for_ev("ev-valid", isDebugBuild);
   224     ocspResponder.stop(run_next_test);
   225   });
   227   // Bug 991815 old but valid end-entities are NOT OK for EV
   228   // Unfortunatelly because of soft-fail we consider these OK for DV
   229   // libpkix does not enforce the age restriction and thus EV is valid
   230   add_test(function () {
   231     clearOCSPCache();
   232     // Since Mozilla::pkix does not consider the old amost invalid OCSP
   233     // response valid, it does not cache the old response and thus
   234     // makes a separate request for DV
   235     let debugCertNickArray = ["int-ev-valid", "ev-valid", "ev-valid"];
   236     let debugResponseArray = ["good", "longvalidityalmostold",
   237                               "longvalidityalmostold"];
   238     if (!useMozillaPKIX) {
   239       debugCertNickArray = ["int-ev-valid", "ev-valid"];
   240       debugResponseArray = ["good", "longvalidityalmostold"];
   241     }
   242     let ocspResponder = startOCSPResponder(SERVER_PORT, "www.example.com", [],
   243                           "test_ev_certs",
   244                           isDebugBuild ? debugCertNickArray : ["ev-valid"],
   245                           [], [],
   246                           isDebugBuild ? debugResponseArray
   247                                        : ["longvalidityalmostold"]);
   248     check_ee_for_ev("ev-valid", !useMozillaPKIX && isDebugBuild);
   249     ocspResponder.stop(run_next_test);
   250   });
   252   // Bug 991815 Valid but Ancient (almost two year old) responses are Not OK for
   253   // EV (still OK for soft fail DV)
   254   add_test(function () {
   255     clearOCSPCache();
   256     let debugCertNickArray = ["int-ev-valid", "ev-valid", "ev-valid"];
   257     let debugResponseArray = ["good", "ancientstillvalid",
   258                               "ancientstillvalid"];
   259     if (!useMozillaPKIX) {
   260       debugCertNickArray = ["int-ev-valid", "ev-valid"];
   261       debugResponseArray = ["good", "ancientstillvalid"];
   262     }
   263     let ocspResponder = startOCSPResponder(SERVER_PORT, "www.example.com", [],
   264                           "test_ev_certs",
   265                           isDebugBuild ? debugCertNickArray : ["ev-valid"],
   266                           [], [],
   267                           isDebugBuild ? debugResponseArray
   268                                        : ["ancientstillvalid"]);
   269     check_ee_for_ev("ev-valid", !useMozillaPKIX && isDebugBuild);
   270     ocspResponder.stop(run_next_test);
   271   });
   272 }
   274 // bug 950240: add FLAG_MUST_BE_EV to CertVerifier::VerifyCert
   275 // to prevent spurious OCSP requests that race with OCSP stapling.
   276 // This has the side-effect of saying an EV certificate is not EV if
   277 // it hasn't already been verified (e.g. on the verification thread when
   278 // connecting to a site).
   279 // This flag is mostly a hack that should be removed once FLAG_LOCAL_ONLY
   280 // works as intended.
   281 function check_no_ocsp_requests(cert_name, expected_error) {
   282   clearOCSPCache();
   283   let ocspResponder = failingOCSPResponder();
   284   let cert = certdb.findCertByNickname(null, cert_name);
   285   let hasEVPolicy = {};
   286   let verifiedChain = {};
   287   let flags = Ci.nsIX509CertDB.FLAG_LOCAL_ONLY |
   288               Ci.nsIX509CertDB.FLAG_MUST_BE_EV;
   289   let error = certdb.verifyCertNow(cert, certificateUsageSSLServer, flags,
   290                                    verifiedChain, hasEVPolicy);
   291   // Since we're not doing OCSP requests, no certificate will be EV.
   292   do_check_eq(hasEVPolicy.value, false);
   293   do_check_eq(expected_error, error);
   294   // Also check that isExtendedValidation doesn't cause OCSP requests.
   295   let identityInfo = cert.QueryInterface(Ci.nsIIdentityInfo);
   296   do_check_eq(identityInfo.isExtendedValidation, false);
   297   ocspResponder.stop(run_next_test);
   298 }

mercurial