Test renegotiation with BoringSSL as the client.

This also contains a test for the issue fixed in
88333ef7d7d47221ede66a2a31626fc426466297.

Change-Id: Id705a82cee34c018491dc301eba8b5097b9c83d5
Reviewed-on: https://boringssl-review.googlesource.com/2083
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index ef72374..4b43481 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -150,6 +150,12 @@
 	// shimWritesFirst controls whether the shim sends an initial "hello"
 	// message before doing a roundtrip with the runner.
 	shimWritesFirst bool
+	// renegotiate indicates the the connection should be renegotiated
+	// during the exchange.
+	renegotiate bool
+	// renegotiateCiphers is a list of ciphersuite ids that will be
+	// switched in just before renegotiation.
+	renegotiateCiphers []uint16
 	// flags, if not empty, contains a list of command-line flags that will
 	// be passed to the shim program.
 	flags []string
@@ -565,6 +571,17 @@
 		}
 	}
 
+	if test.renegotiate {
+		if test.renegotiateCiphers != nil {
+			config.CipherSuites = test.renegotiateCiphers
+		}
+		if err := tlsConn.Renegotiate(); err != nil {
+			return err
+		}
+	} else if test.renegotiateCiphers != nil {
+		panic("renegotiateCiphers without renegotiate")
+	}
+
 	if messageLen < 0 {
 		if test.protocol == dtls {
 			return fmt.Errorf("messageLen < 0 not supported for DTLS tests")
@@ -1793,6 +1810,48 @@
 		expectedError:   ":RENEGOTIATION_MISMATCH:",
 	})
 	// TODO(agl): test the renegotiation info SCSV.
+	testCases = append(testCases, testCase{
+		name:        "Renegotiate-Client",
+		renegotiate: true,
+	})
+	testCases = append(testCases, testCase{
+		name:        "Renegotiate-Client-EmptyExt",
+		renegotiate: true,
+		config: Config{
+			Bugs: ProtocolBugs{
+				EmptyRenegotiationInfo: true,
+			},
+		},
+		shouldFail:    true,
+		expectedError: ":RENEGOTIATION_MISMATCH:",
+	})
+	testCases = append(testCases, testCase{
+		name:        "Renegotiate-Client-BadExt",
+		renegotiate: true,
+		config: Config{
+			Bugs: ProtocolBugs{
+				BadRenegotiationInfo: true,
+			},
+		},
+		shouldFail:    true,
+		expectedError: ":RENEGOTIATION_MISMATCH:",
+	})
+	testCases = append(testCases, testCase{
+		name:        "Renegotiate-Client-SwitchCiphers",
+		renegotiate: true,
+		config: Config{
+			CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+		},
+		renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+	})
+	testCases = append(testCases, testCase{
+		name:        "Renegotiate-Client-SwitchCiphers2",
+		renegotiate: true,
+		config: Config{
+			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+		},
+		renegotiateCiphers: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+	})
 }
 
 func worker(statusChan chan statusMsg, c chan *testCase, buildDir string, wg *sync.WaitGroup) {