Add (and refactor) tests for bad data in handshake

This commit is contained in:
Hans Svensson 2018-12-21 09:34:24 +01:00
parent 49b8047772
commit 6de4d0bf71
3 changed files with 115 additions and 44 deletions

View File

@ -0,0 +1,27 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2018, Aeternity Anstalt
%%%-------------------------------------------------------------------
-module(enoise_bad_data_tests).
-include_lib("eunit/include/eunit.hrl").
bad_data_hs_1_test() ->
SrvKeyPair = enoise_keypair:new(dh25519),
Proto = enoise_protocol:to_name(xk, dh25519, 'ChaChaPoly', blake2b),
Opts = [{echos, 1}, {reply, self()}],
Srv = enoise_utils:echo_srv_start(4567, Proto, SrvKeyPair, Opts),
bad_client(4567),
SrvRes =
receive {Srv, server_result, Res0} -> Res0
after 500 -> timeout end,
?assertMatch({error, {bad_data, _}}, SrvRes),
ok.
bad_client(Port) ->
{ok, Sock} = gen_tcp:connect("localhost", Port, [binary, {reuseaddr, true}], 100),
gen_tcp:send(Sock, <<0:256/unit:8>>),
timer:sleep(100),
gen_tcp:close(Sock).

View File

@ -69,8 +69,6 @@ noise_interactive([#{ payload := PL0, ciphertext := CT0 } | Msgs], SendHS, RecvH
?assertEqual(HSHash, HSHash1), ?assertEqual(HSHash, HSHash2)
end.
noise_dh25519_test_() ->
%% Test vectors from https://raw.githubusercontent.com/rweather/noise-c/master/tests/vector/noise-c-basic.txt
{setup,
@ -85,8 +83,8 @@ noise_monitor_test_() ->
{setup,
fun() -> setup_dh25519() end,
fun(_X) -> ok end,
fun({[T|Tests] = _Tests, SKP, CKP}) ->
[ {T, fun() -> noise_monitor_test(T, SKP, CKP) end} ]
fun({Tests, SKP, CKP}) ->
[ {T, fun() -> noise_monitor_test(T, SKP, CKP) end} || T <- Tests ]
end
}.
@ -104,7 +102,7 @@ setup_dh25519() ->
noise_test(Conf, SKP, CKP) ->
#{econn := EConn, echo_srv := EchoSrv} = noise_test_run(Conf, SKP, CKP),
enoise:close(EConn),
echo_srv_stop(EchoSrv),
enoise_utils:echo_srv_stop(EchoSrv),
ok.
noise_test_run(Conf, SKP, CKP) ->
@ -151,11 +149,12 @@ noise_test_run_(Conf, SKP, CKP) ->
Protocol = enoise_protocol:from_name(Conf),
Port = 4556,
EchoSrv = echo_srv_start(Port, Protocol, SKP, CKP),
SrvOpts = [{echos, 2}, {cpub, CKP}],
EchoSrv = enoise_utils:echo_srv_start(Port, Protocol, SKP, SrvOpts),
{ok, TcpSock} = gen_tcp:connect("localhost", Port, [{active, once}, binary, {reuseaddr, true}], 100),
Opts = [{noise, Protocol}, {s, CKP}] ++ [{rs, SKP} || need_rs(initiator, Conf) ],
Opts = [{noise, Protocol}, {s, CKP}] ++ [{rs, SKP} || enoise_utils:need_rs(initiator, Conf) ],
{ok, EConn, _} = enoise:connect(TcpSock, Opts),
ok = enoise:send(EConn, <<"Hello World!">>),
@ -176,7 +175,7 @@ noise_test_run_(Conf, SKP, CKP) ->
noise_monitor_test(Conf, SKP, CKP) ->
#{ econn := {enoise, EConnPid}
, proxy := Proxy
, tcp_sock := TcpSock } = noise_test_run(Conf, SKP, CKP),
, tcp_sock := _TcpSock } = noise_test_run(Conf, SKP, CKP),
try proxy_exec(Proxy, fun() -> exit(normal) end)
catch
error:normal ->
@ -185,42 +184,6 @@ noise_monitor_test(Conf, SKP, CKP) ->
end
end.
echo_srv_start(Port, Protocol, SKP, CPub) ->
Pid = spawn(fun() -> echo_srv(Port, Protocol, SKP, CPub) end),
timer:sleep(10),
Pid.
echo_srv(Port, Protocol, SKP, CPub) ->
TcpOpts = [{active, true}, binary, {reuseaddr, true}],
{ok, LSock} = gen_tcp:listen(Port, TcpOpts),
{ok, TcpSock} = gen_tcp:accept(LSock, 500),
Opts = [{noise, Protocol}, {s, SKP}] ++ [{rs, CPub} || need_rs(responder, Protocol)],
{ok, EConn, _} = enoise:accept(TcpSock, Opts),
gen_tcp:close(LSock),
%% {ok, Msg} = enoise:recv(EConn, 0, 100),
Msg0 = receive {noise, EConn, Data0} -> Data0
after 200 -> error(timeout) end,
ok = enoise:send(EConn, Msg0),
%% {ok, Msg} = enoise:recv(EConn, 0, 100),
Msg1 = receive {noise, EConn, Data1} -> Data1
after 200 -> error(timeout) end,
ok = enoise:send(EConn, Msg1),
ok.
echo_srv_stop(Pid) ->
erlang:exit(Pid, kill).
need_rs(Role, Conf) when is_binary(Conf) -> need_rs(Role, enoise_protocol:from_name(Conf));
need_rs(Role, Protocol) ->
PreMsgs = enoise_protocol:pre_msgs(Role, Protocol),
lists:member({in, [s]}, PreMsgs).
%% Talks to local echo-server (noise-c)
%% client_test() ->
%% TestProtocol = enoise_protocol:from_name("Noise_XK_25519_ChaChaPoly_BLAKE2b"),

81
test/enoise_utils.erl Normal file
View File

@ -0,0 +1,81 @@
%%%-------------------------------------------------------------------
%%% @copyright (C) 2018, Aeternity Anstalt
%%%-------------------------------------------------------------------
-module(enoise_utils).
-compile([export_all, nowarn_export_all]).
echo_srv_start(Port, Protocol, SKP, Opts) ->
Pid = spawn(fun() -> echo_srv(Port, Protocol, SKP, Opts) end),
timer:sleep(10),
Pid.
echo_srv_stop(Pid) ->
erlang:exit(Pid, kill).
echo_srv(Port, Protocol, SKP, SrvOpts) ->
TcpOpts = [{active, true}, binary, {reuseaddr, true}],
{ok, LSock} = gen_tcp:listen(Port, TcpOpts),
{ok, TcpSock} = gen_tcp:accept(LSock, 500),
Opts = [{noise, Protocol}, {s, SKP}] ++
[{rs, proplists:get_value(cpub, SrvOpts)} || need_rs(responder, Protocol)],
AcceptRes =
try
enoise:accept(TcpSock, Opts)
catch _:R -> gen_tcp:close(TcpSock), {error, {R, erlang:get_stacktrace()}} end,
gen_tcp:close(LSock),
case AcceptRes of
{ok, EConn, _} -> echo_srv_loop(EConn, SrvOpts);
Err = {error, _} -> srv_reply(Err, SrvOpts)
end.
echo_srv_loop(EConn, SrvOpts) ->
Recv =
case proplists:get_value(mode, SrvOpts, passive) of
passive ->
fun() ->
receive {noise, EConn, Data} -> Data
after 200 -> error(timeout) end
end;
active ->
fun() ->
{ok, Msg} = enoise:recv(EConn, 0, 100),
Msg
end
end,
Echos = proplists:get_value(echos, SrvOpts, 2),
Res =
try
[ begin
Msg = Recv(),
ok = enoise:send(EConn, Msg)
end || _ <- lists:seq(1, Echos) ],
ok
catch _:R -> {error, R} end,
srv_reply(Res, SrvOpts),
enoise:close(EConn),
Res.
srv_reply(Reply, SrvOpts) ->
case proplists:get_value(reply, SrvOpts, undefined) of
undefined -> ok;
Pid -> Pid ! {self(), server_result, Reply}
end.
need_rs(Role, Conf) when is_binary(Conf) ->
need_rs(Role, enoise_protocol:from_name(Conf));
need_rs(Role, Protocol) ->
PreMsgs = enoise_protocol:pre_msgs(Role, Protocol),
lists:member({in, [s]}, PreMsgs).