Use shadowsocket's bloomring for shadowsocket's replay protection (#764)

* use shadowsocket's bloomring for shadowsocket's replay protection

* added shadowsockets iv check for tcp socket

* Rename to shadowsockets iv check

* shadowsocks iv check config file

* iv check should proceed after decryption

* use shadowsocket's bloomring for shadowsocket's replay protection

* Chore: format code (#842)

Co-authored-by: Shelikhoo <xiaokangwang@outlook.com>
Co-authored-by: Loyalsoldier <10487845+Loyalsoldier@users.noreply.github.com>
This commit is contained in:
yuhan6665 2021-10-22 00:03:09 -04:00 committed by 世界
parent 0f0a424e8c
commit 45dc97e2b6
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
9 changed files with 138 additions and 53 deletions

View file

@ -71,6 +71,7 @@ func ReadTCPSession(validator *Validator, reader io.Reader) (*protocol.RequestHe
var user *protocol.MemoryUser
var ivLen int32
var iv []byte
var err error
count := validator.Count()
@ -91,6 +92,9 @@ func ReadTCPSession(validator *Validator, reader io.Reader) (*protocol.RequestHe
user, aead, _, ivLen, err = validator.Get(bs, protocol.RequestCommandTCP)
if user != nil {
if ivLen > 0 {
iv = append([]byte(nil), bs[:ivLen]...)
}
reader = &FullReader{reader, bs[ivLen:]}
auth := &crypto.AEADAuthenticator{
AEAD: aead,
@ -108,7 +112,6 @@ func ReadTCPSession(validator *Validator, reader io.Reader) (*protocol.RequestHe
user, ivLen = validator.GetOnlyUser()
account := user.Account.(*MemoryAccount)
hashkdf.Write(account.Key)
var iv []byte
if ivLen > 0 {
if _, err := buffer.ReadFullFrom(reader, ivLen); err != nil {
readSizeRemain -= int(buffer.Len())
@ -154,6 +157,13 @@ func ReadTCPSession(validator *Validator, reader io.Reader) (*protocol.RequestHe
return nil, nil, newError("invalid remote address.")
}
account := user.Account.(*MemoryAccount)
if ivError := account.CheckIV(iv); ivError != nil {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader, readSizeRemain)
return nil, nil, newError("failed iv check").Base(ivError)
}
return request, br, nil
}
@ -171,6 +181,9 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
if account.Cipher.IVSize() > 0 {
iv = make([]byte, account.Cipher.IVSize())
common.Must2(rand.Read(iv))
if ivError := account.CheckIV(iv); ivError != nil {
return nil, newError("failed to mark outgoing iv").Base(ivError)
}
if err := buf.WriteAllBytes(writer, iv, nil); err != nil {
return nil, newError("failed to write IV")
}
@ -205,6 +218,10 @@ func ReadTCPResponse(user *protocol.MemoryUser, reader io.Reader) (buf.Reader, e
}
}
if ivError := account.CheckIV(iv); ivError != nil {
return nil, newError("failed iv check").Base(ivError)
}
return account.Cipher.NewDecryptionReader(account.Key, iv, reader)
}
@ -216,6 +233,9 @@ func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Wr
if account.Cipher.IVSize() > 0 {
iv = make([]byte, account.Cipher.IVSize())
common.Must2(rand.Read(iv))
if ivError := account.CheckIV(iv); ivError != nil {
return nil, newError("failed to mark outgoing iv").Base(ivError)
}
if err := buf.WriteAllBytes(writer, iv, nil); err != nil {
return nil, newError("failed to write IV.").Base(err)
}