github.com/sagernet/sing-box@v1.9.0-rc.20/transport/simple-obfs/tls.go (about) 1 package obfs 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "io" 7 "math/rand" 8 "net" 9 "time" 10 11 B "github.com/sagernet/sing/common/buf" 12 "github.com/sagernet/sing/common/random" 13 ) 14 15 func init() { 16 random.InitializeSeed() 17 } 18 19 const ( 20 chunkSize = 1 << 14 // 2 ** 14 == 16 * 1024 21 ) 22 23 // TLSObfs is shadowsocks tls simple-obfs implementation 24 type TLSObfs struct { 25 net.Conn 26 server string 27 remain int 28 firstRequest bool 29 firstResponse bool 30 } 31 32 func (to *TLSObfs) read(b []byte, discardN int) (int, error) { 33 buf := B.Get(discardN) 34 _, err := io.ReadFull(to.Conn, buf) 35 B.Put(buf) 36 if err != nil { 37 return 0, err 38 } 39 40 sizeBuf := make([]byte, 2) 41 _, err = io.ReadFull(to.Conn, sizeBuf) 42 if err != nil { 43 return 0, nil 44 } 45 46 length := int(binary.BigEndian.Uint16(sizeBuf)) 47 if length > len(b) { 48 n, err := to.Conn.Read(b) 49 if err != nil { 50 return n, err 51 } 52 to.remain = length - n 53 return n, nil 54 } 55 56 return io.ReadFull(to.Conn, b[:length]) 57 } 58 59 func (to *TLSObfs) Read(b []byte) (int, error) { 60 if to.remain > 0 { 61 length := to.remain 62 if length > len(b) { 63 length = len(b) 64 } 65 66 n, err := io.ReadFull(to.Conn, b[:length]) 67 to.remain -= n 68 return n, err 69 } 70 71 if to.firstResponse { 72 // type + ver + lensize + 91 = 96 73 // type + ver + lensize + 1 = 6 74 // type + ver = 3 75 to.firstResponse = false 76 return to.read(b, 105) 77 } 78 79 // type + ver = 3 80 return to.read(b, 3) 81 } 82 83 func (to *TLSObfs) Write(b []byte) (int, error) { 84 length := len(b) 85 for i := 0; i < length; i += chunkSize { 86 end := i + chunkSize 87 if end > length { 88 end = length 89 } 90 91 n, err := to.write(b[i:end]) 92 if err != nil { 93 return n, err 94 } 95 } 96 return length, nil 97 } 98 99 func (to *TLSObfs) write(b []byte) (int, error) { 100 if to.firstRequest { 101 helloMsg := makeClientHelloMsg(b, to.server) 102 _, err := to.Conn.Write(helloMsg) 103 to.firstRequest = false 104 return len(b), err 105 } 106 107 buf := B.NewSize(5 + len(b)) 108 defer buf.Release() 109 buf.Write([]byte{0x17, 0x03, 0x03}) 110 binary.Write(buf, binary.BigEndian, uint16(len(b))) 111 buf.Write(b) 112 _, err := to.Conn.Write(buf.Bytes()) 113 return len(b), err 114 } 115 116 // NewTLSObfs return a SimpleObfs 117 func NewTLSObfs(conn net.Conn, server string) net.Conn { 118 return &TLSObfs{ 119 Conn: conn, 120 server: server, 121 firstRequest: true, 122 firstResponse: true, 123 } 124 } 125 126 func makeClientHelloMsg(data []byte, server string) []byte { 127 random := make([]byte, 28) 128 sessionID := make([]byte, 32) 129 rand.Read(random) 130 rand.Read(sessionID) 131 132 buf := &bytes.Buffer{} 133 134 // handshake, TLS 1.0 version, length 135 buf.WriteByte(22) 136 buf.Write([]byte{0x03, 0x01}) 137 length := uint16(212 + len(data) + len(server)) 138 buf.WriteByte(byte(length >> 8)) 139 buf.WriteByte(byte(length & 0xff)) 140 141 // clientHello, length, TLS 1.2 version 142 buf.WriteByte(1) 143 buf.WriteByte(0) 144 binary.Write(buf, binary.BigEndian, uint16(208+len(data)+len(server))) 145 buf.Write([]byte{0x03, 0x03}) 146 147 // random with timestamp, sid len, sid 148 binary.Write(buf, binary.BigEndian, uint32(time.Now().Unix())) 149 buf.Write(random) 150 buf.WriteByte(32) 151 buf.Write(sessionID) 152 153 // cipher suites 154 buf.Write([]byte{0x00, 0x38}) 155 buf.Write([]byte{ 156 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x2b, 0xc0, 0x2f, 157 0x00, 0x9e, 0xc0, 0x24, 0xc0, 0x28, 0x00, 0x6b, 0xc0, 0x23, 0xc0, 0x27, 0x00, 0x67, 0xc0, 0x0a, 158 0xc0, 0x14, 0x00, 0x39, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x33, 0x00, 0x9d, 0x00, 0x9c, 0x00, 0x3d, 159 0x00, 0x3c, 0x00, 0x35, 0x00, 0x2f, 0x00, 0xff, 160 }) 161 162 // compression 163 buf.Write([]byte{0x01, 0x00}) 164 165 // extension length 166 binary.Write(buf, binary.BigEndian, uint16(79+len(data)+len(server))) 167 168 // session ticket 169 buf.Write([]byte{0x00, 0x23}) 170 binary.Write(buf, binary.BigEndian, uint16(len(data))) 171 buf.Write(data) 172 173 // server name 174 buf.Write([]byte{0x00, 0x00}) 175 binary.Write(buf, binary.BigEndian, uint16(len(server)+5)) 176 binary.Write(buf, binary.BigEndian, uint16(len(server)+3)) 177 buf.WriteByte(0) 178 binary.Write(buf, binary.BigEndian, uint16(len(server))) 179 buf.Write([]byte(server)) 180 181 // ec_point 182 buf.Write([]byte{0x00, 0x0b, 0x00, 0x04, 0x03, 0x01, 0x00, 0x02}) 183 184 // groups 185 buf.Write([]byte{0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x19, 0x00, 0x18}) 186 187 // signature 188 buf.Write([]byte{ 189 0x00, 0x0d, 0x00, 0x20, 0x00, 0x1e, 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x05, 190 0x01, 0x05, 0x02, 0x05, 0x03, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x03, 0x01, 191 0x03, 0x02, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 192 }) 193 194 // encrypt then mac 195 buf.Write([]byte{0x00, 0x16, 0x00, 0x00}) 196 197 // extended master secret 198 buf.Write([]byte{0x00, 0x17, 0x00, 0x00}) 199 200 return buf.Bytes() 201 }