quic.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package sniff
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto"
  6. "crypto/aes"
  7. "encoding/binary"
  8. "io"
  9. "os"
  10. "github.com/sagernet/sing-box/adapter"
  11. "github.com/sagernet/sing-box/common/sniff/internal/qtls"
  12. C "github.com/sagernet/sing-box/constant"
  13. "golang.org/x/crypto/hkdf"
  14. )
  15. func QUICClientHello(ctx context.Context, packet []byte) (*adapter.InboundContext, error) {
  16. reader := bytes.NewReader(packet)
  17. typeByte, err := reader.ReadByte()
  18. if err != nil {
  19. return nil, err
  20. }
  21. if typeByte&0x80 == 0 || typeByte&0x40 == 0 {
  22. return nil, os.ErrInvalid
  23. }
  24. var versionNumber uint32
  25. err = binary.Read(reader, binary.BigEndian, &versionNumber)
  26. if err != nil {
  27. return nil, err
  28. }
  29. if versionNumber != qtls.VersionDraft29 && versionNumber != qtls.Version1 && versionNumber != qtls.Version2 {
  30. return nil, os.ErrInvalid
  31. }
  32. if (typeByte&0x30)>>4 == 0x0 {
  33. } else if (typeByte&0x30)>>4 != 0x01 {
  34. // 0-rtt
  35. } else {
  36. return nil, os.ErrInvalid
  37. }
  38. destConnIDLen, err := reader.ReadByte()
  39. if err != nil {
  40. return nil, err
  41. }
  42. destConnID := make([]byte, destConnIDLen)
  43. _, err = io.ReadFull(reader, destConnID)
  44. if err != nil {
  45. return nil, err
  46. }
  47. srcConnIDLen, err := reader.ReadByte()
  48. if err != nil {
  49. return nil, err
  50. }
  51. _, err = io.CopyN(io.Discard, reader, int64(srcConnIDLen))
  52. if err != nil {
  53. return nil, err
  54. }
  55. tokenLen, err := qtls.ReadUvarint(reader)
  56. if err != nil {
  57. return nil, err
  58. }
  59. _, err = io.CopyN(io.Discard, reader, int64(tokenLen))
  60. if err != nil {
  61. return nil, err
  62. }
  63. packetLen, err := qtls.ReadUvarint(reader)
  64. if err != nil {
  65. return nil, err
  66. }
  67. hdrLen := int(reader.Size()) - reader.Len()
  68. if hdrLen != len(packet)-int(packetLen) {
  69. return nil, os.ErrInvalid
  70. }
  71. _, err = io.CopyN(io.Discard, reader, 4)
  72. if err != nil {
  73. return nil, err
  74. }
  75. pnBytes := make([]byte, aes.BlockSize)
  76. _, err = io.ReadFull(reader, pnBytes)
  77. if err != nil {
  78. return nil, err
  79. }
  80. var salt []byte
  81. switch versionNumber {
  82. case qtls.Version1:
  83. salt = qtls.SaltV1
  84. case qtls.Version2:
  85. salt = qtls.SaltV2
  86. default:
  87. salt = qtls.SaltOld
  88. }
  89. var hkdfHeaderProtectionLabel string
  90. switch versionNumber {
  91. case qtls.Version2:
  92. hkdfHeaderProtectionLabel = qtls.HKDFLabelHeaderProtectionV2
  93. default:
  94. hkdfHeaderProtectionLabel = qtls.HKDFLabelHeaderProtectionV1
  95. }
  96. initialSecret := hkdf.Extract(crypto.SHA256.New, destConnID, salt)
  97. secret := qtls.HKDFExpandLabel(crypto.SHA256, initialSecret, []byte{}, "client in", crypto.SHA256.Size())
  98. hpKey := qtls.HKDFExpandLabel(crypto.SHA256, secret, []byte{}, hkdfHeaderProtectionLabel, 16)
  99. block, err := aes.NewCipher(hpKey)
  100. if err != nil {
  101. return nil, err
  102. }
  103. mask := make([]byte, aes.BlockSize)
  104. block.Encrypt(mask, pnBytes)
  105. newPacket := make([]byte, len(packet))
  106. copy(newPacket, packet)
  107. newPacket[0] ^= mask[0] & 0xf
  108. for i := range newPacket[hdrLen : hdrLen+4] {
  109. newPacket[hdrLen+i] ^= mask[i+1]
  110. }
  111. packetNumberLength := newPacket[0]&0x3 + 1
  112. if packetNumberLength != 1 {
  113. return nil, os.ErrInvalid
  114. }
  115. packetNumber := newPacket[hdrLen]
  116. if err != nil {
  117. return nil, err
  118. }
  119. if packetNumber != 0 {
  120. return nil, os.ErrInvalid
  121. }
  122. extHdrLen := hdrLen + int(packetNumberLength)
  123. copy(newPacket[extHdrLen:hdrLen+4], packet[extHdrLen:])
  124. data := newPacket[extHdrLen : int(packetLen)+hdrLen]
  125. var keyLabel string
  126. var ivLabel string
  127. switch versionNumber {
  128. case qtls.Version2:
  129. keyLabel = qtls.HKDFLabelKeyV2
  130. ivLabel = qtls.HKDFLabelIVV2
  131. default:
  132. keyLabel = qtls.HKDFLabelKeyV1
  133. ivLabel = qtls.HKDFLabelIVV1
  134. }
  135. key := qtls.HKDFExpandLabel(crypto.SHA256, secret, []byte{}, keyLabel, 16)
  136. iv := qtls.HKDFExpandLabel(crypto.SHA256, secret, []byte{}, ivLabel, 12)
  137. cipher := qtls.AEADAESGCMTLS13(key, iv)
  138. nonce := make([]byte, int32(cipher.NonceSize()))
  139. binary.BigEndian.PutUint64(nonce[len(nonce)-8:], uint64(packetNumber))
  140. decrypted, err := cipher.Open(newPacket[extHdrLen:extHdrLen], nonce, data, newPacket[:extHdrLen])
  141. if err != nil {
  142. return nil, err
  143. }
  144. decryptedReader := bytes.NewReader(decrypted)
  145. frameType, err := decryptedReader.ReadByte()
  146. if frameType != 0x6 {
  147. // not crypto frame
  148. return &adapter.InboundContext{Protocol: C.ProtocolQUIC}, nil
  149. }
  150. _, err = qtls.ReadUvarint(decryptedReader)
  151. if err != nil {
  152. return nil, err
  153. }
  154. _, err = qtls.ReadUvarint(decryptedReader)
  155. if err != nil {
  156. return nil, err
  157. }
  158. tlsHdr := make([]byte, 5)
  159. tlsHdr[0] = 0x16
  160. binary.BigEndian.PutUint16(tlsHdr[1:], uint16(0x0303))
  161. binary.BigEndian.PutUint16(tlsHdr[3:], uint16(decryptedReader.Len()))
  162. metadata, err := TLSClientHello(ctx, io.MultiReader(bytes.NewReader(tlsHdr), decryptedReader))
  163. if err != nil {
  164. return nil, err
  165. }
  166. metadata.Protocol = C.ProtocolQUIC
  167. return metadata, nil
  168. }