Implement downgrade signaling in Go.

[Originally written by nharper, revised by davidben.]

When we add this in the real code, this will want ample tests and hooks
for bugs, but get the core logic in to start with.

Change-Id: I86cf0b6416c9077dbb6471a1802ae984b8fa6c72
Reviewed-on: https://boringssl-review.googlesource.com/8598
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index db3f270..f0b945d 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -1262,3 +1262,9 @@
 	}
 	return false
 }
+
+var (
+	// See draft-ietf-tls-tls13-13, section 6.3.1.2.
+	downgradeTLS13 = []byte{0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01}
+	downgradeTLS12 = []byte{0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x00}
+)
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
index 5496fa2..544eec3 100644
--- a/ssl/test/runner/handshake_client.go
+++ b/ssl/test/runner/handshake_client.go
@@ -301,6 +301,21 @@
 	}
 	c.haveVers = true
 
+	// Check for downgrade signals in the server random, per
+	// draft-ietf-tls-tls13-13, section 6.3.1.2.
+	if c.vers <= VersionTLS12 && c.config.maxVersion(c.isDTLS) >= VersionTLS13 {
+		if bytes.Equal(serverHello.random[:8], downgradeTLS13) {
+			c.sendAlert(alertProtocolVersion)
+			return errors.New("tls: downgrade from TLS 1.3 detected")
+		}
+	}
+	if c.vers <= VersionTLS11 && c.config.maxVersion(c.isDTLS) >= VersionTLS12 {
+		if bytes.Equal(serverHello.random[:8], downgradeTLS12) {
+			c.sendAlert(alertProtocolVersion)
+			return errors.New("tls: downgrade from TLS 1.2 detected")
+		}
+	}
+
 	suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
 	if suite == nil {
 		c.sendAlert(alertHandshakeFailure)
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index cb9ef2c..a5bfed7 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -263,6 +263,13 @@
 		c.sendAlert(alertInternalError)
 		return false, err
 	}
+	// Signal downgrades in the server random, per draft-ietf-tls-tls13-13, section 6.3.1.2.
+	if c.vers <= VersionTLS12 && config.maxVersion(c.isDTLS) >= VersionTLS13 {
+		copy(hs.hello.random[:8], downgradeTLS13)
+	}
+	if c.vers <= VersionTLS11 && config.maxVersion(c.isDTLS) == VersionTLS12 {
+		copy(hs.hello.random[:8], downgradeTLS12)
+	}
 
 	foundCompression := false
 	// We only support null compression, so check that the client offered it.