authid.go 2.9 KB

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