Add a packed renegotiation test.

Ridiculous as it is, the protocol does not forbid packing HelloRequest
and Finished into the same record. Add a test for this case.

Change-Id: I8e1455b261f56169309070bf44d14d40a63eae50
Reviewed-on: https://boringssl-review.googlesource.com/8901
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index b2d31dc..240a7ec 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -997,6 +997,10 @@
 	// SkipHelloRetryRequest, if true, causes the TLS 1.3 server to not send
 	// HelloRetryRequest.
 	SkipHelloRetryRequest bool
+
+	// PackHelloRequestWithFinished, if true, causes the TLS server to send
+	// HelloRequest in the same record as Finished.
+	PackHelloRequestWithFinished bool
 }
 
 func (c *Config) serverInit() {
diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go
index fbd501a..1b6c557 100644
--- a/ssl/test/runner/conn.go
+++ b/ssl/test/runner/conn.go
@@ -1268,6 +1268,10 @@
 	c.out.Lock()
 	defer c.out.Unlock()
 
+	// Flush any pending handshake data. PackHelloRequestWithFinished may
+	// have been set and the handshake not followed by Renegotiate.
+	c.flushHandshake()
+
 	if err := c.out.err; err != nil {
 		return 0, err
 	}
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index f8b5dee..aeda2f1 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -1391,7 +1391,10 @@
 
 	if !c.config.Bugs.SkipFinished && len(postCCSBytes) > 0 {
 		c.writeRecord(recordTypeHandshake, postCCSBytes)
-		c.flushHandshake()
+		if !c.config.Bugs.PackHelloRequestWithFinished {
+			// Defer flushing until renegotiation.
+			c.flushHandshake()
+		}
 	}
 
 	c.cipherSuite = hs.suite
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index fd263e6..f8cb4d9 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -5021,6 +5021,24 @@
 		},
 	})
 
+	// Test renegotiation works if HelloRequest and server Finished come in
+	// the same record.
+	testCases = append(testCases, testCase{
+		name: "Renegotiate-Client-Packed",
+		config: Config{
+			MaxVersion: VersionTLS12,
+			Bugs: ProtocolBugs{
+				PackHandshakeFlight:          true,
+				PackHelloRequestWithFinished: true,
+			},
+		},
+		renegotiate: 1,
+		flags: []string{
+			"-renegotiate-freely",
+			"-expect-total-renegotiations", "1",
+		},
+	})
+
 	// Renegotiation is forbidden in TLS 1.3.
 	//
 	// TODO(davidben): This test current asserts that we ignore