Check duplicate extensions before processing.
ClientHello and ServerHello are not allowed to include duplicate extensions.
Add a new helper function to check this and call as appropriate. Remove ad-hoc
per-extension duplicate checks which are no unnecessary.
Add runner.go tests to verify such message correctly rejected.
Change-Id: I7babd5b642dfec941459512869e2dd6de26a831c
Reviewed-on: https://boringssl-review.googlesource.com/1100
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index fd78eb6..df7cacf 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -345,6 +345,10 @@
// FailIfNotFallbackSCSV causes a server handshake to fail if the
// client doesn't send the fallback SCSV value.
FailIfNotFallbackSCSV bool
+
+ // DuplicateExtension causes an extra empty extension of bogus type to
+ // be emitted in either the ClientHello or the ServerHello.
+ DuplicateExtension bool
}
func (c *Config) serverInit() {
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
index f335d03..220e489 100644
--- a/ssl/test/runner/handshake_client.go
+++ b/ssl/test/runner/handshake_client.go
@@ -47,6 +47,7 @@
supportedPoints: []uint8{pointFormatUncompressed},
nextProtoNeg: len(c.config.NextProtos) > 0,
secureRenegotiation: true,
+ duplicateExtension: c.config.Bugs.DuplicateExtension,
}
possibleCipherSuites := c.config.cipherSuites()
diff --git a/ssl/test/runner/handshake_messages.go b/ssl/test/runner/handshake_messages.go
index e31f47b..edb45d8 100644
--- a/ssl/test/runner/handshake_messages.go
+++ b/ssl/test/runner/handshake_messages.go
@@ -22,6 +22,7 @@
sessionTicket []uint8
signatureAndHashes []signatureAndHash
secureRenegotiation bool
+ duplicateExtension bool
}
func (m *clientHelloMsg) equal(i interface{}) bool {
@@ -86,6 +87,9 @@
extensionsLength += 1
numExtensions++
}
+ if m.duplicateExtension {
+ numExtensions += 2
+ }
if numExtensions > 0 {
extensionsLength += 4 * numExtensions
length += 2 + extensionsLength
@@ -118,6 +122,12 @@
z[1] = byte(extensionsLength)
z = z[2:]
}
+ if m.duplicateExtension {
+ // Add a duplicate bogus extension at the beginning and end.
+ z[0] = 0xff
+ z[1] = 0xff
+ z = z[4:]
+ }
if m.nextProtoNeg {
z[0] = byte(extensionNextProtoNeg >> 8)
z[1] = byte(extensionNextProtoNeg & 0xff)
@@ -237,6 +247,12 @@
z[3] = 1
z = z[5:]
}
+ if m.duplicateExtension {
+ // Add a duplicate bogus extension at the beginning and end.
+ z[0] = 0xff
+ z[1] = 0xff
+ z = z[4:]
+ }
m.raw = x
@@ -419,6 +435,7 @@
ocspStapling bool
ticketSupported bool
secureRenegotiation bool
+ duplicateExtension bool
}
func (m *serverHelloMsg) equal(i interface{}) bool {
@@ -468,6 +485,9 @@
extensionsLength += 1
numExtensions++
}
+ if m.duplicateExtension {
+ numExtensions += 2
+ }
if numExtensions > 0 {
extensionsLength += 4 * numExtensions
length += 2 + extensionsLength
@@ -494,6 +514,12 @@
z[1] = byte(extensionsLength)
z = z[2:]
}
+ if m.duplicateExtension {
+ // Add a duplicate bogus extension at the beginning and end.
+ z[0] = 0xff
+ z[1] = 0xff
+ z = z[4:]
+ }
if m.nextProtoNeg {
z[0] = byte(extensionNextProtoNeg >> 8)
z[1] = byte(extensionNextProtoNeg & 0xff)
@@ -528,6 +554,12 @@
z[3] = 1
z = z[5:]
}
+ if m.duplicateExtension {
+ // Add a duplicate bogus extension at the beginning and end.
+ z[0] = 0xff
+ z[1] = 0xff
+ z = z[4:]
+ }
m.raw = x
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index 854c7ff..328c15f 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -157,6 +157,7 @@
}
hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation
hs.hello.compressionMethod = compressionNone
+ hs.hello.duplicateExtension = c.config.Bugs.DuplicateExtension
if len(hs.clientHello.serverName) > 0 {
c.serverName = hs.clientHello.serverName
}
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index f253f89..96b52fa 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -137,12 +137,34 @@
},
{
testType: serverTest,
- name: "ServerNameExtension",
+ name: "ServerNameExtension",
config: Config{
ServerName: "example.com",
},
flags: []string{"-expect-server-name", "example.com"},
},
+ {
+ testType: clientTest,
+ name: "DuplicateExtensionClient",
+ config: Config{
+ Bugs: ProtocolBugs{
+ DuplicateExtension: true,
+ },
+ },
+ shouldFail: true,
+ expectedLocalError: "remote error: error decoding message",
+ },
+ {
+ testType: serverTest,
+ name: "DuplicateExtensionServer",
+ config: Config{
+ Bugs: ProtocolBugs{
+ DuplicateExtension: true,
+ },
+ },
+ shouldFail: true,
+ expectedLocalError: "remote error: error decoding message",
+ },
}
func doExchange(tlsConn *Conn, messageLen int) error {