]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Missing encoded transport parameters for QUIC OpenSSL wrapper
authorFrédéric Lécaille <flecaille@haproxy.com>
Fri, 21 Jul 2023 15:27:40 +0000 (17:27 +0200)
committerFrédéric Lécaille <flecaille@haproxy.com>
Fri, 21 Jul 2023 15:27:40 +0000 (17:27 +0200)
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.

include/haproxy/quic_conn-t.h
src/quic_conn.c

index 3f9e1a38d104b0acade9ca60e74e08c790a4009a..c311d89845e1de35af22df7b6d2827da33c26250 100644 (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 */
index d998ad24eb720d7902b9aa9e557bbef966609677..b735cfa27d6fa02a4a65e665e2271305e5b2a1cf 100644 (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. */