Implement KeyUpdate in Go.
Implemented in preparation for testing the C implementation. Tested
against itself.
BUG=74
Change-Id: Iec1b9ad22e09711fa4e67c97cc3eb257585c3ae5
Reviewed-on: https://boringssl-review.googlesource.com/8873
Reviewed-by: Nick Harper <nharper@chromium.org>
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>
diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go
index 969c50a..cefdde3 100644
--- a/ssl/test/runner/conn.go
+++ b/ssl/test/runner/conn.go
@@ -159,6 +159,9 @@
// used to save allocating a new buffer for each MAC.
inDigestBuf, outDigestBuf []byte
+ trafficSecret []byte
+ keyUpdateGeneration int
+
config *Config
}
@@ -203,13 +206,23 @@
return nil
}
-// updateKeys sets the current cipher state.
-func (hc *halfConn) updateKeys(cipher interface{}, version uint16) {
+// useTrafficSecret sets the current cipher state for TLS 1.3.
+func (hc *halfConn) useTrafficSecret(version uint16, suite *cipherSuite, secret, phase []byte, side trafficDirection) {
hc.version = version
- hc.cipher = cipher
+ hc.cipher = deriveTrafficAEAD(version, suite, secret, phase, side)
+ hc.trafficSecret = secret
hc.incEpoch()
}
+func (hc *halfConn) doKeyUpdate(c *Conn, isOutgoing bool) {
+ side := serverWrite
+ if c.isClient == isOutgoing {
+ side = clientWrite
+ }
+ hc.useTrafficSecret(hc.version, c.cipherSuite, updateTrafficSecret(c.cipherSuite.hash(), hc.trafficSecret), applicationPhase, side)
+ hc.keyUpdateGeneration++
+}
+
// incSeq increments the sequence number.
func (hc *halfConn) incSeq(isOutgoing bool) {
limit := 0
@@ -1175,6 +1188,8 @@
m = new(helloVerifyRequestMsg)
case typeChannelID:
m = new(channelIDMsg)
+ case typeKeyUpdate:
+ m = new(keyUpdateMsg)
default:
return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
}
@@ -1280,6 +1295,13 @@
return 0, alertInternalError
}
+ // Catch up with KeyUpdates from the peer.
+ for c.out.keyUpdateGeneration < c.in.keyUpdateGeneration {
+ if err := c.sendKeyUpdateLocked(); err != nil {
+ return 0, err
+ }
+ }
+
if c.config.Bugs.SendSpuriousAlert != 0 {
c.sendAlertLocked(alertLevelError, c.config.Bugs.SendSpuriousAlert)
}
@@ -1357,6 +1379,11 @@
}
}
+ if _, ok := msg.(*keyUpdateMsg); ok {
+ c.in.doKeyUpdate(c, true)
+ return nil
+ }
+
// TODO(davidben): Add support for KeyUpdate.
c.sendAlert(alertUnexpectedMessage)
return alertUnexpectedMessage
@@ -1648,3 +1675,21 @@
_, err := c.writeRecord(recordTypeHandshake, m.marshal())
return err
}
+
+func (c *Conn) SendKeyUpdate() error {
+ c.out.Lock()
+ defer c.out.Unlock()
+ return c.sendKeyUpdateLocked()
+}
+
+func (c *Conn) sendKeyUpdateLocked() error {
+ m := new(keyUpdateMsg)
+ if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
+ return err
+ }
+ if err := c.flushHandshake(); err != nil {
+ return err
+ }
+ c.out.doKeyUpdate(c, false)
+ return nil
+}