Merge pull request #922 from lucas-clemente/fix-920

reject packets that use the wrong or unknown packet types
This commit is contained in:
Marten Seemann
2017-11-02 21:28:20 +07:00
committed by GitHub
3 changed files with 56 additions and 26 deletions

View File

@@ -63,13 +63,13 @@ var _ = Describe("Header", func() {
buf := &bytes.Buffer{}
err := (&Header{
IsLongHeader: true,
Type: 3,
Type: protocol.PacketType0RTT,
PacketNumber: 0x42,
}).writeHeader(buf)
Expect(err).ToNot(HaveOccurred())
hdr, err := ParseHeader(bytes.NewReader(buf.Bytes()), protocol.PerspectiveClient, protocol.VersionUnknown)
Expect(err).ToNot(HaveOccurred())
Expect(hdr.Type).To(BeEquivalentTo(3))
Expect(hdr.Type).To(Equal(protocol.PacketType0RTT))
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0x42)))
Expect(hdr.isPublicHeader).To(BeFalse())
})

View File

@@ -21,7 +21,7 @@ func parseHeader(b *bytes.Reader, packetSentBy protocol.Perspective) (*Header, e
return parseShortHeader(b, typeByte)
}
func parseLongHeader(b *bytes.Reader, packetSentBy protocol.Perspective, typeByte byte) (*Header, error) {
func parseLongHeader(b *bytes.Reader, sentBy protocol.Perspective, typeByte byte) (*Header, error) {
connID, err := utils.BigEndian.ReadUint64(b)
if err != nil {
return nil, err
@@ -34,18 +34,25 @@ func parseLongHeader(b *bytes.Reader, packetSentBy protocol.Perspective, typeByt
if err != nil {
return nil, err
}
packetType := protocol.PacketType(typeByte & 0x7f)
if sentBy == protocol.PerspectiveClient && (packetType != protocol.PacketTypeInitial && packetType != protocol.PacketTypeCleartext && packetType != protocol.PacketType0RTT) {
if packetType == protocol.PacketTypeVersionNegotiation {
return nil, qerr.Error(qerr.InvalidVersionNegotiationPacket, "sent by the client")
}
return nil, qerr.Error(qerr.InvalidPacketHeader, fmt.Sprintf("Received packet with invalid packet type: %d", packetType))
}
if sentBy == protocol.PerspectiveServer && (packetType != protocol.PacketTypeVersionNegotiation && packetType != protocol.PacketTypeRetry && packetType != protocol.PacketTypeCleartext) {
return nil, qerr.Error(qerr.InvalidPacketHeader, fmt.Sprintf("Received packet with invalid packet type: %d", packetType))
}
h := &Header{
Type: protocol.PacketType(typeByte & 0x7f),
Type: packetType,
IsLongHeader: true,
ConnectionID: protocol.ConnectionID(connID),
PacketNumber: protocol.PacketNumber(pn),
PacketNumberLen: protocol.PacketNumberLen4,
Version: protocol.VersionNumber(v),
}
if h.Type == 0x1 { // Version Negotiation Packet
if packetSentBy == protocol.PerspectiveClient {
return nil, qerr.Error(qerr.InvalidVersionNegotiationPacket, "sent by the client")
}
if h.Type == protocol.PacketTypeVersionNegotiation {
if b.Len() == 0 {
return nil, qerr.Error(qerr.InvalidVersionNegotiationPacket, "empty version list")
}

View File

@@ -2,6 +2,7 @@ package wire
import (
"bytes"
"fmt"
"io"
"log"
"os"
@@ -17,22 +18,20 @@ import (
var _ = Describe("IETF draft Header", func() {
Context("parsing", func() {
Context("long headers", func() {
var data []byte
BeforeEach(func() {
data = []byte{
0x80 ^ 0x3,
generatePacket := func(t protocol.PacketType) []byte {
return []byte{
0x80 ^ uint8(t),
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID
0xde, 0xca, 0xfb, 0xad, // packet number
0x1, 0x2, 0x3, 0x4, // version number
}
})
}
It("parses a long header", func() {
b := bytes.NewReader(data)
b := bytes.NewReader(generatePacket(protocol.PacketTypeInitial))
h, err := parseHeader(b, protocol.PerspectiveClient)
Expect(err).ToNot(HaveOccurred())
Expect(h.Type).To(Equal(protocol.PacketType(3)))
Expect(h.Type).To(Equal(protocol.PacketTypeInitial))
Expect(h.IsLongHeader).To(BeTrue())
Expect(h.OmitConnectionID).To(BeFalse())
Expect(h.ConnectionID).To(Equal(protocol.ConnectionID(0xdeadbeefcafe1337)))
@@ -42,7 +41,26 @@ var _ = Describe("IETF draft Header", func() {
Expect(b.Len()).To(BeZero())
})
It("rejects packets sent by the client that use packet types for packets sent by the server", func() {
b := bytes.NewReader(generatePacket(protocol.PacketTypeRetry))
_, err := parseHeader(b, protocol.PerspectiveClient)
Expect(err).To(MatchError(fmt.Sprintf("InvalidPacketHeader: Received packet with invalid packet type: %d", protocol.PacketTypeRetry)))
})
It("rejects packets sent by the client that use packet types for packets sent by the server", func() {
b := bytes.NewReader(generatePacket(protocol.PacketType0RTT))
_, err := parseHeader(b, protocol.PerspectiveServer)
Expect(err).To(MatchError(fmt.Sprintf("InvalidPacketHeader: Received packet with invalid packet type: %d", protocol.PacketType0RTT)))
})
It("rejects packets sent with an unknown packet type", func() {
b := bytes.NewReader(generatePacket(42))
_, err := parseHeader(b, protocol.PerspectiveServer)
Expect(err).To(MatchError("InvalidPacketHeader: Received packet with invalid packet type: 42"))
})
It("errors on EOF", func() {
data := generatePacket(protocol.PacketTypeInitial)
for i := 0; i < len(data); i++ {
_, err := parseHeader(bytes.NewReader(data[:i]), protocol.PerspectiveClient)
Expect(err).To(Equal(io.EOF))
@@ -50,14 +68,13 @@ var _ = Describe("IETF draft Header", func() {
})
Context("Version Negotiation Packets", func() {
BeforeEach(func() {
data[0] = 0x80 ^ 0x1 // set the type byte to Version Negotiation Packet
})
It("parses", func() {
data = append(data, []byte{
0x22, 0x33, 0x44, 0x55,
0x33, 0x44, 0x55, 0x66}...,
data := append(
generatePacket(protocol.PacketTypeVersionNegotiation),
[]byte{
0x22, 0x33, 0x44, 0x55,
0x33, 0x44, 0x55, 0x66,
}...,
)
b := bytes.NewReader(data)
h, err := parseHeader(b, protocol.PerspectiveServer)
@@ -70,21 +87,27 @@ var _ = Describe("IETF draft Header", func() {
})
It("errors if it contains versions of the wrong length", func() {
data = append(data, []byte{0x22, 0x33}...) // too short. Should be 4 bytes.
data := append(
generatePacket(protocol.PacketTypeVersionNegotiation),
[]byte{0x22, 0x33}..., // too short. Should be 4 bytes.
)
b := bytes.NewReader(data)
_, err := parseHeader(b, protocol.PerspectiveServer)
Expect(err).To(MatchError(qerr.InvalidVersionNegotiationPacket))
})
It("errors if it was sent by the client", func() {
data = append(data, []byte{0x22, 0x33, 0x44, 0x55}...)
data := append(
generatePacket(protocol.PacketTypeVersionNegotiation),
[]byte{0x22, 0x33, 0x44, 0x55}...,
)
b := bytes.NewReader(data)
_, err := parseHeader(b, protocol.PerspectiveClient)
Expect(err).To(MatchError("InvalidVersionNegotiationPacket: sent by the client"))
})
It("errors if the version list is emtpy", func() {
b := bytes.NewReader(data)
b := bytes.NewReader(generatePacket(protocol.PacketTypeVersionNegotiation))
_, err := parseHeader(b, protocol.PerspectiveServer)
Expect(err).To(MatchError("InvalidVersionNegotiationPacket: empty version list"))
})