| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- 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")
- 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 {
- continue
- }
- if math.Abs(math.Abs(float64(t))-float64(time.Now().Unix())) > 120 {
- continue
- }
- if !a.filter.Check(authID[:]) {
- return nil, ErrReplay
- }
- return v.ticket, nil
- }
- return nil, ErrNotFound
- }
|