1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/manager/ssl/tests/unit/test_ocsp_caching.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,130 @@ 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 +let gFetchCount = 0; 1.11 +let gGoodOCSPResponse = null; 1.12 + 1.13 +function generateGoodOCSPResponse() { 1.14 + let args = [ ["good", "localhostAndExampleCom", "unused" ] ]; 1.15 + let responses = generateOCSPResponses(args, "tlsserver"); 1.16 + return responses[0]; 1.17 +} 1.18 + 1.19 +function run_test() { 1.20 + do_get_profile(); 1.21 + Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true); 1.22 + add_tls_server_setup("OCSPStaplingServer"); 1.23 + 1.24 + let ocspResponder = new HttpServer(); 1.25 + ocspResponder.registerPrefixHandler("/", function(request, response) { 1.26 + ++gFetchCount; 1.27 + 1.28 + do_print("gFetchCount: " + gFetchCount); 1.29 + 1.30 + if (gFetchCount != 2) { 1.31 + do_print("returning 500 Internal Server Error"); 1.32 + 1.33 + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); 1.34 + let body = "Refusing to return a response"; 1.35 + response.bodyOutputStream.write(body, body.length); 1.36 + return; 1.37 + } 1.38 + 1.39 + do_print("returning 200 OK"); 1.40 + response.setStatusLine(request.httpVersion, 200, "OK"); 1.41 + response.setHeader("Content-Type", "application/ocsp-response"); 1.42 + response.write(gGoodOCSPResponse); 1.43 + }); 1.44 + ocspResponder.start(8080); 1.45 + 1.46 + add_tests_in_mode(true); 1.47 + add_tests_in_mode(false); 1.48 + 1.49 + add_test(function() { ocspResponder.stop(run_next_test); }); 1.50 + run_next_test(); 1.51 +} 1.52 + 1.53 +function add_tests_in_mode(useMozillaPKIX) { 1.54 + add_test(function () { 1.55 + Services.prefs.setBoolPref("security.use_mozillapkix_verification", 1.56 + useMozillaPKIX); 1.57 + run_next_test(); 1.58 + }); 1.59 + 1.60 + // This test assumes that OCSPStaplingServer uses the same cert for 1.61 + // ocsp-stapling-unknown.example.com and ocsp-stapling-none.example.com. 1.62 + 1.63 + // Get an Unknown response for the *.exmaple.com cert and put it in the 1.64 + // OCSP cache. 1.65 + add_connection_test("ocsp-stapling-unknown.example.com", 1.66 + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT), 1.67 + clearSessionCache); 1.68 + add_test(function() { do_check_eq(gFetchCount, 0); run_next_test(); }); 1.69 + 1.70 + // A failure to retrieve an OCSP response must result in the cached Unkown 1.71 + // response being recognized and honored. 1.72 + add_connection_test("ocsp-stapling-none.example.com", 1.73 + getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT), 1.74 + clearSessionCache); 1.75 + add_test(function() { do_check_eq(gFetchCount, 1); run_next_test(); }); 1.76 + 1.77 + // A valid Good response from the OCSP responder must override the cached 1.78 + // Unknown response. 1.79 + // 1.80 + // Note that We need to make sure that the Unknown response and the Good 1.81 + // response have different thisUpdate timestamps; otherwise, the Good 1.82 + // response will be seen as "not newer" and it won't replace the existing 1.83 + // entry. 1.84 + add_test(function() { 1.85 + let duration = 1200; 1.86 + do_print("Sleeping for " + duration + "ms"); 1.87 + let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); 1.88 + timer.initWithCallback(run_next_test, duration, Ci.nsITimer.TYPE_ONE_SHOT); 1.89 + }); 1.90 + add_test(function() { 1.91 + gGoodOCSPResponse = generateGoodOCSPResponse(); 1.92 + run_next_test(); 1.93 + }); 1.94 + add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK, 1.95 + clearSessionCache); 1.96 + add_test(function() { do_check_eq(gFetchCount, 2); run_next_test(); }); 1.97 + 1.98 + // The Good response retrieved from the previous fetch must have replaced 1.99 + // the Unknown response in the cache, resulting in the catched Good response 1.100 + // being returned and no fetch. 1.101 + add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK, 1.102 + clearSessionCache); 1.103 + add_test(function() { do_check_eq(gFetchCount, 2); run_next_test(); }); 1.104 + 1.105 + 1.106 + //--------------------------------------------------------------------------- 1.107 + 1.108 + // Reset state 1.109 + add_test(function() { clearOCSPCache(); gFetchCount = 0; run_next_test(); }); 1.110 + 1.111 + // A failure to retrieve an OCSP response will result in an error entry being 1.112 + // added to the cache. 1.113 + add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK, 1.114 + clearSessionCache); 1.115 + add_test(function() { do_check_eq(gFetchCount, 1); run_next_test(); }); 1.116 + 1.117 + // The error entry will prevent a fetch from happening for a while. 1.118 + add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK, 1.119 + clearSessionCache); 1.120 + add_test(function() { do_check_eq(gFetchCount, 1); run_next_test(); }); 1.121 + 1.122 + // The error entry must not prevent a stapled OCSP response from being 1.123 + // honored. 1.124 + add_connection_test("ocsp-stapling-revoked.example.com", 1.125 + getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE), 1.126 + clearSessionCache); 1.127 + add_test(function() { do_check_eq(gFetchCount, 1); run_next_test(); }); 1.128 + 1.129 + //--------------------------------------------------------------------------- 1.130 + 1.131 + // Reset state 1.132 + add_test(function() { clearOCSPCache(); gFetchCount = 0; run_next_test(); }); 1.133 +}