packet_unpacker.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package quic
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/lucas-clemente/quic-go/internal/handshake"
  6. "github.com/lucas-clemente/quic-go/internal/protocol"
  7. "github.com/lucas-clemente/quic-go/internal/utils"
  8. "github.com/lucas-clemente/quic-go/internal/wire"
  9. )
  10. type unpackedPacket struct {
  11. packetNumber protocol.PacketNumber // the decoded packet number
  12. hdr *wire.ExtendedHeader
  13. encryptionLevel protocol.EncryptionLevel
  14. data []byte
  15. }
  16. // The packetUnpacker unpacks QUIC packets.
  17. type packetUnpacker struct {
  18. cs handshake.CryptoSetup
  19. largestRcvdPacketNumber protocol.PacketNumber
  20. version protocol.VersionNumber
  21. }
  22. var _ unpacker = &packetUnpacker{}
  23. func newPacketUnpacker(cs handshake.CryptoSetup, version protocol.VersionNumber) unpacker {
  24. return &packetUnpacker{
  25. cs: cs,
  26. version: version,
  27. }
  28. }
  29. func (u *packetUnpacker) Unpack(hdr *wire.Header, data []byte) (*unpackedPacket, error) {
  30. r := bytes.NewReader(data)
  31. var encLevel protocol.EncryptionLevel
  32. switch hdr.Type {
  33. case protocol.PacketTypeInitial:
  34. encLevel = protocol.EncryptionInitial
  35. case protocol.PacketTypeHandshake:
  36. encLevel = protocol.EncryptionHandshake
  37. default:
  38. if hdr.IsLongHeader {
  39. return nil, fmt.Errorf("unknown packet type: %s", hdr.Type)
  40. }
  41. encLevel = protocol.Encryption1RTT
  42. }
  43. opener, err := u.cs.GetOpener(encLevel)
  44. if err != nil {
  45. return nil, err
  46. }
  47. hdrLen := int(hdr.ParsedLen())
  48. if len(data) < hdrLen+4+16 {
  49. return nil, fmt.Errorf("Packet too small. Expected at least 20 bytes after the header, got %d", len(data)-hdrLen)
  50. }
  51. // The packet number can be up to 4 bytes long, but we won't know the length until we decrypt it.
  52. // 1. save a copy of the 4 bytes
  53. origPNBytes := make([]byte, 4)
  54. copy(origPNBytes, data[hdrLen:hdrLen+4])
  55. // 2. decrypt the header, assuming a 4 byte packet number
  56. opener.DecryptHeader(
  57. data[hdrLen+4:hdrLen+4+16],
  58. &data[0],
  59. data[hdrLen:hdrLen+4],
  60. )
  61. // 3. parse the header (and learn the actual length of the packet number)
  62. extHdr, err := hdr.ParseExtended(r, u.version)
  63. if err != nil {
  64. return nil, fmt.Errorf("error parsing extended header: %s", err)
  65. }
  66. extHdrLen := hdrLen + int(extHdr.PacketNumberLen)
  67. // 4. if the packet number is shorter than 4 bytes, replace the remaining bytes with the copy we saved earlier
  68. if extHdr.PacketNumberLen != protocol.PacketNumberLen4 {
  69. copy(data[extHdrLen:hdrLen+4], origPNBytes[int(extHdr.PacketNumberLen):])
  70. }
  71. pn := protocol.DecodePacketNumber(
  72. extHdr.PacketNumberLen,
  73. u.largestRcvdPacketNumber,
  74. extHdr.PacketNumber,
  75. )
  76. decrypted, err := opener.Open(data[extHdrLen:extHdrLen], data[extHdrLen:], pn, data[:extHdrLen])
  77. if err != nil {
  78. return nil, err
  79. }
  80. // Only do this after decrypting, so we are sure the packet is not attacker-controlled
  81. u.largestRcvdPacketNumber = utils.MaxPacketNumber(u.largestRcvdPacketNumber, pn)
  82. return &unpackedPacket{
  83. hdr: extHdr,
  84. packetNumber: pn,
  85. encryptionLevel: encLevel,
  86. data: decrypted,
  87. }, nil
  88. }