Implement TLS_FALLBACK_SCSV support for the client.

With this change, calling SSL_enable_fallback_scsv on a client SSL* will
cause the fallback SCSV to be sent.

This is intended to be set when the client is performing TLS fallback
after a failed connection. (This only happens if the application itself
implements this behaviour: OpenSSL does not do fallback automatically.)

The fallback SCSV indicates to the server that it should reject the
connection if the version indicated by the client is less than the
version supported by the server.

See http://tools.ietf.org/html/draft-bmoeller-tls-downgrade-scsv-02.

Change-Id: I478d6d5135016f1b7c4aaa6c306a1a64b1d215a6
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index b5743c5..1ec3795 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -47,9 +47,15 @@
 	config        Config
 	shouldFail    bool
 	expectedError string
+	// expectedLocalError, if not empty, contains a substring that must be
+	// found in the local error.
+	expectedLocalError string
 	// messageLen is the length, in bytes, of the test message that will be
 	// sent.
 	messageLen int
+	// flag, if not nil, contains a command line flag that will be passed
+	// to the shim program.
+	flag string
 }
 
 var clientTests = []testCase{
@@ -88,6 +94,16 @@
 		shouldFail:    true,
 		expectedError: ":WRONG_CURVE:",
 	},
+	{
+		name: "FallbackSCSV",
+		config: Config{
+			Bugs: ProtocolBugs{
+				FailIfNotFallbackSCSV: true,
+			},
+		},
+		shouldFail:         true,
+		expectedLocalError: "no fallback SCSV found",
+	},
 }
 
 func doExchange(tlsConn *Conn, messageLen int) error {
@@ -185,13 +201,16 @@
 	stderr := string(stderrBuf.Bytes())
 	failed := err != nil || childErr != nil
 	correctFailure := len(test.expectedError) == 0 || strings.Contains(stdout, test.expectedError)
+	localError := "none"
+	if err != nil {
+		localError = err.Error()
+	}
+	if len(test.expectedLocalError) != 0 {
+		correctFailure = correctFailure && strings.Contains(localError, test.expectedLocalError)
+	}
 
 	if failed != test.shouldFail || failed && !correctFailure {
-		localError := "none"
 		childError := "none"
-		if err != nil {
-			localError = err.Error()
-		}
 		if childErr != nil {
 			childError = childErr.Error()
 		}
@@ -203,7 +222,7 @@
 		case !failed && test.shouldFail:
 			msg = "unexpected success"
 		case failed && !correctFailure:
-			msg = "bad error (wanted '" + test.expectedError + "')"
+			msg = "bad error (wanted '" + test.expectedError + "' / '" + test.expectedLocalError + "')"
 		default:
 			panic("internal error")
 		}