github.com/metacubex/sing-shadowsocks2@v0.2.0/shadowstream/method.go (about)

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