瀏覽代碼

handle AEAD cipher

Darien Raymond 8 年之前
父節點
當前提交
80258c0542
共有 2 個文件被更改,包括 19 次插入2 次删除
  1. 13 0
      proxy/shadowsocks/config.go
  2. 6 2
      proxy/shadowsocks/protocol.go

+ 13 - 0
proxy/shadowsocks/config.go

@@ -102,12 +102,17 @@ type Cipher interface {
 	IVSize() int
 	NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error)
 	NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error)
+	IsAEAD() bool
 }
 
 type AesCfb struct {
 	KeyBytes int
 }
 
+func (*AesCfb) IsAEAD() bool {
+	return false
+}
+
 func (v *AesCfb) KeySize() int {
 	return v.KeyBytes
 }
@@ -132,6 +137,10 @@ type AEADCipher struct {
 	AEADAuthCreator func(key []byte) cipher.AEAD
 }
 
+func (*AEADCipher) IsAEAD() bool {
+	return true
+}
+
 func (c *AEADCipher) KeySize() int {
 	return c.KeyBytes
 }
@@ -170,6 +179,10 @@ type ChaCha20 struct {
 	IVBytes int
 }
 
+func (*ChaCha20) IsAEAD() bool {
+	return false
+}
+
 func (v *ChaCha20) KeySize() int {
 	return 32
 }

+ 6 - 2
proxy/shadowsocks/protocol.go

@@ -61,7 +61,7 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
 		request.Option.Set(RequestOptionOneTimeAuth)
 	}
 
-	if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled {
+	if request.Option.Has(RequestOptionOneTimeAuth) && (account.OneTimeAuth == Account_Disabled || account.Cipher.IsAEAD()) {
 		return nil, nil, newError("rejecting connection with OTA enabled, while server disables OTA")
 	}
 
@@ -136,8 +136,12 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
 	}
 	account := rawAccount.(*ShadowsocksAccount)
 
+	if account.Cipher.IsAEAD() {
+		request.Option.Clear(RequestOptionOneTimeAuth)
+	}
+
 	iv := make([]byte, account.Cipher.IVSize())
-	rand.Read(iv)
+	common.Must2(rand.Read(iv))
 	_, err = writer.Write(iv)
 	if err != nil {
 		return nil, newError("failed to write IV")