security/manager/ssl/tests/unit/test_ocsp_stapling_expired.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_ocsp_stapling_expired.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,193 @@
     1.4 +// -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 +// This Source Code Form is subject to the terms of the Mozilla Public
     1.6 +// License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 +// file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.8 +"use strict";
     1.9 +
    1.10 +// In which we connect to a number of domains (as faked by a server running
    1.11 +// locally) with OCSP stapling enabled to determine that good things happen
    1.12 +// and bad things don't, specifically with respect to various expired OCSP
    1.13 +// responses (stapled and otherwise).
    1.14 +
    1.15 +let gCurrentOCSPResponse = null;
    1.16 +let gOCSPRequestCount = 0;
    1.17 +
    1.18 +function add_ocsp_test(aHost, aExpectedResult, aOCSPResponseToServe) {
    1.19 +  add_connection_test(aHost, aExpectedResult,
    1.20 +    function() {
    1.21 +      clearOCSPCache();
    1.22 +      clearSessionCache();
    1.23 +      gCurrentOCSPResponse = aOCSPResponseToServe;
    1.24 +      gOCSPRequestCount = 0;
    1.25 +    },
    1.26 +    function() {
    1.27 +      do_check_eq(gOCSPRequestCount, 1);
    1.28 +    });
    1.29 +}
    1.30 +
    1.31 +do_get_profile();
    1.32 +Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
    1.33 +let args = [["good", "localhostAndExampleCom", "unused"],
    1.34 +             ["expiredresponse", "localhostAndExampleCom", "unused"],
    1.35 +             ["oldvalidperiod", "localhostAndExampleCom", "unused"],
    1.36 +             ["revoked", "localhostAndExampleCom", "unused"],
    1.37 +             ["unknown", "localhostAndExampleCom", "unused"],
    1.38 +            ];
    1.39 +let ocspResponses = generateOCSPResponses(args, "tlsserver");
    1.40 +// Fresh response, certificate is good.
    1.41 +let ocspResponseGood = ocspResponses[0];
    1.42 +// Expired response, certificate is good.
    1.43 +let expiredOCSPResponseGood = ocspResponses[1];
    1.44 +// Fresh signature, old validity period, certificate is good.
    1.45 +let oldValidityPeriodOCSPResponseGood = ocspResponses[2];
    1.46 +// Fresh signature, certificate is revoked.
    1.47 +let ocspResponseRevoked = ocspResponses[3];
    1.48 +// Fresh signature, certificate is unknown.
    1.49 +let ocspResponseUnknown = ocspResponses[4];
    1.50 +
    1.51 +function run_test() {
    1.52 +  let ocspResponder = new HttpServer();
    1.53 +  ocspResponder.registerPrefixHandler("/", function(request, response) {
    1.54 +    if (gCurrentOCSPResponse) {
    1.55 +      response.setStatusLine(request.httpVersion, 200, "OK");
    1.56 +      response.setHeader("Content-Type", "application/ocsp-response");
    1.57 +      response.write(gCurrentOCSPResponse);
    1.58 +    } else {
    1.59 +      response.setStatusLine(request.httpVersion, 500, "Internal Server Error");
    1.60 +      response.write("Internal Server Error");
    1.61 +    }
    1.62 +    gOCSPRequestCount++;
    1.63 +  });
    1.64 +  ocspResponder.start(8080);
    1.65 +  add_tls_server_setup("OCSPStaplingServer");
    1.66 +  add_tests_in_mode(true);
    1.67 +  add_tests_in_mode(false);
    1.68 +  add_test(function () { ocspResponder.stop(run_next_test); });
    1.69 +  add_test(check_ocsp_stapling_telemetry);
    1.70 +  run_next_test();
    1.71 +}
    1.72 +
    1.73 +function add_tests_in_mode(useMozillaPKIX)
    1.74 +{
    1.75 +  add_test(function () {
    1.76 +    Services.prefs.setBoolPref("security.use_mozillapkix_verification",
    1.77 +                               useMozillaPKIX);
    1.78 +    run_next_test();
    1.79 +  });
    1.80 +
    1.81 +  // In these tests, the OCSP stapling server gives us a stapled
    1.82 +  // response based on the host name ("ocsp-stapling-expired" or
    1.83 +  // "ocsp-stapling-expired-fresh-ca"). We then ensure that we're
    1.84 +  // properly falling back to fetching revocation information.
    1.85 +  // For ocsp-stapling-expired.example.com, the OCSP stapling server
    1.86 +  // staples an expired OCSP response. The certificate has not expired.
    1.87 +  // For ocsp-stapling-expired-fresh-ca.example.com, the OCSP stapling
    1.88 +  // server staples an OCSP response with a recent signature but with an
    1.89 +  // out-of-date validity period. The certificate has not expired.
    1.90 +  add_ocsp_test("ocsp-stapling-expired.example.com", Cr.NS_OK,
    1.91 +                ocspResponseGood);
    1.92 +  add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com", Cr.NS_OK,
    1.93 +                ocspResponseGood);
    1.94 +  // With mozilla::pkix, if we can't fetch a more recent response when
    1.95 +  // given an expired stapled response, we terminate the connection.
    1.96 +  add_ocsp_test("ocsp-stapling-expired.example.com",
    1.97 +                useMozillaPKIX
    1.98 +                  ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
    1.99 +                  : Cr.NS_OK,
   1.100 +                expiredOCSPResponseGood);
   1.101 +  add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com",
   1.102 +                useMozillaPKIX
   1.103 +                  ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
   1.104 +                  : Cr.NS_OK,
   1.105 +                expiredOCSPResponseGood);
   1.106 +  add_ocsp_test("ocsp-stapling-expired.example.com",
   1.107 +                useMozillaPKIX
   1.108 +                  ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
   1.109 +                  : Cr.NS_OK,
   1.110 +                oldValidityPeriodOCSPResponseGood);
   1.111 +  add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com",
   1.112 +                useMozillaPKIX
   1.113 +                  ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
   1.114 +                  : Cr.NS_OK,
   1.115 +                oldValidityPeriodOCSPResponseGood);
   1.116 +  add_ocsp_test("ocsp-stapling-expired.example.com",
   1.117 +                useMozillaPKIX
   1.118 +                  ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
   1.119 +                  : Cr.NS_OK,
   1.120 +                null);
   1.121 +  add_ocsp_test("ocsp-stapling-expired.example.com",
   1.122 +                useMozillaPKIX
   1.123 +                  ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
   1.124 +                  : Cr.NS_OK,
   1.125 +                null);
   1.126 +  // Of course, if the newer response indicates Revoked or Unknown,
   1.127 +  // that status must be returned.
   1.128 +  add_ocsp_test("ocsp-stapling-expired.example.com",
   1.129 +                getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE),
   1.130 +                ocspResponseRevoked);
   1.131 +  add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com",
   1.132 +                getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE),
   1.133 +                ocspResponseRevoked);
   1.134 +  add_ocsp_test("ocsp-stapling-expired.example.com",
   1.135 +                getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT),
   1.136 +                ocspResponseUnknown);
   1.137 +  add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com",
   1.138 +                getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT),
   1.139 +                ocspResponseUnknown);
   1.140 +
   1.141 +  if (useMozillaPKIX) {
   1.142 +    // If the response is expired but indicates Revoked or Unknown and a
   1.143 +    // newer status can't be fetched, the Revoked or Unknown status will
   1.144 +    // be returned.
   1.145 +    add_ocsp_test("ocsp-stapling-revoked-old.example.com",
   1.146 +                  getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE),
   1.147 +                  null);
   1.148 +    add_ocsp_test("ocsp-stapling-unknown-old.example.com",
   1.149 +                  getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT),
   1.150 +                  null);
   1.151 +    // If the response is expired but indicates Revoked or Unknown and
   1.152 +    // a newer status can be fetched and successfully verified, this
   1.153 +    // should result in a successful certificate verification.
   1.154 +    add_ocsp_test("ocsp-stapling-revoked-old.example.com", Cr.NS_OK,
   1.155 +                  ocspResponseGood);
   1.156 +    add_ocsp_test("ocsp-stapling-unknown-old.example.com", Cr.NS_OK,
   1.157 +                  ocspResponseGood);
   1.158 +    // If a newer status can be fetched but it fails to verify, the
   1.159 +    // Revoked or Unknown status of the expired stapled response
   1.160 +    // should be returned.
   1.161 +    add_ocsp_test("ocsp-stapling-revoked-old.example.com",
   1.162 +                  getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE),
   1.163 +                  expiredOCSPResponseGood);
   1.164 +    add_ocsp_test("ocsp-stapling-unknown-old.example.com",
   1.165 +                  getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT),
   1.166 +                  expiredOCSPResponseGood);
   1.167 +  }
   1.168 +
   1.169 +  if (useMozillaPKIX) {
   1.170 +    // These tests are verifying that an valid but very old response
   1.171 +    // is rejected as a valid stapled response, requiring a fetch
   1.172 +    // from the ocsp responder.
   1.173 +    add_ocsp_test("ocsp-stapling-ancient-valid.example.com", Cr.NS_OK,
   1.174 +                  ocspResponseGood);
   1.175 +    add_ocsp_test("ocsp-stapling-ancient-valid.example.com",
   1.176 +                  getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE),
   1.177 +                  ocspResponseRevoked);
   1.178 +    add_ocsp_test("ocsp-stapling-ancient-valid.example.com",
   1.179 +                  getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT),
   1.180 +                  ocspResponseUnknown);
   1.181 +  }
   1.182 +}
   1.183 +
   1.184 +function check_ocsp_stapling_telemetry() {
   1.185 +  let histogram = Cc["@mozilla.org/base/telemetry;1"]
   1.186 +                    .getService(Ci.nsITelemetry)
   1.187 +                    .getHistogramById("SSL_OCSP_STAPLING")
   1.188 +                    .snapshot();
   1.189 +  do_check_eq(histogram.counts[0], 2 * 0); // histogram bucket 0 is unused
   1.190 +  do_check_eq(histogram.counts[1], 2 * 0); // 0 connections with a good response
   1.191 +  do_check_eq(histogram.counts[2], 2 * 0); // 0 connections with no stapled resp.
   1.192 +  do_check_eq(histogram.counts[3], 2 * 12 + 9); // 12 connections with an expired response
   1.193 +                                                // +9 more mozilla::pkix-only expired responses
   1.194 +  do_check_eq(histogram.counts[4], 2 * 0); // 0 connections with bad responses
   1.195 +  run_next_test();
   1.196 +}

mercurial