From 1ef54db63f3205c6f1ceaa3b3dd69eacf200bdce Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 12 Jun 2019 21:41:40 +0800 Subject: [PATCH] check that the peer starts with key phase 0 after the handshake --- internal/handshake/updatable_aead.go | 9 ++++++++- internal/handshake/updatable_aead_test.go | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/internal/handshake/updatable_aead.go b/internal/handshake/updatable_aead.go index e5cf2f71f..153c1eb55 100644 --- a/internal/handshake/updatable_aead.go +++ b/internal/handshake/updatable_aead.go @@ -5,6 +5,8 @@ import ( "crypto/cipher" "encoding/binary" + "github.com/lucas-clemente/quic-go/internal/qerr" + "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/marten-seemann/qtls" ) @@ -94,7 +96,12 @@ func (a *updatableAEAD) Open(dst, src []byte, pn protocol.PacketNumber, kp proto binary.BigEndian.PutUint64(a.nonceBuf[len(a.nonceBuf)-8:], uint64(pn)) if kp != a.keyPhase { if a.firstRcvdWithCurrentKey == protocol.InvalidPacketNumber || pn < a.firstRcvdWithCurrentKey { - // TODO: check that prevRcv actually exists + if a.prevRcvAEAD == nil { + // This can only occur when the first packet received has key phase 1. + // This is an error, since the key phase starts at 0, + // and peers are only allowed to update keys after the handshake is confirmed. + return nil, qerr.Error(qerr.ProtocolViolation, "wrong initial keyphase") + } // we updated the key, but the peer hasn't updated yet dec, err := a.prevRcvAEAD.Open(dst, a.nonceBuf, src, ad) if err != nil { diff --git a/internal/handshake/updatable_aead_test.go b/internal/handshake/updatable_aead_test.go index 5a6cacdc8..7737cb04d 100644 --- a/internal/handshake/updatable_aead_test.go +++ b/internal/handshake/updatable_aead_test.go @@ -143,6 +143,13 @@ var _ = Describe("Updatable AEAD", func() { Expect(decrypted).To(Equal(msg)) Expect(server.KeyPhase()).To(Equal(protocol.KeyPhaseOne)) }) + + It("errors when the peer starts with key phase 1", func() { + client.rollKeys() + encrypted := client.Seal(nil, msg, 0x1337, ad) + _, err := server.Open(nil, encrypted, 0x1337, protocol.KeyPhaseOne, ad) + Expect(err).To(MatchError("PROTOCOL_VIOLATION: wrong initial keyphase")) + }) }) }) })