Revise TLS 1.3 downgrade feature and metrics.

Due to non-compliant middleboxes, it is possible we'll need to do some
surgery to this mechanism. Fix the double-negative on the base::Feature
so it is less confusing and gather more extensive metrics when
enforcement is disabled. Also flip the default in trunk to disabled and
connect it to about:flags.

Finally, add a bunch of machinery to test this stuff.

Bug: boringssl:226
Change-Id: Ib910328c9733b47db16b4cb811e8f2cb09b69d0c
Reviewed-on: https://chromium-review.googlesource.com/c/1274605
Reviewed-by: Ilya Sherman <isherman@chromium.org>
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Commit-Queue: David Benjamin <davidben@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#599879}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 570460e9b6482055b236a8b60ef5521506bf991c
diff --git a/README.chromium b/README.chromium
index c1e444d..d84deb2 100644
--- a/README.chromium
+++ b/README.chromium
@@ -57,3 +57,5 @@
 - patches/renegotiation_indication.patch: Implement the renegotiation
   indication extension (RFC 5746) without supporting renegotiation.
 - patches/tls13_intolerance.patch: Extend the intolerance simulation to TLS 1.3.
+- patches/simulate_tls13_downgrade.patch: Add an option to simulate the TLS 1.3
+  downgrade signal.
diff --git a/patches/simulate_tls13_downgrade.patch b/patches/simulate_tls13_downgrade.patch
new file mode 100644
index 0000000..775e079
--- /dev/null
+++ b/patches/simulate_tls13_downgrade.patch
@@ -0,0 +1,61 @@
+diff --git a/third_party/tlslite/tlslite/handshakesettings.py b/third_party/tlslite/tlslite/handshakesettings.py
+index 69fc6f455e10..a647af53c13e 100644
+--- a/third_party/tlslite/tlslite/handshakesettings.py
++++ b/third_party/tlslite/tlslite/handshakesettings.py
+@@ -125,7 +125,15 @@ class HandshakeSettings(object):
+     corresponding to the TokenBindingKeyParameters enum in the Token Binding
+     Negotiation spec (draft-ietf-tokbind-negotiation-00). Values are in server's
+     preference order, with most preferred params first.
+-    
++
++    @type simulateTLS13Downgrade: bool
++    @ivar simulateTLS13Downgrade: If true, the server will simulate a TLS 1.3
++    to TLS 1.2 downgrade in the ServerHello random.
++
++    @type simulateTLS12Downgrade: bool
++    @ivar simulateTLS12Downgrade: If true, the server will simulate a TLS 1.2
++    to TLS 1.1 downgrade in the ServerHello random.
++
+     Note that TACK support is not standardized by IETF and uses a temporary
+     TLS Extension number, so should NOT be used in production software.
+ 
+@@ -153,6 +161,8 @@ class HandshakeSettings(object):
+         self.enableExtendedMasterSecret = True
+         self.supportedTokenBindingParams = []
+         self.alpnProtos = None
++        self.simulateTLS13Downgrade = False
++        self.simulateTLS12Downgrade = False
+ 
+     # Validates the min/max fields, and certificateTypes
+     # Filters out unsupported cipherNames and cipherImplementations
+@@ -174,6 +184,8 @@ class HandshakeSettings(object):
+         other.enableExtendedMasterSecret = self.enableExtendedMasterSecret
+         other.supportedTokenBindingParams = self.supportedTokenBindingParams
+         other.alpnProtos = self.alpnProtos;
++        other.simulateTLS13Downgrade = self.simulateTLS13Downgrade
++        other.simulateTLS12Downgrade = self.simulateTLS12Downgrade
+ 
+         if not cipherfactory.tripleDESPresent:
+             other.cipherNames = [e for e in self.cipherNames if e != "3des"]
+diff --git a/third_party/tlslite/tlslite/tlsconnection.py b/third_party/tlslite/tlslite/tlsconnection.py
+index 2309d4fa8f3a..cb7160f25cc9 100644
+--- a/third_party/tlslite/tlslite/tlsconnection.py
++++ b/third_party/tlslite/tlslite/tlsconnection.py
+@@ -1352,8 +1352,16 @@ class TLSConnection(TLSRecordLayer):
+             tackExt = TackExtension.create(tacks, activationFlags)
+         else:
+             tackExt = None
++        serverRandom = getRandomBytes(32)
++        # See https://tools.ietf.org/html/rfc8446#section-4.1.3
++        if settings.simulateTLS13Downgrade:
++            serverRandom = serverRandom[:24] + \
++                bytearray("\x44\x4f\x57\x4e\x47\x52\x44\x01")
++        elif settings.simulateTLS12Downgrade:
++            serverRandom = serverRandom[:24] + \
++                bytearray("\x44\x4f\x57\x4e\x47\x52\x44\x00")
+         serverHello = ServerHello()
+-        serverHello.create(self.version, getRandomBytes(32), sessionID, \
++        serverHello.create(self.version, serverRandom, sessionID, \
+                             cipherSuite, CertificateType.x509, tackExt,
+                             alpn_proto_selected,
+                             nextProtos)
diff --git a/tlslite/handshakesettings.py b/tlslite/handshakesettings.py
index 69fc6f4..a647af5 100644
--- a/tlslite/handshakesettings.py
+++ b/tlslite/handshakesettings.py
@@ -125,7 +125,15 @@
     corresponding to the TokenBindingKeyParameters enum in the Token Binding
     Negotiation spec (draft-ietf-tokbind-negotiation-00). Values are in server's
     preference order, with most preferred params first.
-    
+
+    @type simulateTLS13Downgrade: bool
+    @ivar simulateTLS13Downgrade: If true, the server will simulate a TLS 1.3
+    to TLS 1.2 downgrade in the ServerHello random.
+
+    @type simulateTLS12Downgrade: bool
+    @ivar simulateTLS12Downgrade: If true, the server will simulate a TLS 1.2
+    to TLS 1.1 downgrade in the ServerHello random.
+
     Note that TACK support is not standardized by IETF and uses a temporary
     TLS Extension number, so should NOT be used in production software.
 
@@ -153,6 +161,8 @@
         self.enableExtendedMasterSecret = True
         self.supportedTokenBindingParams = []
         self.alpnProtos = None
+        self.simulateTLS13Downgrade = False
+        self.simulateTLS12Downgrade = False
 
     # Validates the min/max fields, and certificateTypes
     # Filters out unsupported cipherNames and cipherImplementations
@@ -174,6 +184,8 @@
         other.enableExtendedMasterSecret = self.enableExtendedMasterSecret
         other.supportedTokenBindingParams = self.supportedTokenBindingParams
         other.alpnProtos = self.alpnProtos;
+        other.simulateTLS13Downgrade = self.simulateTLS13Downgrade
+        other.simulateTLS12Downgrade = self.simulateTLS12Downgrade
 
         if not cipherfactory.tripleDESPresent:
             other.cipherNames = [e for e in self.cipherNames if e != "3des"]
diff --git a/tlslite/tlsconnection.py b/tlslite/tlsconnection.py
index 2309d4f..cb7160f 100644
--- a/tlslite/tlsconnection.py
+++ b/tlslite/tlsconnection.py
@@ -1352,8 +1352,16 @@
             tackExt = TackExtension.create(tacks, activationFlags)
         else:
             tackExt = None
+        serverRandom = getRandomBytes(32)
+        # See https://tools.ietf.org/html/rfc8446#section-4.1.3
+        if settings.simulateTLS13Downgrade:
+            serverRandom = serverRandom[:24] + \
+                bytearray("\x44\x4f\x57\x4e\x47\x52\x44\x01")
+        elif settings.simulateTLS12Downgrade:
+            serverRandom = serverRandom[:24] + \
+                bytearray("\x44\x4f\x57\x4e\x47\x52\x44\x00")
         serverHello = ServerHello()
-        serverHello.create(self.version, getRandomBytes(32), sessionID, \
+        serverHello.create(self.version, serverRandom, sessionID, \
                             cipherSuite, CertificateType.x509, tackExt,
                             alpn_proto_selected,
                             nextProtos)