github.com/sagernet/sing-shadowsocks@v0.2.6/shadowstream/protocol.go (about)

     1  package shadowstream
     2  
     3  import (
     4  	"crypto/aes"
     5  	"crypto/cipher"
     6  	"crypto/md5"
     7  	"crypto/rand"
     8  	"crypto/rc4"
     9  	"io"
    10  	"net"
    11  	"os"
    12  
    13  	"github.com/sagernet/sing-shadowsocks"
    14  	"github.com/sagernet/sing/common"
    15  	"github.com/sagernet/sing/common/buf"
    16  	M "github.com/sagernet/sing/common/metadata"
    17  	N "github.com/sagernet/sing/common/network"
    18  
    19  	"golang.org/x/crypto/chacha20"
    20  )
    21  
    22  var List = []string{
    23  	"aes-128-ctr",
    24  	"aes-192-ctr",
    25  	"aes-256-ctr",
    26  	"aes-128-cfb",
    27  	"aes-192-cfb",
    28  	"aes-256-cfb",
    29  	"rc4-md5",
    30  	"chacha20-ietf",
    31  	"xchacha20",
    32  }
    33  
    34  type Method struct {
    35  	name               string
    36  	keyLength          int
    37  	saltLength         int
    38  	encryptConstructor func(key []byte, salt []byte) (cipher.Stream, error)
    39  	decryptConstructor func(key []byte, salt []byte) (cipher.Stream, error)
    40  	key                []byte
    41  }
    42  
    43  func New(method string, key []byte, password string) (shadowsocks.Method, error) {
    44  	m := &Method{
    45  		name: method,
    46  	}
    47  	switch method {
    48  	case "aes-128-ctr":
    49  		m.keyLength = 16
    50  		m.saltLength = aes.BlockSize
    51  		m.encryptConstructor = blockStream(aes.NewCipher, cipher.NewCTR)
    52  		m.decryptConstructor = blockStream(aes.NewCipher, cipher.NewCTR)
    53  	case "aes-192-ctr":
    54  		m.keyLength = 24
    55  		m.saltLength = aes.BlockSize
    56  		m.encryptConstructor = blockStream(aes.NewCipher, cipher.NewCTR)
    57  		m.decryptConstructor = blockStream(aes.NewCipher, cipher.NewCTR)
    58  	case "aes-256-ctr":
    59  		m.keyLength = 32
    60  		m.saltLength = aes.BlockSize
    61  		m.encryptConstructor = blockStream(aes.NewCipher, cipher.NewCTR)
    62  		m.decryptConstructor = blockStream(aes.NewCipher, cipher.NewCTR)
    63  	case "aes-128-cfb":
    64  		m.keyLength = 16
    65  		m.saltLength = aes.BlockSize
    66  		m.encryptConstructor = blockStream(aes.NewCipher, cipher.NewCFBEncrypter)
    67  		m.decryptConstructor = blockStream(aes.NewCipher, cipher.NewCFBDecrypter)
    68  	case "aes-192-cfb":
    69  		m.keyLength = 24
    70  		m.saltLength = aes.BlockSize
    71  		m.encryptConstructor = blockStream(aes.NewCipher, cipher.NewCFBEncrypter)
    72  		m.decryptConstructor = blockStream(aes.NewCipher, cipher.NewCFBDecrypter)
    73  	case "aes-256-cfb":
    74  		m.keyLength = 32
    75  		m.saltLength = aes.BlockSize
    76  		m.encryptConstructor = blockStream(aes.NewCipher, cipher.NewCFBEncrypter)
    77  		m.decryptConstructor = blockStream(aes.NewCipher, cipher.NewCFBDecrypter)
    78  	case "rc4-md5":
    79  		m.keyLength = 16
    80  		m.saltLength = 16
    81  		m.encryptConstructor = func(key []byte, salt []byte) (cipher.Stream, error) {
    82  			h := md5.New()
    83  			h.Write(key)
    84  			h.Write(salt)
    85  			return rc4.NewCipher(h.Sum(nil))
    86  		}
    87  		m.decryptConstructor = func(key []byte, salt []byte) (cipher.Stream, error) {
    88  			h := md5.New()
    89  			h.Write(key)
    90  			h.Write(salt)
    91  			return rc4.NewCipher(h.Sum(nil))
    92  		}
    93  	case "chacha20-ietf":
    94  		m.keyLength = chacha20.KeySize
    95  		m.saltLength = chacha20.NonceSize
    96  		m.encryptConstructor = func(key []byte, salt []byte) (cipher.Stream, error) {
    97  			return chacha20.NewUnauthenticatedCipher(key, salt)
    98  		}
    99  		m.decryptConstructor = func(key []byte, salt []byte) (cipher.Stream, error) {
   100  			return chacha20.NewUnauthenticatedCipher(key, salt)
   101  		}
   102  	case "xchacha20":
   103  		m.keyLength = chacha20.KeySize
   104  		m.saltLength = chacha20.NonceSizeX
   105  		m.encryptConstructor = func(key []byte, salt []byte) (cipher.Stream, error) {
   106  			return chacha20.NewUnauthenticatedCipher(key, salt)
   107  		}
   108  		m.decryptConstructor = func(key []byte, salt []byte) (cipher.Stream, error) {
   109  			return chacha20.NewUnauthenticatedCipher(key, salt)
   110  		}
   111  	default:
   112  		return nil, os.ErrInvalid
   113  	}
   114  	if len(key) == m.keyLength {
   115  		m.key = key
   116  	} else if len(key) > 0 {
   117  		return nil, shadowsocks.ErrBadKey
   118  	} else if password != "" {
   119  		m.key = shadowsocks.Key([]byte(password), m.keyLength)
   120  	} else {
   121  		return nil, shadowsocks.ErrMissingPassword
   122  	}
   123  	return m, nil
   124  }
   125  
   126  func blockStream(blockCreator func(key []byte) (cipher.Block, error), streamCreator func(block cipher.Block, iv []byte) cipher.Stream) func([]byte, []byte) (cipher.Stream, error) {
   127  	return func(key []byte, iv []byte) (cipher.Stream, error) {
   128  		block, err := blockCreator(key)
   129  		if err != nil {
   130  			return nil, err
   131  		}
   132  		return streamCreator(block, iv), err
   133  	}
   134  }
   135  
   136  func (m *Method) Name() string {
   137  	return m.name
   138  }
   139  
   140  func (m *Method) DialConn(conn net.Conn, destination M.Socksaddr) (net.Conn, error) {
   141  	shadowsocksConn := &clientConn{
   142  		Method:      m,
   143  		Conn:        conn,
   144  		destination: destination,
   145  	}
   146  	return shadowsocksConn, shadowsocksConn.writeRequest()
   147  }
   148  
   149  func (m *Method) DialEarlyConn(conn net.Conn, destination M.Socksaddr) net.Conn {
   150  	return &clientConn{
   151  		Method:      m,
   152  		Conn:        conn,
   153  		destination: destination,
   154  	}
   155  }
   156  
   157  func (m *Method) DialPacketConn(conn net.Conn) N.NetPacketConn {
   158  	return &clientPacketConn{m, conn}
   159  }
   160  
   161  type clientConn struct {
   162  	*Method
   163  	net.Conn
   164  	destination M.Socksaddr
   165  	readStream  cipher.Stream
   166  	writeStream cipher.Stream
   167  }
   168  
   169  func (c *clientConn) writeRequest() error {
   170  	buffer := buf.NewSize(c.saltLength + M.SocksaddrSerializer.AddrPortLen(c.destination))
   171  	defer buffer.Release()
   172  
   173  	salt := buffer.Extend(c.saltLength)
   174  	common.Must1(io.ReadFull(rand.Reader, salt))
   175  
   176  	stream, err := c.encryptConstructor(c.key, salt)
   177  	if err != nil {
   178  		return err
   179  	}
   180  
   181  	err = M.SocksaddrSerializer.WriteAddrPort(buffer, c.destination)
   182  	if err != nil {
   183  		return err
   184  	}
   185  
   186  	stream.XORKeyStream(buffer.From(c.saltLength), buffer.From(c.saltLength))
   187  
   188  	_, err = c.Conn.Write(buffer.Bytes())
   189  	if err != nil {
   190  		return err
   191  	}
   192  
   193  	c.writeStream = stream
   194  	return nil
   195  }
   196  
   197  func (c *clientConn) readResponse() error {
   198  	if c.readStream != nil {
   199  		return nil
   200  	}
   201  	salt := make([]byte, c.saltLength)
   202  	_, err := io.ReadFull(c.Conn, salt)
   203  	if err != nil {
   204  		return err
   205  	}
   206  	c.readStream, err = c.decryptConstructor(c.key, salt)
   207  	return err
   208  }
   209  
   210  func (c *clientConn) Read(p []byte) (n int, err error) {
   211  	if c.readStream == nil {
   212  		err = c.readResponse()
   213  		if err != nil {
   214  			return
   215  		}
   216  	}
   217  	n, err = c.Conn.Read(p)
   218  	if err != nil {
   219  		return
   220  	}
   221  	c.readStream.XORKeyStream(p[:n], p[:n])
   222  	return
   223  }
   224  
   225  func (c *clientConn) Write(p []byte) (n int, err error) {
   226  	if c.writeStream == nil {
   227  		err = c.writeRequest()
   228  		if err != nil {
   229  			return
   230  		}
   231  	}
   232  
   233  	c.writeStream.XORKeyStream(p, p)
   234  	return c.Conn.Write(p)
   235  }
   236  
   237  func (c *clientConn) NeedAdditionalReadDeadline() bool {
   238  	return true
   239  }
   240  
   241  func (c *clientConn) Upstream() any {
   242  	return c.Conn
   243  }
   244  
   245  type clientPacketConn struct {
   246  	*Method
   247  	net.Conn
   248  }
   249  
   250  func (c *clientPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
   251  	defer buffer.Release()
   252  	header := buf.With(buffer.ExtendHeader(c.saltLength + M.SocksaddrSerializer.AddrPortLen(destination)))
   253  	common.Must1(header.ReadFullFrom(rand.Reader, c.saltLength))
   254  	err := M.SocksaddrSerializer.WriteAddrPort(header, destination)
   255  	if err != nil {
   256  		return err
   257  	}
   258  	stream, err := c.encryptConstructor(c.key, buffer.To(c.saltLength))
   259  	if err != nil {
   260  		return err
   261  	}
   262  	stream.XORKeyStream(buffer.From(c.saltLength), buffer.From(c.saltLength))
   263  	return common.Error(c.Write(buffer.Bytes()))
   264  }
   265  
   266  func (c *clientPacketConn) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
   267  	n, err := c.Read(buffer.FreeBytes())
   268  	if err != nil {
   269  		return M.Socksaddr{}, err
   270  	}
   271  	buffer.Truncate(n)
   272  	stream, err := c.decryptConstructor(c.key, buffer.To(c.saltLength))
   273  	if err != nil {
   274  		return M.Socksaddr{}, err
   275  	}
   276  	stream.XORKeyStream(buffer.From(c.saltLength), buffer.From(c.saltLength))
   277  	buffer.Advance(c.saltLength)
   278  	return M.SocksaddrSerializer.ReadAddrPort(buffer)
   279  }
   280  
   281  func (c *clientPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
   282  	n, err = c.Read(p)
   283  	if err != nil {
   284  		return
   285  	}
   286  	stream, err := c.decryptConstructor(c.key, p[:c.saltLength])
   287  	if err != nil {
   288  		return
   289  	}
   290  	buffer := buf.As(p[c.saltLength:n])
   291  	stream.XORKeyStream(buffer.Bytes(), buffer.Bytes())
   292  	destination, err := M.SocksaddrSerializer.ReadAddrPort(buffer)
   293  	if err != nil {
   294  		return
   295  	}
   296  	if destination.IsFqdn() {
   297  		addr = destination
   298  	} else {
   299  		addr = destination.UDPAddr()
   300  	}
   301  	n = copy(p, buffer.Bytes())
   302  	return
   303  }
   304  
   305  func (c *clientPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
   306  	destination := M.SocksaddrFromNet(addr)
   307  	buffer := buf.NewSize(c.saltLength + M.SocksaddrSerializer.AddrPortLen(destination) + len(p))
   308  	defer buffer.Release()
   309  	common.Must1(buffer.ReadFullFrom(rand.Reader, c.saltLength))
   310  	err = M.SocksaddrSerializer.WriteAddrPort(buffer, M.SocksaddrFromNet(addr))
   311  	if err != nil {
   312  		return
   313  	}
   314  	_, err = buffer.Write(p)
   315  	if err != nil {
   316  		return
   317  	}
   318  	stream, err := c.encryptConstructor(c.key, buffer.To(c.saltLength))
   319  	if err != nil {
   320  		return
   321  	}
   322  	stream.XORKeyStream(buffer.From(c.saltLength), buffer.From(c.saltLength))
   323  	_, err = c.Write(buffer.Bytes())
   324  	if err != nil {
   325  		return
   326  	}
   327  	return len(p), nil
   328  }
   329  
   330  func (c *clientPacketConn) FrontHeadroom() int {
   331  	return c.saltLength + M.MaxSocksaddrLength
   332  }
   333  
   334  func (c *clientPacketConn) Upstream() any {
   335  	return c.Conn
   336  }