Add tests for CVE-2014-3511.

Also change MaxHandshakeRecordLength to 1 in the handshake coverage tests to
better stress the state machine.

Change-Id: I27fce2c000b3d4818fd2e9a47fb09d3f646dd1bd
Reviewed-on: https://boringssl-review.googlesource.com/1452
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2014-08-07 18:02:39 -04:00 committed by Adam Langley
parent 7e2e6cf1a0
commit 9821454f2b
3 changed files with 29 additions and 3 deletions

View File

@ -393,10 +393,15 @@ type ProtocolBugs struct {
SendFallbackSCSV bool SendFallbackSCSV bool
// MaxHandshakeRecordLength, if non-zero, is the maximum size of a // MaxHandshakeRecordLength, if non-zero, is the maximum size of a
// handshake record. Handshake messages will be split at the record // handshake record. Handshake messages will be split into multiple
// layer. // records at the specified size, except that the client_version will
// never be fragmented.
MaxHandshakeRecordLength int MaxHandshakeRecordLength int
// FragmentClientVersion will allow MaxHandshakeRecordLength to apply to
// the first 6 bytes of the ClientHello.
FragmentClientVersion bool
// RsaClientKeyExchangeVersion, if non-zero, causes the client to send a // RsaClientKeyExchangeVersion, if non-zero, causes the client to send a
// ClientKeyExchange with the specified version rather than the // ClientKeyExchange with the specified version rather than the
// client_version when performing the RSA key exchange. // client_version when performing the RSA key exchange.

View File

@ -714,6 +714,8 @@ func (c *Conn) writeV2Record(data []byte) (n int, err error) {
// c.out.Mutex <= L. // c.out.Mutex <= L.
func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) { func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
b := c.out.newBlock() b := c.out.newBlock()
first := true
isClientHello := typ == recordTypeHandshake && len(data) > 0 && data[0] == typeClientHello
for len(data) > 0 { for len(data) > 0 {
m := len(data) m := len(data)
if m > maxPlaintext { if m > maxPlaintext {
@ -721,9 +723,16 @@ func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
} }
if typ == recordTypeHandshake && c.config.Bugs.MaxHandshakeRecordLength > 0 && m > c.config.Bugs.MaxHandshakeRecordLength { if typ == recordTypeHandshake && c.config.Bugs.MaxHandshakeRecordLength > 0 && m > c.config.Bugs.MaxHandshakeRecordLength {
m = c.config.Bugs.MaxHandshakeRecordLength m = c.config.Bugs.MaxHandshakeRecordLength
// By default, do not fragment the client_version or
// server_version, which are located in the first 6
// bytes.
if first && isClientHello && !c.config.Bugs.FragmentClientVersion && m < 6 {
m = 6
}
} }
explicitIVLen := 0 explicitIVLen := 0
explicitIVIsSeq := false explicitIVIsSeq := false
first = false
var cbc cbcMode var cbc cbcMode
if c.out.version >= VersionTLS11 { if c.out.version >= VersionTLS11 {

View File

@ -383,6 +383,18 @@ var testCases = []testCase{
}, },
}, },
}, },
{
testType: serverTest,
name: "FragmentedClientVersion",
config: Config{
Bugs: ProtocolBugs{
MaxHandshakeRecordLength: 1,
FragmentClientVersion: true,
},
},
shouldFail: true,
expectedError: ":RECORD_TOO_SMALL:",
},
} }
func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int) error { func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int) error {
@ -863,7 +875,7 @@ func addStateMachineCoverageTests(async bool, splitHandshake bool) {
} }
if splitHandshake { if splitHandshake {
suffix += "-SplitHandshakeRecords" suffix += "-SplitHandshakeRecords"
maxHandshakeRecordLength = 10 maxHandshakeRecordLength = 1
} }
// Basic handshake, with resumption. Client and server. // Basic handshake, with resumption. Client and server.