| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- package obfuscated2
-
- import (
- "crypto/aes"
- "crypto/cipher"
- "crypto/sha256"
-
- "github.com/juju/errors"
-
- "github.com/9seconds/mtg/mtproto"
- )
-
- // Obfuscated2 contains AES CTR encryption and decryption streams
- // for telegram connection.
- type Obfuscated2 struct {
- Decryptor cipher.Stream
- Encryptor cipher.Stream
- }
-
- // ParseObfuscated2ClientFrame parses client frame. Please check this link for
- // details: http://telegra.ph/telegram-blocks-wtf-05-26
- //
- // Beware, link above is in russian.
- func ParseObfuscated2ClientFrame(secret []byte, frame *Frame) (*Obfuscated2, *mtproto.ConnectionOpts, error) {
- decHasher := sha256.New()
- decHasher.Write(frame.Key()) // nolint: errcheck
- decHasher.Write(secret) // nolint: errcheck
- decryptor := makeStreamCipher(decHasher.Sum(nil), frame.IV())
-
- invertedFrame := frame.Invert()
- encHasher := sha256.New()
- encHasher.Write(invertedFrame.Key()) // nolint: errcheck
- encHasher.Write(secret) // nolint: errcheck
- encryptor := makeStreamCipher(encHasher.Sum(nil), invertedFrame.IV())
-
- decryptedFrame := MakeFrame()
- defer ReturnFrame(decryptedFrame)
- decryptor.XORKeyStream(*decryptedFrame, *frame)
- connType, err := decryptedFrame.ConnectionType()
- if err != nil {
- return nil, nil, errors.Annotate(err, "Unknown protocol")
- }
-
- obfs := &Obfuscated2{
- Decryptor: decryptor,
- Encryptor: encryptor,
- }
- connOpts := &mtproto.ConnectionOpts{
- DC: decryptedFrame.DC(),
- ConnectionType: connType,
- }
-
- return obfs, connOpts, nil
- }
-
- // MakeTelegramObfuscated2Frame creates new handshake frame to send to
- // Telegram.
- // https://blog.susanka.eu/how-telegram-obfuscates-its-mtproto-traffic/
- func MakeTelegramObfuscated2Frame(opts *mtproto.ConnectionOpts) (*Obfuscated2, *Frame) {
- frame := generateFrame(opts.ConnectionType)
-
- encryptor := makeStreamCipher(frame.Key(), frame.IV())
- decryptorFrame := frame.Invert()
- decryptor := makeStreamCipher(decryptorFrame.Key(), decryptorFrame.IV())
-
- copyFrame := MakeFrame()
- defer ReturnFrame(copyFrame)
- copy((*copyFrame)[:frameOffsetIV], (*frame)[:frameOffsetIV])
- encryptor.XORKeyStream(*frame, *frame)
- copy((*frame)[:frameOffsetIV], (*copyFrame)[:frameOffsetIV])
-
- obfs := &Obfuscated2{
- Decryptor: decryptor,
- Encryptor: encryptor,
- }
-
- return obfs, frame
- }
-
- func makeStreamCipher(key, iv []byte) cipher.Stream {
- block, _ := aes.NewCipher(key)
- return cipher.NewCTR(block, iv)
- }
|