9seconds 7 лет назад
Родитель
Сommit
c76d8307c2
8 измененных файлов: 66 добавлений и 30 удалений
  1. 2
    2
      Gopkg.lock
  2. 1
    0
      client/direct.go
  3. 16
    10
      obfuscated2/frame.go
  4. 24
    0
      obfuscated2/frame_pool.go
  5. 5
    4
      obfuscated2/frame_test.go
  6. 10
    8
      obfuscated2/obfuscated2.go
  7. 5
    5
      obfuscated2/obfuscated2_test.go
  8. 3
    1
      telegram/direct.go

+ 2
- 2
Gopkg.lock Просмотреть файл

43
 [[projects]]
43
 [[projects]]
44
   name = "github.com/stretchr/testify"
44
   name = "github.com/stretchr/testify"
45
   packages = ["assert"]
45
   packages = ["assert"]
46
-  revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
47
-  version = "v1.2.1"
46
+  revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
47
+  version = "v1.2.2"
48
 
48
 
49
 [[projects]]
49
 [[projects]]
50
   name = "go.uber.org/atomic"
50
   name = "go.uber.org/atomic"

+ 1
- 0
client/direct.go Просмотреть файл

18
 	if err != nil {
18
 	if err != nil {
19
 		return 0, nil, errors.Annotate(err, "Cannot extract frame")
19
 		return 0, nil, errors.Annotate(err, "Cannot extract frame")
20
 	}
20
 	}
21
+	defer obfuscated2.ReturnFrame(frame)
21
 
22
 
22
 	obfs2, dc, err := obfuscated2.ParseObfuscated2ClientFrame(conf.Secret, frame)
23
 	obfs2, dc, err := obfuscated2.ParseObfuscated2ClientFrame(conf.Secret, frame)
23
 	if err != nil {
24
 	if err != nil {

+ 16
- 10
obfuscated2/frame.go Просмотреть файл

68
 
68
 
69
 // Invert inverts frame for extracting encryption keys. Pkease check that link:
69
 // Invert inverts frame for extracting encryption keys. Pkease check that link:
70
 // https://blog.susanka.eu/how-telegram-obfuscates-its-mtproto-traffic/
70
 // https://blog.susanka.eu/how-telegram-obfuscates-its-mtproto-traffic/
71
-func (f Frame) Invert() Frame {
72
-	reversed := make(Frame, FrameLen)
73
-	copy(reversed, f)
71
+func (f Frame) Invert() *Frame {
72
+	reversed := MakeFrame()
73
+	copy(*reversed, f)
74
 
74
 
75
 	for i := 0; i < frameLenKey+frameLenIV; i++ {
75
 	for i := 0; i < frameLenKey+frameLenIV; i++ {
76
-		reversed[frameOffsetFirst+i] = f[frameOffsetIV-1-i]
76
+		(*reversed)[frameOffsetFirst+i] = f[frameOffsetIV-1-i]
77
 	}
77
 	}
78
 
78
 
79
 	return reversed
79
 	return reversed
80
 }
80
 }
81
 
81
 
82
 // ExtractFrame extracts exact obfuscated2 handshake frame from given reader.
82
 // ExtractFrame extracts exact obfuscated2 handshake frame from given reader.
83
-func ExtractFrame(conn io.Reader) (Frame, error) {
84
-	buf := &bytes.Buffer{}
83
+func ExtractFrame(conn io.Reader) (*Frame, error) {
84
+	frame := MakeFrame()
85
+	buf := bytes.NewBuffer(*frame)
86
+	buf.Reset()
87
+
85
 	if _, err := io.CopyN(buf, conn, FrameLen); err != nil {
88
 	if _, err := io.CopyN(buf, conn, FrameLen); err != nil {
89
+		ReturnFrame(frame)
86
 		return nil, errors.Annotate(err, "Cannot extract obfuscated header")
90
 		return nil, errors.Annotate(err, "Cannot extract obfuscated header")
87
 	}
91
 	}
92
+	copy(*frame, buf.Bytes())
88
 
93
 
89
-	return Frame(buf.Bytes()), nil
94
+	return frame, nil
90
 }
95
 }
91
 
96
 
92
-func generateFrame() Frame {
93
-	data := make(Frame, FrameLen)
97
+func generateFrame() *Frame {
98
+	frame := MakeFrame()
99
+	data := *frame
94
 
100
 
95
 	for {
101
 	for {
96
 		if _, err := rand.Read(data); err != nil {
102
 		if _, err := rand.Read(data); err != nil {
112
 
118
 
113
 		copy(data.Magic(), tgMagicBytes)
119
 		copy(data.Magic(), tgMagicBytes)
114
 
120
 
115
-		return data
121
+		return frame
116
 	}
122
 	}
117
 }
123
 }

+ 24
- 0
obfuscated2/frame_pool.go Просмотреть файл

1
+package obfuscated2
2
+
3
+import "sync"
4
+
5
+var framePool sync.Pool
6
+
7
+// MakeFrame returns new pointer to the handshake frame.
8
+func MakeFrame() *Frame {
9
+	return framePool.Get().(*Frame)
10
+}
11
+
12
+// ReturnFrame returns pointer to the handshake frame back to the pool.
13
+func ReturnFrame(f *Frame) {
14
+	framePool.Put(f)
15
+}
16
+
17
+func init() {
18
+	framePool = sync.Pool{
19
+		New: func() interface{} {
20
+			data := make(Frame, FrameLen)
21
+			return &data
22
+		},
23
+	}
24
+}

+ 5
- 4
obfuscated2/frame_test.go Просмотреть файл

1
 package obfuscated2
1
 package obfuscated2
2
 
2
 
3
 import (
3
 import (
4
+	"bytes"
4
 	"testing"
5
 	"testing"
5
 
6
 
6
 	"github.com/stretchr/testify/assert"
7
 	"github.com/stretchr/testify/assert"
47
 
48
 
48
 func TestFrameDoubleInvert(t *testing.T) {
49
 func TestFrameDoubleInvert(t *testing.T) {
49
 	frame := makeFrame()
50
 	frame := makeFrame()
50
-	assert.Equal(t, frame, frame.Invert().Invert())
51
+	assert.True(t, bytes.Equal(frame, *frame.Invert().Invert()))
51
 }
52
 }
52
 
53
 
53
 func TestFrameInvert(t *testing.T) {
54
 func TestFrameInvert(t *testing.T) {
54
 	frame := makeFrame()
55
 	frame := makeFrame()
55
 	reversed := frame.Invert()
56
 	reversed := frame.Invert()
56
 
57
 
57
-	assert.Exactly(t, frame[:8], reversed[:8])
58
-	assert.Exactly(t, frame[56:], reversed[56:])
58
+	assert.Exactly(t, frame[:8], (*reversed)[:8])
59
+	assert.Exactly(t, frame[56:], (*reversed)[56:])
59
 
60
 
60
 	toCompare := make([]byte, 48)
61
 	toCompare := make([]byte, 48)
61
 	for i := 0; i < 48; i++ {
62
 	for i := 0; i < 48; i++ {
62
 		toCompare[i] = frame[55-i]
63
 		toCompare[i] = frame[55-i]
63
 	}
64
 	}
64
-	assert.Equal(t, []byte(reversed[8:56]), toCompare)
65
+	assert.Equal(t, []byte((*reversed)[8:56]), toCompare)
65
 }
66
 }
66
 
67
 
67
 func TestFrameGenerateValid(t *testing.T) {
68
 func TestFrameGenerateValid(t *testing.T) {

+ 10
- 8
obfuscated2/obfuscated2.go Просмотреть файл

19
 // details: http://telegra.ph/telegram-blocks-wtf-05-26
19
 // details: http://telegra.ph/telegram-blocks-wtf-05-26
20
 //
20
 //
21
 // Beware, link above is in russian.
21
 // Beware, link above is in russian.
22
-func ParseObfuscated2ClientFrame(secret []byte, frame Frame) (*Obfuscated2, int16, error) {
22
+func ParseObfuscated2ClientFrame(secret []byte, frame *Frame) (*Obfuscated2, int16, error) {
23
 	decHasher := sha256.New()
23
 	decHasher := sha256.New()
24
 	decHasher.Write(frame.Key()) // nolint: errcheck
24
 	decHasher.Write(frame.Key()) // nolint: errcheck
25
 	decHasher.Write(secret)      // nolint: errcheck
25
 	decHasher.Write(secret)      // nolint: errcheck
31
 	encHasher.Write(secret)              // nolint: errcheck
31
 	encHasher.Write(secret)              // nolint: errcheck
32
 	encryptor := makeStreamCipher(encHasher.Sum(nil), invertedFrame.IV())
32
 	encryptor := makeStreamCipher(encHasher.Sum(nil), invertedFrame.IV())
33
 
33
 
34
-	decryptedFrame := make(Frame, FrameLen)
35
-	decryptor.XORKeyStream(decryptedFrame, frame)
34
+	decryptedFrame := MakeFrame()
35
+	defer ReturnFrame(decryptedFrame)
36
+	decryptor.XORKeyStream(*decryptedFrame, *frame)
36
 	if !decryptedFrame.Valid() {
37
 	if !decryptedFrame.Valid() {
37
 		return nil, 0, errors.New("Unknown protocol")
38
 		return nil, 0, errors.New("Unknown protocol")
38
 	}
39
 	}
48
 // MakeTelegramObfuscated2Frame creates new handshake frame to send to
49
 // MakeTelegramObfuscated2Frame creates new handshake frame to send to
49
 // Telegram.
50
 // Telegram.
50
 // https://blog.susanka.eu/how-telegram-obfuscates-its-mtproto-traffic/
51
 // https://blog.susanka.eu/how-telegram-obfuscates-its-mtproto-traffic/
51
-func MakeTelegramObfuscated2Frame() (*Obfuscated2, Frame) {
52
+func MakeTelegramObfuscated2Frame() (*Obfuscated2, *Frame) {
52
 	frame := generateFrame()
53
 	frame := generateFrame()
53
 
54
 
54
 	encryptor := makeStreamCipher(frame.Key(), frame.IV())
55
 	encryptor := makeStreamCipher(frame.Key(), frame.IV())
55
 	decryptorFrame := frame.Invert()
56
 	decryptorFrame := frame.Invert()
56
 	decryptor := makeStreamCipher(decryptorFrame.Key(), decryptorFrame.IV())
57
 	decryptor := makeStreamCipher(decryptorFrame.Key(), decryptorFrame.IV())
57
 
58
 
58
-	copyFrame := make(Frame, frameOffsetIV)
59
-	copy(copyFrame, frame)
60
-	encryptor.XORKeyStream(frame, frame)
61
-	copy(frame, copyFrame)
59
+	copyFrame := MakeFrame()
60
+	defer ReturnFrame(copyFrame)
61
+	copy((*copyFrame)[:frameOffsetIV], (*frame)[:frameOffsetIV])
62
+	encryptor.XORKeyStream(*frame, *frame)
63
+	copy((*frame)[:frameOffsetIV], (*copyFrame)[:frameOffsetIV])
62
 
64
 
63
 	obfs := &Obfuscated2{
65
 	obfs := &Obfuscated2{
64
 		Decryptor: decryptor,
66
 		Decryptor: decryptor,

+ 5
- 5
obfuscated2/obfuscated2_test.go Просмотреть файл

12
 	decryptor := makeStreamCipher(frame.Key(), frame.IV())
12
 	decryptor := makeStreamCipher(frame.Key(), frame.IV())
13
 
13
 
14
 	decrypted := make(Frame, FrameLen)
14
 	decrypted := make(Frame, FrameLen)
15
-	decryptor.XORKeyStream(decrypted, frame)
15
+	decryptor.XORKeyStream(decrypted, *frame)
16
 
16
 
17
 	assert.True(t, decrypted.Valid())
17
 	assert.True(t, decrypted.Valid())
18
 }
18
 }
42
 
42
 
43
 	encryptor := makeStreamCipher(clientKey, clientFrame.IV())
43
 	encryptor := makeStreamCipher(clientKey, clientFrame.IV())
44
 	encrypted := make(Frame, FrameLen)
44
 	encrypted := make(Frame, FrameLen)
45
-	encryptor.XORKeyStream(encrypted, clientFrame)
46
-	copy(encrypted[:56], clientFrame[:56])
45
+	encryptor.XORKeyStream(encrypted, *clientFrame)
46
+	copy(encrypted[:56], (*clientFrame)[:56])
47
 
47
 
48
 	invertedClientFrame := clientFrame.Invert()
48
 	invertedClientFrame := clientFrame.Invert()
49
 	clientHasher = sha256.New()
49
 	clientHasher = sha256.New()
52
 	invertedClientKey := clientHasher.Sum(nil)
52
 	invertedClientKey := clientHasher.Sum(nil)
53
 	clientDecryptor := makeStreamCipher(invertedClientKey, invertedClientFrame.IV())
53
 	clientDecryptor := makeStreamCipher(invertedClientKey, invertedClientFrame.IV())
54
 
54
 
55
-	clientObfs, _, err := ParseObfuscated2ClientFrame(secret, encrypted)
55
+	clientObfs, _, err := ParseObfuscated2ClientFrame(secret, &encrypted)
56
 	assert.Nil(t, err)
56
 	assert.Nil(t, err)
57
 
57
 
58
 	tgObfs, tgFrame := MakeTelegramObfuscated2Frame()
58
 	tgObfs, tgFrame := MakeTelegramObfuscated2Frame()
59
 	tgDecryptor := makeStreamCipher(tgFrame.Key(), tgFrame.IV())
59
 	tgDecryptor := makeStreamCipher(tgFrame.Key(), tgFrame.IV())
60
 	decrypted := make(Frame, FrameLen)
60
 	decrypted := make(Frame, FrameLen)
61
-	tgDecryptor.XORKeyStream(decrypted, tgFrame)
61
+	tgDecryptor.XORKeyStream(decrypted, *tgFrame)
62
 	assert.True(t, decrypted.Valid())
62
 	assert.True(t, decrypted.Valid())
63
 
63
 
64
 	tgInvertedFrame := tgFrame.Invert()
64
 	tgInvertedFrame := tgFrame.Invert()

+ 3
- 1
telegram/direct.go Просмотреть файл

43
 
43
 
44
 func (t *directTelegram) Init(conn io.ReadWriteCloser) (io.ReadWriteCloser, error) {
44
 func (t *directTelegram) Init(conn io.ReadWriteCloser) (io.ReadWriteCloser, error) {
45
 	obfs2, frame := obfuscated2.MakeTelegramObfuscated2Frame()
45
 	obfs2, frame := obfuscated2.MakeTelegramObfuscated2Frame()
46
-	if n, err := conn.Write(frame); err != nil || n != len(frame) {
46
+	defer obfuscated2.ReturnFrame(frame)
47
+
48
+	if n, err := conn.Write(*frame); err != nil || n != len(*frame) {
47
 		return nil, errors.Annotate(err, "Cannot write hadnshake frame")
49
 		return nil, errors.Annotate(err, "Cannot write hadnshake frame")
48
 	}
50
 	}
49
 
51
 

Загрузка…
Отмена
Сохранить