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/. */
9 const certOverrideService = Cc[
10 "@mozilla.org/security/certoverride;1"
11 ].getService(Ci.nsICertOverrideService);
13 add_setup(async function setup() {
14 // Allow telemetry probes which may otherwise be disabled for some
15 // applications (e.g. Thunderbird).
16 Services.prefs.setBoolPref(
17 "toolkit.telemetry.testing.overrideProductsCheck",
23 Services.prefs.setBoolPref("network.dns.upgrade_with_https_rr", true);
24 Services.prefs.setBoolPref("network.dns.use_https_rr_as_altsvc", true);
25 Services.prefs.setBoolPref("network.dns.echconfig.enabled", true);
26 Services.prefs.setBoolPref("network.dns.http3_echconfig.enabled", false);
27 Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
28 Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRONLY);
30 // Set the server to always select http/1.1
31 Services.env.set("MOZ_TLS_ECH_ALPN_FLAG", 1);
33 await asyncStartTLSTestServer(
34 "EncryptedClientHelloServer",
35 "../../../security/manager/ssl/tests/unit/test_encrypted_client_hello"
39 registerCleanupFunction(async () => {
41 Services.prefs.clearUserPref("network.trr.mode");
42 Services.prefs.clearUserPref("network.trr.uri");
43 Services.prefs.clearUserPref("network.dns.upgrade_with_https_rr");
44 Services.prefs.clearUserPref("network.dns.use_https_rr_as_altsvc");
45 Services.prefs.clearUserPref("network.dns.echconfig.enabled");
46 Services.prefs.clearUserPref("network.dns.http3_echconfig.enabled");
47 Services.prefs.clearUserPref(
48 "network.dns.echconfig.fallback_to_origin_when_all_failed"
50 Services.prefs.clearUserPref("network.http.speculative-parallel-limit");
51 Services.prefs.clearUserPref("network.dns.port_prefixed_qname_https_rr");
52 Services.env.set("MOZ_TLS_ECH_ALPN_FLAG", "");
54 await trrServer.stop();
58 function makeChan(url) {
59 let chan = NetUtil.newChannel({
61 loadUsingSystemPrincipal: true,
62 contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
63 }).QueryInterface(Ci.nsIHttpChannel);
67 function channelOpenPromise(chan, flags) {
68 return new Promise(resolve => {
69 function finish(req, buffer) {
70 certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
73 resolve([req, buffer]);
75 certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
78 let internal = chan.QueryInterface(Ci.nsIHttpChannelInternal);
79 internal.setWaitForHTTPSSVCRecord();
80 chan.asyncOpen(new ChannelListener(finish, null, flags));
84 function ActivityObserver() {}
86 ActivityObserver.prototype = {
88 observeConnectionActivity(
100 "*** Connection Activity 0x" +
101 aActivityType.toString(16) +
103 aActivitySubtype.toString(16) +
108 this.activites.push({ host: aHost, subType: aActivitySubtype });
112 function checkHttpActivities(activites) {
113 let foundDNSAndSocket = false;
114 let foundSettingECH = false;
115 let foundConnectionCreated = false;
116 for (let activity of activites) {
117 switch (activity.subType) {
118 case Ci.nsIHttpActivityObserver.ACTIVITY_SUBTYPE_DNSANDSOCKET_CREATED:
119 case Ci.nsIHttpActivityObserver
120 .ACTIVITY_SUBTYPE_SPECULATIVE_DNSANDSOCKET_CREATED:
121 foundDNSAndSocket = true;
123 case Ci.nsIHttpActivityDistributor.ACTIVITY_SUBTYPE_ECH_SET:
124 foundSettingECH = true;
126 case Ci.nsIHttpActivityDistributor.ACTIVITY_SUBTYPE_CONNECTION_CREATED:
127 foundConnectionCreated = true;
134 Assert.equal(foundDNSAndSocket, true, "Should have one DnsAndSock created");
135 Assert.equal(foundSettingECH, true, "Should have echConfig");
137 foundConnectionCreated,
139 "Should have one connection created"
143 async function testWrapper(alpnAdvertisement) {
144 const ECH_CONFIG_FIXED =
145 "AEn+DQBFTQAgACCKB1Y5SfrGIyk27W82xPpzWTDs3q72c04xSurDWlb9CgAEAAEAA2QWZWNoLXB1YmxpYy5leGFtcGxlLmNvbQAA";
146 trrServer = new TRRServer();
147 await trrServer.start();
149 let observerService = Cc[
150 "@mozilla.org/network/http-activity-distributor;1"
151 ].getService(Ci.nsIHttpActivityDistributor);
152 let observer = new ActivityObserver();
153 observerService.addObserver(observer);
154 observerService.observeConnection = true;
156 Services.prefs.setCharPref(
158 `https://foo.example.com:${trrServer.port}/dns-query`
161 // Only the last record is valid to use.
162 await trrServer.registerDoHAnswers("ech-private.example.com", "HTTPS", {
165 name: "ech-private.example.com",
171 name: "ech-private.example.com",
173 { key: "alpn", value: alpnAdvertisement },
174 { key: "port", value: 8443 },
177 value: ECH_CONFIG_FIXED,
178 needBase64Decode: true,
186 await trrServer.registerDoHAnswers("ech-private.example.com", "A", {
189 name: "ech-private.example.com",
198 await new TRRDNSListener("ech-private.example.com", {
199 type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
202 HandshakeTelemetryHelpers.resetHistograms();
203 let chan = makeChan(`https://ech-private.example.com`);
204 await channelOpenPromise(chan, CL_ALLOW_UNKNOWN_CL);
205 let securityInfo = chan.securityInfo;
206 Assert.ok(securityInfo.isAcceptedEch, "This host should have accepted ECH");
208 // Only check telemetry if network process is disabled.
209 if (!mozinfo.socketprocess_networking) {
210 HandshakeTelemetryHelpers.checkSuccess(["", "_ECH", "_FIRST_TRY"]);
211 HandshakeTelemetryHelpers.checkEmpty(["_CONSERVATIVE", "_ECH_GREASE"]);
214 await trrServer.stop();
215 observerService.removeObserver(observer);
216 observerService.observeConnection = false;
218 let filtered = observer.activites.filter(
219 activity => activity.host === "ech-private.example.com"
221 checkHttpActivities(filtered);
224 add_task(async function h1Advertised() {
225 await testWrapper(["http/1.1"]);
228 add_task(async function h2Advertised() {
229 await testWrapper(["h2"]);
232 add_task(async function h3Advertised() {
233 await testWrapper(["h3"]);
236 add_task(async function h1h2Advertised() {
237 await testWrapper(["http/1.1", "h2"]);
240 add_task(async function h2h3Advertised() {
241 await testWrapper(["h3", "h2"]);
244 add_task(async function unknownAdvertised() {
245 await testWrapper(["foo"]);