package quic import ( "bytes" "crypto/tls" "github.com/lucas-clemente/quic-go/internal/crypto" "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/testdata" "github.com/lucas-clemente/quic-go/internal/wire" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Packing and unpacking Initial packets", func() { var aead crypto.AEAD connID := protocol.ConnectionID(0x1337) ver := protocol.VersionTLS hdr := &wire.Header{ IsLongHeader: true, Type: protocol.PacketTypeRetry, PacketNumber: 0x42, ConnectionID: connID, Version: ver, } BeforeEach(func() { var err error aead, err = crypto.NewNullAEAD(protocol.PerspectiveServer, connID, ver) Expect(err).ToNot(HaveOccurred()) // set hdr.Raw buf := &bytes.Buffer{} err = hdr.Write(buf, protocol.PerspectiveServer, ver) Expect(err).ToNot(HaveOccurred()) hdr.Raw = buf.Bytes() }) Context("generating a mint.Config", func() { It("sets non-blocking mode", func() { mintConf, err := tlsToMintConfig(nil, protocol.PerspectiveClient) Expect(err).ToNot(HaveOccurred()) Expect(mintConf.NonBlocking).To(BeTrue()) }) It("sets the server name", func() { conf := &tls.Config{ServerName: "www.example.com"} mintConf, err := tlsToMintConfig(conf, protocol.PerspectiveClient) Expect(err).ToNot(HaveOccurred()) Expect(mintConf.ServerName).To(Equal("www.example.com")) }) It("sets the certificate chain", func() { tlsConf := testdata.GetTLSConfig() mintConf, err := tlsToMintConfig(tlsConf, protocol.PerspectiveClient) Expect(err).ToNot(HaveOccurred()) Expect(mintConf.Certificates).ToNot(BeEmpty()) Expect(mintConf.Certificates).To(HaveLen(len(tlsConf.Certificates))) }) It("requires client authentication", func() { mintConf, err := tlsToMintConfig(nil, protocol.PerspectiveClient) Expect(err).ToNot(HaveOccurred()) Expect(mintConf.RequireClientAuth).To(BeFalse()) conf := &tls.Config{ClientAuth: tls.RequireAnyClientCert} mintConf, err = tlsToMintConfig(conf, protocol.PerspectiveClient) Expect(err).ToNot(HaveOccurred()) Expect(mintConf.RequireClientAuth).To(BeTrue()) }) It("rejects unsupported client auth types", func() { conf := &tls.Config{ClientAuth: tls.RequireAndVerifyClientCert} _, err := tlsToMintConfig(conf, protocol.PerspectiveClient) Expect(err).To(MatchError("mint currently only support ClientAuthType RequireAnyClientCert")) }) }) Context("unpacking", func() { packPacket := func(frames []wire.Frame) []byte { buf := &bytes.Buffer{} err := hdr.Write(buf, protocol.PerspectiveClient, ver) Expect(err).ToNot(HaveOccurred()) payloadStartIndex := buf.Len() aeadCl, err := crypto.NewNullAEAD(protocol.PerspectiveClient, connID, ver) for _, f := range frames { err := f.Write(buf, ver) Expect(err).ToNot(HaveOccurred()) } raw := buf.Bytes() return aeadCl.Seal(raw[payloadStartIndex:payloadStartIndex], raw[payloadStartIndex:], hdr.PacketNumber, raw[:payloadStartIndex]) } It("unpacks a packet", func() { f := &wire.StreamFrame{ StreamID: 0, Data: []byte("foobar"), } p := packPacket([]wire.Frame{f}) frame, err := unpackInitialPacket(aead, hdr, p, ver) Expect(err).ToNot(HaveOccurred()) Expect(frame).To(Equal(f)) }) It("rejects a packet that doesn't contain a STREAM_FRAME", func() { p := packPacket([]wire.Frame{&wire.PingFrame{}}) _, err := unpackInitialPacket(aead, hdr, p, ver) Expect(err).To(MatchError("Packet doesn't contain a STREAM_FRAME")) }) It("rejects a packet that has a STREAM_FRAME for the wrong stream", func() { f := &wire.StreamFrame{ StreamID: 42, Data: []byte("foobar"), } p := packPacket([]wire.Frame{f}) _, err := unpackInitialPacket(aead, hdr, p, ver) Expect(err).To(MatchError("UnencryptedStreamData: received unencrypted stream data on stream 42")) }) It("rejects a packet that has a STREAM_FRAME with a non-zero offset", func() { f := &wire.StreamFrame{ StreamID: 0, Offset: 10, Data: []byte("foobar"), } p := packPacket([]wire.Frame{f}) _, err := unpackInitialPacket(aead, hdr, p, ver) Expect(err).To(MatchError("received stream data with non-zero offset")) }) }) Context("packing", func() { var unpacker *packetUnpacker BeforeEach(func() { aeadCl, err := crypto.NewNullAEAD(protocol.PerspectiveClient, connID, ver) Expect(err).ToNot(HaveOccurred()) unpacker = &packetUnpacker{aead: &nullAEAD{aeadCl}, version: ver} }) It("packs a packet", func() { f := &wire.StreamFrame{ Data: []byte("foobar"), FinBit: true, } data, err := packUnencryptedPacket(aead, hdr, f, protocol.PerspectiveServer) Expect(err).ToNot(HaveOccurred()) packet, err := unpacker.Unpack(hdr.Raw, hdr, data[len(hdr.Raw):]) Expect(err).ToNot(HaveOccurred()) Expect(packet.frames).To(Equal([]wire.Frame{f})) }) }) })