Do not send unsolicited SCTs in TLS 1.3.

The draft 18 implementation did not compute scts_requested correctly. As
a result, it always believed SCTs were requested. Fix this and add tests
for unsolicited OCSP responses and SCTs at all versions.

Thanks to Daniel Hirche for the report.

Change-Id: Ifc59c5c4d7edba5703fa485c6c7a4055b15954b4
Reviewed-on: https://boringssl-review.googlesource.com/12305
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index c318a9b..08c5db0 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1397,8 +1397,16 @@
 
 static int ext_sct_parse_clienthello(SSL *ssl, uint8_t *out_alert,
                                      CBS *contents) {
+  if (contents == NULL) {
+    return 1;
+  }
+
+  if (CBS_len(contents) != 0) {
+    return 0;
+  }
+
   ssl->s3->hs->scts_requested = 1;
-  return contents == NULL || CBS_len(contents) == 0;
+  return 1;
 }
 
 static int ext_sct_add_serverhello(SSL *ssl, CBB *out) {
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index c3b6b04..a6496fd 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -1201,6 +1201,14 @@
 	// PSKBinderFirst, if true, causes the client to send the PSK Binder
 	// extension as the first extension instead of the last extension.
 	PSKBinderFirst bool
+
+	// NoOCSPStapling, if true, causes the client to not request OCSP
+	// stapling.
+	NoOCSPStapling bool
+
+	// NoSignedCertificateTimestamps, if true, causes the client to not
+	// request signed certificate timestamps.
+	NoSignedCertificateTimestamps bool
 }
 
 func (c *Config) serverInit() {
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
index 36dc1e0..208dcca 100644
--- a/ssl/test/runner/handshake_client.go
+++ b/ssl/test/runner/handshake_client.go
@@ -64,8 +64,8 @@
 		vers:                    versionToWire(maxVersion, c.isDTLS),
 		compressionMethods:      []uint8{compressionNone},
 		random:                  make([]byte, 32),
-		ocspStapling:            true,
-		sctListSupported:        true,
+		ocspStapling:            !c.config.Bugs.NoOCSPStapling,
+		sctListSupported:        !c.config.Bugs.NoSignedCertificateTimestamps,
 		serverName:              c.config.ServerName,
 		supportedCurves:         c.config.curvePreferences(),
 		pskKEModes:              []byte{pskDHEKEMode},
@@ -729,6 +729,22 @@
 		}
 		hs.writeServerHash(certMsg.marshal())
 
+		// Check for unsolicited extensions.
+		for i, cert := range certMsg.certificates {
+			if c.config.Bugs.NoOCSPStapling && cert.ocspResponse != nil {
+				c.sendAlert(alertUnsupportedExtension)
+				return errors.New("tls: unexpected OCSP response in the server certificate")
+			}
+			if c.config.Bugs.NoSignedCertificateTimestamps && cert.sctList != nil {
+				c.sendAlert(alertUnsupportedExtension)
+				return errors.New("tls: unexpected SCT list in the server certificate")
+			}
+			if i > 0 && c.config.Bugs.ExpectNoExtensionsOnIntermediate && (cert.ocspResponse != nil || cert.sctList != nil) {
+				c.sendAlert(alertUnsupportedExtension)
+				return errors.New("tls: unexpected extensions in the server certificate")
+			}
+		}
+
 		if err := hs.verifyCertificates(certMsg); err != nil {
 			return err
 		}
@@ -736,15 +752,6 @@
 		c.ocspResponse = certMsg.certificates[0].ocspResponse
 		c.sctList = certMsg.certificates[0].sctList
 
-		if c.config.Bugs.ExpectNoExtensionsOnIntermediate {
-			for _, cert := range certMsg.certificates[1:] {
-				if cert.ocspResponse != nil || cert.sctList != nil {
-					c.sendAlert(alertUnsupportedExtension)
-					return errors.New("tls: unexpected extensions in the client certificate")
-				}
-			}
-		}
-
 		msg, err = c.readHandshake()
 		if err != nil {
 			return err
@@ -1212,10 +1219,18 @@
 		return errors.New("tls: server advertised OCSP in ServerHello over TLS 1.3")
 	}
 
+	if serverExtensions.ocspStapling && c.config.Bugs.NoOCSPStapling {
+		return errors.New("tls: server advertised unrequested OCSP extension")
+	}
+
 	if len(serverExtensions.sctList) > 0 && c.vers >= VersionTLS13 {
 		return errors.New("tls: server advertised SCTs in ServerHello over TLS 1.3")
 	}
 
+	if len(serverExtensions.sctList) > 0 && c.config.Bugs.NoSignedCertificateTimestamps {
+		return errors.New("tls: server advertised unrequested SCTs")
+	}
+
 	if serverExtensions.srtpProtectionProfile != 0 {
 		if serverExtensions.srtpMasterKeyIdentifier != "" {
 			return errors.New("tls: server selected SRTP MKI value")
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 717c420..918618d 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -5197,6 +5197,25 @@
 			expectedSCTList: testSCTList,
 			resumeSession:   true,
 		})
+
+		// Test that certificate-related extensions are not sent unsolicited.
+		testCases = append(testCases, testCase{
+			testType: serverTest,
+			name:     "UnsolicitedCertificateExtensions-" + ver.name,
+			config: Config{
+				MaxVersion: ver.version,
+				Bugs: ProtocolBugs{
+					NoOCSPStapling:                true,
+					NoSignedCertificateTimestamps: true,
+				},
+			},
+			flags: []string{
+				"-ocsp-response",
+				base64.StdEncoding.EncodeToString(testOCSPResponse),
+				"-signed-cert-timestamps",
+				base64.StdEncoding.EncodeToString(testSCTList),
+			},
+		})
 	}
 
 	testCases = append(testCases, testCase{