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 }