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 +}