Add an option to permute ClientHello extension order.
Although not permitted by the TLS specification, systems sometimes
ossify TLS extension order, or byte offsets of various fields. To
keep the ecosystem healthy, add an API to reorder ClientHello
extensions.
Since ECH, HelloRetryRequest, and HelloVerifyRequest are sensitive to
extension order, I've implemented this by per-connection permutation of
the indices in the kExtensions structure. This ensures that all
ClientHellos within a connection are consistently ordered. As follow-up
work, permuting the other messages would also be nice, though any server
messages would need to be incorporated in handshake hints.
Change-Id: I18ce39b4df5ee376c654943f07ec26a50e0923a9
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index 31ab3bb..1211761 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -562,6 +562,7 @@
signed_cert_timestamps_enabled(false),
channel_id_enabled(false),
grease_enabled(false),
+ permute_extensions(false),
allow_unknown_alpn_protos(false),
false_start_allowed_without_alpn(false),
handoff(false),
@@ -684,6 +685,7 @@
ssl->config->custom_verify_callback = ctx->custom_verify_callback;
ssl->config->retain_only_sha256_of_client_certs =
ctx->retain_only_sha256_of_client_certs;
+ ssl->config->permute_extensions = ctx->permute_extensions;
if (!ssl->config->supported_group_list.CopyFrom(ctx->supported_group_list) ||
!ssl->config->alpn_client_proto_list.CopyFrom(
@@ -730,7 +732,8 @@
handoff(false),
shed_handshake_config(false),
jdk11_workaround(false),
- quic_use_legacy_codepoint(false) {
+ quic_use_legacy_codepoint(false),
+ permute_extensions(false) {
assert(ssl);
}
@@ -2915,6 +2918,17 @@
ctx->grease_enabled = !!enabled;
}
+void SSL_CTX_set_permute_extensions(SSL_CTX *ctx, int enabled) {
+ ctx->permute_extensions = !!enabled;
+}
+
+void SSL_set_permute_extensions(SSL *ssl, int enabled) {
+ if (!ssl->config) {
+ return;
+ }
+ ssl->config->permute_extensions = !!enabled;
+}
+
int32_t SSL_get_ticket_age_skew(const SSL *ssl) {
return ssl->s3->ticket_age_skew;
}