-/* $OpenBSD: ssl_lib.c,v 1.308 2022/11/26 16:08:55 tb Exp $ */
+/* $OpenBSD: ssl_lib.c,v 1.309 2023/04/23 18:51:53 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
s->initial_ctx = ctx;
+ if (!tlsext_randomize_build_order(s))
+ goto err;
+
if (ctx->tlsext_ecpointformatlist != NULL) {
s->tlsext_ecpointformatlist =
calloc(ctx->tlsext_ecpointformatlist_length,
ssl_cert_free(s->cert);
+ free(s->tlsext_build_order);
+
free(s->tlsext_hostname);
SSL_CTX_free(s->initial_ctx);
-/* $OpenBSD: ssl_tlsext.c,v 1.131 2022/11/26 16:08:56 tb Exp $ */
+/* $OpenBSD: ssl_tlsext.c,v 1.132 2023/04/23 18:51:53 tb Exp $ */
/*
* Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
#include "ssl_sigalgs.h"
#include "ssl_tlsext.h"
+#define TLSEXT_TYPE_alpn TLSEXT_TYPE_application_layer_protocol_negotiation
+
/*
* Supported Application-Layer Protocol Negotiation - RFC 7301
*/
return &tlsext->client;
}
+int
+tlsext_randomize_build_order(SSL *s)
+{
+ size_t idx, new_idx, psk_idx;
+ size_t alpn_idx, sni_idx;
+
+ if ((s->tlsext_build_order = calloc(sizeof(*s->tlsext_build_order),
+ N_TLS_EXTENSIONS)) == NULL)
+ return 0;
+
+ /* RFC 8446, section 4.2: PSK must be the last extension in the CH. */
+ psk_idx = N_TLS_EXTENSIONS - 1;
+ s->tlsext_build_order[psk_idx] = &tls_extensions[psk_idx];
+
+ /* Fisher-Yates shuffle with PSK fixed. */
+ for (idx = 0; idx < psk_idx; idx++) {
+ new_idx = arc4random_uniform(idx + 1);
+ s->tlsext_build_order[idx] = s->tlsext_build_order[new_idx];
+ s->tlsext_build_order[new_idx] = &tls_extensions[idx];
+ }
+
+ /*
+ * XXX - Apache2 special until year 2025: ensure that SNI precedes ALPN
+ * for clients so that virtual host setups work correctly.
+ */
+
+ if (s->server)
+ return 1;
+
+ for (idx = 0; idx < N_TLS_EXTENSIONS; idx++) {
+ if (s->tlsext_build_order[idx]->type == TLSEXT_TYPE_alpn)
+ alpn_idx = idx;
+ if (s->tlsext_build_order[idx]->type == TLSEXT_TYPE_server_name)
+ sni_idx = idx;
+ }
+ if (alpn_idx < sni_idx) {
+ const struct tls_extension *tmp;
+
+ tmp = s->tlsext_build_order[alpn_idx];
+ s->tlsext_build_order[alpn_idx] = s->tlsext_build_order[sni_idx];
+ s->tlsext_build_order[sni_idx] = tmp;
+ }
+
+ return 1;
+}
+
+int
+tlsext_linearize_build_order(SSL *s)
+{
+ size_t idx;
+
+ for (idx = 0; idx < N_TLS_EXTENSIONS; idx++)
+ s->tlsext_build_order[idx] = &tls_extensions[idx];
+
+ return 1;
+}
+
static int
tlsext_build(SSL *s, int is_server, uint16_t msg_type, CBB *cbb)
{
return 0;
for (i = 0; i < N_TLS_EXTENSIONS; i++) {
- tlsext = &tls_extensions[i];
+ tlsext = s->tlsext_build_order[i];
ext = tlsext_funcs(tlsext, is_server);
/* RFC 8446 Section 4.2 */
-/* $OpenBSD: ssl_tlsext.h,v 1.32 2022/08/04 09:27:36 tb Exp $ */
+/* $OpenBSD: ssl_tlsext.h,v 1.33 2023/04/23 18:51:53 tb Exp $ */
/*
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
int tlsext_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_extension_seen(SSL *s, uint16_t);
+int tlsext_randomize_build_order(SSL *s);
__END_HIDDEN_DECLS