github.com/xmplusdev/xray-core@v1.8.10/proxy/vmess/aead/authid.go (about) 1 package aead 2 3 import ( 4 "bytes" 5 "crypto/aes" 6 "crypto/cipher" 7 rand3 "crypto/rand" 8 "encoding/binary" 9 "errors" 10 "hash/crc32" 11 "io" 12 "math" 13 "time" 14 15 "github.com/xmplusdev/xray-core/common" 16 "github.com/xmplusdev/xray-core/common/antireplay" 17 ) 18 19 var ( 20 ErrNotFound = errors.New("user do not exist") 21 ErrReplay = errors.New("replayed request") 22 ) 23 24 func CreateAuthID(cmdKey []byte, time int64) [16]byte { 25 buf := bytes.NewBuffer(nil) 26 common.Must(binary.Write(buf, binary.BigEndian, time)) 27 var zero uint32 28 common.Must2(io.CopyN(buf, rand3.Reader, 4)) 29 zero = crc32.ChecksumIEEE(buf.Bytes()) 30 common.Must(binary.Write(buf, binary.BigEndian, zero)) 31 aesBlock := NewCipherFromKey(cmdKey) 32 if buf.Len() != 16 { 33 panic("Size unexpected") 34 } 35 var result [16]byte 36 aesBlock.Encrypt(result[:], buf.Bytes()) 37 return result 38 } 39 40 func NewCipherFromKey(cmdKey []byte) cipher.Block { 41 aesBlock, err := aes.NewCipher(KDF16(cmdKey, KDFSaltConstAuthIDEncryptionKey)) 42 if err != nil { 43 panic(err) 44 } 45 return aesBlock 46 } 47 48 type AuthIDDecoder struct { 49 s cipher.Block 50 } 51 52 func NewAuthIDDecoder(cmdKey []byte) *AuthIDDecoder { 53 return &AuthIDDecoder{NewCipherFromKey(cmdKey)} 54 } 55 56 func (aidd *AuthIDDecoder) Decode(data [16]byte) (int64, uint32, int32, []byte) { 57 aidd.s.Decrypt(data[:], data[:]) 58 var t int64 59 var zero uint32 60 var rand int32 61 reader := bytes.NewReader(data[:]) 62 common.Must(binary.Read(reader, binary.BigEndian, &t)) 63 common.Must(binary.Read(reader, binary.BigEndian, &rand)) 64 common.Must(binary.Read(reader, binary.BigEndian, &zero)) 65 return t, zero, rand, data[:] 66 } 67 68 func NewAuthIDDecoderHolder() *AuthIDDecoderHolder { 69 return &AuthIDDecoderHolder{make(map[string]*AuthIDDecoderItem), antireplay.NewReplayFilter(120)} 70 } 71 72 type AuthIDDecoderHolder struct { 73 decoders map[string]*AuthIDDecoderItem 74 filter *antireplay.ReplayFilter 75 } 76 77 type AuthIDDecoderItem struct { 78 dec *AuthIDDecoder 79 ticket interface{} 80 } 81 82 func NewAuthIDDecoderItem(key [16]byte, ticket interface{}) *AuthIDDecoderItem { 83 return &AuthIDDecoderItem{ 84 dec: NewAuthIDDecoder(key[:]), 85 ticket: ticket, 86 } 87 } 88 89 func (a *AuthIDDecoderHolder) AddUser(key [16]byte, ticket interface{}) { 90 a.decoders[string(key[:])] = NewAuthIDDecoderItem(key, ticket) 91 } 92 93 func (a *AuthIDDecoderHolder) RemoveUser(key [16]byte) { 94 delete(a.decoders, string(key[:])) 95 } 96 97 func (a *AuthIDDecoderHolder) Match(authID [16]byte) (interface{}, error) { 98 for _, v := range a.decoders { 99 t, z, _, d := v.dec.Decode(authID) 100 if z != crc32.ChecksumIEEE(d[:12]) { 101 continue 102 } 103 104 if t < 0 { 105 continue 106 } 107 108 if math.Abs(math.Abs(float64(t))-float64(time.Now().Unix())) > 120 { 109 continue 110 } 111 112 if !a.filter.Check(authID[:]) { 113 return nil, ErrReplay 114 } 115 116 return v.ticket, nil 117 } 118 return nil, ErrNotFound 119 }