Allow enabling all TLS 1.3 variants by setting |tls13_default|.

Update-Note: Enabling TLS 1.3 now enables both draft-23 and draft-28
by default, in preparation for cycling all to draft-28.
Change-Id: I9405f39081f2e5f7049aaae8a9c85399f21df047
Reviewed-on: https://boringssl-review.googlesource.com/28304
Commit-Queue: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 662053d..1033749 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -3379,7 +3379,8 @@
 
 enum tls13_variant_t {
   tls13_default = 0,
-  tls13_draft28 = 1,
+  tls13_draft23,
+  tls13_draft28,
 };
 
 // SSL_CTX_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the
diff --git a/ssl/ssl_versions.cc b/ssl/ssl_versions.cc
index a09efa1..9588dd3 100644
--- a/ssl/ssl_versions.cc
+++ b/ssl/ssl_versions.cc
@@ -299,17 +299,20 @@
     return false;
   }
 
-  // This logic is part of the TLS 1.3 variants mechanism used in TLS 1.3
-  // experimentation. TLS 1.3 variants must match the enabled |tls13_variant|.
-  if (protocol_version != TLS1_3_VERSION ||
-      (ssl->tls13_variant == tls13_draft28 &&
-       version == TLS1_3_DRAFT28_VERSION) ||
-      (ssl->tls13_variant == tls13_default &&
-       version == TLS1_3_DRAFT23_VERSION)) {
-    return true;
+  // If the TLS 1.3 variant is set to |tls13_default|, all variants are enabled,
+  // otherwise only the matching version is enabled.
+  if (protocol_version == TLS1_3_VERSION) {
+    switch (ssl->tls13_variant) {
+      case tls13_draft23:
+        return version == TLS1_3_DRAFT23_VERSION;
+      case tls13_draft28:
+        return version == TLS1_3_DRAFT28_VERSION;
+      case tls13_default:
+        return true;
+    }
   }
 
-  return false;
+  return true;
 }
 
 bool ssl_add_supported_versions(SSL_HANDSHAKE *hs, CBB *cbb) {
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index f5ddaed..dcc1b01 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -39,8 +39,9 @@
 )
 
 const (
-	TLS13Draft23 = 0
-	TLS13Draft28 = 1
+	TLS13Default = 0
+	TLS13Draft23 = 1
+	TLS13Draft28 = 2
 )
 
 var allTLSWireVersions = []uint16{
@@ -1714,8 +1715,8 @@
 // it returns true and the corresponding protocol version. Otherwise, it returns
 // false.
 func (c *Config) isSupportedVersion(wireVers uint16, isDTLS bool) (uint16, bool) {
-	if (c.TLS13Variant != TLS13Draft23 && wireVers == tls13Draft23Version) ||
-		(c.TLS13Variant != TLS13Draft28 && wireVers == tls13Draft28Version) {
+	if (c.TLS13Variant == TLS13Draft23 && wireVers == tls13Draft28Version) ||
+		(c.TLS13Variant == TLS13Draft28 && wireVers == tls13Draft23Version) {
 		return 0, false
 	}
 
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 0ad00c2..53eeb8b 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -1405,6 +1405,23 @@
 	return ret
 }
 
+func allShimVersions(protocol protocol) []tlsVersion {
+	if protocol == dtls {
+		return allVersions(protocol)
+	}
+	tls13Default := tlsVersion{
+		name:         "TLS13Default",
+		version:      VersionTLS13,
+		excludeFlag:  "-no-tls13",
+		versionWire:  0,
+		tls13Variant: TLS13Default,
+	}
+
+	var shimVersions []tlsVersion
+	shimVersions = append(shimVersions, allVersions(protocol)...)
+	return append(shimVersions, tls13Default)
+}
+
 type testCipherSuite struct {
 	name string
 	id   uint16
@@ -5371,7 +5388,7 @@
 
 func addVersionNegotiationTests() {
 	for _, protocol := range []protocol{tls, dtls} {
-		for _, shimVers := range allVersions(protocol) {
+		for _, shimVers := range allShimVersions(protocol) {
 			// Assemble flags to disable all newer versions on the shim.
 			var flags []string
 			for _, vers := range allVersions(protocol) {
@@ -5393,13 +5410,12 @@
 				if runnerVers.version < shimVers.version {
 					expectedVersion = runnerVers.version
 				}
-				// When running and shim have different TLS 1.3 variants enabled,
-				// shim peers are expected to fall back to TLS 1.2.
+
 				if expectedVersion == VersionTLS13 && runnerVers.tls13Variant != shimVers.tls13Variant {
-					expectedVersion = VersionTLS12
+					if shimVers.tls13Variant != TLS13Default {
+						expectedVersion = VersionTLS12
+					}
 				}
-				expectedClientVersion := expectedVersion
-				expectedServerVersion := expectedVersion
 
 				suffix := shimVers.name + "-" + runnerVers.name
 				if protocol == dtls {
@@ -5412,8 +5428,8 @@
 					clientVers = VersionTLS10
 				}
 				clientVers = recordVersionToWire(clientVers, protocol)
-				serverVers := expectedServerVersion
-				if expectedServerVersion >= VersionTLS13 {
+				serverVers := expectedVersion
+				if expectedVersion >= VersionTLS13 {
 					serverVers = VersionTLS12
 				}
 				serverVers = recordVersionToWire(serverVers, protocol)
@@ -5430,7 +5446,7 @@
 						},
 					},
 					flags:           flags,
-					expectedVersion: expectedClientVersion,
+					expectedVersion: expectedVersion,
 				})
 				testCases = append(testCases, testCase{
 					protocol: protocol,
@@ -5444,7 +5460,7 @@
 						},
 					},
 					flags:           flags2,
-					expectedVersion: expectedClientVersion,
+					expectedVersion: expectedVersion,
 				})
 
 				testCases = append(testCases, testCase{
@@ -5459,7 +5475,7 @@
 						},
 					},
 					flags:           flags,
-					expectedVersion: expectedServerVersion,
+					expectedVersion: expectedVersion,
 				})
 				testCases = append(testCases, testCase{
 					protocol: protocol,
@@ -5473,7 +5489,7 @@
 						},
 					},
 					flags:           flags2,
-					expectedVersion: expectedServerVersion,
+					expectedVersion: expectedVersion,
 				})
 			}
 		}
diff --git a/tool/client.cc b/tool/client.cc
index 037e10c..4ab0742 100644
--- a/tool/client.cc
+++ b/tool/client.cc
@@ -330,7 +330,7 @@
 
 static bool GetTLS13Variant(tls13_variant_t *out, const std::string &in) {
   if (in == "draft23") {
-    *out = tls13_default;
+    *out = tls13_draft23;
     return true;
   }
   if (in == "draft28") {
diff --git a/tool/server.cc b/tool/server.cc
index 7a4e53b..bc90630 100644
--- a/tool/server.cc
+++ b/tool/server.cc
@@ -68,7 +68,8 @@
         "-early-data", kBooleanArgument, "Allow early data",
     },
     {
-        "-tls13-variant", kBooleanArgument, "Enables all TLS 1.3 variants",
+        "-tls13-variant", kOptionalArgument,
+        "Enable the specified experimental TLS 1.3 variant",
     },
     {
         "-www", kBooleanArgument,
@@ -147,6 +148,18 @@
   return x509;
 }
 
+static bool GetTLS13Variant(tls13_variant_t *out, const std::string &in) {
+  if (in == "draft23") {
+    *out = tls13_draft23;
+    return true;
+  }
+  if (in == "draft28") {
+    *out = tls13_draft28;
+    return true;
+  }
+  return false;
+}
+
 static void InfoCallback(const SSL *ssl, int type, int value) {
   switch (type) {
     case SSL_CB_HANDSHAKE_START:
@@ -307,7 +320,13 @@
   }
 
   if (args_map.count("-tls13-variant") != 0) {
-    SSL_CTX_set_tls13_variant(ctx.get(), tls13_draft28);
+    tls13_variant_t variant;
+    if (!GetTLS13Variant(&variant, args_map["-tls13-variant"])) {
+      fprintf(stderr, "Unknown TLS 1.3 variant: %s\n",
+              args_map["-tls13-variant"].c_str());
+      return false;
+    }
+    SSL_CTX_set_tls13_variant(ctx.get(), variant);
   }
 
   if (args_map.count("-debug") != 0) {