From 0b736b2cce6759728b1b84d3fdc1c3b8aeac9cda Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 13 Nov 2016 11:53:10 +0700 Subject: [PATCH] create forwardSecureAEAD after receiving all necessary values --- handshake/crypto_setup_client.go | 57 +++++++++++++++++++++++++-- handshake/crypto_setup_client_test.go | 37 ++++++++++++++++- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/handshake/crypto_setup_client.go b/handshake/crypto_setup_client.go index 8015357c8..53b8c24b4 100644 --- a/handshake/crypto_setup_client.go +++ b/handshake/crypto_setup_client.go @@ -29,8 +29,9 @@ type cryptoSetupClient struct { lastSentCHLO []byte certManager crypto.CertManager - keyDerivation KeyDerivationFunction - secureAEAD crypto.AEAD + keyDerivation KeyDerivationFunction + secureAEAD crypto.AEAD + forwardSecureAEAD crypto.AEAD } var _ crypto.AEAD = &cryptoSetupClient{} @@ -83,7 +84,10 @@ func (h *cryptoSetupClient) HandleCryptoStream() error { if messageTag == TagSHLO { utils.Debugf("Got SHLO:\n%s", printHandshakeMessage(cryptoData)) - panic("SHLOs not yet implemented.") + err = h.handleSHLOMessage(cryptoData) + if err != nil { + return err + } } if messageTag == TagREJ { @@ -134,7 +138,51 @@ func (h *cryptoSetupClient) handleREJMessage(cryptoData map[Tag][]byte) error { return nil } +func (h *cryptoSetupClient) handleSHLOMessage(cryptoData map[Tag][]byte) error { + serverPubs, ok := cryptoData[TagPUBS] + if !ok { + return qerr.Error(qerr.CryptoMessageParameterNotFound, "PUBS") + } + + if sno, ok := cryptoData[TagSNO]; ok { + h.sno = sno + } + + nonce := append(h.nonc, h.sno...) + + ephermalSharedSecret, err := h.serverConfig.kex.CalculateSharedKey(serverPubs) + if err != nil { + return err + } + + leafCert := h.certManager.GetLeafCert() + + h.forwardSecureAEAD, err = h.keyDerivation( + true, + ephermalSharedSecret, + nonce, + h.connID, + h.lastSentCHLO, + h.serverConfig.Get(), + leafCert, + nil, + protocol.PerspectiveClient, + ) + if err != nil { + return err + } + + return nil +} + func (h *cryptoSetupClient) Open(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, error) { + if h.forwardSecureAEAD != nil { + data, err := h.forwardSecureAEAD.Open(dst, src, packetNumber, associatedData) + if err == nil { + return data, nil + } + return nil, err + } if h.secureAEAD != nil { data, err := h.secureAEAD.Open(dst, src, packetNumber, associatedData) if err == nil { @@ -146,6 +194,9 @@ func (h *cryptoSetupClient) Open(dst, src []byte, packetNumber protocol.PacketNu } func (h *cryptoSetupClient) Seal(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) []byte { + if h.forwardSecureAEAD != nil { + return h.forwardSecureAEAD.Seal(dst, src, packetNumber, associatedData) + } if h.secureAEAD != nil { return h.secureAEAD.Seal(dst, src, packetNumber, associatedData) } diff --git a/handshake/crypto_setup_client_test.go b/handshake/crypto_setup_client_test.go index d722a070e..a35b643a1 100644 --- a/handshake/crypto_setup_client_test.go +++ b/handshake/crypto_setup_client_test.go @@ -40,7 +40,7 @@ var _ = Describe("Crypto setup", func() { cs.certManager = certManager }) - Context("Reading SHLOs", func() { + Context("Reading REJ", func() { var tagMap map[Tag][]byte BeforeEach(func() { @@ -134,6 +134,41 @@ var _ = Describe("Crypto setup", func() { }) }) + Context("Reading SHLO", func() { + var tagMap map[Tag][]byte + + BeforeEach(func() { + tagMap = make(map[Tag][]byte) + tagMap[TagPUBS] = []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f} + kex, err := crypto.NewCurve25519KEX() + Expect(err).ToNot(HaveOccurred()) + serverConfig := &serverConfigClient{ + kex: kex, + } + cs.serverConfig = serverConfig + }) + + It("rejects SHLOs without a PUBS", func() { + delete(tagMap, TagPUBS) + err := cs.handleSHLOMessage(tagMap) + Expect(err).To(MatchError(qerr.Error(qerr.CryptoMessageParameterNotFound, "PUBS"))) + }) + + It("reads the server nonce, if set", func() { + tagMap[TagSNO] = []byte("server nonce") + err := cs.handleSHLOMessage(tagMap) + Expect(err).ToNot(HaveOccurred()) + Expect(cs.sno).To(Equal(tagMap[TagSNO])) + }) + + It("creates a forwardSecureAEAD", func() { + tagMap[TagSNO] = []byte("server nonce") + err := cs.handleSHLOMessage(tagMap) + Expect(err).ToNot(HaveOccurred()) + Expect(cs.forwardSecureAEAD).ToNot(BeNil()) + }) + }) + Context("CHLO generation", func() { It("is longer than the miminum client hello size", func() { err := cs.sendCHLO()