From 067a82bba14171b34036e8f1e2705d33055dbd04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Fri, 19 Nov 2021 17:02:20 +0100 Subject: [PATCH] MINOR: quic: Set "no_application_protocol" alert We set this TLS error when no application protocol could be negotiated via the TLS callback concerned. It is converted as a QUIC CRYPTO_ERROR error (0x178). --- include/haproxy/xprt_quic-t.h | 3 ++- include/haproxy/xprt_quic.h | 2 ++ src/ssl_sock.c | 6 ++++++ src/xprt_quic.c | 13 +++++++++++-- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/haproxy/xprt_quic-t.h b/include/haproxy/xprt_quic-t.h index 91188c3c5..7ac87e751 100644 --- a/include/haproxy/xprt_quic-t.h +++ b/include/haproxy/xprt_quic-t.h @@ -618,7 +618,8 @@ struct rxbuf { #define QUIC_FL_PKTNS_ACK_REQUIRED_BIT 0 #define QUIC_FL_PKTNS_ACK_REQUIRED (1UL << QUIC_FL_PKTNS_ACK_REQUIRED_BIT) -#define QUIC_FL_CONN_ANTI_AMPLIFICATION_REACHED (1UL << 1) +#define QUIC_FL_CONN_ANTI_AMPLIFICATION_REACHED (1U << 1) +#define QUIC_FL_CONN_IMMEDIATE_CLOSE (1U << 31) struct quic_conn { uint32_t version; /* QUIC transport parameters TLS extension */ diff --git a/include/haproxy/xprt_quic.h b/include/haproxy/xprt_quic.h index 018b30422..14f1de27c 100644 --- a/include/haproxy/xprt_quic.h +++ b/include/haproxy/xprt_quic.h @@ -1104,7 +1104,9 @@ static inline void quic_tx_packet_refdec(struct quic_tx_packet *pkt) pool_free(pool_head_quic_tx_packet, pkt); } +void quic_set_tls_alert(struct quic_conn *qc, int alert); ssize_t quic_lstnr_dgram_read(struct buffer *buf, size_t len, void *owner, struct sockaddr_storage *saddr); + #endif /* USE_QUIC */ #endif /* _HAPROXY_XPRT_QUIC_H */ diff --git a/src/ssl_sock.c b/src/ssl_sock.c index e3e3abf62..ffbfa5031 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -1977,6 +1977,12 @@ static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out, 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 + struct connection *conn = SSL_get_ex_data(s, ssl_app_data_index); + + if (conn->qc) + quic_set_tls_alert(conn->qc, SSL_AD_NO_APPLICATION_PROTOCOL); +#endif return SSL_TLSEXT_ERR_NOACK; } return SSL_TLSEXT_ERR_OK; diff --git a/src/xprt_quic.c b/src/xprt_quic.c index d2b8aae57..6e21cdbfa 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -885,6 +885,14 @@ static int quic_crypto_data_cpy(struct quic_enc_level *qel, } +/* Set TLS alert as QUIC CRYPTO_ERROR error */ +void quic_set_tls_alert(struct quic_conn *qc, int alert) +{ + HA_ATOMIC_STORE(&qc->err, QC_ERR_CRYPTO_ERROR | alert); + HA_ATOMIC_OR(&qc->flags, QUIC_FL_CONN_IMMEDIATE_CLOSE); + TRACE_PROTO("Alert set", QUIC_EV_CONN_SSLDATA, qc->conn); +} + /* ->add_handshake_data QUIC TLS callback used by the QUIC TLS stack when it * wants to provide the QUIC layer with CRYPTO data. * Returns 1 if succeeded, 0 if not. @@ -937,7 +945,7 @@ int ha_quic_send_alert(SSL *ssl, enum ssl_encryption_level_t level, uint8_t aler struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index); TRACE_DEVEL("SSL alert", QUIC_EV_CONN_SSLALERT, conn, &alert, &level); - HA_ATOMIC_STORE(&conn->qc->err, QC_ERR_CRYPTO_ERROR | alert); + quic_set_tls_alert(conn->qc, alert); return 1; } @@ -1694,7 +1702,8 @@ static inline int qc_provide_cdata(struct quic_enc_level *el, /* TODO RFC9001 8.1. Protocol Negotiation * must return no_application_protocol TLS alert */ - ABORT_NOW(); + TRACE_PROTO("No matching ALPN", QUIC_EV_CONN_SSLDATA, ctx->conn); + goto err; } out: