Test unknown TLS 1.3 ServerHello extensions.

These too must be rejected. Test both unknown extensions and extensions
in the wrong context.

Change-Id: I54d5a5060f9efc26e5e4d23a0bde3c0d4d302d09
Reviewed-on: https://boringssl-review.googlesource.com/11501
Reviewed-by: Steven Valdez <svaldez@google.com>
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/common.go b/ssl/test/runner/common.go
index 4e3f014..8fe61a4 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -888,6 +888,10 @@
 	// that will be added to client/server hellos.
 	CustomExtension string
 
+	// CustomUnencryptedExtension, if not empty, contains the contents of
+	// an extension that will be added to ServerHello in TLS 1.3.
+	CustomUnencryptedExtension string
+
 	// ExpectedCustomExtension, if not nil, contains the expected contents
 	// of a custom extension.
 	ExpectedCustomExtension *string
@@ -922,6 +926,10 @@
 	// the client offer.
 	SendALPN string
 
+	// SendUnencryptedALPN, if non-empty, causes the server to send the
+	// specified string in a ServerHello ALPN extension in TLS 1.3.
+	SendUnencryptedALPN string
+
 	// SendEmptySessionTicket, if true, causes the server to send an empty
 	// session ticket.
 	SendEmptySessionTicket bool
diff --git a/ssl/test/runner/handshake_messages.go b/ssl/test/runner/handshake_messages.go
index 546966a..1e91ac3 100644
--- a/ssl/test/runner/handshake_messages.go
+++ b/ssl/test/runner/handshake_messages.go
@@ -782,6 +782,8 @@
 	useCertAuth         bool
 	earlyDataIndication bool
 	compressionMethod   uint8
+	customExtension     string
+	unencryptedALPN     string
 	extensions          serverExtensions
 }
 
@@ -840,6 +842,19 @@
 			extensions.addU16(extensionEarlyData)
 			extensions.addU16(0) // Length
 		}
+		if len(m.customExtension) > 0 {
+			extensions.addU16(extensionCustom)
+			customExt := extensions.addU16LengthPrefixed()
+			customExt.addBytes([]byte(m.customExtension))
+		}
+		if len(m.unencryptedALPN) > 0 {
+			extensions.addU16(extensionALPN)
+			extension := extensions.addU16LengthPrefixed()
+
+			protocolNameList := extension.addU16LengthPrefixed()
+			protocolName := protocolNameList.addU8LengthPrefixed()
+			protocolName.addBytes([]byte(m.unencryptedALPN))
+		}
 	} else {
 		m.extensions.marshal(extensions, vers)
 		if extensions.len() == 0 {
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index abadf3a..59b34fa 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -359,9 +359,11 @@
 	config := c.config
 
 	hs.hello = &serverHelloMsg{
-		isDTLS:       c.isDTLS,
-		vers:         versionToWire(c.vers, c.isDTLS),
-		versOverride: config.Bugs.SendServerHelloVersion,
+		isDTLS:          c.isDTLS,
+		vers:            versionToWire(c.vers, c.isDTLS),
+		versOverride:    config.Bugs.SendServerHelloVersion,
+		customExtension: config.Bugs.CustomUnencryptedExtension,
+		unencryptedALPN: config.Bugs.SendUnencryptedALPN,
 	}
 
 	hs.hello.random = make([]byte, 32)
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 8ca3917..fe2cf84 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -7110,6 +7110,39 @@
 		expectedError:      ":UNEXPECTED_EXTENSION:",
 		expectedLocalError: "remote error: unsupported extension",
 	})
+	testCases = append(testCases, testCase{
+		testType: clientTest,
+		name:     "UnknownUnencryptedExtension-Client-TLS13",
+		config: Config{
+			MaxVersion: VersionTLS13,
+			Bugs: ProtocolBugs{
+				CustomUnencryptedExtension: expectedContents,
+			},
+		},
+		shouldFail:    true,
+		expectedError: ":UNEXPECTED_EXTENSION:",
+		// The shim must send an alert, but alerts at this point do not
+		// get successfully decrypted by the runner.
+		expectedLocalError: "local error: bad record MAC",
+	})
+	testCases = append(testCases, testCase{
+		testType: clientTest,
+		name:     "UnexpectedUnencryptedExtension-Client-TLS13",
+		config: Config{
+			MaxVersion: VersionTLS13,
+			Bugs: ProtocolBugs{
+				SendUnencryptedALPN: "foo",
+			},
+		},
+		flags: []string{
+			"-advertise-alpn", "\x03foo\x03bar",
+		},
+		shouldFail:    true,
+		expectedError: ":UNEXPECTED_EXTENSION:",
+		// The shim must send an alert, but alerts at this point do not
+		// get successfully decrypted by the runner.
+		expectedLocalError: "local error: bad record MAC",
+	})
 
 	// Test a known but unoffered extension from the server.
 	testCases = append(testCases, testCase{