github.com/laof/lite-speed-test@v0.0.0-20230930011949-1f39b7037845/transport/ssr/obfs/tls1.2_ticket_auth.go (about)

     1  package obfs
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/hmac"
     6  	"encoding/binary"
     7  	"math/rand"
     8  	"net"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/laof/lite-speed-test/common/pool"
    13  	"github.com/laof/lite-speed-test/transport/ssr/tools"
    14  )
    15  
    16  func init() {
    17  	register("tls1.2_ticket_auth", newTLS12Ticket, 5)
    18  	register("tls1.2_ticket_fastauth", newTLS12Ticket, 5)
    19  }
    20  
    21  type tls12Ticket struct {
    22  	*Base
    23  	*authData
    24  }
    25  
    26  func newTLS12Ticket(b *Base) Obfs {
    27  	r := &tls12Ticket{Base: b, authData: &authData{}}
    28  	rand.Read(r.clientID[:])
    29  	return r
    30  }
    31  
    32  type tls12TicketConn struct {
    33  	net.Conn
    34  	*tls12Ticket
    35  	handshakeStatus int
    36  	decoded         bytes.Buffer
    37  	underDecoded    bytes.Buffer
    38  	sendBuf         bytes.Buffer
    39  }
    40  
    41  func (t *tls12Ticket) StreamConn(c net.Conn) net.Conn {
    42  	return &tls12TicketConn{Conn: c, tls12Ticket: t}
    43  }
    44  
    45  func (c *tls12TicketConn) Read(b []byte) (int, error) {
    46  	if c.decoded.Len() > 0 {
    47  		return c.decoded.Read(b)
    48  	}
    49  
    50  	buf := pool.Get(pool.RelayBufferSize)
    51  	defer pool.Put(buf)
    52  	n, err := c.Conn.Read(buf)
    53  	if err != nil {
    54  		return 0, err
    55  	}
    56  
    57  	if c.handshakeStatus == 8 {
    58  		c.underDecoded.Write(buf[:n])
    59  		for c.underDecoded.Len() > 5 {
    60  			if !bytes.Equal(c.underDecoded.Bytes()[:3], []byte{0x17, 3, 3}) {
    61  				c.underDecoded.Reset()
    62  				return 0, errTLS12TicketAuthIncorrectMagicNumber
    63  			}
    64  			size := int(binary.BigEndian.Uint16(c.underDecoded.Bytes()[3:5]))
    65  			if c.underDecoded.Len() < 5+size {
    66  				break
    67  			}
    68  			c.underDecoded.Next(5)
    69  			c.decoded.Write(c.underDecoded.Next(size))
    70  		}
    71  		n, _ = c.decoded.Read(b)
    72  		return n, nil
    73  	}
    74  
    75  	if n < 11+32+1+32 {
    76  		return 0, errTLS12TicketAuthTooShortData
    77  	}
    78  
    79  	if !hmac.Equal(buf[33:43], c.hmacSHA1(buf[11:33])[:10]) || !hmac.Equal(buf[n-10:n], c.hmacSHA1(buf[:n-10])[:10]) {
    80  		return 0, errTLS12TicketAuthHMACError
    81  	}
    82  
    83  	c.Write(nil)
    84  	return 0, nil
    85  }
    86  
    87  func (c *tls12TicketConn) Write(b []byte) (int, error) {
    88  	length := len(b)
    89  	if c.handshakeStatus == 8 {
    90  		buf := pool.GetBuffer()
    91  		defer pool.PutBuffer(buf)
    92  		for len(b) > 2048 {
    93  			size := rand.Intn(4096) + 100
    94  			if len(b) < size {
    95  				size = len(b)
    96  			}
    97  			packData(buf, b[:size])
    98  			b = b[size:]
    99  		}
   100  		if len(b) > 0 {
   101  			packData(buf, b)
   102  		}
   103  		_, err := c.Conn.Write(buf.Bytes())
   104  		if err != nil {
   105  			return 0, err
   106  		}
   107  		return length, nil
   108  	}
   109  
   110  	if len(b) > 0 {
   111  		packData(&c.sendBuf, b)
   112  	}
   113  
   114  	if c.handshakeStatus == 0 {
   115  		c.handshakeStatus = 1
   116  
   117  		data := pool.GetBuffer()
   118  		defer pool.PutBuffer(data)
   119  
   120  		data.Write([]byte{3, 3})
   121  		c.packAuthData(data)
   122  		data.WriteByte(0x20)
   123  		data.Write(c.clientID[:])
   124  		data.Write([]byte{0x00, 0x1c, 0xc0, 0x2b, 0xc0, 0x2f, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x9c, 0x00, 0x35, 0x00, 0x2f, 0x00, 0x0a})
   125  		data.Write([]byte{0x1, 0x0})
   126  
   127  		ext := pool.GetBuffer()
   128  		defer pool.PutBuffer(ext)
   129  
   130  		host := c.getHost()
   131  		ext.Write([]byte{0xff, 0x01, 0x00, 0x01, 0x00})
   132  		packSNIData(ext, host)
   133  		ext.Write([]byte{0, 0x17, 0, 0})
   134  		c.packTicketBuf(ext, host)
   135  		ext.Write([]byte{0x00, 0x0d, 0x00, 0x16, 0x00, 0x14, 0x06, 0x01, 0x06, 0x03, 0x05, 0x01, 0x05, 0x03, 0x04, 0x01, 0x04, 0x03, 0x03, 0x01, 0x03, 0x03, 0x02, 0x01, 0x02, 0x03})
   136  		ext.Write([]byte{0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00})
   137  		ext.Write([]byte{0x00, 0x12, 0x00, 0x00})
   138  		ext.Write([]byte{0x75, 0x50, 0x00, 0x00})
   139  		ext.Write([]byte{0x00, 0x0b, 0x00, 0x02, 0x01, 0x00})
   140  		ext.Write([]byte{0x00, 0x0a, 0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x18})
   141  
   142  		binary.Write(data, binary.BigEndian, uint16(ext.Len()))
   143  		data.ReadFrom(ext)
   144  
   145  		ret := pool.GetBuffer()
   146  		defer pool.PutBuffer(ret)
   147  
   148  		ret.Write([]byte{0x16, 3, 1})
   149  		binary.Write(ret, binary.BigEndian, uint16(data.Len()+4))
   150  		ret.Write([]byte{1, 0})
   151  		binary.Write(ret, binary.BigEndian, uint16(data.Len()))
   152  		ret.ReadFrom(data)
   153  
   154  		_, err := c.Conn.Write(ret.Bytes())
   155  		if err != nil {
   156  			return 0, err
   157  		}
   158  		return length, nil
   159  	} else if c.handshakeStatus == 1 && len(b) == 0 {
   160  		buf := pool.GetBuffer()
   161  		defer pool.PutBuffer(buf)
   162  
   163  		buf.Write([]byte{0x14, 3, 3, 0, 1, 1, 0x16, 3, 3, 0, 0x20})
   164  		tools.AppendRandBytes(buf, 22)
   165  		buf.Write(c.hmacSHA1(buf.Bytes())[:10])
   166  		buf.ReadFrom(&c.sendBuf)
   167  
   168  		c.handshakeStatus = 8
   169  
   170  		_, err := c.Conn.Write(buf.Bytes())
   171  		return 0, err
   172  	}
   173  	return length, nil
   174  }
   175  
   176  func packData(buf *bytes.Buffer, data []byte) {
   177  	buf.Write([]byte{0x17, 3, 3})
   178  	binary.Write(buf, binary.BigEndian, uint16(len(data)))
   179  	buf.Write(data)
   180  }
   181  
   182  func (t *tls12Ticket) packAuthData(buf *bytes.Buffer) {
   183  	binary.Write(buf, binary.BigEndian, uint32(time.Now().Unix()))
   184  	tools.AppendRandBytes(buf, 18)
   185  	buf.Write(t.hmacSHA1(buf.Bytes()[buf.Len()-22:])[:10])
   186  }
   187  
   188  func packSNIData(buf *bytes.Buffer, u string) {
   189  	len := uint16(len(u))
   190  	buf.Write([]byte{0, 0})
   191  	binary.Write(buf, binary.BigEndian, len+5)
   192  	binary.Write(buf, binary.BigEndian, len+3)
   193  	buf.WriteByte(0)
   194  	binary.Write(buf, binary.BigEndian, len)
   195  	buf.WriteString(u)
   196  }
   197  
   198  func (c *tls12TicketConn) packTicketBuf(buf *bytes.Buffer, u string) {
   199  	length := 16 * (rand.Intn(17) + 8)
   200  	buf.Write([]byte{0, 0x23})
   201  	binary.Write(buf, binary.BigEndian, uint16(length))
   202  	tools.AppendRandBytes(buf, length)
   203  }
   204  
   205  func (t *tls12Ticket) hmacSHA1(data []byte) []byte {
   206  	key := pool.Get(len(t.Key) + 32)
   207  	defer pool.Put(key)
   208  	copy(key, t.Key)
   209  	copy(key[len(t.Key):], t.clientID[:])
   210  
   211  	sha1Data := tools.HmacSHA1(key, data)
   212  	return sha1Data[:10]
   213  }
   214  
   215  func (t *tls12Ticket) getHost() string {
   216  	host := t.Param
   217  	if len(host) == 0 {
   218  		host = t.Host
   219  	}
   220  	if len(host) > 0 && host[len(host)-1] >= '0' && host[len(host)-1] <= '9' {
   221  		host = ""
   222  	}
   223  	hosts := strings.Split(host, ",")
   224  	host = hosts[rand.Intn(len(hosts))]
   225  	return host
   226  }