mirror of
https://github.com/seriyps/mtproto_proxy.git
synced 2026-05-13 08:46:46 +00:00
Fix decoding of packets split to multiple TLS frames. Fixes gh-16
This commit is contained in:
parent
e0c07667c4
commit
e28e21a77f
4 changed files with 82 additions and 15 deletions
|
|
@ -8,6 +8,7 @@
|
|||
stream_16b/0,
|
||||
packet_16b/0,
|
||||
binary/2,
|
||||
aligned_binary/3,
|
||||
key/0,
|
||||
iv/0,
|
||||
secret/0,
|
||||
|
|
@ -36,11 +37,15 @@ stream_16b() ->
|
|||
|
||||
%% Binary of size between Min and Max
|
||||
binary(Min, Max) when Min < Max ->
|
||||
TailSize = Max - Min,
|
||||
?LET({First, Tail}, {proper_types:binary(Min),
|
||||
proper_types:resize(TailSize,
|
||||
proper_types:list(proper_types:byte()))},
|
||||
iolist_to_binary([First | Tail])).
|
||||
?LET(Size, proper_types:integer(Min, Max), proper_types:binary(Size)).
|
||||
|
||||
%% Binary of size between Min and Max aligned by Align
|
||||
aligned_binary(Align, Min0, Max0) when Min0 > Align,
|
||||
Max0 > Min0 ->
|
||||
Ceil = fun(V) -> V - (V rem Align) end,
|
||||
Min = Ceil(Min0),
|
||||
Max = Ceil(Max0),
|
||||
?LET(Size, proper_types:integer(Min, Max), proper_types:binary(Ceil(Size))).
|
||||
|
||||
%% 32-byte encryption key: `binary()`
|
||||
key() ->
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@
|
|||
-export([prop_obfuscated_secure_stream/1,
|
||||
prop_obfuscated_secure_duplex/1,
|
||||
prop_obfuscated_secure_duplex_multi/1,
|
||||
prop_fullcbc_stream/1]).
|
||||
prop_fullcbc_stream/1,
|
||||
prop_tls_stream/1,
|
||||
prop_tls_big_stream/1]).
|
||||
|
||||
|
||||
prop_obfuscated_secure_stream(doc) ->
|
||||
|
|
@ -147,6 +149,48 @@ mk_fullcbc_codec(EncKey, EncIv, DecKey, DecIv) ->
|
|||
mtp_codec:new(mtp_aes_cbc, Crypto,
|
||||
mtp_full, Packet).
|
||||
|
||||
|
||||
prop_tls_stream(doc) ->
|
||||
"Tests combination of fake-tls + mtp_obfuscated + mtp_secure. It emulates fake-tls client".
|
||||
|
||||
prop_tls_stream() ->
|
||||
?FORALL({Key, Iv, Stream}, stream_arg_set(), tls_obfuscated_secure_stream(Key, Iv, Stream)).
|
||||
|
||||
|
||||
|
||||
prop_tls_big_stream(doc) ->
|
||||
"Tests combination of fake-tls + mtp_obfuscated + mtp_secure with packets >64kb. "
|
||||
"So, single 'packet-layer' packet will be split to multiple TLS packets. "
|
||||
"It emulates file uppload with fake-tls client".
|
||||
|
||||
prop_tls_big_stream() ->
|
||||
?FORALL({Key, Iv, Stream}, tls_big_stream_arg_set(), tls_obfuscated_secure_stream(Key, Iv, Stream)).
|
||||
|
||||
tls_big_stream_arg_set() ->
|
||||
%% Packets more than 64kb but less than 512kb
|
||||
Min = 64 * 1024 + 10,
|
||||
Max = 512 * 1024,
|
||||
proper_types:tuple(
|
||||
[mtp_prop_gen:key(),
|
||||
mtp_prop_gen:iv(),
|
||||
proper_types:list(mtp_prop_gen:aligned_binary(4, Min, Max))
|
||||
]).
|
||||
|
||||
|
||||
tls_obfuscated_secure_stream(Key, Iv, Stream) ->
|
||||
Codec0 = mk_tls_codec(Key, Iv, Key, Iv),
|
||||
{BinStream, Codec2} =
|
||||
lists:foldl(
|
||||
fun(Bin, {Acc, Codec1}) ->
|
||||
{Data, Codec2} = mtp_codec:encode_packet(Bin, Codec1),
|
||||
{<<Acc/binary, (iolist_to_binary(Data))/binary>>,
|
||||
Codec2}
|
||||
end, {<<>>, Codec0}, Stream),
|
||||
{ResStream, _Codec3} = parse_stream(BinStream, Codec2),
|
||||
?assertEqual(Stream, ResStream),
|
||||
true.
|
||||
|
||||
|
||||
parse_stream(Bin, Codec0) ->
|
||||
%% We want to split solid stream to smaller chunks to emulate network packet fragmentation
|
||||
Chunks = split_stream(Bin),
|
||||
|
|
@ -162,6 +206,15 @@ parse_stream(Bin, Codec0) ->
|
|||
end, {[], Codec0}, Chunks),
|
||||
{lists:reverse(DecodedRev), Codec}.
|
||||
|
||||
mk_tls_codec(EncKey, EncIv, DecKey, DecIv) ->
|
||||
Crypto = mtp_obfuscated:new(EncKey, EncIv, DecKey, DecIv),
|
||||
Packet = mtp_secure:new(),
|
||||
Tls = mtp_fake_tls:new(),
|
||||
mtp_codec:new(mtp_obfuscated, Crypto,
|
||||
mtp_secure, Packet,
|
||||
true, Tls,
|
||||
30 * 1024 * 1024).
|
||||
|
||||
split_stream(<<>>) -> [];
|
||||
split_stream(Bin) when byte_size(Bin) < 4 -> [Bin];
|
||||
split_stream(Bin) ->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue