diff --git a/include/haproxy/quic_tls.h b/include/haproxy/quic_tls.h index 1a316b282..208a3c26d 100644 --- a/include/haproxy/quic_tls.h +++ b/include/haproxy/quic_tls.h @@ -552,9 +552,13 @@ static inline void qc_release_pktns_frms(struct quic_conn *qc, TRACE_ENTER(QUIC_EV_CONN_PHPKTS, qc); + if (!pktns) + goto leave; + list_for_each_entry_safe(frm, frmbak, &pktns->tx.frms, list) qc_frm_free(qc, &frm); + leave: TRACE_LEAVE(QUIC_EV_CONN_PHPKTS, qc); } diff --git a/src/quic_ssl.c b/src/quic_ssl.c index 37116ca1a..0f10604f1 100644 --- a/src/quic_ssl.c +++ b/src/quic_ssl.c @@ -192,15 +192,17 @@ static int ha_quic_set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t goto write; rx = &tls_ctx->rx; + rx->aead = tls_aead(cipher); + rx->md = tls_md(cipher); + rx->hp = tls_hp(cipher); + if (!rx->aead || !rx->md || !rx->hp) + goto leave; + if (!quic_tls_secrets_keys_alloc(rx)) { TRACE_ERROR("RX keys allocation failed", QUIC_EV_CONN_RWSEC, qc); goto leave; } - rx->aead = tls_aead(cipher); - rx->md = tls_md(cipher); - rx->hp = tls_hp(cipher); - if (!quic_tls_derive_keys(rx->aead, rx->hp, rx->md, ver, rx->key, rx->keylen, rx->iv, rx->ivlen, rx->hp_key, sizeof rx->hp_key, read_secret, secret_len)) { @@ -233,15 +235,17 @@ write: goto keyupdate_init; tx = &tls_ctx->tx; + tx->aead = tls_aead(cipher); + tx->md = tls_md(cipher); + tx->hp = tls_hp(cipher); + if (!tx->aead || !tx->md || !tx->hp) + goto leave; + if (!quic_tls_secrets_keys_alloc(tx)) { TRACE_ERROR("TX keys allocation failed", QUIC_EV_CONN_RWSEC, qc); goto leave; } - tx->aead = tls_aead(cipher); - tx->md = tls_md(cipher); - tx->hp = tls_hp(cipher); - if (!quic_tls_derive_keys(tx->aead, tx->hp, tx->md, ver, tx->key, tx->keylen, tx->iv, tx->ivlen, tx->hp_key, sizeof tx->hp_key, write_secret, secret_len)) { @@ -298,6 +302,16 @@ write: out: ret = 1; leave: + if (!ret) { + /* Release the CRYPTO frames which have been provided by the TLS stack + * to prevent the transmission of ack-eliciting packets. + */ + qc_release_pktns_frms(qc, qc->ipktns); + qc_release_pktns_frms(qc, qc->hpktns); + qc_release_pktns_frms(qc, qc->apktns); + quic_set_tls_alert(qc, SSL_AD_HANDSHAKE_FAILURE); + } + TRACE_LEAVE(QUIC_EV_CONN_RWSEC, qc, &level); return ret; } diff --git a/src/quic_tls.c b/src/quic_tls.c index 182b62696..8c085e278 100644 --- a/src/quic_tls.c +++ b/src/quic_tls.c @@ -47,9 +47,16 @@ void quic_tls_keys_hexdump(struct buffer *buf, const struct quic_tls_secrets *secs) { int i; - size_t aead_keylen = (size_t)EVP_CIPHER_key_length(secs->aead); - size_t aead_ivlen = (size_t)EVP_CIPHER_iv_length(secs->aead); - size_t hp_len = (size_t)EVP_CIPHER_key_length(secs->hp); + size_t aead_keylen; + size_t aead_ivlen; + size_t hp_len; + + if (!secs->aead || !secs->hp) + return; + + aead_keylen = (size_t)EVP_CIPHER_key_length(secs->aead); + aead_ivlen = (size_t)EVP_CIPHER_iv_length(secs->aead); + hp_len = (size_t)EVP_CIPHER_key_length(secs->hp); chunk_appendf(buf, "\n key="); for (i = 0; i < aead_keylen; i++)