Add cipher suite settings for TLS ≥ 1.0.

This change adds the ability to configure ciphers specifically for
TLS ≥ 1.0. This compliments the existing ability to specify ciphers
for TLS ≥ 1.1.

This is useful because TLS 1.0 is the first version not to suffer from
POODLE. (Assuming that it's implemented correctly[1].) Thus one might
wish to reserve RC4 solely for SSLv3.

[1] https://www.imperialviolet.org/2014/12/08/poodleagain.html

Change-Id: I774d5336fead48f03d8a0a3cf80c369692ee60df
Reviewed-on: https://boringssl-review.googlesource.com/5793
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 6284ef6..8124382 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -2092,6 +2092,94 @@
 		shouldFail:    true,
 		expectedError: "BAD_DH_P_LENGTH",
 	})
+
+	// versionSpecificCiphersTest specifies a test for the TLS 1.0 and TLS
+	// 1.1 specific cipher suite settings. A server is setup with the given
+	// cipher lists and then a connection is made for each member of
+	// expectations. The cipher suite that the server selects must match
+	// the specified one.
+	var versionSpecificCiphersTest = []struct {
+		ciphersDefault, ciphersTLS10, ciphersTLS11 string
+		// expectations is a map from TLS version to cipher suite id.
+		expectations map[uint16]uint16
+	}{
+		{
+			// Test that the null case (where no version-specific ciphers are set)
+			// works as expected.
+			"RC4-SHA:AES128-SHA", // default ciphers
+			"",                   // no ciphers specifically for TLS ≥ 1.0
+			"",                   // no ciphers specifically for TLS ≥ 1.1
+			map[uint16]uint16{
+				VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+				VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
+				VersionTLS11: TLS_RSA_WITH_RC4_128_SHA,
+				VersionTLS12: TLS_RSA_WITH_RC4_128_SHA,
+			},
+		},
+		{
+			// With ciphers_tls10 set, TLS 1.0, 1.1 and 1.2 should get a different
+			// cipher.
+			"RC4-SHA:AES128-SHA", // default
+			"AES128-SHA",         // these ciphers for TLS ≥ 1.0
+			"",                   // no ciphers specifically for TLS ≥ 1.1
+			map[uint16]uint16{
+				VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+				VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
+				VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
+				VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
+			},
+		},
+		{
+			// With ciphers_tls11 set, TLS 1.1 and 1.2 should get a different
+			// cipher.
+			"RC4-SHA:AES128-SHA", // default
+			"",                   // no ciphers specifically for TLS ≥ 1.0
+			"AES128-SHA",         // these ciphers for TLS ≥ 1.1
+			map[uint16]uint16{
+				VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+				VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
+				VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
+				VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
+			},
+		},
+		{
+			// With both ciphers_tls10 and ciphers_tls11 set, ciphers_tls11 should
+			// mask ciphers_tls10 for TLS 1.1 and 1.2.
+			"RC4-SHA:AES128-SHA", // default
+			"AES128-SHA",         // these ciphers for TLS ≥ 1.0
+			"AES256-SHA",         // these ciphers for TLS ≥ 1.1
+			map[uint16]uint16{
+				VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+				VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
+				VersionTLS11: TLS_RSA_WITH_AES_256_CBC_SHA,
+				VersionTLS12: TLS_RSA_WITH_AES_256_CBC_SHA,
+			},
+		},
+	}
+
+	for i, test := range versionSpecificCiphersTest {
+		for version, expectedCipherSuite := range test.expectations {
+			flags := []string{"-cipher", test.ciphersDefault}
+			if len(test.ciphersTLS10) > 0 {
+				flags = append(flags, "-cipher-tls10", test.ciphersTLS10)
+			}
+			if len(test.ciphersTLS11) > 0 {
+				flags = append(flags, "-cipher-tls11", test.ciphersTLS11)
+			}
+
+			testCases = append(testCases, testCase{
+				testType: serverTest,
+				name:     fmt.Sprintf("VersionSpecificCiphersTest-%d-%x", i, version),
+				config: Config{
+					MaxVersion:   version,
+					MinVersion:   version,
+					CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA},
+				},
+				flags:          flags,
+				expectedCipher: expectedCipherSuite,
+			})
+		}
+	}
 }
 
 func addBadECDSASignatureTests() {