Add tests for the point format extension.

Upstream accidentally started rejecting server-sent point formats in
https://github.com/openssl/openssl/issues/2133. Our own test coverage
here is also lacking, so flesh it out.

Change-Id: I99059558bd28d3a540c9687649d6db7e16579d29
Reviewed-on: https://boringssl-review.googlesource.com/12979
Reviewed-by: Steven Valdez <svaldez@google.com>
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>
This commit is contained in:
David Benjamin
2016-12-22 15:33:40 +00:00
committed by CQ bot account: commit-bot@chromium.org
parent 235944126f
commit a81967b47c
5 changed files with 130 additions and 7 deletions
+7 -1
View File
@@ -127,7 +127,8 @@ const (
// TLS Elliptic Curve Point Formats
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
const (
pointFormatUncompressed uint8 = 0
pointFormatUncompressed uint8 = 0
pointFormatCompressedPrime uint8 = 1
)
// TLS CertificateStatusType (RFC 3546)
@@ -1238,6 +1239,11 @@ type ProtocolBugs struct {
// ClearShortHeaderBit, if true, causes the server to send short headers
// without the high bit set.
ClearShortHeaderBit bool
// SendSupportedPointFormats, if not nil, is the list of supported point
// formats to send in ClientHello or ServerHello. If set to a non-nil
// empty slice, no extension will be sent.
SendSupportedPointFormats []byte
}
func (c *Config) serverInit() {
+4
View File
@@ -105,6 +105,10 @@ func (c *Conn) clientHandshake() error {
hello.compressionMethods = c.config.Bugs.SendCompressionMethods
}
if c.config.Bugs.SendSupportedPointFormats != nil {
hello.supportedPoints = c.config.Bugs.SendSupportedPointFormats
}
if len(c.clientVerify) > 0 && !c.config.Bugs.EmptyRenegotiationInfo {
if c.config.Bugs.BadRenegotiationInfo {
hello.secureRenegotiation = append(hello.secureRenegotiation, c.clientVerify...)
+19 -6
View File
@@ -316,9 +316,7 @@ func (m *clientHelloMsg) marshal() []byte {
extensions.addU16(extensionSupportedPoints)
supportedPointsList := extensions.addU16LengthPrefixed()
supportedPoints := supportedPointsList.addU8LengthPrefixed()
for _, pointFormat := range m.supportedPoints {
supportedPoints.addU8(pointFormat)
}
supportedPoints.addBytes(m.supportedPoints)
}
if m.hasKeyShares {
extensions.addU16(extensionKeyShare)
@@ -607,8 +605,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
if length != l+1 {
return false
}
m.supportedPoints = make([]uint8, l)
copy(m.supportedPoints, data[1:])
m.supportedPoints = data[1 : 1+l]
case extensionSessionTicket:
// http://tools.ietf.org/html/rfc5077#section-3.2
m.ticketSupported = true
@@ -1093,6 +1090,7 @@ type serverExtensions struct {
npnAfterAlpn bool
hasKeyShare bool
keyShare keyShareEntry
supportedPoints []uint8
}
func (m *serverExtensions) marshal(extensions *byteBuilder) {
@@ -1187,6 +1185,13 @@ func (m *serverExtensions) marshal(extensions *byteBuilder) {
keyExchange := keyShare.addU16LengthPrefixed()
keyExchange.addBytes(m.keyShare.keyExchange)
}
if len(m.supportedPoints) > 0 {
// http://tools.ietf.org/html/rfc4492#section-5.1.2
extensions.addU16(extensionSupportedPoints)
supportedPointsList := extensions.addU16LengthPrefixed()
supportedPoints := supportedPointsList.addU8LengthPrefixed()
supportedPoints.addBytes(m.supportedPoints)
}
}
func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
@@ -1287,7 +1292,15 @@ func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
if version >= VersionTLS13 {
return false
}
// Ignore this extension from the server.
// http://tools.ietf.org/html/rfc4492#section-5.5.2
if length < 1 {
return false
}
l := int(data[0])
if length != l+1 {
return false
}
m.supportedPoints = data[1 : 1+l]
case extensionSupportedCurves:
// The server can only send supported_curves in TLS 1.3.
if version < VersionTLS13 {
+4
View File
@@ -1192,6 +1192,10 @@ func (hs *serverHandshakeState) processClientExtensions(serverExtensions *server
serverExtensions.ticketSupported = true
}
if c.config.Bugs.SendSupportedPointFormats != nil {
serverExtensions.supportedPoints = c.config.Bugs.SendSupportedPointFormats
}
if !hs.clientHello.hasGREASEExtension && config.Bugs.ExpectGREASE {
return errors.New("tls: no GREASE extension found")
}
+96
View File
@@ -8121,6 +8121,102 @@ func addCurveTests() {
},
resumeSession: true,
})
// Server-sent point formats are legal in TLS 1.2, but not in TLS 1.3.
testCases = append(testCases, testCase{
name: "PointFormat-ServerHello-TLS12",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SendSupportedPointFormats: []byte{pointFormatUncompressed},
},
},
})
testCases = append(testCases, testCase{
name: "PointFormat-EncryptedExtensions-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
SendSupportedPointFormats: []byte{pointFormatUncompressed},
},
},
shouldFail: true,
expectedError: ":ERROR_PARSING_EXTENSION:",
})
// Test that we tolerate unknown point formats, as long as
// pointFormatUncompressed is present. Limit ciphers to ECDHE ciphers to
// check they are still functional.
testCases = append(testCases, testCase{
name: "PointFormat-Client-Tolerance",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime},
},
},
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "PointFormat-Server-Tolerance",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
Bugs: ProtocolBugs{
SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime},
},
},
})
// Test TLS 1.2 does not require the point format extension to be
// present.
testCases = append(testCases, testCase{
name: "PointFormat-Client-Missing",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
Bugs: ProtocolBugs{
SendSupportedPointFormats: []byte{},
},
},
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "PointFormat-Server-Missing",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
Bugs: ProtocolBugs{
SendSupportedPointFormats: []byte{},
},
},
})
// If the point format extension is present, uncompressed points must be
// offered. BoringSSL requires this whether or not ECDHE is used.
testCases = append(testCases, testCase{
name: "PointFormat-Client-MissingUncompressed",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SendSupportedPointFormats: []byte{pointFormatCompressedPrime},
},
},
shouldFail: true,
expectedError: ":ERROR_PARSING_EXTENSION:",
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "PointFormat-Server-MissingUncompressed",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
SendSupportedPointFormats: []byte{pointFormatCompressedPrime},
},
},
shouldFail: true,
expectedError: ":ERROR_PARSING_EXTENSION:",
})
}
func addTLS13RecordTests() {