security/manager/ssl/tests/unit/test_ocsp_stapling.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 and without OCSP stapling enabled to determine that good
michael@0 9 // things happen and bad things don't.
michael@0 10
michael@0 11 let gExpectOCSPRequest;
michael@0 12
michael@0 13 function add_ocsp_test(aHost, aExpectedResult, aStaplingEnabled) {
michael@0 14 add_connection_test(aHost, aExpectedResult,
michael@0 15 function() {
michael@0 16 gExpectOCSPRequest = !aStaplingEnabled;
michael@0 17 clearOCSPCache();
michael@0 18 clearSessionCache();
michael@0 19 Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling",
michael@0 20 aStaplingEnabled);
michael@0 21 });
michael@0 22 }
michael@0 23
michael@0 24 function add_tests_in_mode(useMozillaPKIX, certDB, otherTestCA) {
michael@0 25 add_test(function () {
michael@0 26 Services.prefs.setBoolPref("security.use_mozillapkix_verification",
michael@0 27 useMozillaPKIX);
michael@0 28 run_next_test();
michael@0 29 });
michael@0 30
michael@0 31 // In the absence of OCSP stapling, these should actually all work.
michael@0 32 add_ocsp_test("ocsp-stapling-good.example.com", Cr.NS_OK, false);
michael@0 33 add_ocsp_test("ocsp-stapling-revoked.example.com", Cr.NS_OK, false);
michael@0 34 add_ocsp_test("ocsp-stapling-good-other-ca.example.com", Cr.NS_OK, false);
michael@0 35 add_ocsp_test("ocsp-stapling-malformed.example.com", Cr.NS_OK, false);
michael@0 36 add_ocsp_test("ocsp-stapling-srverr.example.com", Cr.NS_OK, false);
michael@0 37 add_ocsp_test("ocsp-stapling-trylater.example.com", Cr.NS_OK, false);
michael@0 38 add_ocsp_test("ocsp-stapling-needssig.example.com", Cr.NS_OK, false);
michael@0 39 add_ocsp_test("ocsp-stapling-unauthorized.example.com", Cr.NS_OK, false);
michael@0 40 add_ocsp_test("ocsp-stapling-unknown.example.com", Cr.NS_OK, false);
michael@0 41 add_ocsp_test("ocsp-stapling-good-other.example.com", Cr.NS_OK, false);
michael@0 42 add_ocsp_test("ocsp-stapling-none.example.com", Cr.NS_OK, false);
michael@0 43 add_ocsp_test("ocsp-stapling-expired.example.com", Cr.NS_OK, false);
michael@0 44 add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com", Cr.NS_OK, false);
michael@0 45 add_ocsp_test("ocsp-stapling-skip-responseBytes.example.com", Cr.NS_OK, false);
michael@0 46 add_ocsp_test("ocsp-stapling-critical-extension.example.com", Cr.NS_OK, false);
michael@0 47 add_ocsp_test("ocsp-stapling-noncritical-extension.example.com", Cr.NS_OK, false);
michael@0 48 add_ocsp_test("ocsp-stapling-empty-extensions.example.com", Cr.NS_OK, false);
michael@0 49
michael@0 50 // Now test OCSP stapling
michael@0 51 // The following error codes are defined in security/nss/lib/util/SECerrs.h
michael@0 52
michael@0 53 add_ocsp_test("ocsp-stapling-good.example.com", Cr.NS_OK, true);
michael@0 54
michael@0 55 add_ocsp_test("ocsp-stapling-revoked.example.com",
michael@0 56 getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE), true);
michael@0 57
michael@0 58 // SEC_ERROR_OCSP_INVALID_SIGNING_CERT vs SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE
michael@0 59 // depends on whether the CA that signed the response is a trusted CA
michael@0 60 // (but only with the classic implementation - mozilla::pkix always
michael@0 61 // results in the error SEC_ERROR_OCSP_INVALID_SIGNING_CERT).
michael@0 62
michael@0 63 // This stapled response is from a CA that is untrusted and did not issue
michael@0 64 // the server's certificate.
michael@0 65 add_test(function() {
michael@0 66 certDB.setCertTrust(otherTestCA, Ci.nsIX509Cert.CA_CERT,
michael@0 67 Ci.nsIX509CertDB.UNTRUSTED);
michael@0 68 run_next_test();
michael@0 69 });
michael@0 70 add_ocsp_test("ocsp-stapling-good-other-ca.example.com",
michael@0 71 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_INVALID_SIGNING_CERT), true);
michael@0 72
michael@0 73 // The stapled response is from a CA that is trusted but did not issue the
michael@0 74 // server's certificate.
michael@0 75 add_test(function() {
michael@0 76 certDB.setCertTrust(otherTestCA, Ci.nsIX509Cert.CA_CERT,
michael@0 77 Ci.nsIX509CertDB.TRUSTED_SSL);
michael@0 78 run_next_test();
michael@0 79 });
michael@0 80 // TODO(bug 979055): When using ByName instead of ByKey, the error here is
michael@0 81 // SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE. We should be testing both cases.
michael@0 82 add_ocsp_test("ocsp-stapling-good-other-ca.example.com",
michael@0 83 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_INVALID_SIGNING_CERT),
michael@0 84 true);
michael@0 85
michael@0 86 // TODO: Test the case where the signing cert can't be found at all, which
michael@0 87 // will result in SEC_ERROR_BAD_DATABASE in the NSS classic case.
michael@0 88
michael@0 89 add_ocsp_test("ocsp-stapling-malformed.example.com",
michael@0 90 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_MALFORMED_REQUEST), true);
michael@0 91 add_ocsp_test("ocsp-stapling-srverr.example.com",
michael@0 92 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_SERVER_ERROR), true);
michael@0 93 add_ocsp_test("ocsp-stapling-trylater.example.com",
michael@0 94 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_TRY_SERVER_LATER), true);
michael@0 95 add_ocsp_test("ocsp-stapling-needssig.example.com",
michael@0 96 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG), true);
michael@0 97 add_ocsp_test("ocsp-stapling-unauthorized.example.com",
michael@0 98 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST),
michael@0 99 true);
michael@0 100 add_ocsp_test("ocsp-stapling-unknown.example.com",
michael@0 101 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT), true);
michael@0 102 add_ocsp_test("ocsp-stapling-good-other.example.com",
michael@0 103 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT), true);
michael@0 104 // If the server doesn't staple an OCSP response, we continue as normal
michael@0 105 // (this means that even though stapling is enabled, we expect an OCSP
michael@0 106 // request).
michael@0 107 add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK,
michael@0 108 function() {
michael@0 109 gExpectOCSPRequest = true;
michael@0 110 clearOCSPCache();
michael@0 111 clearSessionCache();
michael@0 112 Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
michael@0 113 }
michael@0 114 );
michael@0 115 add_ocsp_test("ocsp-stapling-empty.example.com",
michael@0 116 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_MALFORMED_RESPONSE), true);
michael@0 117
michael@0 118 // TODO(bug 979070): NSS can't handle this yet.
michael@0 119 if (useMozillaPKIX) {
michael@0 120 add_ocsp_test("ocsp-stapling-skip-responseBytes.example.com",
michael@0 121 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_MALFORMED_RESPONSE), true);
michael@0 122 }
michael@0 123
michael@0 124 add_ocsp_test("ocsp-stapling-critical-extension.example.com",
michael@0 125 useMozillaPKIX
michael@0 126 ? getXPCOMStatusFromNSS(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION)
michael@0 127 : Cr.NS_OK, // TODO(bug 987426): NSS doesn't handle unknown critical extensions
michael@0 128 true);
michael@0 129 add_ocsp_test("ocsp-stapling-noncritical-extension.example.com", Cr.NS_OK, true);
michael@0 130 // TODO(bug 997994): Disallow empty Extensions in responses
michael@0 131 add_ocsp_test("ocsp-stapling-empty-extensions.example.com", Cr.NS_OK, true);
michael@0 132
michael@0 133 add_ocsp_test("ocsp-stapling-delegated-included.example.com", Cr.NS_OK, true);
michael@0 134 add_ocsp_test("ocsp-stapling-delegated-included-last.example.com", Cr.NS_OK, true);
michael@0 135 add_ocsp_test("ocsp-stapling-delegated-missing.example.com",
michael@0 136 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_INVALID_SIGNING_CERT), true);
michael@0 137 add_ocsp_test("ocsp-stapling-delegated-missing-multiple.example.com",
michael@0 138 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_INVALID_SIGNING_CERT), true);
michael@0 139 add_ocsp_test("ocsp-stapling-delegated-no-extKeyUsage.example.com",
michael@0 140 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_INVALID_SIGNING_CERT), true);
michael@0 141 add_ocsp_test("ocsp-stapling-delegated-from-intermediate.example.com",
michael@0 142 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_INVALID_SIGNING_CERT), true);
michael@0 143 add_ocsp_test("ocsp-stapling-delegated-keyUsage-crlSigning.example.com",
michael@0 144 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_INVALID_SIGNING_CERT), true);
michael@0 145 add_ocsp_test("ocsp-stapling-delegated-wrong-extKeyUsage.example.com",
michael@0 146 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_INVALID_SIGNING_CERT), true);
michael@0 147
michael@0 148 // ocsp-stapling-expired.example.com and
michael@0 149 // ocsp-stapling-expired-fresh-ca.example.com are handled in
michael@0 150 // test_ocsp_stapling_expired.js
michael@0 151 }
michael@0 152
michael@0 153 function check_ocsp_stapling_telemetry() {
michael@0 154 let histogram = Cc["@mozilla.org/base/telemetry;1"]
michael@0 155 .getService(Ci.nsITelemetry)
michael@0 156 .getHistogramById("SSL_OCSP_STAPLING")
michael@0 157 .snapshot();
michael@0 158 do_check_eq(histogram.counts[0], 2 * 0); // histogram bucket 0 is unused
michael@0 159 do_check_eq(histogram.counts[1], 5 + 6); // 5 or 6 connections with a good response (bug 987426)
michael@0 160 do_check_eq(histogram.counts[2], 2 * 18); // 18 connections with no stapled resp.
michael@0 161 do_check_eq(histogram.counts[3], 2 * 0); // 0 connections with an expired response
michael@0 162 do_check_eq(histogram.counts[4], 19 + 17); // 19 or 17 connections with bad responses (bug 979070, bug 987426)
michael@0 163 run_next_test();
michael@0 164 }
michael@0 165
michael@0 166 function run_test() {
michael@0 167 do_get_profile();
michael@0 168
michael@0 169 let certDB = Cc["@mozilla.org/security/x509certdb;1"]
michael@0 170 .getService(Ci.nsIX509CertDB);
michael@0 171 let otherTestCAFile = do_get_file("tlsserver/other-test-ca.der", false);
michael@0 172 let otherTestCADER = readFile(otherTestCAFile);
michael@0 173 let otherTestCA = certDB.constructX509(otherTestCADER, otherTestCADER.length);
michael@0 174
michael@0 175 let fakeOCSPResponder = new HttpServer();
michael@0 176 fakeOCSPResponder.registerPrefixHandler("/", function (request, response) {
michael@0 177 response.setStatusLine(request.httpVersion, 500, "Internal Server Error");
michael@0 178 do_check_true(gExpectOCSPRequest);
michael@0 179 });
michael@0 180 fakeOCSPResponder.start(8080);
michael@0 181
michael@0 182 add_tls_server_setup("OCSPStaplingServer");
michael@0 183
michael@0 184 add_tests_in_mode(true, certDB, otherTestCA);
michael@0 185 add_tests_in_mode(false, certDB, otherTestCA);
michael@0 186
michael@0 187 add_test(function () {
michael@0 188 fakeOCSPResponder.stop(check_ocsp_stapling_telemetry);
michael@0 189 });
michael@0 190
michael@0 191 run_next_test();
michael@0 192 }

mercurial