Implement experimental alternate encoding of TLS 1.3.
TLS 1.3 deployment is currently blocked by buggy middleboxes
throughout the ecosystem. As an experiment to better understand these bugs
and the problems they are causing, implement TLS 1.3 variants with
alternate encodings. These are still the same protocol, only encoded
slightly differently. We will use what we learn from these experiments to
guide the TLS 1.3 deployment strategy and proposals to the IETF, if any.
These experiments only target the basic 1-RTT TLS 1.3 handshake. Based on
what we learn from this experiment, we may try future variations to
explore 0-RTT and HelloRetryRequest.
When enabled, the server supports all TLS 1.3 variants while the client
is configured to use a particular variant.
Change-Id: I532411d1abc41314dc76acce0246879b754b4c61
Reviewed-on: https://boringssl-review.googlesource.com/17327
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/ssl_versions.c b/ssl/ssl_versions.c
index 5d92771..3945f7f 100644
--- a/ssl/ssl_versions.c
+++ b/ssl/ssl_versions.c
@@ -33,6 +33,7 @@
return 1;
case TLS1_3_DRAFT_VERSION:
+ case TLS1_3_EXPERIMENT_VERSION:
*out = TLS1_3_VERSION;
return 1;
@@ -55,6 +56,7 @@
static const uint16_t kTLSVersions[] = {
TLS1_3_DRAFT_VERSION,
+ TLS1_3_EXPERIMENT_VERSION,
TLS1_2_VERSION,
TLS1_1_VERSION,
TLS1_VERSION,
@@ -95,7 +97,8 @@
/* The public API uses wire versions, except we use |TLS1_3_VERSION|
* everywhere to refer to any draft TLS 1.3 versions. In this direction, we
* map it to some representative TLS 1.3 draft version. */
- if (version == TLS1_3_DRAFT_VERSION) {
+ if (version == TLS1_3_DRAFT_VERSION ||
+ version == TLS1_3_EXPERIMENT_VERSION) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION);
return 0;
}
@@ -235,7 +238,7 @@
int SSL_version(const SSL *ssl) {
uint16_t ret = ssl_version(ssl);
/* Report TLS 1.3 draft version as TLS 1.3 in the public API. */
- if (ret == TLS1_3_DRAFT_VERSION) {
+ if (ret == TLS1_3_DRAFT_VERSION || ret == TLS1_3_EXPERIMENT_VERSION) {
return TLS1_3_VERSION;
}
return ret;
@@ -245,6 +248,7 @@
switch (version) {
/* Report TLS 1.3 draft version as TLS 1.3 in the public API. */
case TLS1_3_DRAFT_VERSION:
+ case TLS1_3_EXPERIMENT_VERSION:
return "TLSv1.3";
case TLS1_2_VERSION:
@@ -291,8 +295,26 @@
}
int ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version) {
+ SSL *const ssl = hs->ssl;
+ /* As a client, only allow the configured TLS 1.3 variant. As a server,
+ * support all TLS 1.3 variants as long as tls13_variant is set to a
+ * non-default value. */
+ if (ssl->server) {
+ if (ssl->ctx->tls13_variant == tls13_default &&
+ version == TLS1_3_EXPERIMENT_VERSION) {
+ return 0;
+ }
+ } else {
+ if ((ssl->ctx->tls13_variant != tls13_experiment &&
+ version == TLS1_3_EXPERIMENT_VERSION) ||
+ (ssl->ctx->tls13_variant != tls13_default &&
+ version == TLS1_3_DRAFT_VERSION)) {
+ return 0;
+ }
+ }
+
uint16_t protocol_version;
- return method_supports_version(hs->ssl->method, version) &&
+ return method_supports_version(ssl->method, version) &&
ssl_protocol_version_from_wire(&protocol_version, version) &&
hs->min_version <= protocol_version &&
protocol_version <= hs->max_version;