MINOR: quic: Missing encoded transport parameters for QUIC OpenSSL wrapper

This wrapper needs to have an access to an encoded version of the local transport
parameter (to be sent to the peer). They are provided to the TLS stack thanks to
qc_ssl_compat_add_tps_cb() callback.

These encoded transport parameters were attached to the QUIC connection but
removed by this commit to save memory:

      MINOR: quic: Stop storing the TX encoded transport parameters

This patch restores these transport parameters and attaches them again
to the QUIC connection (quic_conn struct), but only when the QUIC OpenSSL wrapper
is compiled.
Implement qc_set_quic_transport_params() to encode the transport parameters
for a connection and to set them into the stack and make this function work
for both the OpenSSL wrapper or any other TLS stack with QUIC support. Its uses
the encoded version of the transport parameters attached to the connection
when compiled for the OpenSSL wrapper, or local parameters when compiled
with TLS stack with QUIC support. These parameters are passed to
quic_transport_params_encode() and SSL_set_quic_transport_params() as before
this patch.
This commit is contained in:
Frédéric Lécaille 2023-07-21 17:27:40 +02:00
parent bcbd5a287b
commit 2fd67c558a
2 changed files with 46 additions and 15 deletions

View File

@ -591,6 +591,10 @@ struct quic_conn {
int state;
enum qc_mux_state mux_state; /* status of the connection/mux layer */
struct quic_err err;
#ifdef USE_QUIC_OPENSSL_COMPAT
unsigned char enc_params[QUIC_TP_MAX_ENCLEN]; /* encoded QUIC transport parameters */
size_t enc_params_len;
#endif
struct quic_cid odcid; /* First DCID used by client on its Initial packet. */
struct quic_cid dcid; /* DCID of our endpoint - not updated when a new DCID is used */

View File

@ -1035,6 +1035,44 @@ static void quic_tls_rotate_keys(struct quic_conn *qc)
TRACE_LEAVE(QUIC_EV_CONN_RXPKT, qc);
}
/* Set the encoded version of the transport parameter into the TLS
* stack depending on <ver> QUIC version and <server> boolean which must
* be set to 1 for a QUIC server, 0 for a client.
* Return 1 if succeeded, 0 if not.
*/
static int qc_set_quic_transport_params(struct quic_conn *qc,
const struct quic_version *ver, int server)
{
int ret = 0;
#ifdef USE_QUIC_OPENSSL_COMPAT
unsigned char *in = qc->enc_params;
size_t insz = sizeof qc->enc_params;
size_t *enclen = &qc->enc_params_len;
#else
unsigned char tps[QUIC_TP_MAX_ENCLEN];
size_t tpslen;
unsigned char *in = tps;
size_t insz = sizeof tps;
size_t *enclen = &tpslen;
#endif
TRACE_ENTER(QUIC_EV_CONN_RWSEC, qc);
*enclen = quic_transport_params_encode(in, in + insz, &qc->rx.params, ver, server);
if (!*enclen) {
TRACE_ERROR("quic_transport_params_encode() failed", QUIC_EV_CONN_RWSEC);
goto leave;
}
if (!SSL_set_quic_transport_params(qc->xprt_ctx->ssl, in, *enclen)) {
TRACE_ERROR("SSL_set_quic_transport_params() failed", QUIC_EV_CONN_RWSEC);
goto leave;
}
ret = 1;
leave:
TRACE_LEAVE(QUIC_EV_CONN_RWSEC, qc);
return ret;
}
/* returns 0 on error, 1 on success */
int ha_quic_set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t level,
const uint8_t *read_secret,
@ -1141,21 +1179,10 @@ write:
goto leave;
}
if (level == ssl_encryption_handshake && qc_is_listener(qc)) {
int tps_len;
unsigned char tps[QUIC_TP_MAX_ENCLEN];
tps_len = quic_transport_params_encode(tps, tps + sizeof tps, &qc->rx.params, ver, 1);
if (!tps_len) {
TRACE_ERROR("quic_transport_params_encode() failed", QUIC_EV_CONN_RWSEC);
goto leave;
}
if (!SSL_set_quic_transport_params(qc->xprt_ctx->ssl, tps, tps_len)) {
TRACE_ERROR("SSL_set_quic_transport_params() failed", QUIC_EV_CONN_RWSEC);
goto leave;
}
}
/* Set the transport parameters in the TLS stack. */
if (level == ssl_encryption_handshake && qc_is_listener(qc) &&
!qc_set_quic_transport_params(qc, ver, 1))
goto leave;
keyupdate_init:
/* Store the secret provided by the TLS stack, required for keyupdate. */