[client/idd] network: allow unencrypted 1-RTT payloads

Expose the insecure MsQuic draft API and add an opt-in setting on both
peers. Query the negotiated state after connection establishment so
one-sided opt-in remains encrypted and is logged accurately.
This commit is contained in:
Geoffrey McRae
2026-11-06 19:28:18 +11:00
parent ea24c288ad
commit 8bbf9c3056
9 changed files with 166 additions and 44 deletions

View File

@@ -37,6 +37,10 @@ endif()
add_library(transport_Network STATIC ${TRANSPORT_NETWORK_SOURCES})
target_compile_definitions(transport_Network PRIVATE
QUIC_API_ENABLE_INSECURE_FEATURES=1
)
target_include_directories(transport_Network PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../../src
)

View File

@@ -213,6 +213,7 @@ struct NetworkConnection
uint16_t port;
char * password;
char * endpoint;
bool allowUnencrypted;
NetworkKnownHosts * knownHosts;
NetworkTrustPromptFn trustPrompt;
@@ -2922,8 +2923,28 @@ static QUIC_STATUS QUIC_API networkConnectionCallback(HQUIC handle,
return QUIC_STATUS_SUCCESS;
}
HQUIC stream = NULL;
QUIC_STATUS status = this->api->StreamOpen(handle,
BOOLEAN encryptionDisabled = FALSE;
uint32_t encryptionDisabledLength = sizeof(encryptionDisabled);
QUIC_STATUS status = this->api->GetParam(handle,
QUIC_PARAM_CONN_DISABLE_1RTT_ENCRYPTION,
&encryptionDisabledLength, &encryptionDisabled);
if (QUIC_FAILED(status))
{
DEBUG_ERROR("Failed to query 1-RTT encryption for %s: 0x%08x",
this->endpoint, (unsigned)status);
networkConnectionFail(this, LG_TRANSPORT_ERROR);
this->api->ConnectionShutdown(handle,
QUIC_CONNECTION_SHUTDOWN_FLAG_SILENT, 0);
return QUIC_STATUS_SUCCESS;
}
DEBUG_INFO("Network connection to %s established in %s mode "
"(%s 1-RTT payloads)", this->endpoint,
encryptionDisabled ? "insecure" : "secure",
encryptionDisabled ? "unencrypted" : "encrypted");
HQUIC stream = NULL;
status = this->api->StreamOpen(handle,
QUIC_STREAM_OPEN_FLAG_NONE, networkStreamCallback, this, &stream);
if (QUIC_FAILED(status))
{
@@ -3585,15 +3606,16 @@ bool networkConnectionCreate(NetworkConnection ** result,
goto fail;
}
this->port = params->port;
this->knownHosts = params->knownHosts;
this->trustPrompt = params->trustPrompt;
this->trustCancel = params->trustCancel;
this->packet = params->packet;
this->state = params->state;
this->sendReady = params->sendReady;
this->datagramLost = params->datagramLost;
this->opaque = params->opaque;
this->port = params->port;
this->allowUnencrypted = params->allowUnencrypted;
this->knownHosts = params->knownHosts;
this->trustPrompt = params->trustPrompt;
this->trustCancel = params->trustCancel;
this->packet = params->packet;
this->state = params->state;
this->sendReady = params->sendReady;
this->datagramLost = params->datagramLost;
this->opaque = params->opaque;
this->connectEvent = lgCreateEvent(false, 0);
this->closeEvent = lgCreateEvent(false, 0);
@@ -3863,6 +3885,26 @@ LG_TransportStatus networkConnectionConnect(NetworkConnection * this,
return LG_TRANSPORT_ERROR;
}
if (this->allowUnencrypted)
{
const BOOLEAN disableEncryption = TRUE;
status = this->api->SetParam(this->connection,
QUIC_PARAM_CONN_DISABLE_1RTT_ENCRYPTION,
sizeof(disableEncryption), &disableEncryption);
if (QUIC_FAILED(status))
{
DEBUG_ERROR("Failed to allow unencrypted 1-RTT payloads for %s: "
"0x%08x", this->endpoint, (unsigned)status);
this->api->ConnectionClose(this->connection);
this->connection = NULL;
LG_LOCK(this->lock);
this->connecting = false;
this->connectStatus = LG_TRANSPORT_ERROR;
LG_UNLOCK(this->lock);
return LG_TRANSPORT_ERROR;
}
}
status = this->api->ConnectionStart(this->connection, this->configuration,
QUIC_ADDRESS_FAMILY_UNSPEC, this->address, this->port);
if (QUIC_FAILED(status))

View File

@@ -59,6 +59,7 @@ typedef struct NetworkConnectionParams
const char * address;
uint16_t port;
const char * password;
bool allowUnencrypted;
NetworkKnownHosts * knownHosts;
NetworkTrustPromptFn trustPrompt;
NetworkTrustCancelFn trustCancel;

View File

@@ -246,6 +246,13 @@ static void networkSetup(void)
.sensitive = true,
.value.x_string = NULL,
},
{
.module = "network",
.name = "allowUnencrypted",
.description = "Allow unencrypted 1-RTT network payloads",
.type = OPTION_TYPE_BOOL,
.value.x_bool = false,
},
{
.module = "network",
.name = "forgetCertificate",
@@ -555,20 +562,21 @@ static bool networkCreate(LG_Transport ** result)
const NetworkConnectionParams params =
{
.address = address,
.port = port,
.password = option_get_string("network", "password"),
.knownHosts = &this->knownHosts,
.trustPrompt = networkTrustPrompt,
.trustCancel = networkCancelTrustPrompt,
.packet = networkPacket,
.state = networkConnectionState,
.sendReady = networkSendReady,
.datagramLost = networkDatagramLost,
.capabilities = NETWORK_CAPABILITIES,
.capabilityCount = sizeof(NETWORK_CAPABILITIES) /
.address = address,
.port = port,
.password = option_get_string("network", "password"),
.allowUnencrypted = option_get_bool("network", "allowUnencrypted"),
.knownHosts = &this->knownHosts,
.trustPrompt = networkTrustPrompt,
.trustCancel = networkCancelTrustPrompt,
.packet = networkPacket,
.state = networkConnectionState,
.sendReady = networkSendReady,
.datagramLost = networkDatagramLost,
.capabilities = NETWORK_CAPABILITIES,
.capabilityCount = sizeof(NETWORK_CAPABILITIES) /
sizeof(NETWORK_CAPABILITIES[0]),
.opaque = this,
.opaque = this,
};
if (!networkConnectionCreate(&this->connection, &params))
{