Fix alert callback in the QUIC layer
authortb <tb@openbsd.org>
Mon, 9 Sep 2024 03:55:55 +0000 (03:55 +0000)
committertb <tb@openbsd.org>
Mon, 9 Sep 2024 03:55:55 +0000 (03:55 +0000)
Only close_notify and user_cancelled are warning alerts. All others
should be fatal. In order for the lower layers to behave correctly,
the return code for fatal alerts needs to be TLS13_IO_ALERT instead
of TLS13_IO_SUCCESS.

Failure to signal handshake failure in the public API led to a crash
in HAProxy when forcing the tls cipher to TLS_AES_128_CCM_SHA256 as
found by haproxyfred while investigating
https://github.com/haproxy/haproxy/issues/2569

Kenjiro Nakayama found misbehavior of ngtcp2-based servers, wrote a
similar patch and tested this version.

Fixes https://github.com/libressl/portable/issues/1093

ok jsing

lib/libssl/tls13_quic.c

index e5c386e..656af6f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tls13_quic.c,v 1.7 2022/11/26 16:08:56 tb Exp $ */
+/*     $OpenBSD: tls13_quic.c,v 1.8 2024/09/09 03:55:55 tb Exp $ */
 /*
  * Copyright (c) 2022 Joel Sing <jsing@openbsd.org>
  *
@@ -131,6 +131,8 @@ tls13_quic_alert_send_cb(int alert_desc, void *arg)
 {
        struct tls13_ctx *ctx = arg;
        SSL *ssl = ctx->ssl;
+       uint8_t alert_level = TLS13_ALERT_LEVEL_FATAL;
+       int ret = TLS13_IO_ALERT;
 
        if (!ssl->quic_method->send_alert(ssl, ctx->hs->tls13.quic_write_level,
            alert_desc)) {
@@ -138,7 +140,15 @@ tls13_quic_alert_send_cb(int alert_desc, void *arg)
                return TLS13_IO_FAILURE;
        }
 
-       return TLS13_IO_SUCCESS;
+       if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY ||
+           alert_desc == TLS13_ALERT_USER_CANCELED) {
+               alert_level = TLS13_ALERT_LEVEL_WARNING;
+               ret = TLS13_IO_SUCCESS;
+       }
+
+       tls13_record_layer_alert_sent(ctx->rl, alert_level, alert_desc);
+
+       return ret;
 }
 
 static const struct tls13_record_layer_callbacks quic_rl_callbacks = {