Add a test that ALPN is rejected on renegotiation.

We've never allowed this as no good can come of it. Add a test for this.

Change-Id: I4b92372f58c1fe2054e33007adbe496d153a9251
Reviewed-on: https://boringssl-review.googlesource.com/14266
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index b1afc03..ef144c3 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -1182,6 +1182,11 @@
 	}
 
 	if len(hs.clientHello.alpnProtocols) > 0 {
+		// We will never offer ALPN as a client on renegotiation
+		// handshakes.
+		if len(c.clientVerify) > 0 {
+			return errors.New("tls: offered ALPN on renegotiation")
+		}
 		if proto := c.config.Bugs.ALPNProtocol; proto != nil {
 			serverExtensions.alpnProtocol = *proto
 			serverExtensions.alpnProtocolEmpty = len(*proto) == 0
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 262ac28..157307b 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -6593,6 +6593,31 @@
 		shouldFail:    true,
 		expectedError: ":SERVER_CERT_CHANGED:",
 	})
+
+	// We do not negotiate ALPN after the initial handshake. This is
+	// error-prone and only risks bugs in consumers.
+	testCases = append(testCases, testCase{
+		testType: clientTest,
+		name:     "Renegotiation-ForbidALPN",
+		config: Config{
+			MaxVersion: VersionTLS12,
+			Bugs: ProtocolBugs{
+				// Forcibly negotiate ALPN on both initial and
+				// renegotiation handshakes. The test stack will
+				// internally check the client does not offer
+				// it.
+				SendALPN: "foo",
+			},
+		},
+		flags: []string{
+			"-advertise-alpn", "\x03foo\x03bar\x03baz",
+			"-expect-alpn", "foo",
+			"-renegotiate-freely",
+		},
+		renegotiate:   1,
+		shouldFail:    true,
+		expectedError: ":UNEXPECTED_EXTENSION:",
+	})
 }
 
 func addDTLSReplayTests() {