tor-browser

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

test_faulty_server.js (4641B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /* based on netwerk/test/unit/test_retry_0rtt.js */
      6 
      7 "use strict";
      8 
      9 /* import-globals-from ../../../../../netwerk/test/unit/head_channels.js */
     10 load("../../../../../netwerk/test/unit/head_channels.js");
     11 
     12 var httpServer = null;
     13 
     14 let handlerCallbacks = {};
     15 
     16 function listenHandler(metadata) {
     17  info(metadata.path);
     18  handlerCallbacks[metadata.path] = (handlerCallbacks[metadata.path] || 0) + 1;
     19 }
     20 
     21 function handlerCount(path) {
     22  return handlerCallbacks[path] || 0;
     23 }
     24 
     25 ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs");
     26 
     27 // Bug 1805371: Tests that require FaultyServer can't currently be built
     28 // with system NSS.
     29 add_setup(
     30  {
     31    skip_if: () => AppConstants.MOZ_SYSTEM_NSS,
     32  },
     33  async () => {
     34    do_get_profile();
     35    Services.fog.initializeFOG();
     36 
     37    httpServer = new HttpServer();
     38    httpServer.registerPrefixHandler("/callback/", listenHandler);
     39    httpServer.start(-1);
     40 
     41    registerCleanupFunction(async () => {
     42      await httpServer.stop();
     43    });
     44 
     45    Services.env.set(
     46      "FAULTY_SERVER_CALLBACK_PORT",
     47      httpServer.identity.primaryPort
     48    );
     49    await asyncStartTLSTestServer("FaultyServer", "test_faulty_server");
     50  }
     51 );
     52 
     53 function makeChan(url) {
     54  let chan = NetUtil.newChannel({
     55    uri: url,
     56    loadUsingSystemPrincipal: true,
     57  }).QueryInterface(Ci.nsIHttpChannel);
     58 
     59  chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
     60  return chan;
     61 }
     62 
     63 function channelOpenPromise(chan, flags) {
     64  return new Promise(resolve => {
     65    chan.asyncOpen(
     66      new ChannelListener((req, buffer) => resolve([req, buffer]), null, flags)
     67    );
     68  });
     69 }
     70 
     71 add_task(
     72  {
     73    skip_if: () => AppConstants.MOZ_SYSTEM_NSS,
     74  },
     75  async function testRetryMlkem768x25519() {
     76    const retryDomain = "mlkem768x25519-net-interrupt.example.com";
     77 
     78    Services.prefs.setBoolPref("security.tls.enable_kyber", true);
     79    Services.prefs.setCharPref("network.dns.localDomains", [retryDomain]);
     80    Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
     81 
     82    // Get the number of mlkem768x25519 and x25519 callbacks prior to making the request
     83    // ssl_grp_kem_mlkem768x25519 = 4588
     84    // ssl_grp_ec_curve25519 = 29
     85    let countOfMlkem = handlerCount("/callback/4588");
     86    let countOfX25519 = handlerCount("/callback/29");
     87    let countOfPrEndOfFileError =
     88      await Glean.tls.xyberIntoleranceReason.PR_END_OF_FILE_ERROR.testGetValue();
     89 
     90    let chan = makeChan(`https://${retryDomain}:8443`);
     91    let [, buf] = await channelOpenPromise(chan, CL_ALLOW_UNKNOWN_CL);
     92    ok(buf);
     93    // The server will make a mlkem768x25519 callback for the initial request, and
     94    // then an x25519 callback for the retry. Both callback counts should
     95    // increment by one.
     96    equal(
     97      handlerCount("/callback/4588"),
     98      countOfMlkem + 1,
     99      "negotiated mlkem768x25519"
    100    );
    101    equal(handlerCount("/callback/29"), countOfX25519 + 1, "negotiated x25519");
    102    if (!mozinfo.socketprocess_networking) {
    103      // Bug 1824574
    104      equal(
    105        countOfPrEndOfFileError + 1,
    106        await Glean.tls.xyberIntoleranceReason.PR_END_OF_FILE_ERROR.testGetValue(),
    107        "PR_END_OF_FILE_ERROR telemetry accumulated"
    108      );
    109    }
    110  }
    111 );
    112 
    113 add_task(
    114  {
    115    skip_if: () => AppConstants.MOZ_SYSTEM_NSS,
    116  },
    117  async function testNoRetryMlkem768x25519() {
    118    const retryDomain = "mlkem768x25519-alert-after-server-hello.example.com";
    119 
    120    Services.prefs.setBoolPref("security.tls.enable_kyber", true);
    121    Services.prefs.setCharPref("network.dns.localDomains", [retryDomain]);
    122    Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
    123 
    124    // Get the number of mlkem768x25519 and x25519 callbacks prior to making
    125    // the request
    126    // ssl_grp_kem_mlkem768x25519 = 4588
    127    // ssl_grp_ec_curve25519 = 29
    128    let countOfMlkem = handlerCount("/callback/4588");
    129    let countOfX25519 = handlerCount("/callback/29");
    130    let chan = makeChan(`https://${retryDomain}:8443`);
    131    let [req] = await channelOpenPromise(chan, CL_EXPECT_FAILURE);
    132    equal(req.status, 0x805a2f4d); // psm::GetXPCOMFromNSSError(SSL_ERROR_HANDSHAKE_FAILED)
    133    // The server will make a mlkem768x25519 callback for the initial request and
    134    // the client should not retry.
    135    equal(
    136      handlerCount("/callback/4588"),
    137      countOfMlkem + 1,
    138      "negotiated mlkem768x25519"
    139    );
    140    equal(
    141      handlerCount("/callback/29"),
    142      countOfX25519,
    143      "did not negotiate x25519"
    144    );
    145  }
    146 );