Add UnauthenticatedECDH bug test.

This works, but there's enough shared codepaths that it's worth a test to
ensure it stays that way.

Change-Id: I5d5a729811e35832170322957258304213204e3b
Reviewed-on: https://boringssl-review.googlesource.com/1155
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index dca3e9d..328807a 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -353,6 +353,12 @@
 	// DuplicateExtension causes an extra empty extension of bogus type to
 	// be emitted in either the ClientHello or the ServerHello.
 	DuplicateExtension bool
+
+	// UnauthenticatedECDH causes the server to pretend ECDHE_RSA
+	// and ECDHE_ECDSA cipher suites are actually ECDH_anon. No
+	// Certificate message is sent and no signature is added to
+	// ServerKeyExchange.
+	UnauthenticatedECDH bool
 }
 
 func (c *Config) serverInit() {
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index a32c078..0b49a00 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -313,8 +313,10 @@
 
 	certMsg := new(certificateMsg)
 	certMsg.certificates = hs.cert.Certificate
-	hs.finishedHash.Write(certMsg.marshal())
-	c.writeRecord(recordTypeHandshake, certMsg.marshal())
+	if !config.Bugs.UnauthenticatedECDH {
+		hs.finishedHash.Write(certMsg.marshal())
+		c.writeRecord(recordTypeHandshake, certMsg.marshal())
+	}
 
 	if hs.hello.ocspStapling {
 		certStatus := new(certificateStatusMsg)
diff --git a/ssl/test/runner/key_agreement.go b/ssl/test/runner/key_agreement.go
index 991a91d..8681475 100644
--- a/ssl/test/runner/key_agreement.go
+++ b/ssl/test/runner/key_agreement.go
@@ -294,21 +294,25 @@
 	}
 
 	skx := new(serverKeyExchangeMsg)
-	sigAndHashLen := 0
-	if ka.version >= VersionTLS12 {
-		sigAndHashLen = 2
+	if config.Bugs.UnauthenticatedECDH {
+		skx.key = serverECDHParams
+	} else {
+		sigAndHashLen := 0
+		if ka.version >= VersionTLS12 {
+			sigAndHashLen = 2
+		}
+		skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig))
+		copy(skx.key, serverECDHParams)
+		k := skx.key[len(serverECDHParams):]
+		if ka.version >= VersionTLS12 {
+			k[0] = tls12HashId
+			k[1] = ka.sigType
+			k = k[2:]
+		}
+		k[0] = byte(len(sig) >> 8)
+		k[1] = byte(len(sig))
+		copy(k[2:], sig)
 	}
-	skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig))
-	copy(skx.key, serverECDHParams)
-	k := skx.key[len(serverECDHParams):]
-	if ka.version >= VersionTLS12 {
-		k[0] = tls12HashId
-		k[1] = ka.sigType
-		k = k[2:]
-	}
-	k[0] = byte(len(sig) >> 8)
-	k[1] = byte(len(sig))
-	copy(k[2:], sig)
 
 	return skx, nil
 }
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 27876fa..0b210cd 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -189,6 +189,17 @@
 		shouldFail:         true,
 		expectedLocalError: "client didn't provide a certificate",
 	},
+	{
+		name: "UnauthenticatedECDH",
+		config: Config{
+			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+			Bugs: ProtocolBugs{
+				UnauthenticatedECDH: true,
+			},
+		},
+		shouldFail:    true,
+		expectedError: ":MISSING_RSA_SIGNING_CERT:",
+	},
 }
 
 func doExchange(tlsConn *Conn, messageLen int) error {