packet.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright (c) 2014, Yawning Angel <yawning at torproject dot org>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. *
  11. * * Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  19. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. * POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. package obfs4
  28. import (
  29. "crypto/sha256"
  30. "encoding/binary"
  31. "fmt"
  32. "io"
  33. "gitlab.com/yawning/obfs4.git/common/drbg"
  34. "gitlab.com/yawning/obfs4.git/transports/obfs4/framing"
  35. )
  36. const (
  37. packetOverhead = 2 + 1
  38. maxPacketPayloadLength = framing.MaximumFramePayloadLength - packetOverhead
  39. maxPacketPaddingLength = maxPacketPayloadLength
  40. seedPacketPayloadLength = seedLength
  41. consumeReadSize = framing.MaximumSegmentLength * 16
  42. )
  43. const (
  44. packetTypePayload = iota
  45. packetTypePrngSeed
  46. )
  47. // InvalidPacketLengthError is the error returned when decodePacket detects a
  48. // invalid packet length/
  49. type InvalidPacketLengthError int
  50. func (e InvalidPacketLengthError) Error() string {
  51. return fmt.Sprintf("packet: Invalid packet length: %d", int(e))
  52. }
  53. // InvalidPayloadLengthError is the error returned when decodePacket rejects the
  54. // payload length.
  55. type InvalidPayloadLengthError int
  56. func (e InvalidPayloadLengthError) Error() string {
  57. return fmt.Sprintf("packet: Invalid payload length: %d", int(e))
  58. }
  59. var zeroPadBytes [maxPacketPaddingLength]byte
  60. func (conn *obfs4Conn) makePacket(w io.Writer, pktType uint8, data []byte, padLen uint16) error {
  61. var pkt [framing.MaximumFramePayloadLength]byte
  62. if len(data)+int(padLen) > maxPacketPayloadLength {
  63. panic(fmt.Sprintf("BUG: makePacket() len(data) + padLen > maxPacketPayloadLength: %d + %d > %d",
  64. len(data), padLen, maxPacketPayloadLength))
  65. }
  66. // Packets are:
  67. // uint8_t type packetTypePayload (0x00)
  68. // uint16_t length Length of the payload (Big Endian).
  69. // uint8_t[] payload Data payload.
  70. // uint8_t[] padding Padding.
  71. pkt[0] = pktType
  72. binary.BigEndian.PutUint16(pkt[1:], uint16(len(data)))
  73. if len(data) > 0 {
  74. copy(pkt[3:], data[:])
  75. }
  76. copy(pkt[3+len(data):], zeroPadBytes[:padLen])
  77. pktLen := packetOverhead + len(data) + int(padLen)
  78. // Encode the packet in an AEAD frame.
  79. var frame [framing.MaximumSegmentLength]byte
  80. frameLen, err := conn.encoder.Encode(frame[:], pkt[:pktLen])
  81. if err != nil {
  82. // All encoder errors are fatal.
  83. return err
  84. }
  85. wrLen, err := w.Write(frame[:frameLen])
  86. if err != nil {
  87. return err
  88. } else if wrLen < frameLen {
  89. return io.ErrShortWrite
  90. }
  91. return nil
  92. }
  93. func (conn *obfs4Conn) readPackets() (err error) {
  94. // Attempt to read off the network.
  95. rdLen, rdErr := conn.Conn.Read(conn.readBuffer)
  96. conn.receiveBuffer.Write(conn.readBuffer[:rdLen])
  97. var decoded [framing.MaximumFramePayloadLength]byte
  98. for conn.receiveBuffer.Len() > 0 {
  99. // Decrypt an AEAD frame.
  100. decLen := 0
  101. decLen, err = conn.decoder.Decode(decoded[:], conn.receiveBuffer)
  102. if err == framing.ErrAgain {
  103. break
  104. } else if err != nil {
  105. break
  106. } else if decLen < packetOverhead {
  107. err = InvalidPacketLengthError(decLen)
  108. break
  109. }
  110. // Decode the packet.
  111. pkt := decoded[0:decLen]
  112. pktType := pkt[0]
  113. payloadLen := binary.BigEndian.Uint16(pkt[1:])
  114. if int(payloadLen) > len(pkt)-packetOverhead {
  115. err = InvalidPayloadLengthError(int(payloadLen))
  116. break
  117. }
  118. payload := pkt[3 : 3+payloadLen]
  119. switch pktType {
  120. case packetTypePayload:
  121. if payloadLen > 0 {
  122. conn.receiveDecodedBuffer.Write(payload)
  123. }
  124. case packetTypePrngSeed:
  125. // Only regenerate the distribution if we are the client.
  126. if len(payload) == seedPacketPayloadLength && !conn.isServer {
  127. var seed *drbg.Seed
  128. seed, err = drbg.SeedFromBytes(payload)
  129. if err != nil {
  130. break
  131. }
  132. conn.lenDist.Reset(seed)
  133. if conn.iatDist != nil {
  134. iatSeedSrc := sha256.Sum256(seed.Bytes()[:])
  135. iatSeed, err := drbg.SeedFromBytes(iatSeedSrc[:])
  136. if err != nil {
  137. break
  138. }
  139. conn.iatDist.Reset(iatSeed)
  140. }
  141. }
  142. default:
  143. // Ignore unknown packet types.
  144. }
  145. }
  146. // Read errors (all fatal) take priority over various frame processing
  147. // errors.
  148. if rdErr != nil {
  149. return rdErr
  150. }
  151. return
  152. }