From c2b41b2fdcfd4ba238da69ff7b5976aa1c4e2dbb Mon Sep 17 00:00:00 2001 From: tb <> Date: Sat, 29 Aug 2026 05:12:51 +0000 Subject: libssl: ensure server selected ALPN was advertised Per RFC 7301, section 3.2, "In the event that the server supports no protocols that the client advertises, then the server SHALL respond with a fatal "no_application_protocol" alert. If a server does not do that and chooses a protocol that we have not advertised, we should abort the handshake. The RFC does not specify an alert for this case. BoringSSL chose illegal_parameter and OpenSSL decode_error. I slightly prefer illegal_parameter, so went with that. Reported by Acts1631 with a similar diff. ok jsing kenjiro --- src/lib/libssl/ssl_tlsext.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index f298ec4d11..e3dbfd82cf 100644 --- a/src/lib/libssl/ssl_tlsext.c +++ b/src/lib/libssl/ssl_tlsext.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_tlsext.c,v 1.167 2026/08/29 04:54:43 tb Exp $ */ +/* $OpenBSD: ssl_tlsext.c,v 1.168 2026/08/29 05:12:51 tb Exp $ */ /* * Copyright (c) 2016, 2017, 2019 Joel Sing * Copyright (c) 2017 Doug Hogan @@ -163,8 +163,8 @@ tlsext_alpn_server_build(SSL *s, uint16_t msg_type, CBB *cbb) static int tlsext_alpn_client_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) { - CBS server_list; - CBS selected; + CBS server_list, supported_list; + CBS selected, proto; if (s->alpn_client_proto_list == NULL) { *alert = SSL_AD_UNSUPPORTED_EXTENSION; @@ -181,10 +181,24 @@ tlsext_alpn_client_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) if (CBS_len(&selected) == 0) return 0; - if (!CBS_stow(&selected, &s->s3->alpn_selected, &s->s3->alpn_selected_len)) - return 0; + /* + * Check the server selected a protocol that we advertised as supported. + */ - return 1; + CBS_init(&supported_list, s->alpn_client_proto_list, + s->alpn_client_proto_list_len); + + while (CBS_len(&supported_list) > 0) { + if (!CBS_get_u8_length_prefixed(&supported_list, &proto)) + return 0; + if (CBS_mem_equal(&selected, CBS_data(&proto), CBS_len(&proto))) + return CBS_stow(&selected, + &s->s3->alpn_selected, &s->s3->alpn_selected_len); + } + + *alert = SSL_AD_ILLEGAL_PARAMETER; + + return 0; } /* -- cgit v1.2.3-55-g6feb