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 );