aboutsummaryrefslogtreecommitdiffstats
path: root/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl
diff options
context:
space:
mode:
authorSiri Hansen <[email protected]>2014-07-01 11:37:53 +0200
committerSiri Hansen <[email protected]>2014-07-01 11:40:27 +0200
commit466c4a2c075f0b43727bfb226f7be15ff081a57c (patch)
tree30719d06a2a9adad6a1c25d8e797838a73480701 /lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl
parenta6de62be5de44b249bc2d1c963c0c31bed5d32d0 (diff)
downloadotp-466c4a2c075f0b43727bfb226f7be15ff081a57c.tar.gz
otp-466c4a2c075f0b43727bfb226f7be15ff081a57c.tar.bz2
otp-466c4a2c075f0b43727bfb226f7be15ff081a57c.zip
[ct] Add test with netconf server on remote node
The new test is related to support sequence seq12645. It tests that the netconf client process dies if the node hosting the netconf server terminates.
Diffstat (limited to 'lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl')
-rw-r--r--lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl166
1 files changed, 166 insertions, 0 deletions
diff --git a/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl
new file mode 100644
index 0000000000..e058bc7600
--- /dev/null
+++ b/lib/common_test/test/ct_netconfc_SUITE_data/netconfc_test_lib.erl
@@ -0,0 +1,166 @@
+-module(netconfc_test_lib).
+
+-export([get_id_keys/1, remove_id_keys/1, make_dsa_files/1]).
+-include_lib("common_test/include/ct.hrl").
+-include_lib("public_key/include/public_key.hrl").
+
+%%%-----------------------------------------------------------------
+%%% BEGIN SSH key management
+%% copy private keys to given dir from ~/.ssh
+get_id_keys(Config) ->
+ DstDir = ?config(priv_dir, Config),
+ SrcDir = filename:join(os:getenv("HOME"), ".ssh"),
+ RsaOk = copyfile(SrcDir, DstDir, "id_rsa"),
+ DsaOk = copyfile(SrcDir, DstDir, "id_dsa"),
+ case {RsaOk, DsaOk} of
+ {{ok, _}, {ok, _}} -> {ok, both};
+ {{ok, _}, _} -> {ok, rsa};
+ {_, {ok, _}} -> {ok, dsa};
+ {Error, _} -> Error
+ end.
+
+%% Remove later on. Use make_dsa_files instead.
+remove_id_keys(Config) ->
+ Dir = ?config(priv_dir, Config),
+ file:delete(filename:join(Dir, "id_rsa")),
+ file:delete(filename:join(Dir, "id_dsa")).
+
+
+make_dsa_files(Config) ->
+ make_dsa_files(Config, rfc4716_public_key).
+make_dsa_files(Config, Type) ->
+ {DSA, EncodedKey} = gen_dsa(128, 20),
+ PKey = DSA#'DSAPrivateKey'.y,
+ P = DSA#'DSAPrivateKey'.p,
+ Q = DSA#'DSAPrivateKey'.q,
+ G = DSA#'DSAPrivateKey'.g,
+ Dss = #'Dss-Parms'{p=P, q=Q, g=G},
+ {ok, Hostname} = inet:gethostname(),
+ {ok, {A, B, C, D}} = inet:getaddr(Hostname, inet),
+ IP = lists:concat([A, ".", B, ".", C, ".", D]),
+ Attributes = [], % Could be [{comment,"user@" ++ Hostname}],
+ HostNames = [{hostnames,[IP, IP]}],
+ PublicKey = [{{PKey, Dss}, Attributes}],
+ KnownHosts = [{{PKey, Dss}, HostNames}],
+
+ KnownHostsEnc = public_key:ssh_encode(KnownHosts, known_hosts),
+ KnownHosts = public_key:ssh_decode(KnownHostsEnc, known_hosts),
+
+ PublicKeyEnc = public_key:ssh_encode(PublicKey, Type),
+
+ SystemTmpDir = ?config(data_dir, Config),
+ filelib:ensure_dir(SystemTmpDir),
+ file:make_dir(SystemTmpDir),
+
+ DSAFile = filename:join(SystemTmpDir, "ssh_host_dsa_key.pub"),
+ file:delete(DSAFile),
+
+ DSAPrivateFile = filename:join(SystemTmpDir, "ssh_host_dsa_key"),
+ file:delete(DSAPrivateFile),
+
+ KHFile = filename:join(SystemTmpDir, "known_hosts"),
+ file:delete(KHFile),
+
+ PemBin = public_key:pem_encode([EncodedKey]),
+
+ file:write_file(DSAFile, PublicKeyEnc),
+ file:write_file(KHFile, KnownHostsEnc),
+ file:write_file(DSAPrivateFile, PemBin),
+ ok.
+
+
+%%--------------------------------------------------------------------
+%% @doc Creates a dsa key (OBS: for testing only)
+%% the sizes are in bytes
+%% @spec (::integer()) -> {::atom(), ::binary(), ::opaque()}
+%% @end
+%%--------------------------------------------------------------------
+gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) ->
+ Key = gen_dsa2(LSize, NSize),
+ {Key, encode_key(Key)}.
+
+encode_key(Key = #'DSAPrivateKey'{}) ->
+ Der = public_key:der_encode('DSAPrivateKey', Key),
+ {'DSAPrivateKey', Der, not_encrypted}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% DSA key generation (OBS: for testing only)
+%% See http://en.wikipedia.org/wiki/Digital_Signature_Algorithm
+%% and the fips_186-3.pdf
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+gen_dsa2(LSize, NSize) ->
+ Q = prime(NSize), %% Choose N-bit prime Q
+ X0 = prime(LSize),
+ P0 = prime((LSize div 2) +1),
+
+ %% Choose L-bit prime modulus P such that p-1 is a multiple of q.
+ case dsa_search(X0 div (2*Q*P0), P0, Q, 1000) of
+ error ->
+ gen_dsa2(LSize, NSize);
+ P ->
+ G = crypto:mod_pow(2, (P-1) div Q, P), % Choose G a number whose multiplicative order modulo p is q.
+ %% such that This may be done by setting g = h^(p-1)/q mod p, commonly h=2 is used.
+
+ X = prime(20), %% Choose x by some random method, where 0 < x < q.
+ Y = crypto:mod_pow(G, X, P), %% Calculate y = g^x mod p.
+
+ #'DSAPrivateKey'{version=0, p = P, q = Q,
+ g = crypto:bytes_to_integer(G), y = crypto:bytes_to_integer(Y), x = X}
+ end.
+
+%% See fips_186-3.pdf
+dsa_search(T, P0, Q, Iter) when Iter > 0 ->
+ P = 2*T*Q*P0 + 1,
+ case is_prime(P, 50) of
+ true -> P;
+ false -> dsa_search(T+1, P0, Q, Iter-1)
+ end;
+dsa_search(_,_,_,_) ->
+ error.
+
+
+%%%%%%% Crypto Math %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+prime(ByteSize) ->
+ Rand = odd_rand(ByteSize),
+ prime_odd(Rand, 0).
+
+prime_odd(Rand, N) ->
+ case is_prime(Rand, 50) of
+ true ->
+ Rand;
+ false ->
+ prime_odd(Rand+2, N+1)
+ end.
+
+%% see http://en.wikipedia.org/wiki/Fermat_primality_test
+is_prime(_, 0) -> true;
+is_prime(Candidate, Test) ->
+ CoPrime = odd_rand(10000, Candidate),
+ Result = crypto:mod_pow(CoPrime, Candidate, Candidate) ,
+ is_prime(CoPrime, crypto:bytes_to_integer(Result), Candidate, Test).
+
+is_prime(CoPrime, CoPrime, Candidate, Test) ->
+ is_prime(Candidate, Test-1);
+is_prime(_,_,_,_) ->
+ false.
+
+odd_rand(Size) ->
+ Min = 1 bsl (Size*8-1),
+ Max = (1 bsl (Size*8))-1,
+ odd_rand(Min, Max).
+
+odd_rand(Min,Max) ->
+ Rand = crypto:rand_uniform(Min,Max),
+ case Rand rem 2 of
+ 0 ->
+ Rand + 1;
+ _ ->
+ Rand
+ end.
+
+copyfile(SrcDir, DstDir, Fn) ->
+ file:copy(filename:join(SrcDir, Fn),
+ filename:join(DstDir, Fn)).
+
+%%% END SSH key management
+%%%-----------------------------------------------------------------