1 // -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
2 // This Source Code Form is subject to the terms of the Mozilla Public
3 // License, v. 2.0. If a copy of the MPL was not distributed with this
4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 // Enable the collection (during test) for all products so even products
8 // that don't collect the data will be able to run the test without failure.
9 Services.prefs.setBoolPref(
10 "toolkit.telemetry.testing.overrideProductsCheck",
14 // In which we connect to a number of domains (as faked by a server running
15 // locally) with OCSP stapling enabled to determine that good things happen
16 // and bad things don't, specifically with respect to various expired OCSP
17 // responses (stapled and otherwise).
18 // According to RFC 6066, if a stapled OCSP response can't be satisfactorilly
19 // verified, the client should terminate the connection. Unfortunately, due to
20 // some bugs where servers will staple any old garbage without verifying it, we
21 // can't be this strict in practice. Originally this caveat only applied to
22 // expired responses, but recent high-profile failures have caused us to expand
23 // this to "try later" responses and responses where the signing certificate
24 // doesn't verify successfully.
26 var gCurrentOCSPResponse = null;
27 var gOCSPRequestCount = 0;
29 function add_ocsp_test(
41 gCurrentOCSPResponse = aOCSPResponseToServe;
42 gOCSPRequestCount = 0;
47 aExpectedRequestCount,
49 aExpectedRequestCount +
50 " fallback OCSP request" +
51 (aExpectedRequestCount == 1 ? "" : "s")
58 Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
59 Services.prefs.setIntPref("security.OCSP.enabled", 1);
60 // Sometimes this test will fail on android due to an OCSP request timing out.
61 // That aspect of OCSP requests is not what we're testing here, so we can just
62 // bump the timeout and hopefully avoid these failures.
63 Services.prefs.setIntPref("security.OCSP.timeoutMilliseconds.soft", 5000);
65 ["good", "default-ee", "unused", 0],
66 ["expiredresponse", "default-ee", "unused", 0],
67 ["oldvalidperiod", "default-ee", "unused", 0],
68 ["revoked", "default-ee", "unused", 0],
69 ["unknown", "default-ee", "unused", 0],
70 ["good", "must-staple-ee", "unused", 0],
72 var ocspResponses = generateOCSPResponses(args, "ocsp_certs");
73 // Fresh response, certificate is good.
74 var ocspResponseGood = ocspResponses[0];
75 // Expired response, certificate is good.
76 var expiredOCSPResponseGood = ocspResponses[1];
77 // Fresh signature, old validity period, certificate is good.
78 var oldValidityPeriodOCSPResponseGood = ocspResponses[2];
79 // Fresh signature, certificate is revoked.
80 var ocspResponseRevoked = ocspResponses[3];
81 // Fresh signature, certificate is unknown.
82 var ocspResponseUnknown = ocspResponses[4];
83 var ocspResponseGoodMustStaple = ocspResponses[5];
85 // sometimes we expect a result without re-fetch
87 // but sometimes, since a bad response is in the cache, OCSP fetch will be
88 // attempted for each validation - in practice, for these test certs, this
89 // means 2 requests because various key sizes are tried.
93 let ocspResponder = new HttpServer();
94 ocspResponder.registerPrefixHandler("/", function (request, response) {
95 if (gCurrentOCSPResponse) {
96 response.setStatusLine(request.httpVersion, 200, "OK");
97 response.setHeader("Content-Type", "application/ocsp-response");
98 response.write(gCurrentOCSPResponse);
100 response.setStatusLine(request.httpVersion, 500, "Internal Server Error");
101 response.write("Internal Server Error");
105 ocspResponder.start(8888);
106 add_tls_server_setup("OCSPStaplingServer", "ocsp_certs");
108 // In these tests, the OCSP stapling server gives us a stapled
109 // response based on the host name ("ocsp-stapling-expired" or
110 // "ocsp-stapling-expired-fresh-ca"). We then ensure that we're
111 // properly falling back to fetching revocation information.
112 // For ocsp-stapling-expired.example.com, the OCSP stapling server
113 // staples an expired OCSP response. The certificate has not expired.
114 // For ocsp-stapling-expired-fresh-ca.example.com, the OCSP stapling
115 // server staples an OCSP response with a recent signature but with an
116 // out-of-date validity period. The certificate has not expired.
118 "ocsp-stapling-expired.example.com",
124 "ocsp-stapling-expired-fresh-ca.example.com",
129 // if we can't fetch a more recent response when
130 // given an expired stapled response, we terminate the connection.
132 "ocsp-stapling-expired.example.com",
133 SEC_ERROR_OCSP_OLD_RESPONSE,
134 expiredOCSPResponseGood,
138 "ocsp-stapling-expired-fresh-ca.example.com",
139 SEC_ERROR_OCSP_OLD_RESPONSE,
140 expiredOCSPResponseGood,
144 "ocsp-stapling-expired.example.com",
145 SEC_ERROR_OCSP_OLD_RESPONSE,
146 oldValidityPeriodOCSPResponseGood,
150 "ocsp-stapling-expired-fresh-ca.example.com",
151 SEC_ERROR_OCSP_OLD_RESPONSE,
152 oldValidityPeriodOCSPResponseGood,
156 "ocsp-stapling-expired.example.com",
157 SEC_ERROR_OCSP_OLD_RESPONSE,
162 "ocsp-stapling-expired.example.com",
163 SEC_ERROR_OCSP_OLD_RESPONSE,
167 // Of course, if the newer response indicates Revoked or Unknown,
168 // that status must be returned.
170 "ocsp-stapling-expired.example.com",
171 SEC_ERROR_REVOKED_CERTIFICATE,
176 "ocsp-stapling-expired-fresh-ca.example.com",
177 SEC_ERROR_REVOKED_CERTIFICATE,
182 "ocsp-stapling-expired.example.com",
183 SEC_ERROR_OCSP_UNKNOWN_CERT,
188 "ocsp-stapling-expired-fresh-ca.example.com",
189 SEC_ERROR_OCSP_UNKNOWN_CERT,
194 // If the response is expired but indicates Revoked or Unknown and a
195 // newer status can't be fetched, the Revoked or Unknown status will
198 "ocsp-stapling-revoked-old.example.com",
199 SEC_ERROR_REVOKED_CERTIFICATE,
204 "ocsp-stapling-unknown-old.example.com",
205 SEC_ERROR_OCSP_UNKNOWN_CERT,
209 // If the response is expired but indicates Revoked or Unknown and
210 // a newer status can be fetched and successfully verified, this
211 // should result in a successful certificate verification.
213 "ocsp-stapling-revoked-old.example.com",
219 "ocsp-stapling-unknown-old.example.com",
224 // If a newer status can be fetched but it fails to verify, the
225 // Revoked or Unknown status of the expired stapled response
226 // should be returned.
228 "ocsp-stapling-revoked-old.example.com",
229 SEC_ERROR_REVOKED_CERTIFICATE,
230 expiredOCSPResponseGood,
234 "ocsp-stapling-unknown-old.example.com",
235 SEC_ERROR_OCSP_UNKNOWN_CERT,
236 expiredOCSPResponseGood,
240 // These tests are verifying that an valid but very old response
241 // is rejected as a valid stapled response, requiring a fetch
242 // from the ocsp responder.
244 "ocsp-stapling-ancient-valid.example.com",
250 "ocsp-stapling-ancient-valid.example.com",
251 SEC_ERROR_REVOKED_CERTIFICATE,
256 "ocsp-stapling-ancient-valid.example.com",
257 SEC_ERROR_OCSP_UNKNOWN_CERT,
262 // Test how OCSP-must-staple (i.e. TLS feature) interacts with stapled OCSP
263 // responses that don't successfully verify.
264 // A strict reading of the relevant RFCs might say that these connections
265 // should all fail because a satisfactory stapled OCSP response is not
266 // present, but for compatibility reasons we fall back to active OCSP fetching
267 // in these situations. If the fetch succeeds, then connection succeeds.
269 "ocsp-stapling-must-staple-expired.example.com",
271 ocspResponseGoodMustStaple,
275 "ocsp-stapling-must-staple-try-later.example.com",
277 ocspResponseGoodMustStaple,
281 "ocsp-stapling-must-staple-invalid-signer.example.com",
283 ocspResponseGoodMustStaple,
287 add_test(function () {
288 ocspResponder.stop(run_next_test);
290 add_test(check_ocsp_stapling_telemetry);
294 function check_ocsp_stapling_telemetry() {
295 let histogram = Services.telemetry
296 .getHistogramById("SSL_OCSP_STAPLING")
299 histogram.values[0] || 0,
301 "Should have 0 connections for unused histogram bucket 0"
304 histogram.values[1] || 0,
306 "Actual and expected connections with a good response should match"
309 histogram.values[2] || 0,
311 "Actual and expected connections with no stapled response should match"
316 "Actual and expected connections with an expired response should match"
321 "Actual and expected connections with bad responses should match"