github.com/EagleQL/Xray-core@v1.4.3/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/xtls/xray-core/common"
    16  	"github.com/xtls/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  }