packet_unpacker.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package quic
  2. import (
  3. "bytes"
  4. "fmt"
  5. "time"
  6. "github.com/Psiphon-Labs/quic-go/internal/handshake"
  7. "github.com/Psiphon-Labs/quic-go/internal/protocol"
  8. "github.com/Psiphon-Labs/quic-go/internal/wire"
  9. )
  10. type headerDecryptor interface {
  11. DecryptHeader(sample []byte, firstByte *byte, pnBytes []byte)
  12. }
  13. type headerParseError struct {
  14. err error
  15. }
  16. func (e *headerParseError) Unwrap() error {
  17. return e.err
  18. }
  19. func (e *headerParseError) Error() string {
  20. return e.err.Error()
  21. }
  22. type unpackedPacket struct {
  23. packetNumber protocol.PacketNumber // the decoded packet number
  24. hdr *wire.ExtendedHeader
  25. encryptionLevel protocol.EncryptionLevel
  26. data []byte
  27. }
  28. // The packetUnpacker unpacks QUIC packets.
  29. type packetUnpacker struct {
  30. cs handshake.CryptoSetup
  31. version protocol.VersionNumber
  32. }
  33. var _ unpacker = &packetUnpacker{}
  34. func newPacketUnpacker(cs handshake.CryptoSetup, version protocol.VersionNumber) unpacker {
  35. return &packetUnpacker{
  36. cs: cs,
  37. version: version,
  38. }
  39. }
  40. // If the reserved bits are invalid, the error is wire.ErrInvalidReservedBits.
  41. // If any other error occurred when parsing the header, the error is of type headerParseError.
  42. // If decrypting the payload fails for any reason, the error is the error returned by the AEAD.
  43. func (u *packetUnpacker) Unpack(hdr *wire.Header, rcvTime time.Time, data []byte) (*unpackedPacket, error) {
  44. var encLevel protocol.EncryptionLevel
  45. var extHdr *wire.ExtendedHeader
  46. var decrypted []byte
  47. //nolint:exhaustive // Retry packets can't be unpacked.
  48. switch hdr.Type {
  49. case protocol.PacketTypeInitial:
  50. encLevel = protocol.EncryptionInitial
  51. opener, err := u.cs.GetInitialOpener()
  52. if err != nil {
  53. return nil, err
  54. }
  55. extHdr, decrypted, err = u.unpackLongHeaderPacket(opener, hdr, data)
  56. if err != nil {
  57. return nil, err
  58. }
  59. case protocol.PacketTypeHandshake:
  60. encLevel = protocol.EncryptionHandshake
  61. opener, err := u.cs.GetHandshakeOpener()
  62. if err != nil {
  63. return nil, err
  64. }
  65. extHdr, decrypted, err = u.unpackLongHeaderPacket(opener, hdr, data)
  66. if err != nil {
  67. return nil, err
  68. }
  69. case protocol.PacketType0RTT:
  70. encLevel = protocol.Encryption0RTT
  71. opener, err := u.cs.Get0RTTOpener()
  72. if err != nil {
  73. return nil, err
  74. }
  75. extHdr, decrypted, err = u.unpackLongHeaderPacket(opener, hdr, data)
  76. if err != nil {
  77. return nil, err
  78. }
  79. default:
  80. if hdr.IsLongHeader {
  81. return nil, fmt.Errorf("unknown packet type: %s", hdr.Type)
  82. }
  83. encLevel = protocol.Encryption1RTT
  84. opener, err := u.cs.Get1RTTOpener()
  85. if err != nil {
  86. return nil, err
  87. }
  88. extHdr, decrypted, err = u.unpackShortHeaderPacket(opener, hdr, rcvTime, data)
  89. if err != nil {
  90. return nil, err
  91. }
  92. }
  93. return &unpackedPacket{
  94. hdr: extHdr,
  95. packetNumber: extHdr.PacketNumber,
  96. encryptionLevel: encLevel,
  97. data: decrypted,
  98. }, nil
  99. }
  100. func (u *packetUnpacker) unpackLongHeaderPacket(opener handshake.LongHeaderOpener, hdr *wire.Header, data []byte) (*wire.ExtendedHeader, []byte, error) {
  101. extHdr, parseErr := u.unpackHeader(opener, hdr, data)
  102. // If the reserved bits are set incorrectly, we still need to continue unpacking.
  103. // This avoids a timing side-channel, which otherwise might allow an attacker
  104. // to gain information about the header encryption.
  105. if parseErr != nil && parseErr != wire.ErrInvalidReservedBits {
  106. return nil, nil, parseErr
  107. }
  108. extHdrLen := extHdr.ParsedLen()
  109. extHdr.PacketNumber = opener.DecodePacketNumber(extHdr.PacketNumber, extHdr.PacketNumberLen)
  110. decrypted, err := opener.Open(data[extHdrLen:extHdrLen], data[extHdrLen:], extHdr.PacketNumber, data[:extHdrLen])
  111. if err != nil {
  112. return nil, nil, err
  113. }
  114. if parseErr != nil {
  115. return nil, nil, parseErr
  116. }
  117. return extHdr, decrypted, nil
  118. }
  119. func (u *packetUnpacker) unpackShortHeaderPacket(
  120. opener handshake.ShortHeaderOpener,
  121. hdr *wire.Header,
  122. rcvTime time.Time,
  123. data []byte,
  124. ) (*wire.ExtendedHeader, []byte, error) {
  125. extHdr, parseErr := u.unpackHeader(opener, hdr, data)
  126. // If the reserved bits are set incorrectly, we still need to continue unpacking.
  127. // This avoids a timing side-channel, which otherwise might allow an attacker
  128. // to gain information about the header encryption.
  129. if parseErr != nil && parseErr != wire.ErrInvalidReservedBits {
  130. return nil, nil, parseErr
  131. }
  132. extHdr.PacketNumber = opener.DecodePacketNumber(extHdr.PacketNumber, extHdr.PacketNumberLen)
  133. extHdrLen := extHdr.ParsedLen()
  134. decrypted, err := opener.Open(data[extHdrLen:extHdrLen], data[extHdrLen:], rcvTime, extHdr.PacketNumber, extHdr.KeyPhase, data[:extHdrLen])
  135. if err != nil {
  136. return nil, nil, err
  137. }
  138. if parseErr != nil {
  139. return nil, nil, parseErr
  140. }
  141. return extHdr, decrypted, nil
  142. }
  143. // The error is either nil, a wire.ErrInvalidReservedBits or of type headerParseError.
  144. func (u *packetUnpacker) unpackHeader(hd headerDecryptor, hdr *wire.Header, data []byte) (*wire.ExtendedHeader, error) {
  145. extHdr, err := unpackHeader(hd, hdr, data, u.version)
  146. if err != nil && err != wire.ErrInvalidReservedBits {
  147. return nil, &headerParseError{err: err}
  148. }
  149. return extHdr, err
  150. }
  151. func unpackHeader(hd headerDecryptor, hdr *wire.Header, data []byte, version protocol.VersionNumber) (*wire.ExtendedHeader, error) {
  152. r := bytes.NewReader(data)
  153. hdrLen := hdr.ParsedLen()
  154. if protocol.ByteCount(len(data)) < hdrLen+4+16 {
  155. //nolint:stylecheck
  156. return nil, fmt.Errorf("Packet too small. Expected at least 20 bytes after the header, got %d", protocol.ByteCount(len(data))-hdrLen)
  157. }
  158. // The packet number can be up to 4 bytes long, but we won't know the length until we decrypt it.
  159. // 1. save a copy of the 4 bytes
  160. origPNBytes := make([]byte, 4)
  161. copy(origPNBytes, data[hdrLen:hdrLen+4])
  162. // 2. decrypt the header, assuming a 4 byte packet number
  163. hd.DecryptHeader(
  164. data[hdrLen+4:hdrLen+4+16],
  165. &data[0],
  166. data[hdrLen:hdrLen+4],
  167. )
  168. // 3. parse the header (and learn the actual length of the packet number)
  169. extHdr, parseErr := hdr.ParseExtended(r, version)
  170. if parseErr != nil && parseErr != wire.ErrInvalidReservedBits {
  171. return nil, parseErr
  172. }
  173. // 4. if the packet number is shorter than 4 bytes, replace the remaining bytes with the copy we saved earlier
  174. if extHdr.PacketNumberLen != protocol.PacketNumberLen4 {
  175. copy(data[extHdr.ParsedLen():hdrLen+4], origPNBytes[int(extHdr.PacketNumberLen):])
  176. }
  177. return extHdr, parseErr
  178. }