Files
Xray-core/proxy/vmess/aead/authid.go
风扇滑翔翼 a0c63ba1cf
Some checks failed
Build and Release for Windows 7 / check-assets (push) Has been cancelled
Build and Release for Windows 7 / build (win7-32, 386, windows) (push) Has been cancelled
Build and Release for Windows 7 / build (win7-64, amd64, windows) (push) Has been cancelled
Build and Release / check-assets (push) Has been cancelled
Build and Release / build (386, freebsd, ) (push) Has been cancelled
Build and Release / build (386, linux, ) (push) Has been cancelled
Build and Release / build (386, openbsd, ) (push) Has been cancelled
Build and Release / build (386, windows, ) (push) Has been cancelled
Build and Release / build (amd64, android, android-amd64) (push) Has been cancelled
Build and Release / build (amd64, darwin, ) (push) Has been cancelled
Build and Release / build (amd64, freebsd, ) (push) Has been cancelled
Build and Release / build (amd64, linux, ) (push) Has been cancelled
Build and Release / build (amd64, openbsd, ) (push) Has been cancelled
Build and Release / build (amd64, windows, ) (push) Has been cancelled
Build and Release / build (arm, 5, linux) (push) Has been cancelled
Build and Release / build (arm, 6, linux) (push) Has been cancelled
Build and Release / build (arm, 7, freebsd) (push) Has been cancelled
Build and Release / build (arm, 7, linux) (push) Has been cancelled
Build and Release / build (arm, 7, openbsd) (push) Has been cancelled
Build and Release / build (arm, 7, windows) (push) Has been cancelled
Build and Release / build (arm64, android) (push) Has been cancelled
Build and Release / build (arm64, darwin) (push) Has been cancelled
Build and Release / build (arm64, freebsd) (push) Has been cancelled
Build and Release / build (arm64, linux) (push) Has been cancelled
Build and Release / build (arm64, openbsd) (push) Has been cancelled
Build and Release / build (arm64, windows) (push) Has been cancelled
Build and Release / build (loong64, linux) (push) Has been cancelled
Build and Release / build (mips, linux) (push) Has been cancelled
Build and Release / build (mips64, linux) (push) Has been cancelled
Build and Release / build (mips64le, linux) (push) Has been cancelled
Build and Release / build (mipsle, linux) (push) Has been cancelled
Build and Release / build (ppc64, linux) (push) Has been cancelled
Build and Release / build (ppc64le, linux) (push) Has been cancelled
Build and Release / build (riscv64, linux) (push) Has been cancelled
Build and Release / build (s390x, linux) (push) Has been cancelled
Test / check-assets (push) Has been cancelled
Test / test (macos-latest) (push) Has been cancelled
Test / test (ubuntu-latest) (push) Has been cancelled
Test / test (windows-latest) (push) Has been cancelled
Scheduled assets update / geodat (push) Has been cancelled
VMess: Returns clearer error in AuthIDDecoderHolder (#5090)
2025-09-08 14:19:17 +00:00

122 lines
2.9 KiB
Go

package aead
import (
"bytes"
"crypto/aes"
"crypto/cipher"
rand3 "crypto/rand"
"encoding/binary"
"errors"
"hash/crc32"
"io"
"math"
"time"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/antireplay"
)
var (
ErrNotFound = errors.New("user do not exist")
ErrNeagtiveTime = errors.New("timestamp is negative")
ErrInvalidTime = errors.New("invalid timestamp, perhaps unsynchronized time")
ErrReplay = errors.New("replayed request")
)
func CreateAuthID(cmdKey []byte, time int64) [16]byte {
buf := bytes.NewBuffer(nil)
common.Must(binary.Write(buf, binary.BigEndian, time))
var zero uint32
common.Must2(io.CopyN(buf, rand3.Reader, 4))
zero = crc32.ChecksumIEEE(buf.Bytes())
common.Must(binary.Write(buf, binary.BigEndian, zero))
aesBlock := NewCipherFromKey(cmdKey)
if buf.Len() != 16 {
panic("Size unexpected")
}
var result [16]byte
aesBlock.Encrypt(result[:], buf.Bytes())
return result
}
func NewCipherFromKey(cmdKey []byte) cipher.Block {
aesBlock, err := aes.NewCipher(KDF16(cmdKey, KDFSaltConstAuthIDEncryptionKey))
if err != nil {
panic(err)
}
return aesBlock
}
type AuthIDDecoder struct {
s cipher.Block
}
func NewAuthIDDecoder(cmdKey []byte) *AuthIDDecoder {
return &AuthIDDecoder{NewCipherFromKey(cmdKey)}
}
func (aidd *AuthIDDecoder) Decode(data [16]byte) (int64, uint32, int32, []byte) {
aidd.s.Decrypt(data[:], data[:])
var t int64
var zero uint32
var rand int32
reader := bytes.NewReader(data[:])
common.Must(binary.Read(reader, binary.BigEndian, &t))
common.Must(binary.Read(reader, binary.BigEndian, &rand))
common.Must(binary.Read(reader, binary.BigEndian, &zero))
return t, zero, rand, data[:]
}
func NewAuthIDDecoderHolder() *AuthIDDecoderHolder {
return &AuthIDDecoderHolder{make(map[string]*AuthIDDecoderItem), antireplay.NewReplayFilter(120)}
}
type AuthIDDecoderHolder struct {
decoders map[string]*AuthIDDecoderItem
filter *antireplay.ReplayFilter
}
type AuthIDDecoderItem struct {
dec *AuthIDDecoder
ticket interface{}
}
func NewAuthIDDecoderItem(key [16]byte, ticket interface{}) *AuthIDDecoderItem {
return &AuthIDDecoderItem{
dec: NewAuthIDDecoder(key[:]),
ticket: ticket,
}
}
func (a *AuthIDDecoderHolder) AddUser(key [16]byte, ticket interface{}) {
a.decoders[string(key[:])] = NewAuthIDDecoderItem(key, ticket)
}
func (a *AuthIDDecoderHolder) RemoveUser(key [16]byte) {
delete(a.decoders, string(key[:]))
}
func (a *AuthIDDecoderHolder) Match(authID [16]byte) (interface{}, error) {
for _, v := range a.decoders {
t, z, _, d := v.dec.Decode(authID)
if z != crc32.ChecksumIEEE(d[:12]) {
continue
}
if t < 0 {
return nil, ErrNeagtiveTime
}
if math.Abs(math.Abs(float64(t))-float64(time.Now().Unix())) > 120 {
return nil, ErrInvalidTime
}
if !a.filter.Check(authID[:]) {
return nil, ErrReplay
}
return v.ticket, nil
}
return nil, ErrNotFound
}