runner: Simplify certificate_authorities testing

We had some extra logic for detecting empty certificate_authorities in a
funny way, but since this is a syntax error, runner can just check this
unconditionally and stick with a more straightforward data model.

Also individual CAs cannot be empty, so fix runner to enforce this.

Change-Id: I5e697687d6dcc44e36b4f98a6284889129a077a4
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/76707
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index ee65687..daae594 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -1941,10 +1941,6 @@
 	// renegotiation handshakes.
 	RenegotiationCertificate *Credential
 
-	// ExpectNoCertificateAuthoritiesExtension, if true, causes the client to
-	// reject CertificateRequest with the CertificateAuthorities extension.
-	ExpectNoCertificateAuthoritiesExtension bool
-
 	// SigningAlgorithmForLegacyVersions, if non-zero, is the signature algorithm
 	// to use when signing in TLS 1.1 and earlier where algorithms are not
 	// negotiated.
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
index 91f0833..731902f 100644
--- a/ssl/test/runner/handshake_client.go
+++ b/ssl/test/runner/handshake_client.go
@@ -1257,10 +1257,6 @@
 				return errors.New("tls: non-empty certificate request context sent in handshake")
 			}
 
-			if c.config.Bugs.ExpectNoCertificateAuthoritiesExtension && certReq.hasCAExtension {
-				return errors.New("tls: expected no certificate_authorities extension")
-			}
-
 			hs.writeServerHash(certReq.marshal())
 
 			credential = c.config.Credential
diff --git a/ssl/test/runner/handshake_messages.go b/ssl/test/runner/handshake_messages.go
index 3bffb5a..651efb3 100644
--- a/ssl/test/runner/handshake_messages.go
+++ b/ssl/test/runner/handshake_messages.go
@@ -2391,7 +2391,6 @@
 	signatureAlgorithms     []signatureAlgorithm
 	signatureAlgorithmsCert []signatureAlgorithm
 	certificateAuthorities  [][]byte
-	hasCAExtension          bool
 	customExtension         uint16
 }
 
@@ -2473,7 +2472,7 @@
 	}
 	for len(cas) > 0 {
 		var ca []byte
-		if !readUint16LengthPrefixedBytes(&cas, &ca) {
+		if !readUint16LengthPrefixedBytes(&cas, &ca) || len(ca) == 0 {
 			return false
 		}
 		*out = append(*out, ca)
@@ -2510,10 +2509,11 @@
 					return false
 				}
 			case extensionCertificateAuthorities:
-				if !parseCAs(&body, &m.certificateAuthorities) || len(body) != 0 {
+				if !parseCAs(&body, &m.certificateAuthorities) || len(body) != 0 ||
+					// If present, the CA extension may not be empty.
+					len(m.certificateAuthorities) == 0 {
 					return false
 				}
-				m.hasCAExtension = true
 			}
 		}
 	} else {
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 1042b43..fe59956 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -4852,15 +4852,14 @@
 	})
 
 	// Test that an empty client CA list doesn't send a CA extension.
+	// (This is implicitly tested by the parser. An empty CA extension is
+	// a syntax error.)
 	testCases = append(testCases, testCase{
 		testType: serverTest,
 		name:     "TLS13-Empty-Client-CA-List",
 		config: Config{
 			MaxVersion: VersionTLS13,
 			Credential: &rsaCertificate,
-			Bugs: ProtocolBugs{
-				ExpectNoCertificateAuthoritiesExtension: true,
-			},
 		},
 		flags: []string{
 			"-require-any-client-certificate",