Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

obfuscator.go 1.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package obfuscation
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/sha256"
  6. "crypto/subtle"
  7. "encoding/hex"
  8. "fmt"
  9. "hash"
  10. "io"
  11. "github.com/9seconds/mtg/v2/essentials"
  12. )
  13. type Obfuscator struct {
  14. Secret []byte
  15. }
  16. func (o Obfuscator) ReadHandshake(r essentials.Conn) (int, essentials.Conn, error) {
  17. frame := handshakeFrame{}
  18. if _, err := io.ReadFull(r, frame.data[:]); err != nil {
  19. return 0, nil, fmt.Errorf("cannot read frame: %w", err)
  20. }
  21. hasher := sha256.New()
  22. recvCipher := o.getCipher(&frame, hasher)
  23. frame.revert()
  24. hasher.Reset()
  25. sendCipher := o.getCipher(&frame, hasher)
  26. recvCipher.XORKeyStream(frame.data[:], frame.data[:])
  27. if val := frame.connectionType(); subtle.ConstantTimeCompare(val, hfConnectionType[:]) != 1 {
  28. return 0, nil, fmt.Errorf("unsupported connection type: %s", hex.EncodeToString(val))
  29. }
  30. cn := conn{
  31. Conn: r,
  32. recvCipher: recvCipher,
  33. sendCipher: sendCipher,
  34. }
  35. return frame.dc(), cn, nil
  36. }
  37. func (o Obfuscator) SendHandshake(w essentials.Conn, dc int) (essentials.Conn, error) {
  38. frame := generateHandshake(dc)
  39. copyFrame := frame
  40. hasher := sha256.New()
  41. sendCipher := o.getCipher(&frame, hasher)
  42. frame.revert()
  43. hasher.Reset()
  44. recvCipher := o.getCipher(&frame, hasher)
  45. sendCipher.XORKeyStream(frame.data[:], frame.data[:])
  46. copy(frame.key(), copyFrame.key())
  47. copy(frame.iv(), copyFrame.iv())
  48. if _, err := w.Write(frame.data[:]); err != nil {
  49. return nil, fmt.Errorf("cannot send a handshake: %w", err)
  50. }
  51. return conn{
  52. Conn: w,
  53. recvCipher: recvCipher,
  54. sendCipher: sendCipher,
  55. }, nil
  56. }
  57. func (o Obfuscator) getCipher(f *handshakeFrame, hasher hash.Hash) cipher.Stream {
  58. blockKey := f.key()
  59. if o.Secret != nil {
  60. hasher.Write(blockKey)
  61. hasher.Write(o.Secret)
  62. blockKey = hasher.Sum(nil)
  63. }
  64. block, _ := aes.NewCipher(blockKey)
  65. return cipher.NewCTR(block, f.iv())
  66. }