implementation for Shadowsocks AEAD

This commit is contained in:
Darien Raymond
2017-11-26 00:51:54 +01:00
parent 41961dbd60
commit 713ebfb203
5 changed files with 173 additions and 49 deletions

View File

@@ -8,7 +8,6 @@ import (
"v2ray.com/core/common"
"v2ray.com/core/common/bitmask"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/crypto"
"v2ray.com/core/common/net"
"v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial"
@@ -40,11 +39,11 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
iv := append([]byte(nil), buffer.BytesTo(ivLen)...)
stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
r, err := account.Cipher.NewDecryptionReader(account.Key, iv, reader)
if err != nil {
return nil, nil, newError("failed to initialize decoding stream").Base(err).AtError()
}
reader = crypto.NewCryptionReader(stream, reader)
reader = r.(io.Reader)
authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
request := &protocol.RequestHeader{
@@ -144,12 +143,12 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
return nil, newError("failed to write IV")
}
stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
w, err := account.Cipher.NewEncryptionWriter(account.Key, iv, writer)
if err != nil {
return nil, newError("failed to create encoding stream").Base(err).AtError()
}
writer = crypto.NewCryptionWriter(stream, writer)
writer = w.(io.Writer)
header := buf.NewLocal(512)
@@ -208,11 +207,7 @@ func ReadTCPResponse(user *protocol.User, reader io.Reader) (buf.Reader, error)
return nil, newError("failed to read IV").Base(err)
}
stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
if err != nil {
return nil, newError("failed to initialize decoding stream").Base(err).AtError()
}
return buf.NewReader(crypto.NewCryptionReader(stream, reader)), nil
return account.Cipher.NewDecryptionReader(account.Key, iv, reader)
}
func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) {
@@ -230,12 +225,7 @@ func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Wr
return nil, newError("failed to write IV.").Base(err)
}
stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
if err != nil {
return nil, newError("failed to create encoding stream.").Base(err).AtError()
}
return buf.NewWriter(crypto.NewCryptionWriter(stream, writer)), nil
return account.Cipher.NewEncryptionWriter(account.Key, iv, writer)
}
func EncodeUDPPacket(request *protocol.RequestHeader, payload []byte) (*buf.Buffer, error) {
@@ -251,36 +241,41 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload []byte) (*buf.Buff
buffer.AppendSupplier(buf.ReadFullFrom(rand.Reader, ivLen))
iv := buffer.Bytes()
payloadBuffer := buf.NewLocal(512)
defer payloadBuffer.Release()
switch request.Address.Family() {
case net.AddressFamilyIPv4:
buffer.AppendBytes(AddrTypeIPv4)
buffer.Append([]byte(request.Address.IP()))
payloadBuffer.AppendBytes(AddrTypeIPv4)
payloadBuffer.Append([]byte(request.Address.IP()))
case net.AddressFamilyIPv6:
buffer.AppendBytes(AddrTypeIPv6)
buffer.Append([]byte(request.Address.IP()))
payloadBuffer.AppendBytes(AddrTypeIPv6)
payloadBuffer.Append([]byte(request.Address.IP()))
case net.AddressFamilyDomain:
buffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain())))
buffer.Append([]byte(request.Address.Domain()))
payloadBuffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain())))
payloadBuffer.Append([]byte(request.Address.Domain()))
default:
return nil, newError("unsupported address type: ", request.Address.Family()).AtError()
}
buffer.AppendSupplier(serial.WriteUint16(uint16(request.Port)))
buffer.Append(payload)
payloadBuffer.AppendSupplier(serial.WriteUint16(uint16(request.Port)))
payloadBuffer.Append(payload)
if request.Option.Has(RequestOptionOneTimeAuth) {
authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
buffer.SetByte(ivLen, buffer.Byte(ivLen)|0x10)
payloadBuffer.SetByte(0, payloadBuffer.Byte(0)|0x10)
buffer.AppendSupplier(authenticator.Authenticate(buffer.BytesFrom(ivLen)))
payloadBuffer.AppendSupplier(authenticator.Authenticate(payloadBuffer.Bytes()))
}
stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
w, err := account.Cipher.NewEncryptionWriter(account.Key, iv, buffer)
if err != nil {
return nil, newError("failed to create encoding stream").Base(err).AtError()
}
if err := w.WriteMultiBuffer(buf.NewMultiBufferValue(payloadBuffer)); err != nil {
return nil, newError("failed to encrypt UDP payload").Base(err).AtWarning()
}
stream.XORKeyStream(buffer.BytesFrom(ivLen), buffer.BytesFrom(ivLen))
return buffer, nil
}
@@ -295,11 +290,17 @@ func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.Reques
iv := payload.BytesTo(ivLen)
payload.SliceFrom(ivLen)
stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
r, err := account.Cipher.NewDecryptionReader(account.Key, iv, payload)
if err != nil {
return nil, nil, newError("failed to initialize decoding stream").Base(err).AtError()
}
stream.XORKeyStream(payload.Bytes(), payload.Bytes())
mb, err := r.ReadMultiBuffer()
if err != nil {
return nil, nil, newError("failed to decrypt UDP payload").Base(err).AtWarning()
}
payload.Release()
payload = mb.SplitFirst()
mb.Release()
authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
request := &protocol.RequestHeader{