security/manager/ssl/tests/unit/test_ocsp_stapling_expired.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 // -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 // This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 // License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 5 "use strict";
michael@0 6
michael@0 7 // In which we connect to a number of domains (as faked by a server running
michael@0 8 // locally) with OCSP stapling enabled to determine that good things happen
michael@0 9 // and bad things don't, specifically with respect to various expired OCSP
michael@0 10 // responses (stapled and otherwise).
michael@0 11
michael@0 12 let gCurrentOCSPResponse = null;
michael@0 13 let gOCSPRequestCount = 0;
michael@0 14
michael@0 15 function add_ocsp_test(aHost, aExpectedResult, aOCSPResponseToServe) {
michael@0 16 add_connection_test(aHost, aExpectedResult,
michael@0 17 function() {
michael@0 18 clearOCSPCache();
michael@0 19 clearSessionCache();
michael@0 20 gCurrentOCSPResponse = aOCSPResponseToServe;
michael@0 21 gOCSPRequestCount = 0;
michael@0 22 },
michael@0 23 function() {
michael@0 24 do_check_eq(gOCSPRequestCount, 1);
michael@0 25 });
michael@0 26 }
michael@0 27
michael@0 28 do_get_profile();
michael@0 29 Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
michael@0 30 let args = [["good", "localhostAndExampleCom", "unused"],
michael@0 31 ["expiredresponse", "localhostAndExampleCom", "unused"],
michael@0 32 ["oldvalidperiod", "localhostAndExampleCom", "unused"],
michael@0 33 ["revoked", "localhostAndExampleCom", "unused"],
michael@0 34 ["unknown", "localhostAndExampleCom", "unused"],
michael@0 35 ];
michael@0 36 let ocspResponses = generateOCSPResponses(args, "tlsserver");
michael@0 37 // Fresh response, certificate is good.
michael@0 38 let ocspResponseGood = ocspResponses[0];
michael@0 39 // Expired response, certificate is good.
michael@0 40 let expiredOCSPResponseGood = ocspResponses[1];
michael@0 41 // Fresh signature, old validity period, certificate is good.
michael@0 42 let oldValidityPeriodOCSPResponseGood = ocspResponses[2];
michael@0 43 // Fresh signature, certificate is revoked.
michael@0 44 let ocspResponseRevoked = ocspResponses[3];
michael@0 45 // Fresh signature, certificate is unknown.
michael@0 46 let ocspResponseUnknown = ocspResponses[4];
michael@0 47
michael@0 48 function run_test() {
michael@0 49 let ocspResponder = new HttpServer();
michael@0 50 ocspResponder.registerPrefixHandler("/", function(request, response) {
michael@0 51 if (gCurrentOCSPResponse) {
michael@0 52 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 53 response.setHeader("Content-Type", "application/ocsp-response");
michael@0 54 response.write(gCurrentOCSPResponse);
michael@0 55 } else {
michael@0 56 response.setStatusLine(request.httpVersion, 500, "Internal Server Error");
michael@0 57 response.write("Internal Server Error");
michael@0 58 }
michael@0 59 gOCSPRequestCount++;
michael@0 60 });
michael@0 61 ocspResponder.start(8080);
michael@0 62 add_tls_server_setup("OCSPStaplingServer");
michael@0 63 add_tests_in_mode(true);
michael@0 64 add_tests_in_mode(false);
michael@0 65 add_test(function () { ocspResponder.stop(run_next_test); });
michael@0 66 add_test(check_ocsp_stapling_telemetry);
michael@0 67 run_next_test();
michael@0 68 }
michael@0 69
michael@0 70 function add_tests_in_mode(useMozillaPKIX)
michael@0 71 {
michael@0 72 add_test(function () {
michael@0 73 Services.prefs.setBoolPref("security.use_mozillapkix_verification",
michael@0 74 useMozillaPKIX);
michael@0 75 run_next_test();
michael@0 76 });
michael@0 77
michael@0 78 // In these tests, the OCSP stapling server gives us a stapled
michael@0 79 // response based on the host name ("ocsp-stapling-expired" or
michael@0 80 // "ocsp-stapling-expired-fresh-ca"). We then ensure that we're
michael@0 81 // properly falling back to fetching revocation information.
michael@0 82 // For ocsp-stapling-expired.example.com, the OCSP stapling server
michael@0 83 // staples an expired OCSP response. The certificate has not expired.
michael@0 84 // For ocsp-stapling-expired-fresh-ca.example.com, the OCSP stapling
michael@0 85 // server staples an OCSP response with a recent signature but with an
michael@0 86 // out-of-date validity period. The certificate has not expired.
michael@0 87 add_ocsp_test("ocsp-stapling-expired.example.com", Cr.NS_OK,
michael@0 88 ocspResponseGood);
michael@0 89 add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com", Cr.NS_OK,
michael@0 90 ocspResponseGood);
michael@0 91 // With mozilla::pkix, if we can't fetch a more recent response when
michael@0 92 // given an expired stapled response, we terminate the connection.
michael@0 93 add_ocsp_test("ocsp-stapling-expired.example.com",
michael@0 94 useMozillaPKIX
michael@0 95 ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
michael@0 96 : Cr.NS_OK,
michael@0 97 expiredOCSPResponseGood);
michael@0 98 add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com",
michael@0 99 useMozillaPKIX
michael@0 100 ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
michael@0 101 : Cr.NS_OK,
michael@0 102 expiredOCSPResponseGood);
michael@0 103 add_ocsp_test("ocsp-stapling-expired.example.com",
michael@0 104 useMozillaPKIX
michael@0 105 ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
michael@0 106 : Cr.NS_OK,
michael@0 107 oldValidityPeriodOCSPResponseGood);
michael@0 108 add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com",
michael@0 109 useMozillaPKIX
michael@0 110 ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
michael@0 111 : Cr.NS_OK,
michael@0 112 oldValidityPeriodOCSPResponseGood);
michael@0 113 add_ocsp_test("ocsp-stapling-expired.example.com",
michael@0 114 useMozillaPKIX
michael@0 115 ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
michael@0 116 : Cr.NS_OK,
michael@0 117 null);
michael@0 118 add_ocsp_test("ocsp-stapling-expired.example.com",
michael@0 119 useMozillaPKIX
michael@0 120 ? getXPCOMStatusFromNSS(SEC_ERROR_OCSP_OLD_RESPONSE)
michael@0 121 : Cr.NS_OK,
michael@0 122 null);
michael@0 123 // Of course, if the newer response indicates Revoked or Unknown,
michael@0 124 // that status must be returned.
michael@0 125 add_ocsp_test("ocsp-stapling-expired.example.com",
michael@0 126 getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE),
michael@0 127 ocspResponseRevoked);
michael@0 128 add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com",
michael@0 129 getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE),
michael@0 130 ocspResponseRevoked);
michael@0 131 add_ocsp_test("ocsp-stapling-expired.example.com",
michael@0 132 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT),
michael@0 133 ocspResponseUnknown);
michael@0 134 add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com",
michael@0 135 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT),
michael@0 136 ocspResponseUnknown);
michael@0 137
michael@0 138 if (useMozillaPKIX) {
michael@0 139 // If the response is expired but indicates Revoked or Unknown and a
michael@0 140 // newer status can't be fetched, the Revoked or Unknown status will
michael@0 141 // be returned.
michael@0 142 add_ocsp_test("ocsp-stapling-revoked-old.example.com",
michael@0 143 getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE),
michael@0 144 null);
michael@0 145 add_ocsp_test("ocsp-stapling-unknown-old.example.com",
michael@0 146 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT),
michael@0 147 null);
michael@0 148 // If the response is expired but indicates Revoked or Unknown and
michael@0 149 // a newer status can be fetched and successfully verified, this
michael@0 150 // should result in a successful certificate verification.
michael@0 151 add_ocsp_test("ocsp-stapling-revoked-old.example.com", Cr.NS_OK,
michael@0 152 ocspResponseGood);
michael@0 153 add_ocsp_test("ocsp-stapling-unknown-old.example.com", Cr.NS_OK,
michael@0 154 ocspResponseGood);
michael@0 155 // If a newer status can be fetched but it fails to verify, the
michael@0 156 // Revoked or Unknown status of the expired stapled response
michael@0 157 // should be returned.
michael@0 158 add_ocsp_test("ocsp-stapling-revoked-old.example.com",
michael@0 159 getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE),
michael@0 160 expiredOCSPResponseGood);
michael@0 161 add_ocsp_test("ocsp-stapling-unknown-old.example.com",
michael@0 162 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT),
michael@0 163 expiredOCSPResponseGood);
michael@0 164 }
michael@0 165
michael@0 166 if (useMozillaPKIX) {
michael@0 167 // These tests are verifying that an valid but very old response
michael@0 168 // is rejected as a valid stapled response, requiring a fetch
michael@0 169 // from the ocsp responder.
michael@0 170 add_ocsp_test("ocsp-stapling-ancient-valid.example.com", Cr.NS_OK,
michael@0 171 ocspResponseGood);
michael@0 172 add_ocsp_test("ocsp-stapling-ancient-valid.example.com",
michael@0 173 getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE),
michael@0 174 ocspResponseRevoked);
michael@0 175 add_ocsp_test("ocsp-stapling-ancient-valid.example.com",
michael@0 176 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT),
michael@0 177 ocspResponseUnknown);
michael@0 178 }
michael@0 179 }
michael@0 180
michael@0 181 function check_ocsp_stapling_telemetry() {
michael@0 182 let histogram = Cc["@mozilla.org/base/telemetry;1"]
michael@0 183 .getService(Ci.nsITelemetry)
michael@0 184 .getHistogramById("SSL_OCSP_STAPLING")
michael@0 185 .snapshot();
michael@0 186 do_check_eq(histogram.counts[0], 2 * 0); // histogram bucket 0 is unused
michael@0 187 do_check_eq(histogram.counts[1], 2 * 0); // 0 connections with a good response
michael@0 188 do_check_eq(histogram.counts[2], 2 * 0); // 0 connections with no stapled resp.
michael@0 189 do_check_eq(histogram.counts[3], 2 * 12 + 9); // 12 connections with an expired response
michael@0 190 // +9 more mozilla::pkix-only expired responses
michael@0 191 do_check_eq(histogram.counts[4], 2 * 0); // 0 connections with bad responses
michael@0 192 run_next_test();
michael@0 193 }

mercurial