Test that False Start fails if the server second leg is omitted.

This works fine, but I believe NSS had a bug here a couple years ago. Also move
all the Skip* bug options next to each other in order.

Change-Id: I72dcb3babeee7ba73b3d7dc5ebef2e2298e37438
Reviewed-on: https://boringssl-review.googlesource.com/3333
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index a253cb9..e8df1aa 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -429,15 +429,27 @@
 	// ServerKeyExchange.
 	UnauthenticatedECDH bool
 
+	// SkipHelloVerifyRequest causes a DTLS server to skip the
+	// HelloVerifyRequest message.
+	SkipHelloVerifyRequest bool
+
 	// SkipServerKeyExchange causes the server to skip sending
 	// ServerKeyExchange messages.
 	SkipServerKeyExchange bool
 
+	// SkipNewSessionTicket causes the server to skip sending the
+	// NewSessionTicket message despite promising to in ServerHello.
+	SkipNewSessionTicket bool
+
 	// SkipChangeCipherSpec causes the implementation to skip
 	// sending the ChangeCipherSpec message (and adjusting cipher
 	// state accordingly for the Finished message).
 	SkipChangeCipherSpec bool
 
+	// SkipFinished causes the implementation to skip sending the Finished
+	// message.
+	SkipFinished bool
+
 	// EarlyChangeCipherSpec causes the client to send an early
 	// ChangeCipherSpec message before the ClientKeyExchange. A value of
 	// zero disables this behavior. One and two configure variants for 0.9.8
@@ -449,10 +461,6 @@
 	// messages.
 	FragmentAcrossChangeCipherSpec bool
 
-	// SkipNewSessionTicket causes the server to skip sending the
-	// NewSessionTicket message despite promising to in ServerHello.
-	SkipNewSessionTicket bool
-
 	// SendV2ClientHello causes the client to send a V2ClientHello
 	// instead of a normal ClientHello.
 	SendV2ClientHello bool
@@ -492,10 +500,6 @@
 	// TLS version in the ClientHello than the maximum supported version.
 	SendClientVersion uint16
 
-	// SkipHelloVerifyRequest causes a DTLS server to skip the
-	// HelloVerifyRequest message.
-	SkipHelloVerifyRequest bool
-
 	// ExpectFalseStart causes the server to, on full handshakes,
 	// expect the peer to False Start; the server Finished message
 	// isn't sent until we receive an application data record
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
index 5ad3602..c798109 100644
--- a/ssl/test/runner/handshake_client.go
+++ b/ssl/test/runner/handshake_client.go
@@ -872,9 +872,11 @@
 		c.writeRecord(recordTypeApplicationData, c.config.Bugs.AppDataAfterChangeCipherSpec)
 	}
 
-	c.writeRecord(recordTypeHandshake, postCCSBytes)
-	if err := c.dtlsFlushHandshake(false); err != nil {
-		return err
+	if !c.config.Bugs.SkipFinished {
+		c.writeRecord(recordTypeHandshake, postCCSBytes)
+		if err := c.dtlsFlushHandshake(false); err != nil {
+			return err
+		}
 	}
 	return nil
 }
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index c13de9b..de5d7b7 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -857,9 +857,11 @@
 		c.writeRecord(recordTypeApplicationData, c.config.Bugs.AppDataAfterChangeCipherSpec)
 	}
 
-	c.writeRecord(recordTypeHandshake, postCCSBytes)
-	if err := c.dtlsFlushHandshake(false); err != nil {
-		return err
+	if !c.config.Bugs.SkipFinished {
+		c.writeRecord(recordTypeHandshake, postCCSBytes)
+		if err := c.dtlsFlushHandshake(false); err != nil {
+			return err
+		}
 	}
 
 	c.cipherSuite = hs.suite.id
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 70ed314..dd63c5b 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -739,6 +739,26 @@
 		shouldFail:    true,
 		expectedError: ":UNEXPECTED_RECORD:",
 	},
+	{
+		name: "FalseStart-SkipServerSecondLeg",
+		config: Config{
+			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+			NextProtos:   []string{"foo"},
+			Bugs: ProtocolBugs{
+				SkipNewSessionTicket: true,
+				SkipChangeCipherSpec: true,
+				SkipFinished:         true,
+				ExpectFalseStart:     true,
+			},
+		},
+		flags: []string{
+			"-false-start",
+			"-advertise-alpn", "\x03foo",
+		},
+		shimWritesFirst: true,
+		shouldFail:      true,
+		expectedError:   ":UNEXPECTED_RECORD:",
+	},
 }
 
 func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, isResume bool) error {