aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh/test')
-rw-r--r--lib/ssh/test/Makefile3
-rw-r--r--lib/ssh/test/property_test/ssh_eqc_client_info_timing.erl9
-rw-r--r--lib/ssh/test/ssh_basic_SUITE.erl110
-rw-r--r--lib/ssh/test/ssh_bench_SUITE.erl48
-rw-r--r--lib/ssh/test/ssh_engine_SUITE.erl140
-rw-r--r--lib/ssh/test/ssh_engine_SUITE_data/dsa_private_key.pem9
-rw-r--r--lib/ssh/test/ssh_engine_SUITE_data/ecdsa_private_key.pem8
-rw-r--r--lib/ssh/test/ssh_engine_SUITE_data/rsa_private_key.pem28
-rw-r--r--lib/ssh/test/ssh_engine_SUITE_data/rsa_private_key_pwd.pem30
-rw-r--r--lib/ssh/test/ssh_key_cb_engine_keys.erl62
-rw-r--r--lib/ssh/test/ssh_protocol_SUITE.erl11
-rw-r--r--lib/ssh/test/ssh_test_lib.erl37
-rw-r--r--lib/ssh/test/ssh_to_openssh_SUITE.erl2
13 files changed, 458 insertions, 39 deletions
diff --git a/lib/ssh/test/Makefile b/lib/ssh/test/Makefile
index 32e76cf077..a18383d148 100644
--- a/lib/ssh/test/Makefile
+++ b/lib/ssh/test/Makefile
@@ -38,7 +38,9 @@ MODULES= \
ssh_basic_SUITE \
ssh_bench_SUITE \
ssh_connection_SUITE \
+ ssh_engine_SUITE \
ssh_protocol_SUITE \
+ ssh_property_test_SUITE \
ssh_sftp_SUITE \
ssh_sftpd_SUITE \
ssh_sftpd_erlclient_SUITE \
@@ -48,6 +50,7 @@ MODULES= \
ssh_test_lib \
ssh_key_cb \
ssh_key_cb_options \
+ ssh_key_cb_engine_keys \
ssh_trpt_test_lib \
ssh_echo_server \
ssh_bench_dev_null \
diff --git a/lib/ssh/test/property_test/ssh_eqc_client_info_timing.erl b/lib/ssh/test/property_test/ssh_eqc_client_info_timing.erl
index c07140dc43..19e2754eba 100644
--- a/lib/ssh/test/property_test/ssh_eqc_client_info_timing.erl
+++ b/lib/ssh/test/property_test/ssh_eqc_client_info_timing.erl
@@ -57,9 +57,9 @@
%%% Properties:
-prop_seq(_Config) ->
+prop_seq(Config) ->
{ok,Pid} = ssh_eqc_event_handler:add_report_handler(),
- {_, _, Port} = init_daemon(),
+ {_, _, Port} = init_daemon(Config),
numtests(1000,
?FORALL(Delay, choose(0,100),%% Micro seconds
try
@@ -86,7 +86,8 @@ any_relevant_error_report(Pid) ->
end, Reports).
%%%================================================================
-init_daemon() ->
+init_daemon(Config) ->
ok = begin ssh:stop(), ssh:start() end,
- ssh_test_lib:daemon([]).
+ DataDir = proplists:get_value(data_dir, Config),
+ ssh_test_lib:daemon([{system_dir,DataDir}]).
diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index 62e2a585e4..202b0afe57 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -46,6 +46,7 @@
exec_key_differs2/1,
exec_key_differs3/1,
exec_key_differs_fail/1,
+ fail_daemon_start/1,
idle_time_client/1,
idle_time_server/1,
inet6_option/1,
@@ -99,9 +100,13 @@ all() ->
{group, ecdsa_sha2_nistp521_key},
{group, dsa_pass_key},
{group, rsa_pass_key},
+ {group, ecdsa_sha2_nistp256_pass_key},
+ {group, ecdsa_sha2_nistp384_pass_key},
+ {group, ecdsa_sha2_nistp521_pass_key},
{group, host_user_key_differs},
{group, key_cb},
{group, internal_error},
+ {group, rsa_host_key_is_actualy_ecdsa},
daemon_already_started,
double_close,
daemon_opt_fd,
@@ -118,12 +123,16 @@ groups() ->
{ecdsa_sha2_nistp256_key, [], basic_tests()},
{ecdsa_sha2_nistp384_key, [], basic_tests()},
{ecdsa_sha2_nistp521_key, [], basic_tests()},
+ {rsa_host_key_is_actualy_ecdsa, [], [fail_daemon_start]},
{host_user_key_differs, [], [exec_key_differs1,
exec_key_differs2,
exec_key_differs3,
exec_key_differs_fail]},
{dsa_pass_key, [], [pass_phrase]},
{rsa_pass_key, [], [pass_phrase]},
+ {ecdsa_sha2_nistp256_pass_key, [], [pass_phrase]},
+ {ecdsa_sha2_nistp384_pass_key, [], [pass_phrase]},
+ {ecdsa_sha2_nistp521_pass_key, [], [pass_phrase]},
{key_cb, [], [key_callback, key_callback_options]},
{internal_error, [], [internal_error]},
{login_bad_pwd_no_retry, [], [login_bad_pwd_no_retry1,
@@ -174,6 +183,31 @@ init_per_group(rsa_key, Config) ->
false ->
{skip, unsupported_pub_key}
end;
+init_per_group(rsa_host_key_is_actualy_ecdsa, Config) ->
+ case
+ lists:member('ssh-rsa',
+ ssh_transport:default_algorithms(public_key)) and
+ lists:member('ecdsa-sha2-nistp256',
+ ssh_transport:default_algorithms(public_key))
+ of
+ true ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ ssh_test_lib:setup_ecdsa("256", DataDir, PrivDir),
+ %% The following sets up bad rsa keys:
+ begin
+ UserDir = PrivDir,
+ System = filename:join(UserDir, "system"),
+ file:copy(filename:join(DataDir, "id_rsa"), filename:join(UserDir, "id_rsa")),
+ file:rename(filename:join(System, "ssh_host_ecdsa_key"), filename:join(System, "ssh_host_rsa_key")),
+ file:rename(filename:join(System, "ssh_host_ecdsa_key.pub"), filename:join(System, "ssh_host_rsa_key.pub")),
+ ssh_test_lib:setup_rsa_known_host(DataDir, UserDir),
+ ssh_test_lib:setup_rsa_auth_keys(DataDir, UserDir)
+ end,
+ Config;
+ false ->
+ {skip, unsupported_pub_key}
+ end;
init_per_group(ecdsa_sha2_nistp256_key, Config) ->
case lists:member('ecdsa-sha2-nistp256',
ssh_transport:default_algorithms(public_key)) of
@@ -229,6 +263,45 @@ init_per_group(dsa_pass_key, Config) ->
false ->
{skip, unsupported_pub_key}
end;
+init_per_group(ecdsa_sha2_nistp256_pass_key, Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ case lists:member('ecdsa-sha2-nistp256',
+ ssh_transport:default_algorithms(public_key))
+ andalso
+ ssh_test_lib:setup_ecdsa_pass_phrase("256", DataDir, PrivDir, "Password")
+ of
+ true ->
+ [{pass_phrase, {ecdsa_pass_phrase, "Password"}}| Config];
+ false ->
+ {skip, unsupported_pub_key}
+ end;
+init_per_group(ecdsa_sha2_nistp384_pass_key, Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ case lists:member('ecdsa-sha2-nistp384',
+ ssh_transport:default_algorithms(public_key))
+ andalso
+ ssh_test_lib:setup_ecdsa_pass_phrase("384", DataDir, PrivDir, "Password")
+ of
+ true ->
+ [{pass_phrase, {ecdsa_pass_phrase, "Password"}}| Config];
+ false ->
+ {skip, unsupported_pub_key}
+ end;
+init_per_group(ecdsa_sha2_nistp521_pass_key, Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ case lists:member('ecdsa-sha2-nistp521',
+ ssh_transport:default_algorithms(public_key))
+ andalso
+ ssh_test_lib:setup_ecdsa_pass_phrase("521", DataDir, PrivDir, "Password")
+ of
+ true ->
+ [{pass_phrase, {ecdsa_pass_phrase, "Password"}}| Config];
+ false ->
+ {skip, unsupported_pub_key}
+ end;
init_per_group(host_user_key_differs, Config) ->
Data = proplists:get_value(data_dir, Config),
Sys = filename:join(proplists:get_value(priv_dir, Config), system_rsa),
@@ -241,7 +314,7 @@ init_per_group(host_user_key_differs, Config) ->
file:copy(filename:join(Data, "ssh_host_rsa_key.pub"), filename:join(Sys, "ssh_host_rsa_key.pub")),
file:copy(filename:join(Data, "id_ecdsa256"), filename:join(Usr, "id_ecdsa")),
file:copy(filename:join(Data, "id_ecdsa256.pub"), filename:join(Usr, "id_ecdsa.pub")),
- ssh_test_lib:setup_ecdsa_auth_keys("256", Usr, SysUsr),
+ ssh_test_lib:setup_ecdsa_auth_keys("256", Data, SysUsr),
ssh_test_lib:setup_rsa_known_host(Sys, Usr),
Config;
init_per_group(key_cb, Config) ->
@@ -259,7 +332,8 @@ init_per_group(internal_error, Config) ->
DataDir = proplists:get_value(data_dir, Config),
PrivDir = proplists:get_value(priv_dir, Config),
ssh_test_lib:setup_dsa(DataDir, PrivDir),
- file:delete(filename:join(PrivDir, "system/ssh_host_dsa_key")),
+ %% In the test case the key will be deleted after the daemon start:
+ %% ... file:delete(filename:join(PrivDir, "system/ssh_host_dsa_key")),
Config;
init_per_group(dir_options, Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
@@ -306,6 +380,7 @@ init_per_group(dir_options, Config) ->
init_per_group(_, Config) ->
Config.
+
end_per_group(dsa_key, Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
ssh_test_lib:clean_dsa(PrivDir),
@@ -822,12 +897,17 @@ key_callback_options(Config) when is_list(Config) ->
%%% Test that client does not hang if disconnects due to internal error
internal_error(Config) when is_list(Config) ->
process_flag(trap_exit, true),
- SystemDir = filename:join(proplists:get_value(priv_dir, Config), system),
+ PrivDir = proplists:get_value(priv_dir, Config),
UserDir = proplists:get_value(priv_dir, Config),
+ SystemDir = filename:join(PrivDir, system),
{Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir},
{user_dir, UserDir},
{failfun, fun ssh_test_lib:failfun/2}]),
+
+ %% Now provoke an error in the following connect:
+ file:delete(filename:join(PrivDir, "system/ssh_host_dsa_key")),
+
{error, Error} =
ssh:connect(Host, Port, [{silently_accept_hosts, true},
{user_dir, UserDir},
@@ -856,6 +936,17 @@ send(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
+%%%
+fail_daemon_start(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ SystemDir = filename:join(proplists:get_value(priv_dir, Config), system),
+ UserDir = proplists:get_value(priv_dir, Config),
+
+ {error,_} = ssh_test_lib:daemon([{system_dir, SystemDir},
+ {user_dir, UserDir},
+ {failfun, fun ssh_test_lib:failfun/2}]).
+
+%%--------------------------------------------------------------------
%%% Test ssh:connection_info([peername, sockname])
peername_sockname(Config) when is_list(Config) ->
process_flag(trap_exit, true),
@@ -1254,14 +1345,11 @@ shell_exit_status(Config) when is_list(Config) ->
%%--------------------------------------------------------------------
%% Due to timing the error message may or may not be delivered to
%% the "tcp-application" before the socket closed message is recived
-check_error("Invalid state") ->
- ok;
-check_error("Connection closed") ->
- ok;
-check_error("Selection of key exchange algorithm failed"++_) ->
- ok;
-check_error(Error) ->
- ct:fail(Error).
+check_error("Invalid state") -> ok;
+check_error("Connection closed") -> ok;
+check_error("Selection of key exchange algorithm failed"++_) -> ok;
+check_error("No host key available") -> ok;
+check_error(Error) -> ct:fail(Error).
basic_test(Config) ->
ClientOpts = proplists:get_value(client_opts, Config),
diff --git a/lib/ssh/test/ssh_bench_SUITE.erl b/lib/ssh/test/ssh_bench_SUITE.erl
index 2c0cd8fc8e..b6c6147646 100644
--- a/lib/ssh/test/ssh_bench_SUITE.erl
+++ b/lib/ssh/test/ssh_bench_SUITE.erl
@@ -57,12 +57,19 @@ init_per_suite(Config) ->
ok ->
DataSize = 1000000,
SystemDir = proplists:get_value(data_dir, Config),
- Algs = insert_none(ssh:default_algorithms()),
+ Algs = ssh:default_algorithms(),
{_ServerPid, _Host, Port} =
ssh_test_lib:daemon([{system_dir, SystemDir},
{user_passwords, [{?UID,?PWD}]},
{failfun, fun ssh_test_lib:failfun/2},
{preferred_algorithms, Algs},
+ {modify_algorithms,[{prepend,[{cipher,[none]},
+ {mac,[none]}
+ ]},
+ {rm, [{cipher,['[email protected]',
+ ]}
+ ]},
{max_random_length_padding, 0},
{subsystems, [{"/dev/null", {ssh_bench_dev_null,[DataSize]}}]}
]),
@@ -175,11 +182,34 @@ gen_data(DataSz) ->
%% {suite, ?MODULE},
%% {name, mk_name(["Transfer 1M bytes ",Cipher,"/",Mac," [µs]"])}]);
connect_measure(Port, Cipher, Mac, Data, Options) ->
+ AES_GCM = {cipher,['[email protected]',
+
+ AlgOpt = case {Cipher,Mac} of
+ {none,none} ->
+ [{modify_algorithms,[{prepend, [{cipher,[Cipher]},
+ {mac,[Mac]}]},
+ {rm,[AES_GCM]}
+ ]}];
+ {none,_} ->
+ [{modify_algorithms,[{prepend, [{cipher,[Cipher]}]},
+ {rm,[AES_GCM]}
+ ]},
+ {preferred_algorithms, [{mac,[Mac]}]}];
+ {_,none} ->
+ [{modify_algorithms,[{prepend, [{mac,[Mac]}]},
+ {rm,[AES_GCM]}
+ ]},
+ {preferred_algorithms, [{cipher,[Cipher]}]}];
+ _ ->
+ [{preferred_algorithms, [{cipher,[Cipher]},
+ {mac,[Mac]}]},
+ {modify_algorithms, [{rm,[AES_GCM]}]}
+ ]
+ end,
Times =
[begin
- {ok,C} = ssh:connect("localhost", Port, [{preferred_algorithms, [{cipher,[Cipher]},
- {mac,[Mac]}]}
- |Options]),
+ {ok,C} = ssh:connect("localhost", Port, AlgOpt ++ Options),
{ok,Ch} = ssh_connection:session_channel(C, 10000),
success = ssh_connection:subsystem(C, Ch, "/dev/null", 10000),
{Time,ok} = timer:tc(?MODULE, send_wait_acc, [C, Ch, Data]),
@@ -205,16 +235,6 @@ send_wait_acc(C, Ch, Data) ->
%%%
%%%----------------------------------------------------------------
-insert_none(L) ->
- lists:foldl(fun insert_none/2, [], L).
-
-insert_none({T,L}, Acc) when T==cipher ;
- T==mac ->
- [{T, [{T1,L1++[none]} || {T1,L1} <- L]} | Acc];
-insert_none(_, Acc) ->
- Acc.
-
-%%%----------------------------------------------------------------
mk_name(Name) -> [char(C) || C <- lists:concat(Name)].
char($-) -> $_;
diff --git a/lib/ssh/test/ssh_engine_SUITE.erl b/lib/ssh/test/ssh_engine_SUITE.erl
new file mode 100644
index 0000000000..daf93891e9
--- /dev/null
+++ b/lib/ssh/test/ssh_engine_SUITE.erl
@@ -0,0 +1,140 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssh_engine_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+-include("ssh_test_lib.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+%%--------------------------------------------------------------------
+%% Common Test interface functions -----------------------------------
+%%--------------------------------------------------------------------
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap,{seconds,40}}].
+
+all() ->
+ [{group, dsa_key},
+ {group, rsa_key}
+ ].
+
+groups() ->
+ [{dsa_key, [], basic_tests()},
+ {rsa_key, [], basic_tests()}
+ ].
+
+basic_tests() ->
+ [simple_connect
+ ].
+
+
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ ssh:start(),
+ ?CHECK_CRYPTO(
+ case load_engine() of
+ {ok,E} ->
+ [{engine,E}|Config];
+ {error, notsup} ->
+ {skip, "Engine not supported on this OpenSSL version"};
+ {error, bad_engine_id} ->
+ {skip, "Dynamic Engine not supported"};
+ Other ->
+ ct:log("Engine load failed: ~p",[Other]),
+ {fail, "Engine load failed"}
+ end
+ ).
+
+end_per_suite(Config) ->
+ catch crypto:engine_unload( proplists:get_value(engine,Config) ),
+ ssh:stop().
+
+%%--------------------------------------------------------------------
+init_per_group(dsa_key, Config) ->
+ case lists:member('ssh-dss',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ start_daemon(Config, 'ssh-dss', "dsa_private_key.pem");
+ false ->
+ {skip, unsupported_pub_key}
+ end;
+init_per_group(rsa_key, Config) ->
+ case lists:member('ssh-rsa',
+ ssh_transport:default_algorithms(public_key)) of
+ true ->
+ start_daemon(Config, 'ssh-rsa', "rsa_private_key.pem");
+ false ->
+ {skip, unsupported_pub_key}
+ end.
+
+start_daemon(Config, KeyType, KeyId) ->
+ SystemDir = proplists:get_value(data_dir, Config),
+ FullKeyId = filename:join(SystemDir, KeyId),
+ KeyCBOpts = [{engine, proplists:get_value(engine,Config)},
+ {KeyType, FullKeyId}
+ ],
+ Opts = [{key_cb, {ssh_key_cb_engine_keys, KeyCBOpts}}],
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config, Opts),
+ [{host_port,{Host,Port}}, {daemon_pid,Pid}| Config].
+
+
+end_per_group(_, Config) ->
+ catch ssh:stop_daemon(proplists:get_value(daemon_pid,Config)),
+ Config.
+
+%%--------------------------------------------------------------------
+%% Test Cases --------------------------------------------------------
+%%--------------------------------------------------------------------
+
+%% A simple exec call
+simple_connect(Config) ->
+ {Host,Port} = proplists:get_value(host_port, Config),
+ CRef = ssh_test_lib:std_connect(Config, Host, Port, []),
+ ssh:close(CRef).
+
+%%--------------------------------------------------------------------
+%%--------------------------------------------------------------------
+load_engine() ->
+ case crypto:get_test_engine() of
+ {ok, Engine} ->
+ try crypto:engine_load(<<"dynamic">>,
+ [{<<"SO_PATH">>, Engine},
+ <<"LOAD">>],
+ [])
+ catch
+ error:notsup ->
+ {error, notsup}
+ end;
+
+ {error, Error} ->
+ {error, Error}
+ end.
+
+start_std_daemon(Opts, Config) ->
+ ct:log("starting std_daemon",[]),
+ {Pid, Host, Port} = ssh_test_lib:std_daemon(Config, Opts),
+ ct:log("started ~p:~p ~p",[Host,Port,Opts]),
+ [{srvr_pid,Pid},{srvr_addr,{Host,Port}} | Config].
diff --git a/lib/ssh/test/ssh_engine_SUITE_data/dsa_private_key.pem b/lib/ssh/test/ssh_engine_SUITE_data/dsa_private_key.pem
new file mode 100644
index 0000000000..778ffac675
--- /dev/null
+++ b/lib/ssh/test/ssh_engine_SUITE_data/dsa_private_key.pem
@@ -0,0 +1,9 @@
+-----BEGIN PRIVATE KEY-----
+MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAMyitTMR7vPbpqyAXJpqnB0AhFwQ
+F87IE+JKFl5bD/MSkhhRV5sM73HUU1ooXY0FjhZ+cdLUCATuZR5ta4ydANqWIcAB
+gX3IwF1B4zf5SXEKTWkUYneL9dOKtiZLtoG28swrk8xMxwX+0fLHkltCEj6FiTW9
+PFrv8GmIfV6DjcI9AhUAqXWbb3RtoN9Ld28fVMhGZrj3LJUCgYEAwnxGHGBMpJaF
+2w7zAw3jHjL8PMYlV6vnufGHQlwF0ZUXJxRsvagMb/X1qACTu2VPYEVoLQGM3cfH
+EhHoQmvSXGAyTfR7Bmn3gf1n/s/DcFbdZduUCZ/rAyIrfd0eSbc1I+kZk85UCsKK
+w/IYdlqcuYa4Cgm2TapT5uEMqH4jhzEEFgIULh8swEUWmU8aJNWsrWl4eCiuUUg=
+-----END PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_engine_SUITE_data/ecdsa_private_key.pem b/lib/ssh/test/ssh_engine_SUITE_data/ecdsa_private_key.pem
new file mode 100644
index 0000000000..a45522064f
--- /dev/null
+++ b/lib/ssh/test/ssh_engine_SUITE_data/ecdsa_private_key.pem
@@ -0,0 +1,8 @@
+-----BEGIN PRIVATE KEY-----
+MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIBparGjr0KcdNrVM2J
+G0mW5ltP1QyvxDqBMyWLWo3fruRZv6Qoohl5skd1u4O+KJoM/UrrSTOXI/MDR7NN
+i1yl7O+hgYkDgYYABAG8K2XVsK0ahG9+HIIPwCO0pJY8ulwSTXwIjkCGyB2lpglh
+8qJmRzuyGcfRTslv8wfv0sPlT9H9PKDvgrTUL7rvQQDdOODNgVPXSecUoXoPn+X+
+eqxs77bjx+A5x0t/i3m5PfkaNPh5MZ1H/bWuOOdj2ZXZw0R4rlVc0zVrgnPU8L8S
+BQ==
+-----END PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_engine_SUITE_data/rsa_private_key.pem b/lib/ssh/test/ssh_engine_SUITE_data/rsa_private_key.pem
new file mode 100644
index 0000000000..ea0e3d3958
--- /dev/null
+++ b/lib/ssh/test/ssh_engine_SUITE_data/rsa_private_key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCwwb0/ddXGXTFK
+4FLxXdV6a/WJMSoPPS55RvZIAHFsiTtvPLbJ8LxDsZ6wSVZLN0/UQ4wdWn9jftyj
+U5/IxBVG8XOtKimTMvm3/ZOzVLueGHBbrLYscRv9oL85ulTKHWgrZDu0lBX5JJTI
+v5UTCErzJRQbka9DG1GaBgDb1PlXfkzBWMwfsBZmwoC77KvCcIGCgbW/XCY03TP2
+3Tg8drvpByMStddP2FQ4fZ91qFUzPu8uhZEsqSQTFlmhgGEx7dLlky0xvu62RuAD
+RTpINpcWZtWDHTdssOqu653LwwqBY8lBopCZ/4Af8QR3ZYkQhen1YLEbVheXRuzI
+LSCZIiJNAgMBAAECggEBAJH4/fxpqQkvr2Shy33Pu1xlyhnpw01gfn/jrcKasxEq
+aC4eWup86E2TY3U8q4pkfIXU3uLi+O9HNpmflwargNLc1mY8uqb44ygiv5bLNEKE
+9k2PXcdoBfC4jxPyoNFl5cBn/7LK1TazEjiTl15na9ZPWcLG1pG5/vMPYCgsQ1sP
+8J3c4E3aaXIj9QceYxBprl490OCzieGyZlRipncz3g4UShRc/b4cycvDZOJpmAy4
+zbWTcBcSMPVPi5coF0K8UcimiqZkotfb/2RLc433i34IdsIXMM+brdq+g8rmjg5a
++oQPy02M6tFApBruEhAz8DGgaLtDY6MLtyZAt3SjXnUCgYEA1zLgamdTHOqrrmIi
+eIQBnAJiyIfcY8B9SX1OsLGYFCHiPVwgUY35B2c7MavMsGcExJhtE+uxU7o5djtM
+R6r9cRHOXJ6EQwa8OwzzPqbM17/YqNDeK39bc9WOFUqRWrhDhVMPy6z8rmZr73mG
+IUC7mBNx/1GBdVYXIlsXzC96dI8CgYEA0kUAhz6I5nyPa70NDEUYHLHf3IW1BCmE
+UoVbraSePJtIEY/IqFx7oDuFo30d4n5z+8ICCtyid1h/Cp3mf3akOiqltYUfgV1G
+JgcEjKKYWEnO7cfFyO7LB7Y3GYYDJNy6EzVWPiwTGk9ZTfFJEESmHC45Unxgd17m
+Dx/R58rFgWMCgYBQXQWFdtSI5fH7C1bIHrPjKNju/h2FeurOuObcAVZDnmu4cmD3
+U8d9xkVKxVeJQM99A1coq0nrdI3k4zwXP3mp8fZYjDHkPe2pN6rW6L9yiohEcsuk
+/siON1/5/4DMmidM8LnjW9R45HLGWWGHpX7oyco2iJ+Jy/6Tq+T1MX3PbQKBgQCm
+hdsbQJ0u3CrBSmFQ/E9SOlRt0r4+45pVuCOY6yweF2QF9HcXTtbhWQJHLclDHJ5C
+Ha18aKuKFN3XzKFFBPKe1jOSBDGlQ/dQGnKx5fr8wMdObM3oiaTlIJuWbRmEUgJT
+QARjDIi8Z2b0YUhZx+Q9oSXoe3PyVYehJrQX+/BavQKBgQCIr7Zp0rQPbfqcTL+M
+OYHUoNcb14f9f8hXeXHQOqVpsGwxGdRQAU9wbx/4+obKB5xIkzBsVNcJwavisNja
+hegnGjTB/9Hc4m+5bMGwH0bhS2eQO4o+YYM2ypDmFQqDLRfFUlZ5PVHffm/aA9+g
+GanNBCsmtoHtV6CJ1UZ7NmBuIA==
+-----END PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_engine_SUITE_data/rsa_private_key_pwd.pem b/lib/ssh/test/ssh_engine_SUITE_data/rsa_private_key_pwd.pem
new file mode 100644
index 0000000000..501662fc35
--- /dev/null
+++ b/lib/ssh/test/ssh_engine_SUITE_data/rsa_private_key_pwd.pem
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIh888Iq6gxuMCAggA
+MBQGCCqGSIb3DQMHBAic/11YZ8Nt5gSCBMjG/Jb4qiMoBS50iQvHXqcETPE+0NBr
+jhsn9w94LkdRBstMPAsoKmY98Er96Rnde/NfmqlU9CupKTkd7Ce5poBf72Y6KMED
+cPURyjbGRFsu6x9skXB2obhyKYEqAEF2oQAg4Qbe5v1qXBIgDuC/NgiJnM+w2zCZ
+LkHSZB2/NmcnvDzcgPF7TM8pTO23xCJ33m37qjfWvHsgocVqZmL9wQ4+wr/NMYjJ
+pJvX1OHW1vBsZsXh40WchalYRSB1VeO368QfsE8coRJztqbMzdce9EQdMB6Q6jlO
+cetd3moLIoMP4I7HW0/SgokbycTbRiYSvRyU1TGc2WbW6BrFZV24IckcnnVUFatf
+6HKUcaYLG68dJcRgs5QMGkcmgVvlddENHFmHZlo0eym/xSiUl/AT8/5odscm6ML8
+wW5sneax+TF4J2eYmiN7yjAUCodXVTNYNDVKo6uUhntlymbM0o4UitVIbPIfTDHl
+sxJAEZ7vpuPqeNMxUk6G6zipuEjqsVbnuFSBSZmgKiGYcifRPUmqqINa3DdS4WVx
+xaPWdHbHVRD//ze3h/FsA+1lIE5q2kUE0xXseJA1ISog++kJp14XeaaL2j/tx3Ob
+OsbcaOAD/IUw/ItDt9kn0qzfnar7sS0Wov8AmJQxHmH7Lm93jHTLM05yE0AR/eBr
+Mig2ZdC+9OqVC+GPuBkRjSs8NpltQIDroz6EV9IMwPwXm0szSYoyoPLmlHJUdnLs
+ZUef+au6hYkEJBrvuisagnq5eT/fCV3hsjD7yODebNU2CmBTo6X2PRx/xsBHRMWl
+QkoM9PBdSCnKv6HpHl4pchuoqU2NpFjN0BCaad6aHfZSTnqgzK4bEh1oO6dI8/rB
+/eh71JyFFG5J4xbpaqz5Su01V1iwU5leK5bDwqals4M4+ZGHGciou7qnXUmX2fJl
+r6DlMUa/xy+A2ZG0NuZR05yk2oB3+KVNMgp6zFty3XaxwoNtc8GTLtLnBnIh2rlP
+mE1+I65LRWwrNQalPeOAUrYuEzhyp2Df7a8Ykas5PUH7MGR/S0Ge/dLxtE2bJuK4
+znbLAsGhvo/SbNxYqIp6D4iDtd3va6yUGncy41paA/vTKFVvXZDrXcwJQYYCVOGT
+OwdzNuozU8Dc7oxsd8oakfC46kvmVaOrGvZbm56PFfprcaL/Hslska5xxEni/eZe
+WRxZbCBhAVqS1pn5zkDQVUe9uFlR/x39Qi01HIlKLBsjpSs6qQsFArMe8hgXmXLG
+xP+dyVuOE18NzSewdEjeqSRKIM7Qi8EOjZsI4HdSRBY7bh9VhmaVXDZiCSf33TTE
+3y8nimzQAeuGoYg6WqHmWWC2Qnpki2HlaIH/ayXEyQWkP/qvg61e8ovdg9Fy8JOO
+0AacXVt5zj0q00AW5bKx7usi4NIjZedi86hUm6H19aBm7r86BKjwYTEI/GOcdrbV
+9HC/8ayOimgwiAG3gq+aLioWym+Z6KnsbVd7XReVbvM/InQx54WA2y5im0A+/c67
+oQFFPV84XGX9waeqv/K4Wzkm6HW+qVAEM67482VGOf0PVrlQMno6dOotT/Y7ljoZ
+2iz0LmN9yylJnLPDrr1i6gzbs5OhhUgbF5LI2YP2wWdCZTl/DrKSIvQZWl8U+tw3
+ciA=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/lib/ssh/test/ssh_key_cb_engine_keys.erl b/lib/ssh/test/ssh_key_cb_engine_keys.erl
new file mode 100644
index 0000000000..fc9cbfd49b
--- /dev/null
+++ b/lib/ssh/test/ssh_key_cb_engine_keys.erl
@@ -0,0 +1,62 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-2017. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+
+%% Note: This module is used by ssh_basic_SUITE
+
+-module(ssh_key_cb_engine_keys).
+-behaviour(ssh_server_key_api).
+-compile(export_all).
+
+host_key(SshAlg, Options) ->
+ KBopts = proplists:get_value(key_cb_private, Options, []),
+ Engine = proplists:get_value(engine, KBopts),
+ case proplists:get_value(SshAlg, KBopts) of
+ undefined ->
+ {error, {unknown_alg,SshAlg}};
+ KeyId ->
+ case crypto_alg(SshAlg) of
+ undefined ->
+ {error, {unsupported_alg,SshAlg}};
+ CryptoAlg ->
+ PrivKey = #{engine => Engine,
+ key_id => KeyId,
+ algorithm => CryptoAlg},
+ %% Is there a key with this reference ?
+ case crypto:privkey_to_pubkey(CryptoAlg, PrivKey) of
+ [_|_] ->
+ {ok, PrivKey};
+ _ ->
+ {error, {no_hostkey,SshAlg}}
+ end
+ end
+ end.
+
+is_auth_key(_PublicUserKey, _User, _Options) ->
+ false.
+
+
+
+crypto_alg('ssh-rsa') -> rsa;
+crypto_alg('ssh-dss') -> dss;
+crypto_alg(_) -> undefined.
+
diff --git a/lib/ssh/test/ssh_protocol_SUITE.erl b/lib/ssh/test/ssh_protocol_SUITE.erl
index 7da921adb2..3e3e151781 100644
--- a/lib/ssh/test/ssh_protocol_SUITE.erl
+++ b/lib/ssh/test/ssh_protocol_SUITE.erl
@@ -630,11 +630,12 @@ client_handles_keyboard_interactive_0_pwds(Config) ->
%%%--------------------------------------------------------------------
-client_info_line(_Config) ->
+client_info_line(Config) ->
%% A client must not send an info-line. If it does, the server should handle
%% handle this gracefully
{ok,Pid} = ssh_eqc_event_handler:add_report_handler(),
- {_, _, Port} = ssh_test_lib:daemon([]),
+ DataDir = proplists:get_value(data_dir, Config),
+ {_, _, Port} = ssh_test_lib:daemon([{system_dir,DataDir}]),
%% Fake client:
{ok,S} = gen_tcp:connect("localhost",Port,[]),
@@ -884,9 +885,9 @@ chk_pref_algs(Config,
filter_supported(K, Algs) -> Algs -- (Algs--supported(K)).
-supported(K) -> proplists:get_value(
- server2client,
- ssh_transport:supported_algorithms(cipher)).
+supported(_K) -> proplists:get_value(
+ server2client,
+ ssh_transport:supported_algorithms(cipher)).
to_lists(L) -> lists:map(fun erlang:atom_to_list/1, L).
diff --git a/lib/ssh/test/ssh_test_lib.erl b/lib/ssh/test/ssh_test_lib.erl
index 7b273fecef..83819b97a5 100644
--- a/lib/ssh/test/ssh_test_lib.erl
+++ b/lib/ssh/test/ssh_test_lib.erl
@@ -404,7 +404,7 @@ setup_ecdsa(Size, DataDir, UserDir) ->
file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size++".pub"), filename:join(System, "ssh_host_ecdsa_key.pub")),
ct:log("DataDir ~p:~n ~p~n~nSystDir ~p:~n ~p~n~nUserDir ~p:~n ~p",[DataDir, file:list_dir(DataDir), System, file:list_dir(System), UserDir, file:list_dir(UserDir)]),
setup_ecdsa_known_host(Size, System, UserDir),
- setup_ecdsa_auth_keys(Size, UserDir, UserDir).
+ setup_ecdsa_auth_keys(Size, DataDir, UserDir).
clean_dsa(UserDir) ->
del_dirs(filename:join(UserDir, "system")),
@@ -438,6 +438,29 @@ setup_rsa_pass_pharse(DataDir, UserDir, Phrase) ->
setup_rsa_known_host(DataDir, UserDir),
setup_rsa_auth_keys(DataDir, UserDir).
+setup_ecdsa_pass_phrase(Size, DataDir, UserDir, Phrase) ->
+ try
+ {ok, KeyBin} =
+ case file:read_file(F=filename:join(DataDir, "id_ecdsa"++Size)) of
+ {error,E} ->
+ ct:log("Failed (~p) to read ~p~nFiles: ~p", [E,F,file:list_dir(DataDir)]),
+ file:read_file(filename:join(DataDir, "id_ecdsa"));
+ Other ->
+ Other
+ end,
+ setup_pass_pharse(KeyBin, filename:join(UserDir, "id_ecdsa"), Phrase),
+ System = filename:join(UserDir, "system"),
+ file:make_dir(System),
+ file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size), filename:join(System, "ssh_host_ecdsa_key")),
+ file:copy(filename:join(DataDir, "ssh_host_ecdsa_key"++Size++".pub"), filename:join(System, "ssh_host_ecdsa_key.pub")),
+ setup_ecdsa_known_host(Size, System, UserDir),
+ setup_ecdsa_auth_keys(Size, DataDir, UserDir)
+ of
+ _ -> true
+ catch
+ _:_ -> false
+ end.
+
setup_pass_pharse(KeyBin, OutFile, Phrase) ->
[{KeyType, _,_} = Entry0] = public_key:pem_decode(KeyBin),
Key = public_key:pem_entry_decode(Entry0),
@@ -489,8 +512,15 @@ setup_rsa_auth_keys(Dir, UserDir) ->
PKey = #'RSAPublicKey'{publicExponent = E, modulus = N},
setup_auth_keys([{ PKey, [{comment, "Test"}]}], UserDir).
-setup_ecdsa_auth_keys(_Size, Dir, UserDir) ->
- {ok, Pem} = file:read_file(filename:join(Dir, "id_ecdsa")),
+setup_ecdsa_auth_keys(Size, Dir, UserDir) ->
+ {ok, Pem} =
+ case file:read_file(F=filename:join(Dir, "id_ecdsa"++Size)) of
+ {error,E} ->
+ ct:log("Failed (~p) to read ~p~nFiles: ~p", [E,F,file:list_dir(Dir)]),
+ file:read_file(filename:join(Dir, "id_ecdsa"));
+ Other ->
+ Other
+ end,
ECDSA = public_key:pem_entry_decode(hd(public_key:pem_decode(Pem))),
#'ECPrivateKey'{publicKey = Q,
parameters = Param = {namedCurve,_Id0}} = ECDSA,
@@ -572,7 +602,6 @@ check_ssh_client_support2(P) ->
{P, {exit_status, E}} ->
E
after 5000 ->
-
ct:log("Openssh command timed out ~n"),
-1
end.
diff --git a/lib/ssh/test/ssh_to_openssh_SUITE.erl b/lib/ssh/test/ssh_to_openssh_SUITE.erl
index 4d6aa93d4e..75d5b5e296 100644
--- a/lib/ssh/test/ssh_to_openssh_SUITE.erl
+++ b/lib/ssh/test/ssh_to_openssh_SUITE.erl
@@ -332,7 +332,7 @@ erlang_client_openssh_server_publickey_dsa(Config) ->
erlang_client_openssh_server_publickey_X(Config, 'ssh-dss').
-erlang_client_openssh_server_publickey_X(Config, Alg) ->
+erlang_client_openssh_server_publickey_X(_Config, Alg) ->
ConnectionRef =
ssh_test_lib:connect(?SSH_DEFAULT_PORT,
[{pref_public_key_algs, [Alg]},