mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 20:01:50 +00:00
Bug 1892528 - part 2: enable Xyber768 in Http/3 under a pref. r=valentin,necko-reviewers,kershaw
Differential Revision: https://phabricator.services.mozilla.com/D208048
This commit is contained in:
parent
5194094269
commit
29e702a9ad
@ -13287,6 +13287,18 @@
|
||||
mirror: always
|
||||
rust: true
|
||||
|
||||
# Whether to send a Xyber768 key share in HTTP/3 TLS handshakes.
|
||||
# Has no effect unless security.tls.enable_kyber is true.
|
||||
- name: network.http.http3.enable_kyber
|
||||
type: RelaxedAtomicBool
|
||||
#ifdef ANDROID
|
||||
value: false
|
||||
#else
|
||||
value: @IS_NIGHTLY_BUILD@
|
||||
#endif
|
||||
mirror: always
|
||||
rust: true
|
||||
|
||||
# When true, a http request will be upgraded to https when HTTPS RR is
|
||||
# available.
|
||||
- name: network.dns.upgrade_with_https_rr
|
||||
@ -15052,6 +15064,7 @@
|
||||
value: @IS_NIGHTLY_BUILD@
|
||||
#endif
|
||||
mirror: always
|
||||
rust: true
|
||||
|
||||
- name: security.ssl.treat_unsafe_negotiation_as_broken
|
||||
type: RelaxedAtomicBool
|
||||
|
@ -91,7 +91,7 @@ static nsresult RawBytesToNetAddr(uint16_t aFamily, const uint8_t* aRemoteAddr,
|
||||
|
||||
nsresult Http3Session::Init(const nsHttpConnectionInfo* aConnInfo,
|
||||
nsINetAddr* aSelfAddr, nsINetAddr* aPeerAddr,
|
||||
HttpConnectionUDP* udpConn, uint32_t controlFlags,
|
||||
HttpConnectionUDP* udpConn, uint32_t aProviderFlags,
|
||||
nsIInterfaceRequestor* callbacks) {
|
||||
LOG3(("Http3Session::Init %p", this));
|
||||
|
||||
@ -108,7 +108,7 @@ nsresult Http3Session::Init(const nsHttpConnectionInfo* aConnInfo,
|
||||
mSocketControl = new QuicSocketControl(
|
||||
httpsProxy ? aConnInfo->ProxyInfo()->Host() : aConnInfo->GetOrigin(),
|
||||
httpsProxy ? aConnInfo->ProxyInfo()->Port() : aConnInfo->OriginPort(),
|
||||
controlFlags, this);
|
||||
aProviderFlags, this);
|
||||
|
||||
NetAddr selfAddr;
|
||||
MOZ_ALWAYS_SUCCEEDS(aSelfAddr->GetNetAddr(&selfAddr));
|
||||
@ -142,7 +142,7 @@ nsresult Http3Session::Init(const nsHttpConnectionInfo* aConnInfo,
|
||||
StaticPrefs::network_http_http3_max_stream_data(),
|
||||
StaticPrefs::network_http_http3_version_negotiation_enabled(),
|
||||
mConnInfo->GetWebTransport(), gHttpHandler->Http3QlogDir(), datagramSize,
|
||||
StaticPrefs::network_http_http3_max_accumlated_time_ms(),
|
||||
StaticPrefs::network_http_http3_max_accumlated_time_ms(), aProviderFlags,
|
||||
getter_AddRefs(mHttp3Connection));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
|
@ -130,7 +130,7 @@ class Http3Session final : public nsAHttpTransaction, public nsAHttpConnection {
|
||||
Http3Session();
|
||||
nsresult Init(const nsHttpConnectionInfo* aConnInfo, nsINetAddr* selfAddr,
|
||||
nsINetAddr* peerAddr, HttpConnectionUDP* udpConn,
|
||||
uint32_t controlFlags, nsIInterfaceRequestor* callbacks);
|
||||
uint32_t aProviderFlags, nsIInterfaceRequestor* callbacks);
|
||||
|
||||
bool IsConnected() const { return mState == CONNECTED; }
|
||||
bool CanSendData() const {
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "nsHttpHandler.h"
|
||||
#include "Http3Session.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsISocketProvider.h"
|
||||
#include "nsNetAddr.h"
|
||||
#include "nsINetAddr.h"
|
||||
@ -129,26 +130,31 @@ nsresult HttpConnectionUDP::Init(nsHttpConnectionInfo* info,
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint32_t controlFlags = 0;
|
||||
uint32_t providerFlags = 0;
|
||||
if (caps & NS_HTTP_LOAD_ANONYMOUS) {
|
||||
controlFlags |= nsISocketProvider::ANONYMOUS_CONNECT;
|
||||
providerFlags |= nsISocketProvider::ANONYMOUS_CONNECT;
|
||||
}
|
||||
if (mConnInfo->GetPrivate()) {
|
||||
controlFlags |= nsISocketProvider::NO_PERMANENT_STORAGE;
|
||||
providerFlags |= nsISocketProvider::NO_PERMANENT_STORAGE;
|
||||
}
|
||||
if (((caps & NS_HTTP_BE_CONSERVATIVE) || mConnInfo->GetBeConservative()) &&
|
||||
gHttpHandler->ConnMgr()->BeConservativeIfProxied(
|
||||
mConnInfo->ProxyInfo())) {
|
||||
controlFlags |= nsISocketProvider::BE_CONSERVATIVE;
|
||||
providerFlags |= nsISocketProvider::BE_CONSERVATIVE;
|
||||
}
|
||||
if ((caps & NS_HTTP_IS_RETRY) ||
|
||||
(mConnInfo->GetTlsFlags() &
|
||||
nsIHttpChannelInternal::TLS_FLAG_CONFIGURE_AS_RETRY)) {
|
||||
providerFlags |= nsISocketProvider::IS_RETRY;
|
||||
}
|
||||
|
||||
if (mResolvedByTRR) {
|
||||
controlFlags |= nsISocketProvider::USED_PRIVATE_DNS;
|
||||
providerFlags |= nsISocketProvider::USED_PRIVATE_DNS;
|
||||
}
|
||||
|
||||
mPeerAddr = new nsNetAddr(&peerAddr);
|
||||
mHttp3Session = new Http3Session();
|
||||
rv = mHttp3Session->Init(mConnInfo, mSelfAddr, mPeerAddr, this, controlFlags,
|
||||
rv = mHttp3Session->Init(mConnInfo, mSelfAddr, mPeerAddr, this, providerFlags,
|
||||
callbacks);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(
|
||||
|
@ -315,9 +315,10 @@ interface nsIHttpChannelInternal : nsISupports
|
||||
|
||||
/**
|
||||
* An opaque flags for non-standard behavior of the TLS system.
|
||||
* It is unlikely this will need to be set outside of telemetry studies
|
||||
* relating to the TLS implementation.
|
||||
* It is unlikely this will need to be set outside of tests or telemetry
|
||||
* studies relating to the TLS implementation.
|
||||
*/
|
||||
const unsigned long TLS_FLAG_CONFIGURE_AS_RETRY = (1 << 16);
|
||||
[must_use] attribute unsigned long tlsFlags;
|
||||
|
||||
[must_use] readonly attribute PRTime lastModifiedTime;
|
||||
|
@ -19,12 +19,13 @@ class NeqoHttp3Conn final {
|
||||
uint64_t aMaxData, uint64_t aMaxStreamData,
|
||||
bool aVersionNegotiation, bool aWebTransport,
|
||||
const nsACString& aQlogDir, uint32_t aDatagramSize,
|
||||
uint32_t aMaxAccumulatedTime, NeqoHttp3Conn** aConn) {
|
||||
uint32_t aMaxAccumulatedTime, uint32_t aProviderFlags,
|
||||
NeqoHttp3Conn** aConn) {
|
||||
return neqo_http3conn_new(
|
||||
&aOrigin, &aAlpn, &aLocalAddr, &aRemoteAddr, aMaxTableSize,
|
||||
aMaxBlockedStreams, aMaxData, aMaxStreamData, aVersionNegotiation,
|
||||
aWebTransport, &aQlogDir, aDatagramSize, aMaxAccumulatedTime,
|
||||
(const mozilla::net::NeqoHttp3Conn**)aConn);
|
||||
aProviderFlags, (const mozilla::net::NeqoHttp3Conn**)aConn);
|
||||
}
|
||||
|
||||
void Close(uint64_t aError) { neqo_http3conn_close(this, aError); }
|
||||
|
@ -39,7 +39,7 @@ use thin_vec::ThinVec;
|
||||
use uuid::Uuid;
|
||||
#[cfg(windows)]
|
||||
use winapi::shared::ws2def::{AF_INET, AF_INET6};
|
||||
use xpcom::{AtomicRefcnt, RefCounted, RefPtr};
|
||||
use xpcom::{interfaces::nsISocketProvider, AtomicRefcnt, RefCounted, RefPtr};
|
||||
|
||||
#[repr(C)]
|
||||
pub struct NeqoHttp3Conn {
|
||||
@ -119,6 +119,7 @@ impl NeqoHttp3Conn {
|
||||
qlog_dir: &nsACString,
|
||||
webtransport_datagram_size: u32,
|
||||
max_accumlated_time_ms: u32,
|
||||
provider_flags: u32,
|
||||
) -> Result<RefPtr<NeqoHttp3Conn>, nsresult> {
|
||||
// Nss init.
|
||||
init().map_err(|_| NS_ERROR_UNEXPECTED)?;
|
||||
@ -194,6 +195,24 @@ impl NeqoHttp3Conn {
|
||||
return Err(NS_ERROR_INVALID_ARG);
|
||||
};
|
||||
|
||||
if static_prefs::pref!("security.tls.enable_kyber")
|
||||
&& static_prefs::pref!("network.http.http3.enable_kyber")
|
||||
&& (provider_flags & nsISocketProvider::IS_RETRY) == 0
|
||||
&& (provider_flags & nsISocketProvider::BE_CONSERVATIVE) == 0
|
||||
{
|
||||
// These operations are infallible when conn.state == State::Init.
|
||||
let _ = conn.set_groups(&[
|
||||
neqo_crypto::TLS_GRP_KEM_XYBER768D00,
|
||||
neqo_crypto::TLS_GRP_EC_X25519,
|
||||
neqo_crypto::TLS_GRP_EC_SECP256R1,
|
||||
neqo_crypto::TLS_GRP_EC_SECP384R1,
|
||||
neqo_crypto::TLS_GRP_EC_SECP521R1,
|
||||
]);
|
||||
// This ensures that we send key shares for Xyber768D00, X25519, and P-256,
|
||||
// so that servers are less likely to use HelloRetryRequest.
|
||||
let _ = conn.send_additional_key_shares(2);
|
||||
}
|
||||
|
||||
let mut conn = Http3Client::new_with_conn(conn, http3_settings);
|
||||
|
||||
if !qlog_dir.is_empty() {
|
||||
@ -280,6 +299,7 @@ pub extern "C" fn neqo_http3conn_new(
|
||||
qlog_dir: &nsACString,
|
||||
webtransport_datagram_size: u32,
|
||||
max_accumlated_time_ms: u32,
|
||||
provider_flags: u32,
|
||||
result: &mut *const NeqoHttp3Conn,
|
||||
) -> nsresult {
|
||||
*result = ptr::null_mut();
|
||||
@ -298,6 +318,7 @@ pub extern "C" fn neqo_http3conn_new(
|
||||
qlog_dir,
|
||||
webtransport_datagram_size,
|
||||
max_accumlated_time_ms,
|
||||
provider_flags,
|
||||
) {
|
||||
Ok(http3_conn) => {
|
||||
http3_conn.forget(result);
|
||||
|
79
netwerk/test/unit/test_http3_kyber.js
Normal file
79
netwerk/test/unit/test_http3_kyber.js
Normal file
@ -0,0 +1,79 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
Services.prefs.clearUserPref("security.tls.enable_kyber");
|
||||
Services.prefs.clearUserPref("network.http.http3.enable_kyber");
|
||||
http3_clear_prefs();
|
||||
});
|
||||
|
||||
add_task(async function setup() {
|
||||
Services.prefs.setBoolPref("security.tls.enable_kyber", true);
|
||||
Services.prefs.setBoolPref("network.http.http3.enable_kyber", true);
|
||||
await http3_setup_tests("h3");
|
||||
});
|
||||
|
||||
let Http3Listener = function () {};
|
||||
|
||||
Http3Listener.prototype = {
|
||||
expectedKeaGroup: undefined,
|
||||
|
||||
onStartRequest: function testOnStartRequest(request) {
|
||||
Assert.equal(request.status, Cr.NS_OK);
|
||||
Assert.equal(request.responseStatus, 200);
|
||||
|
||||
Assert.equal(request.securityInfo.keaGroupName, this.expectedKeaGroup);
|
||||
},
|
||||
|
||||
onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) {
|
||||
read_stream(stream, cnt);
|
||||
},
|
||||
|
||||
onStopRequest: function testOnStopRequest(request) {
|
||||
let httpVersion = "";
|
||||
try {
|
||||
httpVersion = request.protocolVersion;
|
||||
} catch (e) {}
|
||||
Assert.equal(httpVersion, "h3");
|
||||
|
||||
this.finish();
|
||||
},
|
||||
};
|
||||
|
||||
function chanPromise(chan, listener) {
|
||||
return new Promise(resolve => {
|
||||
function finish(result) {
|
||||
resolve(result);
|
||||
}
|
||||
listener.finish = finish;
|
||||
chan.asyncOpen(listener);
|
||||
});
|
||||
}
|
||||
|
||||
function makeChan(uri) {
|
||||
let chan = NetUtil.newChannel({
|
||||
uri,
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
|
||||
return chan;
|
||||
}
|
||||
|
||||
add_task(async function test_kyber_success() {
|
||||
let listener = new Http3Listener();
|
||||
listener.expectedKeaGroup = "xyber768d00";
|
||||
let chan = makeChan("https://foo.example.com");
|
||||
await chanPromise(chan, listener);
|
||||
});
|
||||
|
||||
add_task(async function test_no_kyber_on_retry() {
|
||||
Services.obs.notifyObservers(null, "net:cancel-all-connections");
|
||||
|
||||
let listener = new Http3Listener();
|
||||
listener.expectedKeaGroup = "x25519";
|
||||
let chan = makeChan("https://foo.example.com");
|
||||
chan.QueryInterface(Ci.nsIHttpChannelInternal).tlsFlags =
|
||||
Ci.nsIHttpChannelInternal.TLS_FLAG_CONFIGURE_AS_RETRY;
|
||||
await chanPromise(chan, listener);
|
||||
});
|
@ -703,6 +703,12 @@ skip-if = [
|
||||
]
|
||||
run-sequentially = "node server exceptions dont replay well"
|
||||
|
||||
["test_http3_kyber.js"]
|
||||
skip-if = [
|
||||
"os == 'win'",
|
||||
"os == 'android'",
|
||||
]
|
||||
|
||||
["test_http3_large_post.js"]
|
||||
skip-if = [
|
||||
"os == 'win'",
|
||||
@ -718,6 +724,7 @@ disabled = "bug 1771744 - telemetry probe expired"
|
||||
# os == 'android'
|
||||
# socketprocess_networking
|
||||
|
||||
|
||||
["test_http3_perf.js"]
|
||||
skip-if = [
|
||||
"os == 'android'",
|
||||
|
Loading…
x
Reference in New Issue
Block a user