From 8d37b35a3d68a5acf4889d5df20b51790ec19097 Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Thu, 7 Sep 2017 18:24:05 +0200
Subject: ssh: add ecdsa_pass_phrase option in analogy with rsa_pass_phrase

---
 lib/ssh/test/ssh_basic_SUITE.erl | 48 +++++++++++++++++++++++++++++++++++++++-
 lib/ssh/test/ssh_test_lib.erl    | 37 +++++++++++++++++++++++++++----
 2 files changed, 80 insertions(+), 5 deletions(-)

(limited to 'lib/ssh/test')

diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl
index 62e2a585e4..db2ae241e5 100644
--- a/lib/ssh/test/ssh_basic_SUITE.erl
+++ b/lib/ssh/test/ssh_basic_SUITE.erl
@@ -99,6 +99,9 @@ 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},
@@ -124,6 +127,9 @@ groups() ->
 				  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,
@@ -229,6 +235,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 +286,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) ->
@@ -306,6 +351,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),
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.
-- 
cgit v1.2.3