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