diff options
author | tb <> | 2021-09-10 09:25:29 +0000 |
---|---|---|
committer | tb <> | 2021-09-10 09:25:29 +0000 |
commit | 47a94cad06ffc8bf1c64c7870f0dc905ed8485e4 (patch) | |
tree | 2fcdf6ff9ae24aab6ae8fc69b1f46e80b647dd92 /src/lib/libssl/ssl_tlsext.c | |
parent | d17eb2a4cbcb7c76bb5dd38f9d1c26044d64118f (diff) | |
download | openbsd-47a94cad06ffc8bf1c64c7870f0dc905ed8485e4.tar.gz openbsd-47a94cad06ffc8bf1c64c7870f0dc905ed8485e4.tar.bz2 openbsd-47a94cad06ffc8bf1c64c7870f0dc905ed8485e4.zip |
Do not ignore SSL_TLSEXT_ERR_FATAL from the ALPN callback
As reported by Jeremy Harris, we inherited a strange behavior from
OpenSSL, in that we ignore the SSL_TLSEXT_ERR_FATAL return from the
ALPN callback. RFC 7301, 3.2 states: '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.'
Honor this requirement and succeed only on SSL_TLSEXT_ERR_{OK,NOACK}
which is the current behavior of OpenSSL. The documentation change
is taken from OpenSSL 1.1.1 as well.
As pointed out by jsing, there is more to be fixed here:
- ensure that the same protocol is selected on session resumption
- should the callback be called even if no ALPN extension was sent?
- ensure for TLSv1.2 and earlier that the SNI has already been processed
ok beck jsing
Diffstat (limited to '')
-rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index 4d426f1487..3ad564964d 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.98 2021/09/02 11:10:43 beck Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.99 2021/09/10 09:25:29 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> |
@@ -85,9 +85,16 @@ tlsext_alpn_server_parse(SSL *s, uint16_t msg_types, CBS *cbs, int *alert) | |||
85 | if (s->ctx->internal->alpn_select_cb == NULL) | 85 | if (s->ctx->internal->alpn_select_cb == NULL) |
86 | return 1; | 86 | return 1; |
87 | 87 | ||
88 | /* | ||
89 | * XXX - A few things should be considered here: | ||
90 | * 1. Ensure that the same protocol is selected on session resumption. | ||
91 | * 2. Should the callback be called even if no ALPN extension was sent? | ||
92 | * 3. TLSv1.2 and earlier: ensure that SNI has already been processed. | ||
93 | */ | ||
88 | r = s->ctx->internal->alpn_select_cb(s, &selected, &selected_len, | 94 | r = s->ctx->internal->alpn_select_cb(s, &selected, &selected_len, |
89 | CBS_data(&alpn), CBS_len(&alpn), | 95 | CBS_data(&alpn), CBS_len(&alpn), |
90 | s->ctx->internal->alpn_select_cb_arg); | 96 | s->ctx->internal->alpn_select_cb_arg); |
97 | |||
91 | if (r == SSL_TLSEXT_ERR_OK) { | 98 | if (r == SSL_TLSEXT_ERR_OK) { |
92 | free(S3I(s)->alpn_selected); | 99 | free(S3I(s)->alpn_selected); |
93 | if ((S3I(s)->alpn_selected = malloc(selected_len)) == NULL) { | 100 | if ((S3I(s)->alpn_selected = malloc(selected_len)) == NULL) { |
@@ -97,9 +104,18 @@ tlsext_alpn_server_parse(SSL *s, uint16_t msg_types, CBS *cbs, int *alert) | |||
97 | } | 104 | } |
98 | memcpy(S3I(s)->alpn_selected, selected, selected_len); | 105 | memcpy(S3I(s)->alpn_selected, selected, selected_len); |
99 | S3I(s)->alpn_selected_len = selected_len; | 106 | S3I(s)->alpn_selected_len = selected_len; |
107 | |||
108 | return 1; | ||
100 | } | 109 | } |
101 | 110 | ||
102 | return 1; | 111 | /* On SSL_TLSEXT_ERR_NOACK behave as if no callback was present. */ |
112 | if (r == SSL_TLSEXT_ERR_NOACK) | ||
113 | return 1; | ||
114 | |||
115 | *alert = SSL_AD_NO_APPLICATION_PROTOCOL; | ||
116 | SSLerror(s, SSL_R_NO_APPLICATION_PROTOCOL); | ||
117 | |||
118 | return 0; | ||
103 | 119 | ||
104 | err: | 120 | err: |
105 | *alert = SSL_AD_DECODE_ERROR; | 121 | *alert = SSL_AD_DECODE_ERROR; |