mirror of
https://github.com/seriyps/mtproto_proxy.git
synced 2026-05-13 08:46:46 +00:00
Fake TLS protocol
* pretends being TLS1.3 + http2 * mtp_handler state-machine refactored
This commit is contained in:
parent
c711054bf2
commit
0a1604d4be
11 changed files with 457 additions and 82 deletions
|
|
@ -7,6 +7,7 @@
|
|||
packet_4b/0,
|
||||
stream_16b/0,
|
||||
packet_16b/0,
|
||||
binary/2,
|
||||
key/0,
|
||||
iv/0,
|
||||
secret/0,
|
||||
|
|
@ -33,6 +34,14 @@ packet_16b() ->
|
|||
stream_16b() ->
|
||||
proper_types:list(packet_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])).
|
||||
|
||||
%% 32-byte encryption key: `binary()`
|
||||
key() ->
|
||||
proper_types:binary(32).
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ connect(Host, Port, Seed, Secret, DcId, Protocol) ->
|
|||
ok = gen_tcp:send(Sock, Header),
|
||||
PacketLayer = Protocol:new(),
|
||||
Codec = mtp_codec:new(mtp_obfuscated, CryptoLayer,
|
||||
Protocol, PacketLayer),
|
||||
Protocol, PacketLayer, false, undefined, 25 * 1024 * 1024),
|
||||
#client{sock = Sock,
|
||||
codec = Codec}.
|
||||
|
||||
|
|
|
|||
|
|
@ -118,10 +118,8 @@ wait_nonce(info, {tcp, _Sock, TcpData},
|
|||
{DecKey, DecIv} = mtp_down_conn:get_middle_key(Args#{purpose => <<"CLIENT">>}),
|
||||
{EncKey, EncIv} = mtp_down_conn:get_middle_key(Args#{purpose => <<"SERVER">>}),
|
||||
%% Add encryption layer to codec
|
||||
{_, _, PacketMod, PacketState} = mtp_codec:decompose(Codec2),
|
||||
CryptoState = mtp_aes_cbc:new(EncKey, EncIv, DecKey, DecIv, 16),
|
||||
Codec3 = mtp_codec:new(mtp_aes_cbc, CryptoState,
|
||||
PacketMod, PacketState),
|
||||
Codec3 = mtp_codec:replace(crypto, mtp_aes_cbc, CryptoState, Codec2),
|
||||
|
||||
{next_state, wait_handshake,
|
||||
activate(S1#hs_state{codec = Codec3,
|
||||
|
|
|
|||
62
test/prop_mtp_fake_tls.erl
Normal file
62
test/prop_mtp_fake_tls.erl
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
%% @doc property-based tests for mtp_fake_tls
|
||||
-module(prop_mtp_fake_tls).
|
||||
-include_lib("proper/include/proper.hrl").
|
||||
-include_lib("stdlib/include/assert.hrl").
|
||||
|
||||
-export([prop_codec_small/1, prop_codec_big/1, prop_stream/1]).
|
||||
|
||||
prop_codec_small(doc) ->
|
||||
"Tests that any binary below 65535 bytes can be encoded and decoded back as single frame".
|
||||
|
||||
prop_codec_small() ->
|
||||
?FORALL(Bin, mtp_prop_gen:binary(8, 65535), codec_small(Bin)).
|
||||
|
||||
codec_small(Bin) ->
|
||||
%% fake_tls can split big packets to multiple TLS frames of 64kb
|
||||
Codec = mtp_fake_tls:new(),
|
||||
{Data, Codec1} = mtp_fake_tls:encode_packet(Bin, Codec),
|
||||
{ok, Decoded, <<>>, _} = mtp_fake_tls:try_decode_packet(iolist_to_binary(Data), Codec1),
|
||||
Decoded == Bin.
|
||||
|
||||
|
||||
prop_codec_big(doc) ->
|
||||
"Tests that big binaries will be split to multiple chunks".
|
||||
|
||||
prop_codec_big() ->
|
||||
?FORALL(Bin, mtp_prop_gen:binary(65536, 75000), codec_big(Bin)).
|
||||
|
||||
codec_big(Bin) ->
|
||||
Codec = mtp_fake_tls:new(),
|
||||
{Data, Codec1} = mtp_fake_tls:encode_packet(Bin, Codec),
|
||||
Chunks = decode_stream(iolist_to_binary(Data), Codec1, []),
|
||||
?assert(length(Chunks) > 1),
|
||||
?assertEqual(Bin, iolist_to_binary(Chunks)),
|
||||
true.
|
||||
|
||||
|
||||
prop_stream(doc) ->
|
||||
"Tests that set of packets of size below 65535b can be encoded and decoded back".
|
||||
|
||||
prop_stream() ->
|
||||
?FORALL(Stream, proper_types:list(mtp_prop_gen:binary(8, 20000)),
|
||||
codec_stream(Stream)).
|
||||
|
||||
codec_stream(Stream) ->
|
||||
Codec = mtp_fake_tls:new(),
|
||||
{BinStream, Codec1} =
|
||||
lists:foldl(
|
||||
fun(Bin, {Acc, Codec1}) ->
|
||||
{Data, Codec2} = mtp_fake_tls:encode_packet(Bin, Codec1),
|
||||
{<<Acc/binary, (iolist_to_binary(Data))/binary>>,
|
||||
Codec2}
|
||||
end, {<<>>, Codec}, Stream),
|
||||
DecodedStream = decode_stream(BinStream, Codec1, []),
|
||||
Stream == DecodedStream.
|
||||
|
||||
decode_stream(BinStream, Codec, Acc) ->
|
||||
case mtp_fake_tls:try_decode_packet(BinStream, Codec) of
|
||||
{incomplete, _} ->
|
||||
lists:reverse(Acc);
|
||||
{ok, DecPacket, Tail, Codec1} ->
|
||||
decode_stream(Tail, Codec1, [DecPacket | Acc])
|
||||
end.
|
||||
Loading…
Add table
Add a link
Reference in a new issue