Convert the renegotiation extension to the new system.

This change also switches the behaviour of the client. Previously the
client would send the SCSV rather than the extension, but now it'll only
do that for SSLv3 connections.

Change-Id: I67a04b8abbef2234747c0dac450458deb6b0cd0a
Reviewed-on: https://boringssl-review.googlesource.com/5143
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/cipher_suites.go b/ssl/test/runner/cipher_suites.go
index 70c7262..98c833b 100644
--- a/ssl/test/runner/cipher_suites.go
+++ b/ssl/test/runner/cipher_suites.go
@@ -406,6 +406,7 @@
 	TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384   uint16 = 0xc030
 	TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA      uint16 = 0xc035
 	TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA      uint16 = 0xc036
+	renegotiationSCSV                       uint16 = 0x00ff
 	fallbackSCSV                            uint16 = 0x5600
 )
 
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index c7ccf80..2e30208 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -476,6 +476,10 @@
 	// TLS_FALLBACK_SCSV in the ClientHello.
 	SendFallbackSCSV bool
 
+	// SendRenegotiationSCSV causes the client to include the renegotiation
+	// SCSV in the ClientHello.
+	SendRenegotiationSCSV bool
+
 	// MaxHandshakeRecordLength, if non-zero, is the maximum size of a
 	// handshake record. Handshake messages will be split into multiple
 	// records at the specified size, except that the client_version will
@@ -572,6 +576,10 @@
 	// didn't support the renegotiation info extension.
 	NoRenegotiationInfo bool
 
+	// RequireRenegotiationInfo, if true, causes the client to return an
+	// error if the server doesn't reply with the renegotiation extension.
+	RequireRenegotiationInfo bool
+
 	// SequenceNumberIncrement, if non-zero, causes outgoing sequence
 	// numbers in DTLS to increment by that value rather by 1. This is to
 	// stress the replay bitmap window by simulating extreme packet loss and
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
index 00bff0e..951b956 100644
--- a/ssl/test/runner/handshake_client.go
+++ b/ssl/test/runner/handshake_client.go
@@ -123,6 +123,10 @@
 		}
 	}
 
+	if c.config.Bugs.SendRenegotiationSCSV {
+		hello.cipherSuites = append(hello.cipherSuites, renegotiationSCSV)
+	}
+
 	if c.config.Bugs.SendFallbackSCSV {
 		hello.cipherSuites = append(hello.cipherSuites, fallbackSCSV)
 	}
@@ -272,6 +276,10 @@
 		return fmt.Errorf("tls: server selected an unsupported cipher suite")
 	}
 
+	if c.config.Bugs.RequireRenegotiationInfo && serverHello.secureRenegotiation == nil {
+		return errors.New("tls: renegotiation extension missing")
+	}
+
 	if len(c.clientVerify) > 0 && !c.config.Bugs.NoRenegotiationInfo {
 		var expectedRenegInfo []byte
 		expectedRenegInfo = append(expectedRenegInfo, c.clientVerify...)
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 259d43f..6d04354 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -3082,7 +3082,33 @@
 		expectedError:      ":NO_RENEGOTIATION:",
 		expectedLocalError: "remote error: no renegotiation",
 	})
-	// TODO(agl): test the renegotiation info SCSV.
+	// The server shouldn't echo the renegotiation extension unless
+	// requested by the client.
+	testCases = append(testCases, testCase{
+		testType: serverTest,
+		name:     "Renegotiate-Server-NoExt",
+		config: Config{
+			Bugs: ProtocolBugs{
+				NoRenegotiationInfo:      true,
+				RequireRenegotiationInfo: true,
+			},
+		},
+		shouldFail:         true,
+		expectedLocalError: "renegotiation extension missing",
+	})
+	// The renegotiation SCSV should be sufficient for the server to echo
+	// the extension.
+	testCases = append(testCases, testCase{
+		testType: serverTest,
+		name:     "Renegotiate-Server-NoExt-SCSV",
+		config: Config{
+			Bugs: ProtocolBugs{
+				NoRenegotiationInfo:      true,
+				SendRenegotiationSCSV:    true,
+				RequireRenegotiationInfo: true,
+			},
+		},
+	})
 	testCases = append(testCases, testCase{
 		name: "Renegotiate-Client",
 		config: Config{