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>
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index d394b73..8ac76f6 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -368,6 +368,12 @@
// 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() {
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
index 9d07584..32b90e2 100644
--- a/ssl/test/runner/handshake_client.go
+++ b/ssl/test/runner/handshake_client.go
@@ -165,14 +165,21 @@
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 @@
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 @@
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) 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 @@
}
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
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 539a746..47af0e0 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -262,6 +262,28 @@
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 {