github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/proxy/shadowsocksr/obfs/tls12_ticket_auth.go (about) 1 package obfs 2 3 import ( 4 "bytes" 5 "crypto" 6 "crypto/hmac" 7 crand "crypto/rand" 8 "encoding/binary" 9 "fmt" 10 "math/rand/v2" 11 "net" 12 "strings" 13 "time" 14 15 "github.com/Asutorufa/yuhaiin/pkg/log" 16 ssr "github.com/Asutorufa/yuhaiin/pkg/net/proxy/shadowsocksr/utils" 17 "github.com/Asutorufa/yuhaiin/pkg/utils/relay" 18 ) 19 20 type tlsAuthData struct { 21 localClientID [32]byte 22 } 23 24 // tls12TicketAuth tls1.2_ticket_auth obfs encapsulate 25 type tls12TicketAuth struct { 26 Obfs 27 data *tlsAuthData 28 handshakeStatus int 29 sendSaver bytes.Buffer 30 recvBuffer bytes.Buffer 31 buffer bytes.Buffer 32 33 net.Conn 34 } 35 36 // newTLS12TicketAuth create a tlv1.2_ticket_auth object 37 func newTLS12TicketAuth(conn net.Conn, info Obfs) net.Conn { 38 return &tls12TicketAuth{Conn: conn, Obfs: info} 39 } 40 41 func (t *tls12TicketAuth) GetData() *tlsAuthData { 42 if t.data == nil { 43 t.data = &tlsAuthData{} 44 b := make([]byte, 32) 45 46 crand.Read(b) 47 copy(t.data.localClientID[:], b) 48 } 49 return t.data 50 } 51 52 func (t *tls12TicketAuth) getHost() string { 53 host := t.Host 54 if len(t.Param) > 0 { 55 hosts := strings.Split(t.Param, ",") 56 if len(hosts) > 0 { 57 58 host = hosts[rand.IntN(len(hosts))] 59 host = strings.TrimSpace(host) 60 } 61 } 62 if len(host) > 0 && host[len(host)-1] >= byte('0') && host[len(host)-1] <= byte('9') && len(t.Param) == 0 { 63 host = "" 64 } 65 return host 66 } 67 68 func packData(buffer *bytes.Buffer, suffixData []byte) { 69 d := []byte{0x17, 0x3, 0x3, 0, 0} 70 binary.BigEndian.PutUint16(d[3:5], uint16(len(suffixData)&0xFFFF)) 71 buffer.Write(d) 72 buffer.Write(suffixData) 73 } 74 75 func (t *tls12TicketAuth) Encode(data []byte) ([]byte, error) { 76 t.buffer.Reset() 77 switch t.handshakeStatus { 78 case 8: 79 if len(data) < 1024 { 80 d := []byte{0x17, 0x3, 0x3, 0, 0} 81 binary.BigEndian.PutUint16(d[3:5], uint16(len(data)&0xFFFF)) 82 t.buffer.Write(d) 83 t.buffer.Write(data) 84 return t.buffer.Bytes(), nil 85 } else { 86 start := 0 87 var l int 88 for len(data)-start > 2048 { 89 l = rand.IntN(4096) + 100 90 if l > len(data)-start { 91 l = len(data) - start 92 } 93 packData(&t.buffer, data[start:start+l]) 94 start += l 95 } 96 if len(data)-start > 0 { 97 l = len(data) - start 98 packData(&t.buffer, data[start:start+l]) 99 } 100 return t.buffer.Bytes(), nil 101 } 102 case 1: 103 if len(data) > 0 { 104 if len(data) < 1024 { 105 packData(&t.sendSaver, data) 106 } else { 107 start := 0 108 var l int 109 for len(data)-start > 2048 { 110 l = rand.IntN(4096) + 100 111 if l > len(data)-start { 112 l = len(data) - start 113 } 114 packData(&t.buffer, data[start:start+l]) 115 start += l 116 } 117 if len(data)-start > 0 { 118 l = len(data) - start 119 packData(&t.buffer, data[start:start+l]) 120 } 121 _, _ = relay.Copy(&t.sendSaver, &t.buffer) 122 } 123 return []byte{}, nil 124 } 125 hmacData := make([]byte, 43) 126 handshakeFinish := []byte("\x14\x03\x03\x00\x01\x01\x16\x03\x03\x00\x20") 127 copy(hmacData, handshakeFinish) 128 crand.Read(hmacData[11:33]) 129 h := t.hmacSHA1(hmacData[:33]) 130 copy(hmacData[33:], h) 131 t.buffer.Write(hmacData) 132 _, _ = relay.Copy(&t.buffer, &t.sendSaver) 133 t.handshakeStatus = 8 134 return t.buffer.Bytes(), nil 135 case 0: 136 tlsData0 := []byte("\x00\x1c\xc0\x2b\xc0\x2f\xcc\xa9\xcc\xa8\xcc\x14\xcc\x13\xc0\x0a\xc0\x14\xc0\x09\xc0\x13\x00\x9c\x00\x35\x00\x2f\x00\x0a\x01\x00") 137 tlsData1 := []byte("\xff\x01\x00\x01\x00") 138 tlsData2 := []byte("\x00\x17\x00\x00\x00\x23\x00\xd0") 139 tlsData3 := []byte("\x00\x0d\x00\x16\x00\x14\x06\x01\x06\x03\x05\x01\x05\x03\x04\x01\x04\x03\x03\x01\x03\x03\x02\x01\x02\x03\x00\x05\x00\x05\x01\x00\x00\x00\x00\x00\x12\x00\x00\x75\x50\x00\x00\x00\x0b\x00\x02\x01\x00\x00\x0a\x00\x06\x00\x04\x00\x17\x00\x18\x00\x15\x00\x66\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") 140 141 var tlsData [2048]byte 142 tlsDataLen := 0 143 copy(tlsData[0:], tlsData1) 144 tlsDataLen += len(tlsData1) 145 sni := t.sni(t.getHost()) 146 copy(tlsData[tlsDataLen:], sni) 147 tlsDataLen += len(sni) 148 copy(tlsData[tlsDataLen:], tlsData2) 149 tlsDataLen += len(tlsData2) 150 ticketLen := rand.IntN(164)*2 + 64 151 tlsData[tlsDataLen-1] = uint8(ticketLen & 0xff) 152 tlsData[tlsDataLen-2] = uint8(ticketLen >> 8) 153 //ticketLen := 208 154 crand.Read(tlsData[tlsDataLen : tlsDataLen+ticketLen]) 155 tlsDataLen += ticketLen 156 copy(tlsData[tlsDataLen:], tlsData3) 157 tlsDataLen += len(tlsData3) 158 159 length := 11 + 32 + 1 + 32 + len(tlsData0) + 2 + tlsDataLen 160 encodedData := make([]byte, length) 161 pdata := length - tlsDataLen 162 l := tlsDataLen 163 copy(encodedData[pdata:], tlsData[:tlsDataLen]) 164 encodedData[pdata-1] = uint8(tlsDataLen) 165 encodedData[pdata-2] = uint8(tlsDataLen >> 8) 166 pdata -= 2 167 l += 2 168 copy(encodedData[pdata-len(tlsData0):], tlsData0) 169 pdata -= len(tlsData0) 170 l += len(tlsData0) 171 copy(encodedData[pdata-32:], t.GetData().localClientID[:]) 172 pdata -= 32 173 l += 32 174 encodedData[pdata-1] = 0x20 175 pdata -= 1 176 l += 1 177 copy(encodedData[pdata-32:], t.packAuthData()) 178 pdata -= 32 179 l += 32 180 encodedData[pdata-1] = 0x3 181 encodedData[pdata-2] = 0x3 // tls version 182 pdata -= 2 183 l += 2 184 encodedData[pdata-1] = uint8(l) 185 encodedData[pdata-2] = uint8(l >> 8) 186 encodedData[pdata-3] = 0 187 encodedData[pdata-4] = 1 188 pdata -= 4 189 l += 4 190 encodedData[pdata-1] = uint8(l) 191 encodedData[pdata-2] = uint8(l >> 8) 192 pdata -= 2 193 l += 2 194 encodedData[pdata-1] = 0x1 195 encodedData[pdata-2] = 0x3 // tls version 196 pdata -= 2 197 l += 2 198 encodedData[pdata-1] = 0x16 // tls handshake 199 pdata -= 1 200 l += 1 201 packData(&t.sendSaver, data) 202 t.handshakeStatus = 1 203 return encodedData, nil 204 default: 205 //log.Println(fmt.Errorf("unexpected handshake status: %d", t.handshakeStatus)) 206 return nil, fmt.Errorf("unexpected handshake status: %d", t.handshakeStatus) 207 } 208 } 209 210 func (t *tls12TicketAuth) Write(b []byte) (int, error) { 211 data, err := t.Encode(b) 212 if err != nil { 213 return 0, err 214 } 215 216 _, err = t.Conn.Write(data) 217 if err != nil { 218 return 0, err 219 } 220 221 return len(b), nil 222 } 223 func (t *tls12TicketAuth) Decode(data []byte) (decodedData []byte, needSendBack bool, err error) { 224 if t.handshakeStatus == -1 { 225 return data, false, nil 226 } 227 t.buffer.Reset() 228 if t.handshakeStatus == 8 { 229 t.recvBuffer.Write(data) 230 for t.recvBuffer.Len() > 5 { 231 var h [5]byte 232 _, _ = t.recvBuffer.Read(h[:]) 233 if !bytes.Equal(h[0:3], []byte{0x17, 0x3, 0x3}) { 234 log.Warn("incorrect magic number, 0x170303 is expected", "magic number", h[0:3]) 235 return nil, false, ssr.ErrTLS12TicketAuthIncorrectMagicNumber 236 } 237 size := int(binary.BigEndian.Uint16(h[3:5])) 238 if t.recvBuffer.Len() < size { 239 // 不够读,下回再读吧 240 unread := t.recvBuffer.Bytes() 241 t.recvBuffer.Reset() 242 t.recvBuffer.Write(h[:]) 243 t.recvBuffer.Write(unread) 244 break 245 } 246 d := make([]byte, size) 247 _, _ = t.recvBuffer.Read(d) 248 t.buffer.Write(d) 249 } 250 return t.buffer.Bytes(), false, nil 251 } 252 253 if len(data) < 11+32+1+32 { 254 return nil, false, ssr.ErrTLS12TicketAuthTooShortData 255 } 256 257 hash := t.hmacSHA1(data[11 : 11+22]) 258 259 if !hmac.Equal(data[33:33+ssr.ObfsHMACSHA1Len], hash) { 260 return nil, false, ssr.ErrTLS12TicketAuthHMACError 261 } 262 return nil, true, nil 263 } 264 265 func (t *tls12TicketAuth) Read(b []byte) (int, error) { 266 n, err := t.Conn.Read(b) 267 if err != nil { 268 return n, err 269 } 270 271 data, sendBack, err := t.Decode(b[:n]) 272 if err != nil { 273 return n, err 274 } 275 276 if sendBack { 277 t.Conn.Write(nil) 278 return 0, nil 279 } 280 281 return copy(b[0:], data), nil 282 } 283 284 func (t *tls12TicketAuth) packAuthData() (outData []byte) { 285 outSize := 32 286 outData = make([]byte, outSize) 287 288 now := time.Now().Unix() 289 binary.BigEndian.PutUint32(outData[0:4], uint32(now)) 290 291 crand.Read(outData[4 : 4+18]) 292 293 hash := t.hmacSHA1(outData[:outSize-ssr.ObfsHMACSHA1Len]) 294 copy(outData[outSize-ssr.ObfsHMACSHA1Len:], hash) 295 296 return 297 } 298 299 func (t *tls12TicketAuth) hmacSHA1(data []byte) []byte { 300 key := make([]byte, len(t.Key())+32) 301 copy(key, t.Key()) 302 copy(key[len(t.Key()):], t.GetData().localClientID[:]) 303 304 sha1Data := ssr.Hmac(crypto.SHA1, key, data, nil) 305 return sha1Data[:ssr.ObfsHMACSHA1Len] 306 } 307 308 func (t *tls12TicketAuth) sni(u string) []byte { 309 bURL := []byte(u) 310 length := len(bURL) 311 ret := make([]byte, length+9) 312 copy(ret[9:9+length], bURL) 313 binary.BigEndian.PutUint16(ret[7:], uint16(length&0xFFFF)) 314 length += 3 315 binary.BigEndian.PutUint16(ret[4:], uint16(length&0xFFFF)) 316 length += 2 317 binary.BigEndian.PutUint16(ret[2:], uint16(length&0xFFFF)) 318 return ret 319 } 320 321 func (t *tls12TicketAuth) GetOverhead() int { return 5 }