From 4e1942a76e19395a2b8586c7c4a357f44d94014c Mon Sep 17 00:00:00 2001 From: Lucas Clemente Date: Tue, 19 Apr 2016 13:37:59 +0200 Subject: [PATCH] improve inchoate CHLO recognition --- handshake/crypto_setup.go | 16 ++++++++++++++-- handshake/crypto_setup_test.go | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/handshake/crypto_setup.go b/handshake/crypto_setup.go index d1ffad47..e06130f1 100644 --- a/handshake/crypto_setup.go +++ b/handshake/crypto_setup.go @@ -66,7 +66,7 @@ func (h *CryptoSetup) HandleCryptoStream() { chloData := cachingReader.Get() var reply []byte - if scid, ok := cryptoData[TagSCID]; ok && bytes.Equal(h.scfg.ID, scid) { + if !h.isInchoateCHLO(cryptoData) { // We have a CHLO with a proper server config ID, do a 0-RTT handshake reply, err = h.handleCHLO(chloData, cryptoData) if err != nil { @@ -81,7 +81,7 @@ func (h *CryptoSetup) HandleCryptoStream() { return } - // We have an inacholate or non-matching CHLO, we now send a rejection + // We have an inchoate or non-matching CHLO, we now send a rejection reply, err = h.handleInchoateCHLO(chloData) if err != nil { fmt.Printf("error in crypto stream (TODO: handle): %s", err.Error()) @@ -130,6 +130,18 @@ func (h *CryptoSetup) Seal(packetNumber protocol.PacketNumber, associatedData [] } } +func (h *CryptoSetup) isInchoateCHLO(cryptoData map[Tag][]byte) bool { + scid, ok := cryptoData[TagSCID] + if !ok || !bytes.Equal(h.scfg.ID, scid) { + return true + } + sno, ok := cryptoData[TagSNO] + if !ok || !bytes.Equal(h.nonce, sno) { + return true + } + return false +} + func (h *CryptoSetup) handleInchoateCHLO(data []byte) ([]byte, error) { var chloOrNil []byte if h.version > protocol.VersionNumber(30) { diff --git a/handshake/crypto_setup_test.go b/handshake/crypto_setup_test.go index ae75c481..215b09c5 100644 --- a/handshake/crypto_setup_test.go +++ b/handshake/crypto_setup_test.go @@ -138,18 +138,30 @@ var _ = Describe("Crypto setup", func() { It("handles long handshake", func() { WriteHandshakeMessage(&stream.dataToRead, TagCHLO, map[Tag][]byte{}) - WriteHandshakeMessage(&stream.dataToRead, TagCHLO, map[Tag][]byte{TagSCID: scfg.ID}) + WriteHandshakeMessage(&stream.dataToRead, TagCHLO, map[Tag][]byte{TagSCID: scfg.ID, TagSNO: cs.nonce}) cs.HandleCryptoStream() Expect(stream.dataWritten.Bytes()).To(HavePrefix("REJ")) Expect(stream.dataWritten.Bytes()).To(ContainSubstring("SHLO")) }) It("handles 0-RTT handshake", func() { - WriteHandshakeMessage(&stream.dataToRead, TagCHLO, map[Tag][]byte{TagSCID: scfg.ID}) + WriteHandshakeMessage(&stream.dataToRead, TagCHLO, map[Tag][]byte{TagSCID: scfg.ID, TagSNO: cs.nonce}) cs.HandleCryptoStream() Expect(stream.dataWritten.Bytes()).To(HavePrefix("SHLO")) Expect(stream.dataWritten.Bytes()).ToNot(ContainSubstring("REJ")) }) + + It("recognizes inchoate CHLOs missing SCID", func() { + Expect(cs.isInchoateCHLO(map[Tag][]byte{TagSNO: cs.nonce})).To(BeTrue()) + }) + + It("recognizes inchoate CHLOs missing SNO", func() { + Expect(cs.isInchoateCHLO(map[Tag][]byte{TagSCID: scfg.ID})).To(BeTrue()) + }) + + It("recognizes proper CHLOs", func() { + Expect(cs.isInchoateCHLO(map[Tag][]byte{TagSCID: scfg.ID, TagSNO: cs.nonce})).To(BeFalse()) + }) }) Context("escalating crypto", func() {