Adding TLS 1.3 constants.

Constants representing TLS 1.3 are added to allow for future work to be
flagged on TLS1_3_VERSION. To prevent BoringSSL from negotiating the
non-existent TLS 1.3 version, it is explicitly disabled using
SSL_OP_NO_TLSv1_3.

Change-Id: Ie5258a916f4c19ef21646c4073d5b4a7974d6f3f
Reviewed-on: https://boringssl-review.googlesource.com/8041
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index bd583e8..1648922 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -537,6 +537,7 @@
 #define TLS1_VERSION 0x0301
 #define TLS1_1_VERSION 0x0302
 #define TLS1_2_VERSION 0x0303
+#define TLS1_3_VERSION 0x0304
 
 #define DTLS1_VERSION 0xfeff
 #define DTLS1_2_VERSION 0xfefd
@@ -3230,6 +3231,7 @@
 #define SSL_OP_NO_TLSv1 0x04000000L
 #define SSL_OP_NO_TLSv1_2 0x08000000L
 #define SSL_OP_NO_TLSv1_1 0x10000000L
+#define SSL_OP_NO_TLSv1_3 0x20000000L
 #define SSL_OP_NO_DTLSv1 SSL_OP_NO_TLSv1
 #define SSL_OP_NO_DTLSv1_2 SSL_OP_NO_TLSv1_2
 
@@ -3386,6 +3388,7 @@
 #define SSL_TXT_TLSV1 "TLSv1"
 #define SSL_TXT_TLSV1_1 "TLSv1.1"
 #define SSL_TXT_TLSV1_2 "TLSv1.2"
+#define SSL_TXT_TLSV1_3 "TLSv1.3"
 #define SSL_TXT_ALL "ALL"
 #define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT"
 
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 86057d1..51a8a06 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -297,6 +297,9 @@
   if (method->version != 0) {
     SSL_CTX_set_max_version(ret, method->version);
     SSL_CTX_set_min_version(ret, method->version);
+  } else if (!method->method->is_dtls) {
+    /* TODO(svaldez): Enable TLS 1.3 once implemented. */
+    SSL_CTX_set_max_version(ret, TLS1_2_VERSION);
   }
 
   return ret;
@@ -1788,6 +1791,9 @@
 
 static const char *ssl_get_version(int version) {
   switch (version) {
+    case TLS1_3_VERSION:
+      return "TLSv1.3";
+
     case TLS1_2_VERSION:
       return "TLSv1.2";
 
@@ -2298,7 +2304,7 @@
 
   /* False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN. */
   return !SSL_IS_DTLS(ssl) &&
-      SSL_version(ssl) >= TLS1_2_VERSION &&
+      SSL_version(ssl) == TLS1_2_VERSION &&
       (ssl->s3->alpn_selected || ssl->s3->next_proto_neg_seen) &&
       cipher != NULL &&
       cipher->algorithm_mkey == SSL_kECDHE &&
@@ -2313,6 +2319,7 @@
     case TLS1_VERSION:
     case TLS1_1_VERSION:
     case TLS1_2_VERSION:
+    case TLS1_3_VERSION:
     case DTLS1_VERSION:
     case DTLS1_2_VERSION:
       return &TLSv1_enc_data;
@@ -2337,7 +2344,10 @@
     return 0;
   }
 
-  max_version = (ssl->max_version != 0) ? ssl->max_version : TLS1_2_VERSION;
+  max_version = (ssl->max_version != 0) ? ssl->max_version : TLS1_3_VERSION;
+  if (!(ssl->options & SSL_OP_NO_TLSv1_3) && TLS1_3_VERSION <= max_version) {
+    return TLS1_3_VERSION;
+  }
   if (!(ssl->options & SSL_OP_NO_TLSv1_2) && TLS1_2_VERSION <= max_version) {
     return TLS1_2_VERSION;
   }
@@ -2381,8 +2391,11 @@
       client_version = ssl->max_version;
     }
 
-    if (client_version >= TLS1_2_VERSION &&
-        !(ssl->options & SSL_OP_NO_TLSv1_2)) {
+    if (client_version >= TLS1_3_VERSION &&
+        !(ssl->options & SSL_OP_NO_TLSv1_3)) {
+      version = TLS1_3_VERSION;
+    } else if (client_version >= TLS1_2_VERSION &&
+               !(ssl->options & SSL_OP_NO_TLSv1_2)) {
       version = TLS1_2_VERSION;
     } else if (client_version >= TLS1_1_VERSION &&
                !(ssl->options & SSL_OP_NO_TLSv1_1)) {
@@ -2431,7 +2444,10 @@
       version = ssl->max_version;
     }
   } else {
-    if (!(options & SSL_OP_NO_TLSv1_2)) {
+    if (!(options & SSL_OP_NO_TLSv1_3)) {
+      version = TLS1_3_VERSION;
+    }
+    if (!(options & SSL_OP_NO_TLSv1_2) && (options & SSL_OP_NO_TLSv1_3)) {
       version = TLS1_2_VERSION;
     }
     if (!(options & SSL_OP_NO_TLSv1_1) && (options & SSL_OP_NO_TLSv1_2)) {
@@ -2491,6 +2507,9 @@
       case TLS1_2_VERSION:
         return !(ssl->options & SSL_OP_NO_TLSv1_2);
 
+      case TLS1_3_VERSION:
+        return !(ssl->options & SSL_OP_NO_TLSv1_3);
+
       default:
         return 0;
     }
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index 590a2c1..bbac051 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -646,7 +646,10 @@
   if (!ctx) {
     return false;
   }
-  return ctx->min_version == version && ctx->max_version == version;
+  // TODO(svaldez): Remove TLS1_2_VERSION fallback upon implementing TLS 1.3.
+  return ctx->min_version == version &&
+         (ctx->max_version == version ||
+          (version == 0 && ctx->max_version == TLS1_2_VERSION));
 }
 
 static bool CipherGetRFCName(std::string *out, uint16_t value) {
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 6ee1829..8982459 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -1219,6 +1219,9 @@
   if (config->partial_write) {
     SSL_set_mode(ssl.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
   }
+  if (config->no_tls13) {
+    SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_3);
+  }
   if (config->no_tls12) {
     SSL_set_options(ssl.get(), SSL_OP_NO_TLSv1_2);
   }
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index b6e7ac7..806d2fe 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -1405,7 +1405,7 @@
 		},
 		{
 			name:          "DisableEverything",
-			flags:         []string{"-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"},
+			flags:         []string{"-no-tls13", "-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"},
 			shouldFail:    true,
 			expectedError: ":WRONG_SSL_VERSION:",
 		},
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 81b34d3..536978b 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -56,6 +56,7 @@
     &TestConfig::write_different_record_sizes },
   { "-cbc-record-splitting", &TestConfig::cbc_record_splitting },
   { "-partial-write", &TestConfig::partial_write },
+  { "-no-tls13", &TestConfig::no_tls13 },
   { "-no-tls12", &TestConfig::no_tls12 },
   { "-no-tls11", &TestConfig::no_tls11 },
   { "-no-tls1", &TestConfig::no_tls1 },
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index 919fc29..aff194e 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -38,6 +38,7 @@
   bool write_different_record_sizes = false;
   bool cbc_record_splitting = false;
   bool partial_write = false;
+  bool no_tls13 = false;
   bool no_tls12 = false;
   bool no_tls11 = false;
   bool no_tls1 = false;