mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-08-22 17:46:48 +08:00
Allow paddings before handshake; CTR 128->256; Fix panic
https://github.com/XTLS/Xray-core/pull/4952#issuecomment-3187832651
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"crypto/sha256"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -26,13 +27,12 @@ func init() {
|
||||
|
||||
type ClientInstance struct {
|
||||
sync.RWMutex
|
||||
nfsEKey *mlkem.EncapsulationKey768
|
||||
nfsEKeySha256 [32]byte
|
||||
xor uint32
|
||||
minutes time.Duration
|
||||
expire time.Time
|
||||
baseKey []byte
|
||||
ticket []byte
|
||||
nfsEKey *mlkem.EncapsulationKey768
|
||||
xorKey []byte
|
||||
minutes time.Duration
|
||||
expire time.Time
|
||||
baseKey []byte
|
||||
ticket []byte
|
||||
}
|
||||
|
||||
type ClientConn struct {
|
||||
@@ -49,10 +49,17 @@ type ClientConn struct {
|
||||
}
|
||||
|
||||
func (i *ClientInstance) Init(nfsEKeyBytes []byte, xor uint32, minutes time.Duration) (err error) {
|
||||
if i.nfsEKey != nil {
|
||||
err = errors.New("already initialized")
|
||||
return
|
||||
}
|
||||
i.nfsEKey, err = mlkem.NewEncapsulationKey768(nfsEKeyBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if xor > 0 {
|
||||
i.nfsEKeySha256 = sha256.Sum256(nfsEKeyBytes)
|
||||
i.xor = xor
|
||||
xorKey := sha256.Sum256(nfsEKeyBytes)
|
||||
i.xorKey = xorKey[:]
|
||||
}
|
||||
i.minutes = minutes
|
||||
return
|
||||
@@ -62,8 +69,8 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
if i.nfsEKey == nil {
|
||||
return nil, errors.New("uninitialized")
|
||||
}
|
||||
if i.xor > 0 {
|
||||
conn = NewXorConn(conn, i.nfsEKeySha256[:])
|
||||
if i.xorKey != nil {
|
||||
conn = NewXorConn(conn, i.xorKey)
|
||||
}
|
||||
c := &ClientConn{Conn: conn}
|
||||
|
||||
@@ -99,14 +106,14 @@ func (i *ClientInstance) Handshake(conn net.Conn) (net.Conn, error) {
|
||||
}
|
||||
// client can send more padding / NFS AEAD messages if needed
|
||||
|
||||
_, t, l, err := ReadAndDecodeHeader(c.Conn)
|
||||
_, t, l, err := ReadAndDiscardPaddings(c.Conn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if t != 1 {
|
||||
return nil, errors.New("unexpected type ", t, ", expect server hello")
|
||||
}
|
||||
|
||||
peerServerHello := make([]byte, 1088+21)
|
||||
if l != len(peerServerHello) {
|
||||
return nil, errors.New("unexpected length ", l, " for server hello")
|
||||
@@ -183,27 +190,9 @@ func (c *ClientConn) Read(b []byte) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
if c.peerAead == nil {
|
||||
var t byte
|
||||
var l int
|
||||
var err error
|
||||
if c.instance == nil { // from 1-RTT
|
||||
for {
|
||||
if _, t, l, err = ReadAndDecodeHeader(c.Conn); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if t != 23 {
|
||||
break
|
||||
}
|
||||
if _, err := io.ReadFull(c.Conn, make([]byte, l)); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
h := make([]byte, 5)
|
||||
if _, err := io.ReadFull(c.Conn, h); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if t, l, err = DecodeHeader(h); err != nil {
|
||||
_, t, l, err := ReadAndDiscardPaddings(c.Conn)
|
||||
if err != nil {
|
||||
if c.instance != nil && strings.HasPrefix(err.Error(), "invalid header: ") { // from 0-RTT
|
||||
c.instance.Lock()
|
||||
if bytes.Equal(c.ticket, c.instance.ticket) {
|
||||
c.instance.expire = time.Now() // expired
|
||||
@@ -211,6 +200,7 @@ func (c *ClientConn) Read(b []byte) (int, error) {
|
||||
c.instance.Unlock()
|
||||
return 0, errors.New("new handshake needed")
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
if t != 0 {
|
||||
return 0, errors.New("unexpected type ", t, ", expect random hello")
|
||||
|
Reference in New Issue
Block a user