Add tests for very large handshake messages.

OpenSSL recently had a regression here (CVE-2016-6309). We're fine,
but so that we stay that way, add some tests.

Change-Id: I244d7ff327b7aad550f86408c5e5e65e6d1babe5
Reviewed-on: https://boringssl-review.googlesource.com/11321
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 0064e40..c4407da 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -1440,6 +1440,9 @@
     DTLSv1_set_initial_timeout_duration(ssl.get(),
                                         config->initial_timeout_duration_ms);
   }
+  if (config->max_cert_list > 0) {
+    SSL_set_max_cert_list(ssl.get(), config->max_cert_list);
+  }
 
   int sock = Connect(config->port);
   if (sock == -1) {
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index ec20947..5fd333d 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -2331,6 +2331,46 @@
 		},
 	}
 	testCases = append(testCases, basicTests...)
+
+	// Test that very large messages can be received.
+	cert := rsaCertificate
+	for i := 0; i < 50; i++ {
+		cert.Certificate = append(cert.Certificate, cert.Certificate[0])
+	}
+	testCases = append(testCases, testCase{
+		name: "LargeMessage",
+		config: Config{
+			Certificates: []Certificate{cert},
+		},
+	})
+	testCases = append(testCases, testCase{
+		protocol: dtls,
+		name:     "LargeMessage-DTLS",
+		config: Config{
+			Certificates: []Certificate{cert},
+		},
+	})
+
+	// They are rejected if the maximum certificate chain length is capped.
+	testCases = append(testCases, testCase{
+		name: "LargeMessage-Reject",
+		config: Config{
+			Certificates: []Certificate{cert},
+		},
+		flags:         []string{"-max-cert-list", "16384"},
+		shouldFail:    true,
+		expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
+	})
+	testCases = append(testCases, testCase{
+		protocol: dtls,
+		name:     "LargeMessage-Reject-DTLS",
+		config: Config{
+			Certificates: []Certificate{cert},
+		},
+		flags:         []string{"-max-cert-list", "16384"},
+		shouldFail:    true,
+		expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
+	})
 }
 
 func addCipherSuiteTests() {
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index bca194e..425664d 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -155,6 +155,7 @@
   { "-expect-curve-id", &TestConfig::expect_curve_id },
   { "-expect-dhe-group-size", &TestConfig::expect_dhe_group_size },
   { "-initial-timeout-duration-ms", &TestConfig::initial_timeout_duration_ms },
+  { "-max-cert-list", &TestConfig::max_cert_list },
 };
 
 const Flag<std::vector<int>> kIntVectorFlags[] = {
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index d20d1c6..9f74297 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -114,6 +114,7 @@
   bool send_alert = false;
   bool peek_then_read = false;
   bool enable_grease = false;
+  int max_cert_list = 0;
 };
 
 bool ParseConfig(int argc, char **argv, TestConfig *out_config);