Add EarlyChangeCipherSpec tests.
Adapted from patch in https://www.imperialviolet.org/2014/06/05/earlyccs.html. Change-Id: I14bf314d105780e23e6bd09217870deff5744979 Reviewed-on: https://boringssl-review.googlesource.com/1292 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
committed by
Adam Langley
parent
1d5c83e063
commit
f3ec83dee0
@@ -368,6 +368,12 @@ type ProtocolBugs struct {
|
||||
// sending the ChangeCipherSpec message (and adjusting cipher
|
||||
// state accordingly for the Finished message).
|
||||
SkipChangeCipherSpec bool
|
||||
|
||||
// EarlyChangeCipherSpec causes the client to send an early
|
||||
// ChangeCipherSpec message before the ClientKeyExchange. A value of
|
||||
// zero disables this behavior. One and two configure variants for 0.9.8
|
||||
// and 1.0.1 modes, respectively.
|
||||
EarlyChangeCipherSpec int
|
||||
}
|
||||
|
||||
func (c *Config) serverInit() {
|
||||
|
||||
@@ -165,14 +165,21 @@ NextCipherSuite:
|
||||
hs.finishedHash.Write(hs.hello.marshal())
|
||||
hs.finishedHash.Write(hs.serverHello.marshal())
|
||||
|
||||
if c.config.Bugs.EarlyChangeCipherSpec > 0 {
|
||||
hs.establishKeys()
|
||||
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
|
||||
}
|
||||
|
||||
isResume, err := hs.processServerHello()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isResume {
|
||||
if err := hs.establishKeys(); err != nil {
|
||||
return err
|
||||
if c.config.Bugs.EarlyChangeCipherSpec == 0 {
|
||||
if err := hs.establishKeys(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := hs.readSessionTicket(); err != nil {
|
||||
return err
|
||||
@@ -408,7 +415,9 @@ func (hs *clientHandshakeState) doFullHandshake() error {
|
||||
return err
|
||||
}
|
||||
if ckx != nil {
|
||||
hs.finishedHash.Write(ckx.marshal())
|
||||
if c.config.Bugs.EarlyChangeCipherSpec < 2 {
|
||||
hs.finishedHash.Write(ckx.marshal())
|
||||
}
|
||||
c.writeRecord(recordTypeHandshake, ckx.marshal())
|
||||
}
|
||||
|
||||
@@ -532,11 +541,13 @@ func (hs *clientHandshakeState) readFinished() error {
|
||||
return unexpectedMessageError(serverFinished, msg)
|
||||
}
|
||||
|
||||
verify := hs.finishedHash.serverSum(hs.masterSecret)
|
||||
if len(verify) != len(serverFinished.verifyData) ||
|
||||
subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
|
||||
c.sendAlert(alertHandshakeFailure)
|
||||
return errors.New("tls: server's Finished message was incorrect")
|
||||
if c.config.Bugs.EarlyChangeCipherSpec == 0 {
|
||||
verify := hs.finishedHash.serverSum(hs.masterSecret)
|
||||
if len(verify) != len(serverFinished.verifyData) ||
|
||||
subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
|
||||
c.sendAlert(alertHandshakeFailure)
|
||||
return errors.New("tls: server's Finished message was incorrect")
|
||||
}
|
||||
}
|
||||
hs.finishedHash.Write(serverFinished.marshal())
|
||||
return nil
|
||||
@@ -573,7 +584,8 @@ func (hs *clientHandshakeState) readSessionTicket() error {
|
||||
func (hs *clientHandshakeState) sendFinished() error {
|
||||
c := hs.c
|
||||
|
||||
if !c.config.Bugs.SkipChangeCipherSpec {
|
||||
if !c.config.Bugs.SkipChangeCipherSpec &&
|
||||
c.config.Bugs.EarlyChangeCipherSpec == 0 {
|
||||
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
|
||||
}
|
||||
if hs.serverHello.nextProtoNeg {
|
||||
@@ -588,7 +600,11 @@ func (hs *clientHandshakeState) sendFinished() error {
|
||||
}
|
||||
|
||||
finished := new(finishedMsg)
|
||||
finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
|
||||
if c.config.Bugs.EarlyChangeCipherSpec == 2 {
|
||||
finished.verifyData = hs.finishedHash.clientSum(nil)
|
||||
} else {
|
||||
finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
|
||||
}
|
||||
hs.finishedHash.Write(finished.marshal())
|
||||
c.writeRecord(recordTypeHandshake, finished.marshal())
|
||||
return nil
|
||||
|
||||
@@ -262,6 +262,28 @@ var testCases = []testCase{
|
||||
shouldFail: true,
|
||||
expectedError: ":GOT_NEXT_PROTO_BEFORE_A_CCS:",
|
||||
},
|
||||
{
|
||||
testType: serverTest,
|
||||
name: "EarlyChangeCipherSpec-server-1",
|
||||
config: Config{
|
||||
Bugs: ProtocolBugs{
|
||||
EarlyChangeCipherSpec: 1,
|
||||
},
|
||||
},
|
||||
shouldFail: true,
|
||||
expectedError: ":CCS_RECEIVED_EARLY:",
|
||||
},
|
||||
{
|
||||
testType: serverTest,
|
||||
name: "EarlyChangeCipherSpec-server-2",
|
||||
config: Config{
|
||||
Bugs: ProtocolBugs{
|
||||
EarlyChangeCipherSpec: 2,
|
||||
},
|
||||
},
|
||||
shouldFail: true,
|
||||
expectedError: ":CCS_RECEIVED_EARLY:",
|
||||
},
|
||||
}
|
||||
|
||||
func doExchange(testType testType, config *Config, conn net.Conn, messageLen int) error {
|
||||
|
||||
Reference in New Issue
Block a user