auth.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package mtproto
  2. import (
  3. "crypto/rand"
  4. "crypto/sha256"
  5. "io"
  6. "sync"
  7. "v2ray.com/core/common"
  8. )
  9. const (
  10. HeaderSize = 64
  11. )
  12. type Authentication struct {
  13. Header [HeaderSize]byte
  14. DecodingKey [32]byte
  15. EncodingKey [32]byte
  16. DecodingNonce [16]byte
  17. EncodingNonce [16]byte
  18. }
  19. func (a *Authentication) DataCenterID() uint16 {
  20. x := ((int16(a.Header[61]) << 8) | int16(a.Header[60]))
  21. if x < 0 {
  22. x = -x
  23. }
  24. return uint16(x) - 1
  25. }
  26. func (a *Authentication) ApplySecret(b []byte) {
  27. a.DecodingKey = sha256.Sum256(append(a.DecodingKey[:], b...))
  28. a.EncodingKey = sha256.Sum256(append(a.EncodingKey[:], b...))
  29. }
  30. func generateRandomBytes(random []byte) {
  31. for {
  32. common.Must2(rand.Read(random))
  33. if random[0] == 0xef {
  34. continue
  35. }
  36. val := (uint32(random[3]) << 24) | (uint32(random[2]) << 16) | (uint32(random[1]) << 8) | uint32(random[0])
  37. if val == 0x44414548 || val == 0x54534f50 || val == 0x20544547 || val == 0x4954504f || val == 0xeeeeeeee {
  38. continue
  39. }
  40. if 0x00000000 == (uint32(random[7])<<24)|(uint32(random[6])<<16)|(uint32(random[5])<<8)|uint32(random[4]) {
  41. continue
  42. }
  43. random[56] = 0xef
  44. random[57] = 0xef
  45. random[58] = 0xef
  46. random[59] = 0xef
  47. return
  48. }
  49. }
  50. func NewAuthentication() *Authentication {
  51. auth := getAuthenticationObject()
  52. random := auth.Header[:]
  53. generateRandomBytes(random)
  54. copy(auth.EncodingKey[:], random[8:])
  55. copy(auth.EncodingNonce[:], random[8+32:])
  56. keyivInverse := Inverse(random[8 : 8+32+16])
  57. copy(auth.DecodingKey[:], keyivInverse)
  58. copy(auth.DecodingNonce[:], keyivInverse[32:])
  59. return auth
  60. }
  61. func ReadAuthentication(reader io.Reader) (*Authentication, error) {
  62. auth := getAuthenticationObject()
  63. if _, err := io.ReadFull(reader, auth.Header[:]); err != nil {
  64. putAuthenticationObject(auth)
  65. return nil, err
  66. }
  67. copy(auth.DecodingKey[:], auth.Header[8:])
  68. copy(auth.DecodingNonce[:], auth.Header[8+32:])
  69. keyivInverse := Inverse(auth.Header[8 : 8+32+16])
  70. copy(auth.EncodingKey[:], keyivInverse)
  71. copy(auth.EncodingNonce[:], keyivInverse[32:])
  72. return auth, nil
  73. }
  74. // Inverse returns a new byte array. It is a sequence of bytes when the input is read from end to beginning.Inverse
  75. // Visible for testing only.
  76. func Inverse(b []byte) []byte {
  77. lenb := len(b)
  78. b2 := make([]byte, lenb)
  79. for i, v := range b {
  80. b2[lenb-i-1] = v
  81. }
  82. return b2
  83. }
  84. var (
  85. authPool = sync.Pool{
  86. New: func() interface{} {
  87. return new(Authentication)
  88. },
  89. }
  90. )
  91. func getAuthenticationObject() *Authentication {
  92. return authPool.Get().(*Authentication)
  93. }
  94. func putAuthenticationObject(auth *Authentication) {
  95. authPool.Put(auth)
  96. }