|
1 // -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. |
|
5 "use strict"; |
|
6 |
|
7 let gFetchCount = 0; |
|
8 let gGoodOCSPResponse = null; |
|
9 |
|
10 function generateGoodOCSPResponse() { |
|
11 let args = [ ["good", "localhostAndExampleCom", "unused" ] ]; |
|
12 let responses = generateOCSPResponses(args, "tlsserver"); |
|
13 return responses[0]; |
|
14 } |
|
15 |
|
16 function run_test() { |
|
17 do_get_profile(); |
|
18 Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true); |
|
19 add_tls_server_setup("OCSPStaplingServer"); |
|
20 |
|
21 let ocspResponder = new HttpServer(); |
|
22 ocspResponder.registerPrefixHandler("/", function(request, response) { |
|
23 ++gFetchCount; |
|
24 |
|
25 do_print("gFetchCount: " + gFetchCount); |
|
26 |
|
27 if (gFetchCount != 2) { |
|
28 do_print("returning 500 Internal Server Error"); |
|
29 |
|
30 response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); |
|
31 let body = "Refusing to return a response"; |
|
32 response.bodyOutputStream.write(body, body.length); |
|
33 return; |
|
34 } |
|
35 |
|
36 do_print("returning 200 OK"); |
|
37 response.setStatusLine(request.httpVersion, 200, "OK"); |
|
38 response.setHeader("Content-Type", "application/ocsp-response"); |
|
39 response.write(gGoodOCSPResponse); |
|
40 }); |
|
41 ocspResponder.start(8080); |
|
42 |
|
43 add_tests_in_mode(true); |
|
44 add_tests_in_mode(false); |
|
45 |
|
46 add_test(function() { ocspResponder.stop(run_next_test); }); |
|
47 run_next_test(); |
|
48 } |
|
49 |
|
50 function add_tests_in_mode(useMozillaPKIX) { |
|
51 add_test(function () { |
|
52 Services.prefs.setBoolPref("security.use_mozillapkix_verification", |
|
53 useMozillaPKIX); |
|
54 run_next_test(); |
|
55 }); |
|
56 |
|
57 // This test assumes that OCSPStaplingServer uses the same cert for |
|
58 // ocsp-stapling-unknown.example.com and ocsp-stapling-none.example.com. |
|
59 |
|
60 // Get an Unknown response for the *.exmaple.com cert and put it in the |
|
61 // OCSP cache. |
|
62 add_connection_test("ocsp-stapling-unknown.example.com", |
|
63 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT), |
|
64 clearSessionCache); |
|
65 add_test(function() { do_check_eq(gFetchCount, 0); run_next_test(); }); |
|
66 |
|
67 // A failure to retrieve an OCSP response must result in the cached Unkown |
|
68 // response being recognized and honored. |
|
69 add_connection_test("ocsp-stapling-none.example.com", |
|
70 getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT), |
|
71 clearSessionCache); |
|
72 add_test(function() { do_check_eq(gFetchCount, 1); run_next_test(); }); |
|
73 |
|
74 // A valid Good response from the OCSP responder must override the cached |
|
75 // Unknown response. |
|
76 // |
|
77 // Note that We need to make sure that the Unknown response and the Good |
|
78 // response have different thisUpdate timestamps; otherwise, the Good |
|
79 // response will be seen as "not newer" and it won't replace the existing |
|
80 // entry. |
|
81 add_test(function() { |
|
82 let duration = 1200; |
|
83 do_print("Sleeping for " + duration + "ms"); |
|
84 let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); |
|
85 timer.initWithCallback(run_next_test, duration, Ci.nsITimer.TYPE_ONE_SHOT); |
|
86 }); |
|
87 add_test(function() { |
|
88 gGoodOCSPResponse = generateGoodOCSPResponse(); |
|
89 run_next_test(); |
|
90 }); |
|
91 add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK, |
|
92 clearSessionCache); |
|
93 add_test(function() { do_check_eq(gFetchCount, 2); run_next_test(); }); |
|
94 |
|
95 // The Good response retrieved from the previous fetch must have replaced |
|
96 // the Unknown response in the cache, resulting in the catched Good response |
|
97 // being returned and no fetch. |
|
98 add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK, |
|
99 clearSessionCache); |
|
100 add_test(function() { do_check_eq(gFetchCount, 2); run_next_test(); }); |
|
101 |
|
102 |
|
103 //--------------------------------------------------------------------------- |
|
104 |
|
105 // Reset state |
|
106 add_test(function() { clearOCSPCache(); gFetchCount = 0; run_next_test(); }); |
|
107 |
|
108 // A failure to retrieve an OCSP response will result in an error entry being |
|
109 // added to the cache. |
|
110 add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK, |
|
111 clearSessionCache); |
|
112 add_test(function() { do_check_eq(gFetchCount, 1); run_next_test(); }); |
|
113 |
|
114 // The error entry will prevent a fetch from happening for a while. |
|
115 add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK, |
|
116 clearSessionCache); |
|
117 add_test(function() { do_check_eq(gFetchCount, 1); run_next_test(); }); |
|
118 |
|
119 // The error entry must not prevent a stapled OCSP response from being |
|
120 // honored. |
|
121 add_connection_test("ocsp-stapling-revoked.example.com", |
|
122 getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE), |
|
123 clearSessionCache); |
|
124 add_test(function() { do_check_eq(gFetchCount, 1); run_next_test(); }); |
|
125 |
|
126 //--------------------------------------------------------------------------- |
|
127 |
|
128 // Reset state |
|
129 add_test(function() { clearOCSPCache(); gFetchCount = 0; run_next_test(); }); |
|
130 } |