]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Set "no_application_protocol" alert
authorFrédéric Lécaille <flecaille@haproxy.com>
Fri, 19 Nov 2021 16:02:20 +0000 (17:02 +0100)
committerFrédéric Lécaille <flecaille@haproxy.com>
Tue, 30 Nov 2021 10:47:46 +0000 (11:47 +0100)
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
include/haproxy/xprt_quic.h
src/ssl_sock.c
src/xprt_quic.c

index 91188c3c5561696c438ce5006beea4075d097051..7ac87e7514af095a2455a4d9849c327492a9d86d 100644 (file)
@@ -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 */
index 018b3042296d7ff6b6db9f4fcc4a214770295910..14f1de27cbc04c1459d0982085d64adc542dabf2 100644 (file)
@@ -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 */
index e3e3abf62729837e078119a69d8080d5d98423ef..ffbfa5031d9a3f33428c7373e125e8c5639dfbc2 100644 (file)
@@ -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;
index d2b8aae578471269f4e237bff6fac4879b135f40..6e21cdbfa6cbe0e59a3450258452216464240d50 100644 (file)
@@ -885,6 +885,14 @@ static int quic_crypto_data_cpy(struct quic_enc_level *qel,
 }
 
 
+/* Set <alert> 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: