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