diff options
author | beck <> | 2024-03-27 10:44:17 +0000 |
---|---|---|
committer | beck <> | 2024-03-27 10:44:17 +0000 |
commit | e3b2ca9fbeeeae6079da035409c6531ed1f9cf91 (patch) | |
tree | f2c7e3058130c3068f1877f9a7c3499c2f152cae | |
parent | dcbf0a4f999b6c933d8a3b910293af515367fae3 (diff) | |
download | openbsd-e3b2ca9fbeeeae6079da035409c6531ed1f9cf91.tar.gz openbsd-e3b2ca9fbeeeae6079da035409c6531ed1f9cf91.tar.bz2 openbsd-e3b2ca9fbeeeae6079da035409c6531ed1f9cf91.zip |
Do not allow duplicate groups in supported groups.
While we are here refactor this to single return.
ok jsing@ tb@
-rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index e1506e5d60..e4ba549814 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.143 2024/03/26 03:44:11 beck Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.144 2024/03/27 10:44:17 beck 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> |
@@ -33,6 +33,7 @@ | |||
33 | #include "ssl_tlsext.h" | 33 | #include "ssl_tlsext.h" |
34 | 34 | ||
35 | #define TLSEXT_TYPE_alpn TLSEXT_TYPE_application_layer_protocol_negotiation | 35 | #define TLSEXT_TYPE_alpn TLSEXT_TYPE_application_layer_protocol_negotiation |
36 | #define TLSEXT_MAX_SUPPORTED_GROUPS 64 | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Supported Application-Layer Protocol Negotiation - RFC 7301 | 39 | * Supported Application-Layer Protocol Negotiation - RFC 7301 |
@@ -230,21 +231,25 @@ static int | |||
230 | tlsext_supportedgroups_server_process(SSL *s, uint16_t msg_type, CBS *cbs, | 231 | tlsext_supportedgroups_server_process(SSL *s, uint16_t msg_type, CBS *cbs, |
231 | int *alert) | 232 | int *alert) |
232 | { | 233 | { |
233 | CBS grouplist; | 234 | uint16_t *groups = NULL; |
234 | uint16_t *groups; | ||
235 | size_t groups_len; | 235 | size_t groups_len; |
236 | int i; | 236 | CBS grouplist; |
237 | int i, j; | ||
238 | int ret = 0; | ||
237 | 239 | ||
238 | if (!CBS_get_u16_length_prefixed(cbs, &grouplist)) | 240 | if (!CBS_get_u16_length_prefixed(cbs, &grouplist)) |
239 | return 0; | 241 | goto err; |
240 | 242 | ||
241 | groups_len = CBS_len(&grouplist); | 243 | groups_len = CBS_len(&grouplist); |
242 | if (groups_len == 0 || groups_len % 2 != 0) | 244 | if (groups_len == 0 || groups_len % 2 != 0) |
243 | return 0; | 245 | goto err; |
244 | groups_len /= 2; | 246 | groups_len /= 2; |
245 | 247 | ||
248 | if (groups_len > TLSEXT_MAX_SUPPORTED_GROUPS) | ||
249 | goto err; | ||
250 | |||
246 | if (s->hit) | 251 | if (s->hit) |
247 | return 1; | 252 | goto done; |
248 | 253 | ||
249 | if (s->s3->hs.tls13.hrr) { | 254 | if (s->s3->hs.tls13.hrr) { |
250 | if (s->session->tlsext_supportedgroups == NULL) { | 255 | if (s->session->tlsext_supportedgroups == NULL) { |
@@ -257,33 +262,49 @@ tlsext_supportedgroups_server_process(SSL *s, uint16_t msg_type, CBS *cbs, | |||
257 | * did not change its list of supported groups. | 262 | * did not change its list of supported groups. |
258 | */ | 263 | */ |
259 | 264 | ||
260 | return 1; | 265 | goto done; |
261 | } | 266 | } |
262 | 267 | ||
263 | if (s->session->tlsext_supportedgroups != NULL) | 268 | if (s->session->tlsext_supportedgroups != NULL) |
264 | return 0; /* XXX internal error? */ | 269 | goto err; /* XXX internal error? */ |
265 | 270 | ||
266 | if ((groups = reallocarray(NULL, groups_len, sizeof(uint16_t))) == NULL) { | 271 | if ((groups = reallocarray(NULL, groups_len, sizeof(uint16_t))) == NULL) { |
267 | *alert = SSL_AD_INTERNAL_ERROR; | 272 | *alert = SSL_AD_INTERNAL_ERROR; |
268 | return 0; | 273 | goto err; |
269 | } | 274 | } |
270 | 275 | ||
271 | for (i = 0; i < groups_len; i++) { | 276 | for (i = 0; i < groups_len; i++) { |
272 | if (!CBS_get_u16(&grouplist, &groups[i])) { | 277 | if (!CBS_get_u16(&grouplist, &groups[i])) |
273 | free(groups); | 278 | goto err; |
274 | return 0; | 279 | /* |
280 | * Do not allow duplicate groups to be sent. This is not | ||
281 | * currently specified in RFC 8446 or earlier, but there is no | ||
282 | * legitimate justification for this to occur in TLS 1.2 or TLS | ||
283 | * 1.3. | ||
284 | */ | ||
285 | for (j = 0; j < i; j++) { | ||
286 | if (groups[i] == groups[j]) { | ||
287 | *alert = SSL_AD_ILLEGAL_PARAMETER; | ||
288 | goto err; | ||
289 | } | ||
275 | } | 290 | } |
276 | } | 291 | } |
277 | 292 | ||
278 | if (CBS_len(&grouplist) != 0) { | 293 | if (CBS_len(&grouplist) != 0) |
279 | free(groups); | 294 | goto err; |
280 | return 0; | ||
281 | } | ||
282 | 295 | ||
283 | s->session->tlsext_supportedgroups = groups; | 296 | s->session->tlsext_supportedgroups = groups; |
284 | s->session->tlsext_supportedgroups_length = groups_len; | 297 | s->session->tlsext_supportedgroups_length = groups_len; |
298 | groups = NULL; | ||
285 | 299 | ||
286 | return 1; | 300 | |
301 | done: | ||
302 | ret = 1; | ||
303 | |||
304 | err: | ||
305 | free(groups); | ||
306 | |||
307 | return ret; | ||
287 | } | 308 | } |
288 | 309 | ||
289 | /* This extension is never used by the server. */ | 310 | /* This extension is never used by the server. */ |