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 }