mirror of
https://github.com/SagerNet/sing-shadowsocks.git
synced 2025-04-03 20:07:40 +03:00
Refactor cipher usage
This commit is contained in:
parent
f9c820eb0f
commit
6084599638
2 changed files with 160 additions and 167 deletions
|
@ -3,7 +3,6 @@ package shadowaead
|
|||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"io"
|
||||
"net"
|
||||
|
@ -12,7 +11,6 @@ import (
|
|||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/common/rw"
|
||||
|
@ -28,34 +26,28 @@ var List = []string{
|
|||
"xchacha20-ietf-poly1305",
|
||||
}
|
||||
|
||||
func New(method string, key []byte, password string) (shadowsocks.Method, error) {
|
||||
var _ shadowsocks.Method = (*Method)(nil)
|
||||
|
||||
func New(method string, key []byte, password string) (*Method, error) {
|
||||
m := &Method{
|
||||
name: method,
|
||||
}
|
||||
switch method {
|
||||
case "aes-128-gcm":
|
||||
m.keySaltLength = 16
|
||||
m.constructor = newAESGCM
|
||||
m.constructor = aeadCipher(aes.NewCipher, cipher.NewGCM)
|
||||
case "aes-192-gcm":
|
||||
m.keySaltLength = 24
|
||||
m.constructor = newAESGCM
|
||||
m.constructor = aeadCipher(aes.NewCipher, cipher.NewGCM)
|
||||
case "aes-256-gcm":
|
||||
m.keySaltLength = 32
|
||||
m.constructor = newAESGCM
|
||||
m.constructor = aeadCipher(aes.NewCipher, cipher.NewGCM)
|
||||
case "chacha20-ietf-poly1305":
|
||||
m.keySaltLength = 32
|
||||
m.constructor = func(key []byte) cipher.AEAD {
|
||||
cipher, err := chacha20poly1305.New(key)
|
||||
common.Must(err)
|
||||
return cipher
|
||||
}
|
||||
m.constructor = chacha20poly1305.New
|
||||
case "xchacha20-ietf-poly1305":
|
||||
m.keySaltLength = 32
|
||||
m.constructor = func(key []byte) cipher.AEAD {
|
||||
cipher, err := chacha20poly1305.NewX(key)
|
||||
common.Must(err)
|
||||
return cipher
|
||||
}
|
||||
m.constructor = chacha20poly1305.NewX
|
||||
}
|
||||
if len(key) == m.keySaltLength {
|
||||
m.key = key
|
||||
|
@ -69,27 +61,25 @@ func New(method string, key []byte, password string) (shadowsocks.Method, error)
|
|||
return m, nil
|
||||
}
|
||||
|
||||
func Kdf(key, iv []byte, keyLength int) []byte {
|
||||
info := []byte("ss-subkey")
|
||||
subKey := buf.Make(keyLength)
|
||||
kdf := hkdf.New(sha1.New, key, iv, common.Dup(info))
|
||||
common.KeepAlive(info)
|
||||
common.Must1(io.ReadFull(kdf, common.Dup(subKey)))
|
||||
return subKey
|
||||
func Kdf(key, iv []byte, buffer *buf.Buffer) {
|
||||
kdf := hkdf.New(sha1.New, key, iv, []byte("ss-subkey"))
|
||||
common.Must1(buffer.ReadFullFrom(kdf, buffer.FreeLen()))
|
||||
}
|
||||
|
||||
func newAESGCM(key []byte) cipher.AEAD {
|
||||
block, err := aes.NewCipher(key)
|
||||
common.Must(err)
|
||||
aead, err := cipher.NewGCM(block)
|
||||
common.Must(err)
|
||||
return aead
|
||||
func aeadCipher(block func(key []byte) (cipher.Block, error), aead func(block cipher.Block) (cipher.AEAD, error)) func(key []byte) (cipher.AEAD, error) {
|
||||
return func(key []byte) (cipher.AEAD, error) {
|
||||
b, err := block(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return aead(b)
|
||||
}
|
||||
}
|
||||
|
||||
type Method struct {
|
||||
name string
|
||||
keySaltLength int
|
||||
constructor func(key []byte) cipher.AEAD
|
||||
constructor func(key []byte) (cipher.AEAD, error)
|
||||
key []byte
|
||||
}
|
||||
|
||||
|
@ -100,7 +90,7 @@ func (m *Method) Name() string {
|
|||
func (m *Method) DialConn(conn net.Conn, destination M.Socksaddr) (net.Conn, error) {
|
||||
shadowsocksConn := &clientConn{
|
||||
Conn: conn,
|
||||
method: m,
|
||||
Method: m,
|
||||
destination: destination,
|
||||
}
|
||||
return shadowsocksConn, shadowsocksConn.writeRequest(nil)
|
||||
|
@ -109,7 +99,7 @@ func (m *Method) DialConn(conn net.Conn, destination M.Socksaddr) (net.Conn, err
|
|||
func (m *Method) DialEarlyConn(conn net.Conn, destination M.Socksaddr) net.Conn {
|
||||
return &clientConn{
|
||||
Conn: conn,
|
||||
method: m,
|
||||
Method: m,
|
||||
destination: destination,
|
||||
}
|
||||
}
|
||||
|
@ -118,58 +108,38 @@ func (m *Method) DialPacketConn(conn net.Conn) N.NetPacketConn {
|
|||
return &clientPacketConn{m, conn}
|
||||
}
|
||||
|
||||
func (m *Method) EncodePacket(buffer *buf.Buffer) error {
|
||||
key := Kdf(m.key, buffer.To(m.keySaltLength), m.keySaltLength)
|
||||
c := m.constructor(common.Dup(key))
|
||||
common.KeepAlive(key)
|
||||
c.Seal(buffer.Index(m.keySaltLength), rw.ZeroBytes[:c.NonceSize()], buffer.From(m.keySaltLength), nil)
|
||||
buffer.Extend(Overhead)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Method) DecodePacket(buffer *buf.Buffer) error {
|
||||
if buffer.Len() < m.keySaltLength {
|
||||
return E.New("bad packet")
|
||||
}
|
||||
key := Kdf(m.key, buffer.To(m.keySaltLength), m.keySaltLength)
|
||||
c := m.constructor(common.Dup(key))
|
||||
common.KeepAlive(key)
|
||||
packet, err := c.Open(buffer.Index(m.keySaltLength), rw.ZeroBytes[:c.NonceSize()], buffer.From(m.keySaltLength), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buffer.Advance(m.keySaltLength)
|
||||
buffer.Truncate(len(packet))
|
||||
return nil
|
||||
}
|
||||
|
||||
type clientConn struct {
|
||||
net.Conn
|
||||
method *Method
|
||||
*Method
|
||||
destination M.Socksaddr
|
||||
reader *Reader
|
||||
writer *Writer
|
||||
}
|
||||
|
||||
func (c *clientConn) writeRequest(payload []byte) error {
|
||||
_salt := buf.Make(c.method.keySaltLength)
|
||||
_salt := buf.StackNewSize(c.keySaltLength)
|
||||
salt := common.Dup(_salt)
|
||||
common.Must1(io.ReadFull(rand.Reader, salt))
|
||||
salt.WriteRandom(c.keySaltLength)
|
||||
|
||||
key := Kdf(c.method.key, salt, c.method.keySaltLength)
|
||||
_key := buf.StackNewSize(c.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
|
||||
Kdf(c.key, salt.Bytes(), key)
|
||||
salt.Release()
|
||||
common.KeepAlive(_salt)
|
||||
writer := NewWriter(
|
||||
c.Conn,
|
||||
c.method.constructor(common.Dup(key)),
|
||||
MaxPacketSize,
|
||||
)
|
||||
common.KeepAlive(key)
|
||||
writeCipher, err := c.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writer := NewWriter(c.Conn, writeCipher, MaxPacketSize)
|
||||
header := writer.Buffer()
|
||||
header.Write(salt)
|
||||
common.Must1(header.Write(salt.Bytes()))
|
||||
bufferedWriter := writer.BufferedWriter(header.Len())
|
||||
|
||||
if len(payload) > 0 {
|
||||
err := M.SocksaddrSerializer.WriteAddrPort(bufferedWriter, c.destination)
|
||||
err = M.SocksaddrSerializer.WriteAddrPort(bufferedWriter, c.destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -179,13 +149,13 @@ func (c *clientConn) writeRequest(payload []byte) error {
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
err := M.SocksaddrSerializer.WriteAddrPort(bufferedWriter, c.destination)
|
||||
err = M.SocksaddrSerializer.WriteAddrPort(bufferedWriter, c.destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err := bufferedWriter.Flush()
|
||||
err = bufferedWriter.Flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -195,50 +165,58 @@ func (c *clientConn) writeRequest(payload []byte) error {
|
|||
}
|
||||
|
||||
func (c *clientConn) readResponse() error {
|
||||
if c.reader != nil {
|
||||
return nil
|
||||
}
|
||||
_salt := buf.Make(c.method.keySaltLength)
|
||||
_salt := buf.StackNewSize(c.keySaltLength)
|
||||
defer common.KeepAlive(_salt)
|
||||
salt := common.Dup(_salt)
|
||||
_, err := io.ReadFull(c.Conn, salt)
|
||||
defer salt.Release()
|
||||
_, err := salt.ReadFullFrom(c.Conn, c.keySaltLength)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_key := buf.StackNewSize(c.keySaltLength)
|
||||
defer common.KeepAlive(_key)
|
||||
key := common.Dup(_key)
|
||||
defer key.Release()
|
||||
Kdf(c.key, salt.Bytes(), key)
|
||||
readCipher, err := c.constructor(key.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key := Kdf(c.method.key, salt, c.method.keySaltLength)
|
||||
defer common.KeepAlive(key)
|
||||
c.reader = NewReader(
|
||||
c.Conn,
|
||||
c.method.constructor(common.Dup(key)),
|
||||
readCipher,
|
||||
MaxPacketSize,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *clientConn) Read(p []byte) (n int, err error) {
|
||||
if err = c.readResponse(); err != nil {
|
||||
return
|
||||
if c.reader == nil {
|
||||
if err = c.readResponse(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return c.reader.Read(p)
|
||||
}
|
||||
|
||||
func (c *clientConn) WriteTo(w io.Writer) (n int64, err error) {
|
||||
if err = c.readResponse(); err != nil {
|
||||
return
|
||||
if c.reader == nil {
|
||||
if err = c.readResponse(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return c.reader.WriteTo(w)
|
||||
}
|
||||
|
||||
func (c *clientConn) Write(p []byte) (n int, err error) {
|
||||
if c.writer != nil {
|
||||
return c.writer.Write(p)
|
||||
if c.writer == nil {
|
||||
err = c.writeRequest(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
err = c.writeRequest(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return len(p), nil
|
||||
return c.writer.Write(p)
|
||||
}
|
||||
|
||||
func (c *clientConn) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
|
@ -259,16 +237,19 @@ type clientPacketConn struct {
|
|||
|
||||
func (c *clientPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
|
||||
defer buffer.Release()
|
||||
header := buffer.ExtendHeader(c.keySaltLength + M.SocksaddrSerializer.AddrPortLen(destination))
|
||||
common.Must1(io.ReadFull(rand.Reader, header[:c.keySaltLength]))
|
||||
err := M.SocksaddrSerializer.WriteAddrPort(buf.With(header[c.keySaltLength:]), destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = c.EncodePacket(buffer)
|
||||
header := buf.With(buffer.ExtendHeader(c.keySaltLength + M.SocksaddrSerializer.AddrPortLen(destination)))
|
||||
header.WriteRandom(c.keySaltLength)
|
||||
common.Must(M.SocksaddrSerializer.WriteAddrPort(header, destination))
|
||||
_key := buf.StackNewSize(c.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
Kdf(c.key, buffer.To(c.keySaltLength), key)
|
||||
writeCipher, err := c.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
writeCipher.Seal(buffer.Index(c.keySaltLength), rw.ZeroBytes[:writeCipher.NonceSize()], buffer.From(c.keySaltLength), nil)
|
||||
return common.Error(c.Write(buffer.Bytes()))
|
||||
}
|
||||
|
||||
|
@ -278,7 +259,24 @@ func (c *clientPacketConn) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
|
|||
return M.Socksaddr{}, err
|
||||
}
|
||||
buffer.Truncate(n)
|
||||
err = c.DecodePacket(buffer)
|
||||
if buffer.Len() < c.keySaltLength {
|
||||
return M.Socksaddr{}, io.ErrShortBuffer
|
||||
}
|
||||
_key := buf.StackNewSize(c.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
Kdf(c.key, buffer.To(c.keySaltLength), key)
|
||||
readCipher, err := c.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return M.Socksaddr{}, err
|
||||
}
|
||||
packet, err := readCipher.Open(buffer.Index(c.keySaltLength), rw.ZeroBytes[:readCipher.NonceSize()], buffer.From(c.keySaltLength), nil)
|
||||
if err != nil {
|
||||
return M.Socksaddr{}, err
|
||||
}
|
||||
buffer.Advance(c.keySaltLength)
|
||||
buffer.Truncate(len(packet))
|
||||
if err != nil {
|
||||
return M.Socksaddr{}, err
|
||||
}
|
||||
|
@ -286,43 +284,22 @@ func (c *clientPacketConn) ReadPacket(buffer *buf.Buffer) (M.Socksaddr, error) {
|
|||
}
|
||||
|
||||
func (c *clientPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
n, err = c.Read(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
b := buf.As(p[:n])
|
||||
err = c.DecodePacket(b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
destination, err := M.SocksaddrSerializer.ReadAddrPort(b)
|
||||
buffer := buf.With(p)
|
||||
destination, err := c.ReadPacket(buffer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
addr = destination.UDPAddr()
|
||||
n = copy(p, b.Bytes())
|
||||
copy(p, buffer.Bytes())
|
||||
return
|
||||
}
|
||||
|
||||
func (c *clientPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
_buffer := buf.StackNewPacket()
|
||||
destination := M.SocksaddrFromNet(addr)
|
||||
_buffer := buf.StackNewSize(c.keySaltLength + M.SocksaddrSerializer.AddrPortLen(destination) + len(p))
|
||||
defer common.KeepAlive(_buffer)
|
||||
buffer := common.Dup(_buffer)
|
||||
defer buffer.Release()
|
||||
buffer.WriteRandom(c.keySaltLength)
|
||||
err = M.SocksaddrSerializer.WriteAddrPort(buffer, M.SocksaddrFromNet(addr))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = buffer.Write(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = c.EncodePacket(buffer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = c.Write(buffer.Bytes())
|
||||
err = c.WritePacket(buffer, destination)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package shadowaead
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
|
@ -23,16 +24,18 @@ import (
|
|||
|
||||
var ErrBadHeader = E.New("bad header")
|
||||
|
||||
var _ shadowsocks.Service = (*Service)(nil)
|
||||
|
||||
type Service struct {
|
||||
name string
|
||||
keySaltLength int
|
||||
constructor func(key []byte) cipher.AEAD
|
||||
constructor func(key []byte) (cipher.AEAD, error)
|
||||
key []byte
|
||||
handler shadowsocks.Handler
|
||||
udpNat *udpnat.Service[netip.AddrPort]
|
||||
}
|
||||
|
||||
func NewService(method string, key []byte, password string, udpTimeout int64, handler shadowsocks.Handler) (shadowsocks.Service, error) {
|
||||
func NewService(method string, key []byte, password string, udpTimeout int64, handler shadowsocks.Handler) (*Service, error) {
|
||||
s := &Service{
|
||||
name: method,
|
||||
handler: handler,
|
||||
|
@ -41,27 +44,19 @@ func NewService(method string, key []byte, password string, udpTimeout int64, ha
|
|||
switch method {
|
||||
case "aes-128-gcm":
|
||||
s.keySaltLength = 16
|
||||
s.constructor = newAESGCM
|
||||
s.constructor = aeadCipher(aes.NewCipher, cipher.NewGCM)
|
||||
case "aes-192-gcm":
|
||||
s.keySaltLength = 24
|
||||
s.constructor = newAESGCM
|
||||
s.constructor = aeadCipher(aes.NewCipher, cipher.NewGCM)
|
||||
case "aes-256-gcm":
|
||||
s.keySaltLength = 32
|
||||
s.constructor = newAESGCM
|
||||
s.constructor = aeadCipher(aes.NewCipher, cipher.NewGCM)
|
||||
case "chacha20-ietf-poly1305":
|
||||
s.keySaltLength = 32
|
||||
s.constructor = func(key []byte) cipher.AEAD {
|
||||
cipher, err := chacha20poly1305.New(key)
|
||||
common.Must(err)
|
||||
return cipher
|
||||
}
|
||||
s.constructor = chacha20poly1305.New
|
||||
case "xchacha20-ietf-poly1305":
|
||||
s.keySaltLength = 32
|
||||
s.constructor = func(key []byte) cipher.AEAD {
|
||||
cipher, err := chacha20poly1305.NewX(key)
|
||||
common.Must(err)
|
||||
return cipher
|
||||
}
|
||||
s.constructor = chacha20poly1305.NewX
|
||||
}
|
||||
if len(key) == s.keySaltLength {
|
||||
s.key = key
|
||||
|
@ -84,21 +79,27 @@ func (s *Service) NewConnection(ctx context.Context, conn net.Conn, metadata M.M
|
|||
}
|
||||
|
||||
func (s *Service) newConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
|
||||
_header := buf.Make(s.keySaltLength + PacketLengthBufferSize + Overhead)
|
||||
_header := buf.StackNewSize(s.keySaltLength + PacketLengthBufferSize + Overhead)
|
||||
defer common.KeepAlive(_header)
|
||||
header := common.Dup(_header)
|
||||
defer header.Release()
|
||||
|
||||
n, err := conn.Read(header)
|
||||
_, err := header.ReadFrom(conn)
|
||||
if err != nil {
|
||||
return E.Cause(err, "read header")
|
||||
} else if n < len(header) {
|
||||
} else if !header.IsFull() {
|
||||
return ErrBadHeader
|
||||
}
|
||||
|
||||
key := Kdf(s.key, header[:s.keySaltLength], s.keySaltLength)
|
||||
reader := NewReader(conn, s.constructor(common.Dup(key)), MaxPacketSize)
|
||||
_key := buf.StackNewSize(s.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
Kdf(s.key, header.To(s.keySaltLength), key)
|
||||
readCipher, err := s.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
reader := NewReader(conn, readCipher, MaxPacketSize)
|
||||
|
||||
err = reader.ReadWithLengthChunk(header[s.keySaltLength:])
|
||||
err = reader.ReadWithLengthChunk(header.From(s.keySaltLength))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -131,22 +132,28 @@ type serverConn struct {
|
|||
}
|
||||
|
||||
func (c *serverConn) writeResponse(payload []byte) (n int, err error) {
|
||||
_salt := buf.Make(c.keySaltLength)
|
||||
_salt := buf.StackNewSize(c.keySaltLength)
|
||||
salt := common.Dup(_salt)
|
||||
common.Must1(io.ReadFull(rand.Reader, salt))
|
||||
salt.WriteRandom(c.keySaltLength)
|
||||
|
||||
key := Kdf(c.key, salt, c.keySaltLength)
|
||||
common.KeepAlive(_salt)
|
||||
_key := buf.StackNewSize(c.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
|
||||
writer := NewWriter(
|
||||
c.Conn,
|
||||
c.constructor(common.Dup(key)),
|
||||
MaxPacketSize,
|
||||
)
|
||||
common.KeepAlive(key)
|
||||
Kdf(c.key, salt.Bytes(), key)
|
||||
writeCipher, err := c.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
salt.Release()
|
||||
common.KeepAlive(_salt)
|
||||
return
|
||||
}
|
||||
writer := NewWriter(c.Conn, writeCipher, MaxPacketSize)
|
||||
|
||||
header := writer.Buffer()
|
||||
header.Write(salt)
|
||||
common.Must1(header.Write(salt.Bytes()))
|
||||
salt.Release()
|
||||
common.KeepAlive(_salt)
|
||||
|
||||
bufferedWriter := writer.BufferedWriter(header.Len())
|
||||
if len(payload) > 0 {
|
||||
|
@ -206,12 +213,18 @@ func (s *Service) NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.
|
|||
|
||||
func (s *Service) newPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata M.Metadata) error {
|
||||
if buffer.Len() < s.keySaltLength {
|
||||
return E.New("bad packet")
|
||||
return io.ErrShortBuffer
|
||||
}
|
||||
key := Kdf(s.key, buffer.To(s.keySaltLength), s.keySaltLength)
|
||||
c := s.constructor(common.Dup(key))
|
||||
common.KeepAlive(key)
|
||||
packet, err := c.Open(buffer.Index(s.keySaltLength), rw.ZeroBytes[:c.NonceSize()], buffer.From(s.keySaltLength), nil)
|
||||
_key := buf.StackNewSize(s.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
Kdf(s.key, buffer.To(s.keySaltLength), key)
|
||||
readCipher, err := s.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
packet, err := readCipher.Open(buffer.Index(s.keySaltLength), rw.ZeroBytes[:readCipher.NonceSize()], buffer.From(s.keySaltLength), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -245,10 +258,13 @@ func (w *serverPacketWriter) WritePacket(buffer *buf.Buffer, destination M.Socks
|
|||
buffer.Release()
|
||||
return err
|
||||
}
|
||||
key := Kdf(w.key, buffer.To(w.keySaltLength), w.keySaltLength)
|
||||
c := w.constructor(common.Dup(key))
|
||||
common.KeepAlive(key)
|
||||
c.Seal(buffer.From(w.keySaltLength)[:0], rw.ZeroBytes[:c.NonceSize()], buffer.From(w.keySaltLength), nil)
|
||||
_key := buf.StackNewSize(w.keySaltLength)
|
||||
key := common.Dup(_key)
|
||||
Kdf(w.key, buffer.To(w.keySaltLength), key)
|
||||
writeCipher, err := w.constructor(key.Bytes())
|
||||
key.Release()
|
||||
common.KeepAlive(_key)
|
||||
writeCipher.Seal(buffer.From(w.keySaltLength)[:0], rw.ZeroBytes[:writeCipher.NonceSize()], buffer.From(w.keySaltLength), nil)
|
||||
buffer.Extend(Overhead)
|
||||
return w.source.WritePacket(buffer, M.SocksaddrFromNet(w.nat.LocalAddr()))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue