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
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

obfuscated2.go 2.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package obfuscated2
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/sha256"
  6. "github.com/juju/errors"
  7. )
  8. // Obfuscated2 contains AES CTR encryption and decryption streams
  9. // for telegram connection.
  10. type Obfuscated2 struct {
  11. Decryptor cipher.Stream
  12. Encryptor cipher.Stream
  13. }
  14. // ParseObfuscated2ClientFrame parses client frame. Please check this link for
  15. // details: http://telegra.ph/telegram-blocks-wtf-05-26
  16. //
  17. // Beware, link above is in russian.
  18. func ParseObfuscated2ClientFrame(secret []byte, frame *Frame) (*Obfuscated2, int16, error) {
  19. decHasher := sha256.New()
  20. decHasher.Write(frame.Key()) // nolint: errcheck
  21. decHasher.Write(secret) // nolint: errcheck
  22. decryptor := makeStreamCipher(decHasher.Sum(nil), frame.IV())
  23. invertedFrame := frame.Invert()
  24. encHasher := sha256.New()
  25. encHasher.Write(invertedFrame.Key()) // nolint: errcheck
  26. encHasher.Write(secret) // nolint: errcheck
  27. encryptor := makeStreamCipher(encHasher.Sum(nil), invertedFrame.IV())
  28. decryptedFrame := MakeFrame()
  29. defer ReturnFrame(decryptedFrame)
  30. decryptor.XORKeyStream(*decryptedFrame, *frame)
  31. if !decryptedFrame.Valid() {
  32. return nil, 0, errors.New("Unknown protocol")
  33. }
  34. obfs := &Obfuscated2{
  35. Decryptor: decryptor,
  36. Encryptor: encryptor,
  37. }
  38. return obfs, decryptedFrame.DC(), nil
  39. }
  40. // MakeTelegramObfuscated2Frame creates new handshake frame to send to
  41. // Telegram.
  42. // https://blog.susanka.eu/how-telegram-obfuscates-its-mtproto-traffic/
  43. func MakeTelegramObfuscated2Frame() (*Obfuscated2, *Frame) {
  44. frame := generateFrame()
  45. encryptor := makeStreamCipher(frame.Key(), frame.IV())
  46. decryptorFrame := frame.Invert()
  47. decryptor := makeStreamCipher(decryptorFrame.Key(), decryptorFrame.IV())
  48. copyFrame := MakeFrame()
  49. defer ReturnFrame(copyFrame)
  50. copy((*copyFrame)[:frameOffsetIV], (*frame)[:frameOffsetIV])
  51. encryptor.XORKeyStream(*frame, *frame)
  52. copy((*frame)[:frameOffsetIV], (*copyFrame)[:frameOffsetIV])
  53. obfs := &Obfuscated2{
  54. Decryptor: decryptor,
  55. Encryptor: encryptor,
  56. }
  57. return obfs, frame
  58. }
  59. func makeStreamCipher(key, iv []byte) cipher.Stream {
  60. block, _ := aes.NewCipher(key)
  61. return cipher.NewCTR(block, iv)
  62. }