]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: quic/ssl: add new ex data for quic_conn
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 19 Jan 2022 09:03:30 +0000 (10:03 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 24 Jan 2022 09:30:49 +0000 (10:30 +0100)
Allow to register quic_conn as ex-data in SSL callbacks. A new index is
used to identify it as ssl_qc_app_data_index.

Replace connection by quic_conn as SSL ex-data when initializing the QUIC
SSL session. When using SSL callbacks in QUIC context, the connection is
now NULL. Used quic_conn instead to retrieve the required parameters.
Also clean up

The same changes are conducted inside the QUIC SSL methods of xprt-quic
: connection instance usage is replaced by quic_conn.

include/haproxy/ssl_sock.h
src/ssl_sock.c
src/xprt_quic.c

index fd45c4beb3ad06358ca1450b0c1f9f2085d4e568..657d8967ac56d2ab31f061646843652da92cabd1 100644 (file)
@@ -42,6 +42,9 @@ extern struct methodVersions methodVersions[];
 __decl_thread(extern HA_SPINLOCK_T ckch_lock);
 extern struct pool_head *pool_head_ssl_capture;
 extern int ssl_app_data_index;
+#ifdef USE_QUIC
+extern int ssl_qc_app_data_index;
+#endif /* USE_QUIC */
 extern unsigned int openssl_engines_initialized;
 extern int nb_engines;
 extern struct xprt_ops ssl_sock;
index 576b21d38287827699a2c15c544104ebe14a2ecd..1aa46d74f723cea804c467f46c22f5065d215141 100644 (file)
@@ -436,6 +436,9 @@ static STACK_OF(X509_NAME)* ssl_get_client_ca_file(char *path)
 struct pool_head *pool_head_ssl_capture __read_mostly = NULL;
 int ssl_capture_ptr_index = -1;
 int ssl_app_data_index = -1;
+#ifdef USE_QUIC
+int ssl_qc_app_data_index = -1;
+#endif /* USE_QUIC */
 
 #ifdef HAVE_SSL_KEYLOG
 int ssl_keylog_index = -1;
@@ -1520,17 +1523,29 @@ out:
 void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
 {
        struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
-       struct ssl_sock_ctx *ctx = conn->xprt_ctx;
+#ifdef USE_QUIC
+       struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
+#endif /* USE_QUIC */
+       struct ssl_sock_ctx *ctx = NULL;
+
        BIO *write_bio;
        (void)ret; /* shut gcc stupid warning */
 
+       if (conn)
+               ctx = conn->xprt_ctx;
+#ifdef USE_QUIC
+       else if (qc)
+               ctx = qc->xprt_ctx;
+#endif /* USE_QUIC */
+       BUG_ON(!ctx);
+
 #ifndef SSL_OP_NO_RENEGOTIATION
        /* Please note that BoringSSL defines this macro to zero so don't
         * change this to #if and do not assign a default value to this macro!
         */
        if (where & SSL_CB_HANDSHAKE_START) {
                /* Disable renegotiation (CVE-2009-3555) */
-               if ((conn->flags & (CO_FL_WAIT_L6_CONN | CO_FL_EARLY_SSL_HS | CO_FL_EARLY_DATA)) == 0) {
+               if (conn && (conn->flags & (CO_FL_WAIT_L6_CONN | CO_FL_EARLY_SSL_HS | CO_FL_EARLY_DATA)) == 0) {
                        conn->flags |= CO_FL_ERROR;
                        conn->err_code = CO_ER_SSL_RENEG;
                }
@@ -1980,21 +1995,21 @@ static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
 {
        struct ssl_bind_conf *conf = arg;
 #ifdef USE_QUIC
-       struct connection *conn = SSL_get_ex_data(s, ssl_app_data_index);
+       struct quic_conn *qc = SSL_get_ex_data(s, ssl_qc_app_data_index);
 #endif
 
        if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
                                  conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
 #ifdef USE_QUIC
-               if (conn->qc)
-                       quic_set_tls_alert(conn->qc, SSL_AD_NO_APPLICATION_PROTOCOL);
+               if (qc)
+                       quic_set_tls_alert(qc, SSL_AD_NO_APPLICATION_PROTOCOL);
 #endif
                return SSL_TLSEXT_ERR_NOACK;
        }
 
 #ifdef USE_QUIC
-       if (conn->qc && !quic_set_app_ops(conn->qc, *out, *outlen)) {
-               quic_set_tls_alert(conn->qc, SSL_AD_NO_APPLICATION_PROTOCOL);
+       if (qc && !quic_set_app_ops(qc, *out, *outlen)) {
+               quic_set_tls_alert(qc, SSL_AD_NO_APPLICATION_PROTOCOL);
                return SSL_TLSEXT_ERR_NOACK;
        }
 #endif
@@ -2451,8 +2466,11 @@ int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
 int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
 {
 #endif
-       struct connection *conn;
-       struct bind_conf *s;
+       struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
+#ifdef USE_QUIC
+       struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
+#endif /* USE_QUIC */
+       struct bind_conf *s = NULL;
        const uint8_t *extension_data;
        size_t extension_len;
        int has_rsa_sig = 0, has_ecdsa_sig = 0;
@@ -2464,17 +2482,22 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
        int allow_early = 0;
        int i;
 
-       conn = SSL_get_ex_data(ssl, ssl_app_data_index);
-       s = __objt_listener(conn->target)->bind_conf;
+       if (conn)
+               s = __objt_listener(conn->target)->bind_conf;
+#ifdef USE_QUIC
+       else if (qc)
+               s = qc->li->bind_conf;
+#endif /* USE_QUIC */
+       BUG_ON(!s);
 
 #ifdef USE_QUIC
-       if (conn->qc) {
+       if (qc) {
                /* Look for the QUIC transport parameters. */
 #ifdef OPENSSL_IS_BORINGSSL
-               if (!SSL_early_callback_ctx_extension_get(ctx, con->qc->tps_tls_ext,
+               if (!SSL_early_callback_ctx_extension_get(ctx, qc->tps_tls_ext,
                                                          &extension_data, &extension_len))
 #else
-               if (!SSL_client_hello_get0_ext(ssl, conn->qc->tps_tls_ext,
+               if (!SSL_client_hello_get0_ext(ssl, qc->tps_tls_ext,
                                               &extension_data, &extension_len))
 #endif
                {
@@ -2483,17 +2506,17 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
                         * which would be set after calling quic_set_tls_alert().
                         */
                        *al = SSL_AD_MISSING_EXTENSION;
-                       quic_set_tls_alert(conn->qc, SSL_AD_MISSING_EXTENSION);
+                       quic_set_tls_alert(qc, SSL_AD_MISSING_EXTENSION);
                        return 0;
                }
 
-               if (!quic_transport_params_store(conn->qc, 0, extension_data,
+               if (!quic_transport_params_store(qc, 0, extension_data,
                                                 extension_data + extension_len))
                        goto abort;
 
-               quic_mux_transport_params_update(conn->qc->qcc);
+               quic_mux_transport_params_update(qc->qcc);
        }
-#endif
+#endif /* USE_QUIC */
 
        if (s->ssl_conf.early_data)
                allow_early = 1;
@@ -2729,7 +2752,8 @@ int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *arg)
 
  abort:
        /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
-       conn->err_code = CO_ER_SSL_HANDSHAKE;
+       if (conn)
+               conn->err_code = CO_ER_SSL_HANDSHAKE;
 #ifdef OPENSSL_IS_BORINGSSL
        return ssl_select_cert_error;
 #else
@@ -7653,6 +7677,9 @@ static void __ssl_sock_init(void)
 
        ssl_app_data_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
        ssl_capture_ptr_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_capture_free_func);
+#ifdef USE_QUIC
+       ssl_qc_app_data_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+#endif /* USE_QUIC */
 #ifdef HAVE_SSL_KEYLOG
        ssl_keylog_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_keylog_free_func);
 #endif
index 8e3b1dc21ef4ad4a97588cebc072d84625eaf419..71d3b47ef0d6b9eb752d99a01e7a2395eadac21a 100644 (file)
@@ -745,21 +745,20 @@ int ha_quic_set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t level,
                                    const uint8_t *read_secret,
                                    const uint8_t *write_secret, size_t secret_len)
 {
-       struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
-       struct quic_tls_ctx *tls_ctx =
-               &conn->qc->els[ssl_to_quic_enc_level(level)].tls_ctx;
+       struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
+       struct quic_tls_ctx *tls_ctx = &qc->els[ssl_to_quic_enc_level(level)].tls_ctx;
        const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
        struct quic_tls_secrets *rx, *tx;
 
-       TRACE_ENTER(QUIC_EV_CONN_RWSEC, conn->qc);
+       TRACE_ENTER(QUIC_EV_CONN_RWSEC, qc);
        BUG_ON(secret_len > QUIC_TLS_SECRET_LEN);
-       if (HA_ATOMIC_LOAD(&conn->qc->flags) & QUIC_FL_CONN_IMMEDIATE_CLOSE) {
-               TRACE_PROTO("CC required", QUIC_EV_CONN_RWSEC, conn->qc);
+       if (HA_ATOMIC_LOAD(&qc->flags) & QUIC_FL_CONN_IMMEDIATE_CLOSE) {
+               TRACE_PROTO("CC required", QUIC_EV_CONN_RWSEC, qc);
                goto out;
        }
 
        if (!quic_tls_ctx_keys_alloc(tls_ctx)) {
-               TRACE_DEVEL("keys allocation failed", QUIC_EV_CONN_RWSEC, conn->qc);
+               TRACE_DEVEL("keys allocation failed", QUIC_EV_CONN_RWSEC, qc);
                goto err;
        }
 
@@ -773,7 +772,7 @@ int ha_quic_set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t level,
        if (!quic_tls_derive_keys(rx->aead, rx->hp, rx->md, rx->key, rx->keylen,
                                  rx->iv, rx->ivlen, rx->hp_key, sizeof rx->hp_key,
                                  read_secret, secret_len)) {
-               TRACE_DEVEL("RX key derivation failed", QUIC_EV_CONN_RWSEC, conn->qc);
+               TRACE_DEVEL("RX key derivation failed", QUIC_EV_CONN_RWSEC, qc);
                goto err;
        }
 
@@ -785,13 +784,13 @@ int ha_quic_set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t level,
        if (!quic_tls_derive_keys(tx->aead, tx->hp, tx->md, tx->key, tx->keylen,
                                  tx->iv, tx->ivlen, tx->hp_key, sizeof tx->hp_key,
                                  write_secret, secret_len)) {
-               TRACE_DEVEL("TX key derivation failed", QUIC_EV_CONN_RWSEC, conn->qc);
+               TRACE_DEVEL("TX key derivation failed", QUIC_EV_CONN_RWSEC, qc);
                goto err;
        }
 
        tx->flags |= QUIC_FL_TLS_SECRETS_SET;
  tp:
-       if (objt_server(conn->target) && level == ssl_encryption_application) {
+       if (!qc_is_listener(qc) && level == ssl_encryption_application) {
                const unsigned char *buf;
                size_t buflen;
 
@@ -799,19 +798,18 @@ int ha_quic_set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t level,
                if (!buflen)
                        goto err;
 
-               if (!quic_transport_params_store(conn->qc, 1, buf, buf + buflen))
+               if (!quic_transport_params_store(qc, 1, buf, buf + buflen))
                        goto err;
        }
 
        if (level == ssl_encryption_application) {
-               struct quic_conn *qc = conn->qc;
                struct quic_tls_kp *prv_rx = &qc->ku.prv_rx;
                struct quic_tls_kp *nxt_rx = &qc->ku.nxt_rx;
                struct quic_tls_kp *nxt_tx = &qc->ku.nxt_tx;
 
                if (!(rx->secret = pool_alloc(pool_head_quic_tls_secret)) ||
                    !(tx->secret = pool_alloc(pool_head_quic_tls_secret))) {
-                       TRACE_DEVEL("Could not allocate secrete keys", QUIC_EV_CONN_RWSEC, conn->qc);
+                       TRACE_DEVEL("Could not allocate secrete keys", QUIC_EV_CONN_RWSEC, qc);
                        goto err;
                }
 
@@ -826,11 +824,11 @@ int ha_quic_set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t level,
                        goto err;
        }
  out:
-       TRACE_LEAVE(QUIC_EV_CONN_RWSEC, conn->qc, &level);
+       TRACE_LEAVE(QUIC_EV_CONN_RWSEC, qc, &level);
        return 1;
 
  err:
-       TRACE_DEVEL("leaving in error", QUIC_EV_CONN_RWSEC, conn->qc);
+       TRACE_DEVEL("leaving in error", QUIC_EV_CONN_RWSEC, qc);
        return 0;
 }
 #else
@@ -842,13 +840,13 @@ int ha_set_rsec(SSL *ssl, enum ssl_encryption_level_t level,
                 const SSL_CIPHER *cipher,
                 const uint8_t *secret, size_t secret_len)
 {
-       struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
+       struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
        struct quic_tls_ctx *tls_ctx =
-               &conn->qc->els[ssl_to_quic_enc_level(level)].tls_ctx;
+               &qc->els[ssl_to_quic_enc_level(level)].tls_ctx;
 
-       TRACE_ENTER(QUIC_EV_CONN_RSEC, conn->qc);
-       if (HA_ATOMIC_LOAD(&conn->qc->flags) & QUIC_FL_CONN_IMMEDIATE_CLOSE) {
-               TRACE_PROTO("CC required", QUIC_EV_CONN_RSEC, conn->qc);
+       TRACE_ENTER(QUIC_EV_CONN_RSEC, qc);
+       if (HA_ATOMIC_LOAD(&qc->flags) & QUIC_FL_CONN_IMMEDIATE_CLOSE) {
+               TRACE_PROTO("CC required", QUIC_EV_CONN_RSEC, qc);
                goto out;
        }
 
@@ -864,11 +862,11 @@ int ha_set_rsec(SSL *ssl, enum ssl_encryption_level_t level,
                                  tls_ctx->rx.iv, tls_ctx->rx.ivlen,
                                  tls_ctx->rx.hp_key, sizeof tls_ctx->rx.hp_key,
                                  secret, secret_len)) {
-               TRACE_DEVEL("RX key derivation failed", QUIC_EV_CONN_RSEC, conn->qc);
+               TRACE_DEVEL("RX key derivation failed", QUIC_EV_CONN_RSEC, qc);
                goto err;
        }
 
-       if (objt_server(conn->target) && level == ssl_encryption_application) {
+       if (!qc_is_listener(qc) && level == ssl_encryption_application) {
                const unsigned char *buf;
                size_t buflen;
 
@@ -876,18 +874,18 @@ int ha_set_rsec(SSL *ssl, enum ssl_encryption_level_t level,
                if (!buflen)
                        goto err;
 
-               if (!quic_transport_params_store(conn->qc, 1, buf, buf + buflen))
+               if (!quic_transport_params_store(qc, 1, buf, buf + buflen))
                        goto err;
        }
 
        tls_ctx->rx.flags |= QUIC_FL_TLS_SECRETS_SET;
  out:
-       TRACE_LEAVE(QUIC_EV_CONN_RSEC, conn->qc, &level, secret, &secret_len);
+       TRACE_LEAVE(QUIC_EV_CONN_RSEC, qc, &level, secret, &secret_len);
 
        return 1;
 
  err:
-       TRACE_DEVEL("leaving in error", QUIC_EV_CONN_RSEC, conn->qc);
+       TRACE_DEVEL("leaving in error", QUIC_EV_CONN_RSEC, qc);
        return 0;
 }
 
@@ -899,13 +897,12 @@ int ha_set_wsec(SSL *ssl, enum ssl_encryption_level_t level,
                 const SSL_CIPHER *cipher,
                 const uint8_t *secret, size_t secret_len)
 {
-       struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
-       struct quic_tls_ctx *tls_ctx =
-               &conn->qc->els[ssl_to_quic_enc_level(level)].tls_ctx;
+       struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
+       struct quic_tls_ctx *tls_ctx = &qc->els[ssl_to_quic_enc_level(level)].tls_ctx;
 
-       TRACE_ENTER(QUIC_EV_CONN_WSEC, conn->qc);
-       if (HA_ATOMIC_LOAD(&conn->qc->flags) & QUIC_FL_CONN_IMMEDIATE_CLOSE) {
-               TRACE_PROTO("CC required", QUIC_EV_CONN_WSEC, conn->qc);
+       TRACE_ENTER(QUIC_EV_CONN_WSEC, qc);
+       if (HA_ATOMIC_LOAD(&qc->flags) & QUIC_FL_CONN_IMMEDIATE_CLOSE) {
+               TRACE_PROTO("CC required", QUIC_EV_CONN_WSEC, qc);
                goto out;
        }
 
@@ -921,17 +918,17 @@ int ha_set_wsec(SSL *ssl, enum ssl_encryption_level_t level,
                                  tls_ctx->tx.iv, tls_ctx->tx.ivlen,
                                  tls_ctx->tx.hp_key, sizeof tls_ctx->tx.hp_key,
                                  secret, secret_len)) {
-               TRACE_DEVEL("TX key derivation failed", QUIC_EV_CONN_WSEC, conn->qc);
+               TRACE_DEVEL("TX key derivation failed", QUIC_EV_CONN_WSEC, qc);
                goto err;
        }
 
        tls_ctx->tx.flags |= QUIC_FL_TLS_SECRETS_SET;
-       TRACE_LEAVE(QUIC_EV_CONN_WSEC, conn->qc, &level, secret, &secret_len);
+       TRACE_LEAVE(QUIC_EV_CONN_WSEC, qc, &level, secret, &secret_len);
  out:
        return 1;
 
  err:
-       TRACE_DEVEL("leaving in error", QUIC_EV_CONN_WSEC, conn->qc);
+       TRACE_DEVEL("leaving in error", QUIC_EV_CONN_WSEC, qc);
        return 0;
 }
 #endif
@@ -1071,59 +1068,59 @@ int quic_set_app_ops(struct quic_conn *qc, const unsigned char *alpn, size_t alp
 int ha_quic_add_handshake_data(SSL *ssl, enum ssl_encryption_level_t level,
                                const uint8_t *data, size_t len)
 {
-       struct connection *conn;
+       struct quic_conn *qc;
        enum quic_tls_enc_level tel;
        struct quic_enc_level *qel;
 
-       conn = SSL_get_ex_data(ssl, ssl_app_data_index);
-       TRACE_ENTER(QUIC_EV_CONN_ADDDATA, conn->qc);
-       if (HA_ATOMIC_LOAD(&conn->qc->flags) & QUIC_FL_CONN_IMMEDIATE_CLOSE) {
-               TRACE_PROTO("CC required", QUIC_EV_CONN_ADDDATA, conn->qc);
+       qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
+       TRACE_ENTER(QUIC_EV_CONN_ADDDATA, qc);
+       if (HA_ATOMIC_LOAD(&qc->flags) & QUIC_FL_CONN_IMMEDIATE_CLOSE) {
+               TRACE_PROTO("CC required", QUIC_EV_CONN_ADDDATA, qc);
                goto out;
        }
 
        tel = ssl_to_quic_enc_level(level);
-       qel = &conn->qc->els[tel];
+       qel = &qc->els[tel];
 
        if (tel == -1) {
-               TRACE_PROTO("Wrong encryption level", QUIC_EV_CONN_ADDDATA, conn->qc);
+               TRACE_PROTO("Wrong encryption level", QUIC_EV_CONN_ADDDATA, qc);
                goto err;
        }
 
        if (!quic_crypto_data_cpy(qel, data, len)) {
-               TRACE_PROTO("Could not bufferize", QUIC_EV_CONN_ADDDATA, conn->qc);
+               TRACE_PROTO("Could not bufferize", QUIC_EV_CONN_ADDDATA, qc);
                goto err;
        }
 
        TRACE_PROTO("CRYPTO data buffered", QUIC_EV_CONN_ADDDATA,
-                   conn->qc, &level, &len);
+                   qc, &level, &len);
 
  out:
-       TRACE_LEAVE(QUIC_EV_CONN_ADDDATA, conn->qc);
+       TRACE_LEAVE(QUIC_EV_CONN_ADDDATA, qc);
        return 1;
 
  err:
-       TRACE_DEVEL("leaving in error", QUIC_EV_CONN_ADDDATA, conn->qc);
+       TRACE_DEVEL("leaving in error", QUIC_EV_CONN_ADDDATA, qc);
        return 0;
 }
 
 int ha_quic_flush_flight(SSL *ssl)
 {
-       struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
+       struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
 
-       TRACE_ENTER(QUIC_EV_CONN_FFLIGHT, conn->qc);
-       TRACE_LEAVE(QUIC_EV_CONN_FFLIGHT, conn->qc);
+       TRACE_ENTER(QUIC_EV_CONN_FFLIGHT, qc);
+       TRACE_LEAVE(QUIC_EV_CONN_FFLIGHT, qc);
 
        return 1;
 }
 
 int ha_quic_send_alert(SSL *ssl, enum ssl_encryption_level_t level, uint8_t alert)
 {
-       struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
+       struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
 
-       TRACE_DEVEL("SSL alert", QUIC_EV_CONN_SSLALERT, conn->qc, &alert, &level);
-       quic_set_tls_alert(conn->qc, alert);
-       HA_ATOMIC_STORE(&conn->qc->flags, QUIC_FL_CONN_IMMEDIATE_CLOSE);
+       TRACE_DEVEL("SSL alert", QUIC_EV_CONN_SSLALERT, qc, &alert, &level);
+       quic_set_tls_alert(qc, alert);
+       HA_ATOMIC_STORE(&qc->flags, QUIC_FL_CONN_IMMEDIATE_CLOSE);
        return 1;
 }
 
@@ -5384,7 +5381,7 @@ static int qc_ssl_sess_init(struct quic_conn *qc, SSL_CTX *ssl_ctx, SSL **ssl,
        }
 
        if (!SSL_set_quic_method(*ssl, &ha_quic_method) ||
-           !SSL_set_ex_data(*ssl, ssl_app_data_index, qc->conn) ||
+           !SSL_set_ex_data(*ssl, ssl_qc_app_data_index, qc) ||
            !SSL_set_quic_transport_params(*ssl, qc->enc_params, qc->enc_params_len)) {
                        goto err;