conn.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. package vmess
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "crypto/hmac"
  7. "crypto/md5"
  8. "crypto/rand"
  9. "crypto/sha256"
  10. "encoding/binary"
  11. "errors"
  12. "hash/fnv"
  13. "io"
  14. "net"
  15. "time"
  16. "github.com/metacubex/randv2"
  17. "golang.org/x/crypto/chacha20poly1305"
  18. )
  19. // Conn wrapper a net.Conn with vmess protocol
  20. type Conn struct {
  21. net.Conn
  22. reader io.Reader
  23. writer io.Writer
  24. dst *DstAddr
  25. id *ID
  26. reqBodyIV []byte
  27. reqBodyKey []byte
  28. respBodyIV []byte
  29. respBodyKey []byte
  30. respV byte
  31. security byte
  32. isAead bool
  33. received bool
  34. }
  35. func (vc *Conn) Write(b []byte) (int, error) {
  36. return vc.writer.Write(b)
  37. }
  38. func (vc *Conn) Read(b []byte) (int, error) {
  39. if vc.received {
  40. return vc.reader.Read(b)
  41. }
  42. if err := vc.recvResponse(); err != nil {
  43. return 0, err
  44. }
  45. vc.received = true
  46. return vc.reader.Read(b)
  47. }
  48. func (vc *Conn) sendRequest() error {
  49. timestamp := time.Now()
  50. mbuf := &bytes.Buffer{}
  51. if !vc.isAead {
  52. h := hmac.New(md5.New, vc.id.UUID.Bytes())
  53. binary.Write(h, binary.BigEndian, uint64(timestamp.Unix()))
  54. mbuf.Write(h.Sum(nil))
  55. }
  56. buf := &bytes.Buffer{}
  57. // Ver IV Key V Opt
  58. buf.WriteByte(Version)
  59. buf.Write(vc.reqBodyIV[:])
  60. buf.Write(vc.reqBodyKey[:])
  61. buf.WriteByte(vc.respV)
  62. buf.WriteByte(OptionChunkStream)
  63. p := randv2.IntN(16)
  64. // P Sec Reserve Cmd
  65. buf.WriteByte(byte(p<<4) | byte(vc.security))
  66. buf.WriteByte(0)
  67. if vc.dst.UDP {
  68. buf.WriteByte(CommandUDP)
  69. } else {
  70. buf.WriteByte(CommandTCP)
  71. }
  72. // Port AddrType Addr
  73. binary.Write(buf, binary.BigEndian, uint16(vc.dst.Port))
  74. buf.WriteByte(vc.dst.AddrType)
  75. buf.Write(vc.dst.Addr)
  76. // padding
  77. if p > 0 {
  78. padding := make([]byte, p)
  79. rand.Read(padding)
  80. buf.Write(padding)
  81. }
  82. fnv1a := fnv.New32a()
  83. fnv1a.Write(buf.Bytes())
  84. buf.Write(fnv1a.Sum(nil))
  85. if !vc.isAead {
  86. block, err := aes.NewCipher(vc.id.CmdKey)
  87. if err != nil {
  88. return err
  89. }
  90. stream := cipher.NewCFBEncrypter(block, hashTimestamp(timestamp))
  91. stream.XORKeyStream(buf.Bytes(), buf.Bytes())
  92. mbuf.Write(buf.Bytes())
  93. _, err = vc.Conn.Write(mbuf.Bytes())
  94. return err
  95. }
  96. var fixedLengthCmdKey [16]byte
  97. copy(fixedLengthCmdKey[:], vc.id.CmdKey)
  98. vmessout := sealVMessAEADHeader(fixedLengthCmdKey, buf.Bytes(), timestamp)
  99. _, err := vc.Conn.Write(vmessout)
  100. return err
  101. }
  102. func (vc *Conn) recvResponse() error {
  103. var buf []byte
  104. if !vc.isAead {
  105. block, err := aes.NewCipher(vc.respBodyKey[:])
  106. if err != nil {
  107. return err
  108. }
  109. stream := cipher.NewCFBDecrypter(block, vc.respBodyIV[:])
  110. buf = make([]byte, 4)
  111. _, err = io.ReadFull(vc.Conn, buf)
  112. if err != nil {
  113. return err
  114. }
  115. stream.XORKeyStream(buf, buf)
  116. } else {
  117. aeadResponseHeaderLengthEncryptionKey := kdf(vc.respBodyKey[:], kdfSaltConstAEADRespHeaderLenKey)[:16]
  118. aeadResponseHeaderLengthEncryptionIV := kdf(vc.respBodyIV[:], kdfSaltConstAEADRespHeaderLenIV)[:12]
  119. aeadResponseHeaderLengthEncryptionKeyAESBlock, _ := aes.NewCipher(aeadResponseHeaderLengthEncryptionKey)
  120. aeadResponseHeaderLengthEncryptionAEAD, _ := cipher.NewGCM(aeadResponseHeaderLengthEncryptionKeyAESBlock)
  121. aeadEncryptedResponseHeaderLength := make([]byte, 18)
  122. if _, err := io.ReadFull(vc.Conn, aeadEncryptedResponseHeaderLength); err != nil {
  123. return err
  124. }
  125. decryptedResponseHeaderLengthBinaryBuffer, err := aeadResponseHeaderLengthEncryptionAEAD.Open(nil, aeadResponseHeaderLengthEncryptionIV, aeadEncryptedResponseHeaderLength[:], nil)
  126. if err != nil {
  127. return err
  128. }
  129. decryptedResponseHeaderLength := binary.BigEndian.Uint16(decryptedResponseHeaderLengthBinaryBuffer)
  130. aeadResponseHeaderPayloadEncryptionKey := kdf(vc.respBodyKey[:], kdfSaltConstAEADRespHeaderPayloadKey)[:16]
  131. aeadResponseHeaderPayloadEncryptionIV := kdf(vc.respBodyIV[:], kdfSaltConstAEADRespHeaderPayloadIV)[:12]
  132. aeadResponseHeaderPayloadEncryptionKeyAESBlock, _ := aes.NewCipher(aeadResponseHeaderPayloadEncryptionKey)
  133. aeadResponseHeaderPayloadEncryptionAEAD, _ := cipher.NewGCM(aeadResponseHeaderPayloadEncryptionKeyAESBlock)
  134. encryptedResponseHeaderBuffer := make([]byte, decryptedResponseHeaderLength+16)
  135. if _, err := io.ReadFull(vc.Conn, encryptedResponseHeaderBuffer); err != nil {
  136. return err
  137. }
  138. buf, err = aeadResponseHeaderPayloadEncryptionAEAD.Open(nil, aeadResponseHeaderPayloadEncryptionIV, encryptedResponseHeaderBuffer, nil)
  139. if err != nil {
  140. return err
  141. }
  142. if len(buf) < 4 {
  143. return errors.New("unexpected buffer length")
  144. }
  145. }
  146. if buf[0] != vc.respV {
  147. return errors.New("unexpected response header")
  148. }
  149. if buf[2] != 0 {
  150. return errors.New("dynamic port is not supported now")
  151. }
  152. return nil
  153. }
  154. func hashTimestamp(t time.Time) []byte {
  155. md5hash := md5.New()
  156. ts := make([]byte, 8)
  157. binary.BigEndian.PutUint64(ts, uint64(t.Unix()))
  158. md5hash.Write(ts)
  159. md5hash.Write(ts)
  160. md5hash.Write(ts)
  161. md5hash.Write(ts)
  162. return md5hash.Sum(nil)
  163. }
  164. // newConn return a Conn instance
  165. func newConn(conn net.Conn, id *ID, dst *DstAddr, security Security, isAead bool) (*Conn, error) {
  166. randBytes := make([]byte, 33)
  167. rand.Read(randBytes)
  168. reqBodyIV := make([]byte, 16)
  169. reqBodyKey := make([]byte, 16)
  170. copy(reqBodyIV[:], randBytes[:16])
  171. copy(reqBodyKey[:], randBytes[16:32])
  172. respV := randBytes[32]
  173. var (
  174. respBodyKey []byte
  175. respBodyIV []byte
  176. )
  177. if isAead {
  178. bodyKey := sha256.Sum256(reqBodyKey)
  179. bodyIV := sha256.Sum256(reqBodyIV)
  180. respBodyKey = bodyKey[:16]
  181. respBodyIV = bodyIV[:16]
  182. } else {
  183. bodyKey := md5.Sum(reqBodyKey)
  184. bodyIV := md5.Sum(reqBodyIV)
  185. respBodyKey = bodyKey[:]
  186. respBodyIV = bodyIV[:]
  187. }
  188. var writer io.Writer
  189. var reader io.Reader
  190. switch security {
  191. case SecurityNone:
  192. reader = newChunkReader(conn)
  193. writer = newChunkWriter(conn)
  194. case SecurityAES128GCM:
  195. block, _ := aes.NewCipher(reqBodyKey[:])
  196. aead, _ := cipher.NewGCM(block)
  197. writer = newAEADWriter(conn, aead, reqBodyIV[:])
  198. block, _ = aes.NewCipher(respBodyKey[:])
  199. aead, _ = cipher.NewGCM(block)
  200. reader = newAEADReader(conn, aead, respBodyIV[:])
  201. case SecurityCHACHA20POLY1305:
  202. key := make([]byte, 32)
  203. t := md5.Sum(reqBodyKey[:])
  204. copy(key, t[:])
  205. t = md5.Sum(key[:16])
  206. copy(key[16:], t[:])
  207. aead, _ := chacha20poly1305.New(key)
  208. writer = newAEADWriter(conn, aead, reqBodyIV[:])
  209. t = md5.Sum(respBodyKey[:])
  210. copy(key, t[:])
  211. t = md5.Sum(key[:16])
  212. copy(key[16:], t[:])
  213. aead, _ = chacha20poly1305.New(key)
  214. reader = newAEADReader(conn, aead, respBodyIV[:])
  215. }
  216. c := &Conn{
  217. Conn: conn,
  218. id: id,
  219. dst: dst,
  220. reqBodyIV: reqBodyIV,
  221. reqBodyKey: reqBodyKey,
  222. respV: respV,
  223. respBodyIV: respBodyIV[:],
  224. respBodyKey: respBodyKey[:],
  225. reader: reader,
  226. writer: writer,
  227. security: security,
  228. isAead: isAead,
  229. }
  230. if err := c.sendRequest(); err != nil {
  231. return nil, err
  232. }
  233. return c, nil
  234. }