Check the server did not use a TLS 1.2 cipher suite pre-TLS 1.2.

This check got refactored in OpenSSL 1.0.2 and broke in the process. Fix this
and add a test. Otherwise things like client auth can get slightly confused; it
will try to sign the MD5/SHA-1 hash, but the TLS 1.2 cipher suite may not use
SSL_HANDSHAKE_MAC_DEFAULT, so those digests won't be available.

Based on upstream's 226751ae4a1f3e00021c43399d7bb51a99c22c17.

Change-Id: I5b864d3a696f3187b849c53b872c24fb7df27924
Reviewed-on: https://boringssl-review.googlesource.com/1696
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 97d1107..5f8c5db 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -798,6 +798,7 @@
 	CBS server_hello, server_random, session_id;
 	uint16_t server_version, cipher_suite;
 	uint8_t compression_method;
+	unsigned long mask_ssl;
 
 	n=s->method->ssl_get_message(s,
 		SSL3_ST_CR_SRVR_HELLO_A,
@@ -913,10 +914,16 @@
 		OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNKNOWN_CIPHER_RETURNED);
 		goto f_err;
 		}
+	/* ct->mask_ssl was computed from client capabilities. Now
+	 * that the final version is known, compute a new mask_ssl. */
+	if (!SSL_USE_TLS1_2_CIPHERS(s))
+		mask_ssl = SSL_TLSV1_2;
+	else
+		mask_ssl = 0;
 	/* If it is a disabled cipher we didn't send it in client hello,
 	 * so return an error.
 	 */
-	if (c->algorithm_ssl & ct->mask_ssl ||
+	if (c->algorithm_ssl & mask_ssl ||
 		c->algorithm_mkey & ct->mask_k ||
 		c->algorithm_auth & ct->mask_a)
 		{
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index fa0e6d8..f22f95a 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -445,6 +445,10 @@
 	// ClientKeyExchange message without the two-byte length
 	// prefix, as if it were SSL3.
 	SSL3RSAKeyExchange bool
+
+	// SkipCipherVersionCheck causes the server to negotiate
+	// TLS 1.2 ciphers in earlier versions of TLS.
+	SkipCipherVersionCheck bool
 }
 
 func (c *Config) serverInit() {
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index 855f992..6d61fd5 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -832,7 +832,7 @@
 			if (candidate.flags&suiteECDSA != 0) != ecdsaOk {
 				continue
 			}
-			if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
+			if !c.config.Bugs.SkipCipherVersionCheck && version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
 				continue
 			}
 			if c.isDTLS && candidate.flags&suiteNoDTLS != 0 {
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index d238e8a..9322592 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -483,6 +483,18 @@
 		shouldFail:    true,
 		expectedError: ":HTTPS_PROXY_REQUEST:",
 	},
+	{
+		name: "SkipCipherVersionCheck",
+		config: Config{
+			CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+			MaxVersion:   VersionTLS11,
+			Bugs: ProtocolBugs{
+				SkipCipherVersionCheck: true,
+			},
+		},
+		shouldFail:    true,
+		expectedError: ":WRONG_CIPHER_RETURNED:",
+	},
 }
 
 func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int) error {