tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_ocsp_stapling.js (9887B)


      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/.
      5 "use strict";
      6 
      7 // In which we connect to a number of domains (as faked by a server running
      8 // locally) with and without OCSP stapling enabled to determine that good
      9 // things happen and bad things don't.
     10 
     11 // Enable the collection (during test) for all products so even products
     12 // that don't collect the data will be able to run the test without failure.
     13 Services.prefs.setBoolPref(
     14  "toolkit.telemetry.testing.overrideProductsCheck",
     15  true
     16 );
     17 
     18 var gExpectOCSPRequest;
     19 
     20 function add_ocsp_test(
     21  aHost,
     22  aExpectedResult,
     23  aStaplingEnabled,
     24  aExpectOCSPRequest = false
     25 ) {
     26  add_connection_test(aHost, aExpectedResult, function () {
     27    gExpectOCSPRequest = aExpectOCSPRequest;
     28    clearOCSPCache();
     29    clearSessionCache();
     30    Services.prefs.setBoolPref(
     31      "security.ssl.enable_ocsp_stapling",
     32      aStaplingEnabled
     33    );
     34  });
     35 }
     36 
     37 function add_tests() {
     38  // In the absence of OCSP stapling, these should actually all work.
     39  add_ocsp_test(
     40    "ocsp-stapling-good.example.com",
     41    PRErrorCodeSuccess,
     42    false,
     43    true
     44  );
     45  add_ocsp_test(
     46    "ocsp-stapling-revoked.example.com",
     47    PRErrorCodeSuccess,
     48    false,
     49    true
     50  );
     51  add_ocsp_test(
     52    "ocsp-stapling-good-other-ca.example.com",
     53    PRErrorCodeSuccess,
     54    false,
     55    true
     56  );
     57  add_ocsp_test(
     58    "ocsp-stapling-malformed.example.com",
     59    PRErrorCodeSuccess,
     60    false,
     61    true
     62  );
     63  add_ocsp_test(
     64    "ocsp-stapling-srverr.example.com",
     65    PRErrorCodeSuccess,
     66    false,
     67    true
     68  );
     69  add_ocsp_test(
     70    "ocsp-stapling-trylater.example.com",
     71    PRErrorCodeSuccess,
     72    false,
     73    true
     74  );
     75  add_ocsp_test(
     76    "ocsp-stapling-needssig.example.com",
     77    PRErrorCodeSuccess,
     78    false,
     79    true
     80  );
     81  add_ocsp_test(
     82    "ocsp-stapling-unauthorized.example.com",
     83    PRErrorCodeSuccess,
     84    false,
     85    true
     86  );
     87  add_ocsp_test(
     88    "ocsp-stapling-unknown.example.com",
     89    PRErrorCodeSuccess,
     90    false,
     91    true
     92  );
     93  add_ocsp_test(
     94    "ocsp-stapling-good-other.example.com",
     95    PRErrorCodeSuccess,
     96    false,
     97    true
     98  );
     99  add_ocsp_test(
    100    "ocsp-stapling-none.example.com",
    101    PRErrorCodeSuccess,
    102    false,
    103    true
    104  );
    105  add_ocsp_test(
    106    "ocsp-stapling-expired.example.com",
    107    PRErrorCodeSuccess,
    108    false,
    109    true
    110  );
    111  add_ocsp_test(
    112    "ocsp-stapling-expired-fresh-ca.example.com",
    113    PRErrorCodeSuccess,
    114    false,
    115    true
    116  );
    117  add_ocsp_test(
    118    "ocsp-stapling-skip-responseBytes.example.com",
    119    PRErrorCodeSuccess,
    120    false,
    121    true
    122  );
    123  add_ocsp_test(
    124    "ocsp-stapling-critical-extension.example.com",
    125    PRErrorCodeSuccess,
    126    false,
    127    true
    128  );
    129  add_ocsp_test(
    130    "ocsp-stapling-noncritical-extension.example.com",
    131    PRErrorCodeSuccess,
    132    false,
    133    true
    134  );
    135  add_ocsp_test(
    136    "ocsp-stapling-empty-extensions.example.com",
    137    PRErrorCodeSuccess,
    138    false,
    139    true
    140  );
    141 
    142  // Now test OCSP stapling
    143  // The following error codes are defined in security/nss/lib/util/SECerrs.h
    144 
    145  add_ocsp_test("ocsp-stapling-good.example.com", PRErrorCodeSuccess, true);
    146 
    147  add_ocsp_test(
    148    "ocsp-stapling-revoked.example.com",
    149    SEC_ERROR_REVOKED_CERTIFICATE,
    150    true
    151  );
    152 
    153  // This stapled response is from a CA that is untrusted and did not issue
    154  // the server's certificate.
    155  let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService(
    156    Ci.nsIX509CertDB
    157  );
    158  let otherTestCA = constructCertFromFile("ocsp_certs/other-test-ca.pem");
    159  add_test(function () {
    160    certDB.setCertTrust(
    161      otherTestCA,
    162      Ci.nsIX509Cert.CA_CERT,
    163      Ci.nsIX509CertDB.UNTRUSTED
    164    );
    165    run_next_test();
    166  });
    167  add_ocsp_test(
    168    "ocsp-stapling-good-other-ca.example.com",
    169    SEC_ERROR_OCSP_INVALID_SIGNING_CERT,
    170    true,
    171    true
    172  );
    173 
    174  // The stapled response is from a CA that is trusted but did not issue the
    175  // server's certificate.
    176  add_test(function () {
    177    certDB.setCertTrust(
    178      otherTestCA,
    179      Ci.nsIX509Cert.CA_CERT,
    180      Ci.nsIX509CertDB.TRUSTED_SSL
    181    );
    182    run_next_test();
    183  });
    184  // TODO(bug 979055): When using ByName instead of ByKey, the error here is
    185  // SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE. We should be testing both cases.
    186  add_ocsp_test(
    187    "ocsp-stapling-good-other-ca.example.com",
    188    SEC_ERROR_OCSP_INVALID_SIGNING_CERT,
    189    true,
    190    true
    191  );
    192 
    193  // TODO: Test the case where the signing cert can't be found at all, which
    194  // will result in SEC_ERROR_BAD_DATABASE in the NSS classic case.
    195 
    196  add_ocsp_test(
    197    "ocsp-stapling-malformed.example.com",
    198    SEC_ERROR_OCSP_MALFORMED_REQUEST,
    199    true
    200  );
    201  add_ocsp_test(
    202    "ocsp-stapling-srverr.example.com",
    203    SEC_ERROR_OCSP_SERVER_ERROR,
    204    true
    205  );
    206  add_ocsp_test(
    207    "ocsp-stapling-trylater.example.com",
    208    SEC_ERROR_OCSP_TRY_SERVER_LATER,
    209    true,
    210    true
    211  );
    212  add_ocsp_test(
    213    "ocsp-stapling-needssig.example.com",
    214    SEC_ERROR_OCSP_REQUEST_NEEDS_SIG,
    215    true
    216  );
    217  add_ocsp_test(
    218    "ocsp-stapling-unauthorized.example.com",
    219    SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST,
    220    true
    221  );
    222  add_ocsp_test(
    223    "ocsp-stapling-unknown.example.com",
    224    SEC_ERROR_OCSP_UNKNOWN_CERT,
    225    true
    226  );
    227  // If the server staples an OCSP response that doesn't contain a status for
    228  // the server certificate, we defer returning the error and attempt to fetch
    229  // a more suitable response. If that fails, the deferred error is returned.
    230  add_ocsp_test(
    231    "ocsp-stapling-good-other.example.com",
    232    MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING,
    233    true,
    234    true
    235  );
    236  // If the server doesn't staple an OCSP response, we continue as normal
    237  // (this means that even though stapling is enabled, we expect an OCSP
    238  // request).
    239  add_ocsp_test(
    240    "ocsp-stapling-none.example.com",
    241    PRErrorCodeSuccess,
    242    true,
    243    true
    244  );
    245  add_ocsp_test(
    246    "ocsp-stapling-empty.example.com",
    247    SEC_ERROR_OCSP_MALFORMED_RESPONSE,
    248    true
    249  );
    250 
    251  add_ocsp_test(
    252    "ocsp-stapling-skip-responseBytes.example.com",
    253    SEC_ERROR_OCSP_MALFORMED_RESPONSE,
    254    true
    255  );
    256 
    257  add_ocsp_test(
    258    "ocsp-stapling-critical-extension.example.com",
    259    SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION,
    260    true
    261  );
    262  add_ocsp_test(
    263    "ocsp-stapling-noncritical-extension.example.com",
    264    PRErrorCodeSuccess,
    265    true
    266  );
    267  // TODO(bug 997994): Disallow empty Extensions in responses
    268  add_ocsp_test(
    269    "ocsp-stapling-empty-extensions.example.com",
    270    PRErrorCodeSuccess,
    271    true
    272  );
    273 
    274  add_ocsp_test(
    275    "ocsp-stapling-delegated-included.example.com",
    276    PRErrorCodeSuccess,
    277    true
    278  );
    279  add_ocsp_test(
    280    "ocsp-stapling-delegated-included-last.example.com",
    281    PRErrorCodeSuccess,
    282    true
    283  );
    284  add_ocsp_test(
    285    "ocsp-stapling-delegated-missing.example.com",
    286    SEC_ERROR_OCSP_INVALID_SIGNING_CERT,
    287    true,
    288    true
    289  );
    290  add_ocsp_test(
    291    "ocsp-stapling-delegated-missing-multiple.example.com",
    292    SEC_ERROR_OCSP_INVALID_SIGNING_CERT,
    293    true,
    294    true
    295  );
    296  add_ocsp_test(
    297    "ocsp-stapling-delegated-no-extKeyUsage.example.com",
    298    SEC_ERROR_OCSP_INVALID_SIGNING_CERT,
    299    true,
    300    true
    301  );
    302  add_ocsp_test(
    303    "ocsp-stapling-delegated-from-intermediate.example.com",
    304    SEC_ERROR_OCSP_INVALID_SIGNING_CERT,
    305    true,
    306    true
    307  );
    308  add_ocsp_test(
    309    "ocsp-stapling-delegated-keyUsage-crlSigning.example.com",
    310    SEC_ERROR_OCSP_INVALID_SIGNING_CERT,
    311    true,
    312    true
    313  );
    314  add_ocsp_test(
    315    "ocsp-stapling-delegated-wrong-extKeyUsage.example.com",
    316    SEC_ERROR_OCSP_INVALID_SIGNING_CERT,
    317    true,
    318    true
    319  );
    320 
    321  // ocsp-stapling-expired.example.com and
    322  // ocsp-stapling-expired-fresh-ca.example.com are handled in
    323  // test_ocsp_stapling_expired.js
    324 
    325  // Check that OCSP responder certificates with key sizes below 1024 bits are
    326  // rejected, even when the main certificate chain keys are at least 1024 bits.
    327  add_ocsp_test(
    328    "keysize-ocsp-delegated.example.com",
    329    SEC_ERROR_OCSP_INVALID_SIGNING_CERT,
    330    true,
    331    true
    332  );
    333 
    334  add_ocsp_test(
    335    "revoked-ca-cert-used-as-end-entity.example.com",
    336    SEC_ERROR_REVOKED_CERTIFICATE,
    337    true
    338  );
    339 }
    340 
    341 function check_ocsp_stapling_telemetry() {
    342  let histogram = Services.telemetry
    343    .getHistogramById("SSL_OCSP_STAPLING")
    344    .snapshot();
    345  equal(
    346    histogram.values[0],
    347    0,
    348    "Should have 0 connections for unused histogram bucket 0"
    349  );
    350  equal(
    351    histogram.values[1],
    352    5,
    353    "Actual and expected connections with a good response should match"
    354  );
    355  equal(
    356    histogram.values[2],
    357    18,
    358    "Actual and expected connections with no stapled response should match"
    359  );
    360  equal(
    361    histogram.values[3] || 0,
    362    0,
    363    "Actual and expected connections with an expired response should match"
    364  );
    365  equal(
    366    histogram.values[4],
    367    21,
    368    "Actual and expected connections with bad responses should match"
    369  );
    370  run_next_test();
    371 }
    372 
    373 function run_test() {
    374  do_get_profile();
    375  Services.prefs.setIntPref("security.OCSP.enabled", 1);
    376  // This test may sometimes fail on android due to an OCSP request timing out.
    377  // That aspect of OCSP requests is not what we're testing here, so we can just
    378  // bump the timeout and hopefully avoid these failures.
    379  Services.prefs.setIntPref("security.OCSP.timeoutMilliseconds.soft", 5000);
    380 
    381  let fakeOCSPResponder = new HttpServer();
    382  fakeOCSPResponder.registerPrefixHandler("/", function (request, response) {
    383    response.setStatusLine(request.httpVersion, 500, "Internal Server Error");
    384    ok(
    385      gExpectOCSPRequest,
    386      "Should be getting an OCSP request only when expected"
    387    );
    388  });
    389  fakeOCSPResponder.start(8888);
    390 
    391  add_tls_server_setup("OCSPStaplingServer", "ocsp_certs");
    392 
    393  add_tests();
    394 
    395  add_test(function () {
    396    fakeOCSPResponder.stop(check_ocsp_stapling_telemetry);
    397  });
    398 
    399  run_next_test();
    400 }