Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
er
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
er
Commits
7b4c5dde
Unverified
Commit
7b4c5dde
authored
Oct 22, 2019
by
Sergey Prokhorov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tests: add encoder and decoder for unencrypted mtproto messages
req_pq and resPQ messages
parent
d9d812e9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
109 additions
and
6 deletions
+109
-6
mtp_abridged.erl
src/mtp_abridged.erl
+5
-5
mtp_test_client.erl
test/mtp_test_client.erl
+104
-1
No files found.
src/mtp_abridged.erl
View file @
7b4c5dde
...
...
@@ -52,16 +52,16 @@ try_decode_packet_len(Len, LenStripped, St) ->
{
incomplete
,
St
}
end
.
-
spec
encode_packet
(
binary
(),
codec
())
->
{
iodata
(),
codec
()}.
encode_packet
(
Bin
,
St
)
->
Size
=
byte_size
(
Bin
),
-
spec
encode_packet
(
iodata
(),
codec
())
->
{
iodata
(),
codec
()}.
encode_packet
(
Data
,
St
)
->
Size
=
iolist_size
(
Data
),
Len
=
Size
div
4
,
Packet
=
case
Len
<
127
of
true
->
[
Len
|
Bin
];
[
Len
|
Data
];
false
->
[
<<
127
,
Len
:
24
/
unsigned
-
little
-
integer
>>
|
Bin
]
[
<<
127
,
Len
:
24
/
unsigned
-
little
-
integer
>>
|
Data
]
end
,
{
Packet
,
St
}.
...
...
test/mtp_test_client.erl
View file @
7b4c5dde
...
...
@@ -6,7 +6,17 @@
send
/
2
,
recv_packet
/
2
,
recv_all
/
2
,
close
/
1
]).
close
/
1
,
ping_session
/
6
]).
-
export
([
unencrypted_cli_packet
/
1
,
unencrypted_cli_packet
/
3
,
parse_unencrypted_srv_packet
/
1
]).
-
export
([
req_pq
/
0
,
res_pq_matches
/
2
,
ping
/
0
,
pong_matches
/
2
]).
-
export_type
([
client
/
0
]).
-
record
(
client
,
...
...
@@ -128,3 +138,96 @@ tcp_recv_all_inner(Sock, Acc) ->
close
(
#client
{
sock
=
Sock
})
->
ok
=
gen_tcp
:
close
(
Sock
).
ping_session
(
Host
,
Port
,
Secret
,
DcId
,
Protocol
,
Timeout
)
->
Cli0
=
connect
(
Host
,
Port
,
Secret
,
DcId
,
Protocol
),
ReqPQ
=
req_pq
(),
Cli1
=
send
(
unencrypted_cli_packet
(
ReqPQ
),
Cli0
),
{
ok
,
Packet
,
Cli2
}
=
recv_packet
(
Cli1
,
Timeout
),
ok
=
close
(
Cli2
),
{_
MsgId
,
response
,
ResPQ
}
=
parse_unencrypted_srv_packet
(
Packet
),
{
res_pq_matches
(
ReqPQ
,
ResPQ
),
ReqPQ
,
ResPQ
}.
%%
%% Messages
%%
%% @doc encodes payload as unencrypted client message
%% https://core.telegram.org/mtproto/description#unencrypted-message
unencrypted_cli_packet
(
Payload
)
->
Now
=
erlang
:
system_time
(
microsecond
),
%% Is 128 enough?
PadSize
=
rand
:
uniform
(
128
div
4
)
*
4
,
% should be alined to 4b
Padding
=
crypto
:
strong_rand_bytes
(
PadSize
),
unencrypted_cli_packet
(
Payload
,
Now
,
Padding
).
unencrypted_cli_packet
(
Payload
,
Now
,
Pad
)
->
%% Client message identifiers are divisible by 4.
Micro
=
1000000
,
NowSec
=
Now
div
Micro
,
MicroFraction
=
Now
rem
Micro
,
MicroDiv4
=
MicroFraction
-
(
MicroFraction
rem
4
),
%% MsgId = NowSec * (2 bsl 31) + MicroDiv4,
[
<<
0
:
64
,
MicroDiv4
:
32
/
unsigned
-
little
,
NowSec
:
32
/
unsigned
-
little
,
(
byte_size
(
Payload
)
+
byte_size
(
Pad
)):
32
/
unsigned
-
little
>>
,
Payload
|
Pad
].
%% @doc extracts payload from unencrypted server message
parse_unencrypted_srv_packet
(
<<
0
:
64
,
MsgId
:
64
/
unsigned
-
little
,
Size
:
32
/
unsigned
-
little
,
Payload
:
Size
/
binary
>>
)
->
%% Server message identifiers modulo 4 yield 1 if the message is a response to a
%% client message, and 3 otherwise.
Kind
=
case
MsgId
rem
4
of
1
->
response
;
3
->
event
end
,
{
MsgId
,
Kind
,
Payload
}.
%% https://core.telegram.org/mtproto/serialize#base-types
-
define
(
int
,
32
/
signed
-
little
).
-
define
(
long
,
64
/
signed
-
little
).
-
define
(
REQ_PQ
,
16#60469778
:
?
int
).
-
define
(
RES_PQ
,
16#05162463
:
?
int
).
%% @doc creates req_pq packet
req_pq
()
->
%% req_pq#60469778 nonce:int128 = ResPQ;
Nonce
=
<<
(
crypto
:
strong_rand_bytes
(
12
)):
12
/
binary
,
(
erlang
:
unique_integer
()):
32
/
little
>>
,
<<?
REQ_PQ
,
Nonce
:
16
/
binary
>>
.
%% @doc returns `true' if ResPQ nonce matches the nonce for ReqPQ
%% @param ReqPQ: req_pq packet generated by req_pq/0
%% @param ResPQ: resPQ packet received from server
res_pq_matches
(
<<?
REQ_PQ
,
Nonce
:
16
/
binary
>>
,
<<?
RES_PQ
,
Nonce
:
16
/
binary
,
_
/
binary
>>
)
->
%% resPQ#05162463 nonce:int128 server_nonce:int128 pq:bytes \
%% server_public_key_fingerprints:Vector<long> = ResPQ;
true
;
res_pq_matches
(_,
_)
->
false
.
-
define
(
PING
,
16#7abe77ec
:
?
int
).
-
define
(
PONG
,
16#347773c5
:
?
int
).
%% @doc constructs 'ping' message
ping
()
->
%% ping#7abe77ec ping_id:long = Pong;
PingId
=
erlang
:
unique_integer
(),
<<?
PING
,
PingId
:
?
long
>>
.
pong_matches
(
<<?
PING
,
PingId
:
?
long
>>
,
<<?
PONG
,
_
MsgId1
:
?
long
,
PingId
:
?
long
>>
)
->
%% pong#347773c5 msg_id:long ping_id:long = Pong;
true
;
pong_matches
(_,
_)
->
false
.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment