diff options
-rw-r--r-- | src/lib/libssl/ssl_lib.c | 7 | ||||
-rw-r--r-- | src/lib/libssl/ssl_local.h | 3 | ||||
-rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 63 | ||||
-rw-r--r-- | src/lib/libssl/ssl_tlsext.h | 3 |
4 files changed, 71 insertions, 5 deletions
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index de4ef3fb5e..68e60a5481 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_lib.c,v 1.308 2022/11/26 16:08:55 tb Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.309 2023/04/23 18:51:53 tb Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -302,6 +302,9 @@ SSL_new(SSL_CTX *ctx) | |||
302 | CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); | 302 | CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); |
303 | s->initial_ctx = ctx; | 303 | s->initial_ctx = ctx; |
304 | 304 | ||
305 | if (!tlsext_randomize_build_order(s)) | ||
306 | goto err; | ||
307 | |||
305 | if (ctx->tlsext_ecpointformatlist != NULL) { | 308 | if (ctx->tlsext_ecpointformatlist != NULL) { |
306 | s->tlsext_ecpointformatlist = | 309 | s->tlsext_ecpointformatlist = |
307 | calloc(ctx->tlsext_ecpointformatlist_length, | 310 | calloc(ctx->tlsext_ecpointformatlist_length, |
@@ -550,6 +553,8 @@ SSL_free(SSL *s) | |||
550 | 553 | ||
551 | ssl_cert_free(s->cert); | 554 | ssl_cert_free(s->cert); |
552 | 555 | ||
556 | free(s->tlsext_build_order); | ||
557 | |||
553 | free(s->tlsext_hostname); | 558 | free(s->tlsext_hostname); |
554 | SSL_CTX_free(s->initial_ctx); | 559 | SSL_CTX_free(s->initial_ctx); |
555 | 560 | ||
diff --git a/src/lib/libssl/ssl_local.h b/src/lib/libssl/ssl_local.h index d510f80d8c..1748eccbfd 100644 --- a/src/lib/libssl/ssl_local.h +++ b/src/lib/libssl/ssl_local.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_local.h,v 1.3 2022/12/26 07:31:44 jmc Exp $ */ | 1 | /* $OpenBSD: ssl_local.h,v 1.4 2023/04/23 18:51:53 tb Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -974,6 +974,7 @@ struct ssl_st { | |||
974 | 974 | ||
975 | unsigned int max_send_fragment; | 975 | unsigned int max_send_fragment; |
976 | 976 | ||
977 | const struct tls_extension **tlsext_build_order; | ||
977 | char *tlsext_hostname; | 978 | char *tlsext_hostname; |
978 | 979 | ||
979 | /* certificate status request info */ | 980 | /* certificate status request info */ |
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index e576384118..5ff61f39a5 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.131 2022/11/26 16:08:56 tb Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.132 2023/04/23 18:51:53 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> |
@@ -32,6 +32,8 @@ | |||
32 | #include "ssl_sigalgs.h" | 32 | #include "ssl_sigalgs.h" |
33 | #include "ssl_tlsext.h" | 33 | #include "ssl_tlsext.h" |
34 | 34 | ||
35 | #define TLSEXT_TYPE_alpn TLSEXT_TYPE_application_layer_protocol_negotiation | ||
36 | |||
35 | /* | 37 | /* |
36 | * Supported Application-Layer Protocol Negotiation - RFC 7301 | 38 | * Supported Application-Layer Protocol Negotiation - RFC 7301 |
37 | */ | 39 | */ |
@@ -2239,6 +2241,63 @@ tlsext_funcs(const struct tls_extension *tlsext, int is_server) | |||
2239 | return &tlsext->client; | 2241 | return &tlsext->client; |
2240 | } | 2242 | } |
2241 | 2243 | ||
2244 | int | ||
2245 | tlsext_randomize_build_order(SSL *s) | ||
2246 | { | ||
2247 | size_t idx, new_idx, psk_idx; | ||
2248 | size_t alpn_idx, sni_idx; | ||
2249 | |||
2250 | if ((s->tlsext_build_order = calloc(sizeof(*s->tlsext_build_order), | ||
2251 | N_TLS_EXTENSIONS)) == NULL) | ||
2252 | return 0; | ||
2253 | |||
2254 | /* RFC 8446, section 4.2: PSK must be the last extension in the CH. */ | ||
2255 | psk_idx = N_TLS_EXTENSIONS - 1; | ||
2256 | s->tlsext_build_order[psk_idx] = &tls_extensions[psk_idx]; | ||
2257 | |||
2258 | /* Fisher-Yates shuffle with PSK fixed. */ | ||
2259 | for (idx = 0; idx < psk_idx; idx++) { | ||
2260 | new_idx = arc4random_uniform(idx + 1); | ||
2261 | s->tlsext_build_order[idx] = s->tlsext_build_order[new_idx]; | ||
2262 | s->tlsext_build_order[new_idx] = &tls_extensions[idx]; | ||
2263 | } | ||
2264 | |||
2265 | /* | ||
2266 | * XXX - Apache2 special until year 2025: ensure that SNI precedes ALPN | ||
2267 | * for clients so that virtual host setups work correctly. | ||
2268 | */ | ||
2269 | |||
2270 | if (s->server) | ||
2271 | return 1; | ||
2272 | |||
2273 | for (idx = 0; idx < N_TLS_EXTENSIONS; idx++) { | ||
2274 | if (s->tlsext_build_order[idx]->type == TLSEXT_TYPE_alpn) | ||
2275 | alpn_idx = idx; | ||
2276 | if (s->tlsext_build_order[idx]->type == TLSEXT_TYPE_server_name) | ||
2277 | sni_idx = idx; | ||
2278 | } | ||
2279 | if (alpn_idx < sni_idx) { | ||
2280 | const struct tls_extension *tmp; | ||
2281 | |||
2282 | tmp = s->tlsext_build_order[alpn_idx]; | ||
2283 | s->tlsext_build_order[alpn_idx] = s->tlsext_build_order[sni_idx]; | ||
2284 | s->tlsext_build_order[sni_idx] = tmp; | ||
2285 | } | ||
2286 | |||
2287 | return 1; | ||
2288 | } | ||
2289 | |||
2290 | int | ||
2291 | tlsext_linearize_build_order(SSL *s) | ||
2292 | { | ||
2293 | size_t idx; | ||
2294 | |||
2295 | for (idx = 0; idx < N_TLS_EXTENSIONS; idx++) | ||
2296 | s->tlsext_build_order[idx] = &tls_extensions[idx]; | ||
2297 | |||
2298 | return 1; | ||
2299 | } | ||
2300 | |||
2242 | static int | 2301 | static int |
2243 | tlsext_build(SSL *s, int is_server, uint16_t msg_type, CBB *cbb) | 2302 | tlsext_build(SSL *s, int is_server, uint16_t msg_type, CBB *cbb) |
2244 | { | 2303 | { |
@@ -2255,7 +2314,7 @@ tlsext_build(SSL *s, int is_server, uint16_t msg_type, CBB *cbb) | |||
2255 | return 0; | 2314 | return 0; |
2256 | 2315 | ||
2257 | for (i = 0; i < N_TLS_EXTENSIONS; i++) { | 2316 | for (i = 0; i < N_TLS_EXTENSIONS; i++) { |
2258 | tlsext = &tls_extensions[i]; | 2317 | tlsext = s->tlsext_build_order[i]; |
2259 | ext = tlsext_funcs(tlsext, is_server); | 2318 | ext = tlsext_funcs(tlsext, is_server); |
2260 | 2319 | ||
2261 | /* RFC 8446 Section 4.2 */ | 2320 | /* RFC 8446 Section 4.2 */ |
diff --git a/src/lib/libssl/ssl_tlsext.h b/src/lib/libssl/ssl_tlsext.h index 7a41c8095d..da14f7fa94 100644 --- a/src/lib/libssl/ssl_tlsext.h +++ b/src/lib/libssl/ssl_tlsext.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_tlsext.h,v 1.32 2022/08/04 09:27:36 tb Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.h,v 1.33 2023/04/23 18:51:53 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> | 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
@@ -41,6 +41,7 @@ int tlsext_server_build(SSL *s, uint16_t msg_type, CBB *cbb); | |||
41 | int tlsext_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert); | 41 | int tlsext_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert); |
42 | 42 | ||
43 | int tlsext_extension_seen(SSL *s, uint16_t); | 43 | int tlsext_extension_seen(SSL *s, uint16_t); |
44 | int tlsext_randomize_build_order(SSL *s); | ||
44 | 45 | ||
45 | __END_HIDDEN_DECLS | 46 | __END_HIDDEN_DECLS |
46 | 47 | ||