diff options
Diffstat (limited to 'src/lib/libssl/ssl_tlsext.c')
| -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. */ |
