don't drop keys for key phase N before receiving a N+1-protected packet

This commit is contained in:
Marten Seemann
2020-09-09 11:38:44 +07:00
parent 8c348c2d59
commit 854940cecc
2 changed files with 57 additions and 19 deletions

View File

@@ -122,14 +122,14 @@ var _ = Describe("Updatable AEAD", func() {
now := time.Now()
Expect(server.KeyPhase()).To(Equal(protocol.KeyPhaseZero))
encrypted0 := server.Seal(nil, msg, 0x1337, ad)
server.rollKeys(now)
server.rollKeys()
Expect(server.KeyPhase()).To(Equal(protocol.KeyPhaseOne))
encrypted1 := server.Seal(nil, msg, 0x1337, ad)
Expect(encrypted0).ToNot(Equal(encrypted1))
// expect opening to fail. The client didn't roll keys yet
_, err := client.Open(nil, encrypted1, now, 0x1337, protocol.KeyPhaseZero, ad)
Expect(err).To(MatchError(ErrDecryptionFailed))
client.rollKeys(now)
client.rollKeys()
decrypted, err := client.Open(nil, encrypted1, now, 0x1337, protocol.KeyPhaseOne, ad)
Expect(err).ToNot(HaveOccurred())
Expect(decrypted).To(Equal(msg))
@@ -146,7 +146,7 @@ var _ = Describe("Updatable AEAD", func() {
Expect(server.KeyPhase()).To(Equal(protocol.KeyPhaseZero))
_ = server.Seal(nil, msg, 0x1, ad)
// now received a message at key phase one
client.rollKeys(now)
client.rollKeys()
encrypted1 := client.Seal(nil, msg, 0x43, ad)
serverTracer.EXPECT().UpdatedKey(protocol.KeyPhase(1), true)
decrypted, err = server.Open(nil, encrypted1, now, 0x43, protocol.KeyPhaseOne, ad)
@@ -165,7 +165,7 @@ var _ = Describe("Updatable AEAD", func() {
// send one packet at key phase zero
_ = server.Seal(nil, msg, 0x1, ad)
// now receive a packet with key phase 1
client.rollKeys(now)
client.rollKeys()
encrypted1 := client.Seal(nil, msg, 0x44, ad)
Expect(server.KeyPhase()).To(Equal(protocol.KeyPhaseZero))
serverTracer.EXPECT().UpdatedKey(protocol.KeyPhase(1), true)
@@ -191,7 +191,7 @@ var _ = Describe("Updatable AEAD", func() {
// send one packet at key phase zero
_ = server.Seal(nil, msg, 0x1, ad)
// now receive a packet with key phase 1
client.rollKeys(now)
client.rollKeys()
encrypted1 := client.Seal(nil, msg, 0x44, ad)
Expect(server.KeyPhase()).To(Equal(protocol.KeyPhaseZero))
serverTracer.EXPECT().UpdatedKey(protocol.KeyPhase(1), true)
@@ -205,14 +205,14 @@ var _ = Describe("Updatable AEAD", func() {
})
It("errors when the peer starts with key phase 1", func() {
client.rollKeys(time.Now())
client.rollKeys()
encrypted := client.Seal(nil, msg, 0x1337, ad)
_, err := server.Open(nil, encrypted, time.Now(), 0x1337, protocol.KeyPhaseOne, ad)
Expect(err).To(MatchError("PROTOCOL_VIOLATION: wrong initial key phase"))
})
It("only errors when the peer starts with key phase 1 if decrypting the packet succeeds", func() {
client.rollKeys(time.Now())
client.rollKeys()
encrypted := client.Seal(nil, msg, 0x1337, ad)
encrypted = encrypted[:len(encrypted)-1]
_, err := server.Open(nil, encrypted, time.Now(), 0x1337, protocol.KeyPhaseOne, ad)
@@ -225,7 +225,7 @@ var _ = Describe("Updatable AEAD", func() {
_, err := server.Open(nil, encrypted0, time.Now(), 0x42, protocol.KeyPhaseZero, ad)
Expect(err).ToNot(HaveOccurred())
// now receive a packet at key phase one, before having sent any packets
client.rollKeys(time.Now())
client.rollKeys()
encrypted1 := client.Seal(nil, msg, 0x42, ad)
_, err = server.Open(nil, encrypted1, time.Now(), 0x42, protocol.KeyPhaseOne, ad)
Expect(err).To(MatchError("PROTOCOL_VIOLATION: keys updated too quickly"))
@@ -268,6 +268,36 @@ var _ = Describe("Updatable AEAD", func() {
serverTracer.EXPECT().UpdatedKey(protocol.KeyPhase(1), false)
Expect(server.KeyPhase()).To(Equal(protocol.KeyPhaseOne))
})
It("drops keys 3 PTOs after a key update", func() {
now := time.Now()
for i := 0; i < keyUpdateInterval; i++ {
pn := protocol.PacketNumber(i)
Expect(server.KeyPhase()).To(Equal(protocol.KeyPhaseZero))
server.Seal(nil, msg, pn, ad)
server.SetLargestAcked(pn)
}
// Now we've initiated the first key update.
// Decrypt a message sent from the client more than 3 PTO later to make sure the key is still there
threePTO := 3 * rttStats.PTO(false)
dataKeyPhaseZero := client.Seal(nil, msg, 1, ad)
_, err := server.Open(nil, dataKeyPhaseZero, now.Add(threePTO).Add(time.Second), 1, protocol.KeyPhaseZero, ad)
Expect(err).ToNot(HaveOccurred())
// Now receive a packet with key phase 1.
// This should start the timer to drop the keys after 3 PTOs.
client.rollKeys()
dataKeyPhaseOne := client.Seal(nil, msg, 10, ad)
t := now.Add(threePTO).Add(time.Second)
serverTracer.EXPECT().UpdatedKey(protocol.KeyPhase(1), true)
_, err = server.Open(nil, dataKeyPhaseOne, t, 10, protocol.KeyPhaseOne, ad)
Expect(err).ToNot(HaveOccurred())
// Make sure the keys are still here.
_, err = server.Open(nil, dataKeyPhaseZero, t.Add(threePTO*9/10), 1, protocol.KeyPhaseZero, ad)
Expect(err).ToNot(HaveOccurred())
serverTracer.EXPECT().DroppedKey(protocol.KeyPhase(0))
_, err = server.Open(nil, dataKeyPhaseZero, t.Add(threePTO).Add(time.Nanosecond), 1, protocol.KeyPhaseZero, ad)
Expect(err).To(MatchError(ErrKeysDropped))
})
})
Context("reading the key update env", func() {