diff options
| author | tb <> | 2026-08-29 05:12:51 +0000 |
|---|---|---|
| committer | tb <> | 2026-08-29 05:12:51 +0000 |
| commit | c2b41b2fdcfd4ba238da69ff7b5976aa1c4e2dbb (patch) | |
| tree | 3883cbb70d3cda040a107b076036c9870efe2ff2 /src/lib/libssl | |
| parent | c087cfb4dd519b837fdf6897a81c00d4bf2fa78e (diff) | |
| download | openbsd-c2b41b2fdcfd4ba238da69ff7b5976aa1c4e2dbb.tar.gz openbsd-c2b41b2fdcfd4ba238da69ff7b5976aa1c4e2dbb.tar.bz2 openbsd-c2b41b2fdcfd4ba238da69ff7b5976aa1c4e2dbb.zip | |
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
Diffstat (limited to 'src/lib/libssl')
| -rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 26 |
1 files changed, 20 insertions, 6 deletions
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 @@ | |||
| 1 | /* $OpenBSD: ssl_tlsext.c,v 1.167 2026/08/29 04:54:43 tb Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.168 2026/08/29 05:12:51 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org> |
| 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> | 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
| @@ -163,8 +163,8 @@ tlsext_alpn_server_build(SSL *s, uint16_t msg_type, CBB *cbb) | |||
| 163 | static int | 163 | static int |
| 164 | tlsext_alpn_client_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) | 164 | tlsext_alpn_client_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) |
| 165 | { | 165 | { |
| 166 | CBS server_list; | 166 | CBS server_list, supported_list; |
| 167 | CBS selected; | 167 | CBS selected, proto; |
| 168 | 168 | ||
| 169 | if (s->alpn_client_proto_list == NULL) { | 169 | if (s->alpn_client_proto_list == NULL) { |
| 170 | *alert = SSL_AD_UNSUPPORTED_EXTENSION; | 170 | *alert = SSL_AD_UNSUPPORTED_EXTENSION; |
| @@ -181,10 +181,24 @@ tlsext_alpn_client_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) | |||
| 181 | if (CBS_len(&selected) == 0) | 181 | if (CBS_len(&selected) == 0) |
| 182 | return 0; | 182 | return 0; |
| 183 | 183 | ||
| 184 | if (!CBS_stow(&selected, &s->s3->alpn_selected, &s->s3->alpn_selected_len)) | 184 | /* |
| 185 | return 0; | 185 | * Check the server selected a protocol that we advertised as supported. |
| 186 | */ | ||
| 186 | 187 | ||
| 187 | return 1; | 188 | CBS_init(&supported_list, s->alpn_client_proto_list, |
| 189 | s->alpn_client_proto_list_len); | ||
| 190 | |||
| 191 | while (CBS_len(&supported_list) > 0) { | ||
| 192 | if (!CBS_get_u8_length_prefixed(&supported_list, &proto)) | ||
| 193 | return 0; | ||
| 194 | if (CBS_mem_equal(&selected, CBS_data(&proto), CBS_len(&proto))) | ||
| 195 | return CBS_stow(&selected, | ||
| 196 | &s->s3->alpn_selected, &s->s3->alpn_selected_len); | ||
| 197 | } | ||
| 198 | |||
| 199 | *alert = SSL_AD_ILLEGAL_PARAMETER; | ||
| 200 | |||
| 201 | return 0; | ||
| 188 | } | 202 | } |
| 189 | 203 | ||
| 190 | /* | 204 | /* |
