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 }