aboutsummaryrefslogtreecommitdiffstats
path: root/lib/public_key/src/pubkey_ssh.erl
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2015-10-21 17:25:42 +0200
committerHans Nilsson <[email protected]>2015-11-04 12:10:06 +0100
commitc50a9a6562a14f3a9fbd2071e3b19eed8c9c9b4b (patch)
treee521160deb7797e1b2180eb31219ede9df877708 /lib/public_key/src/pubkey_ssh.erl
parent4f085471fc4e1886bd7549cf135e7038a87e6a8e (diff)
downloadotp-c50a9a6562a14f3a9fbd2071e3b19eed8c9c9b4b.tar.gz
otp-c50a9a6562a14f3a9fbd2071e3b19eed8c9c9b4b.tar.bz2
otp-c50a9a6562a14f3a9fbd2071e3b19eed8c9c9b4b.zip
ssh, public_key: random selection of diffie-hellman moduli
Also tool (public_key:gen_moduli_hrl) to convert an openssh moduli file to erlang format.
Diffstat (limited to 'lib/public_key/src/pubkey_ssh.erl')
-rw-r--r--lib/public_key/src/pubkey_ssh.erl50
1 files changed, 49 insertions, 1 deletions
diff --git a/lib/public_key/src/pubkey_ssh.erl b/lib/public_key/src/pubkey_ssh.erl
index 82042550a0..9b281aa482 100644
--- a/lib/public_key/src/pubkey_ssh.erl
+++ b/lib/public_key/src/pubkey_ssh.erl
@@ -20,8 +20,12 @@
-module(pubkey_ssh).
-include("public_key.hrl").
+-include("pubkey_moduli.hrl").
--export([decode/2, encode/2
+
+-export([decode/2, encode/2,
+ dh_gex_group/4,
+ dh_gex_group_sizes/0
]).
-define(UINT32(X), X:32/unsigned-big-integer).
@@ -77,6 +81,50 @@ encode(Entries, Type) ->
end, Entries)).
%%--------------------------------------------------------------------
+-spec dh_gex_group(integer(), integer(), integer(),
+ undefined | [{integer(),[{integer(),integer()}]}]) ->
+ {ok,{integer(),{integer(),integer()}}} | {error,any()} .
+%%
+%% Description: Returns Generator and Modulus given MinSize, WantedSize
+%% and MaxSize
+%%--------------------------------------------------------------------
+dh_gex_group(Min, N, Max, undefined) ->
+ dh_gex_group(Min, N, Max, ?dh_default_groups);
+dh_gex_group(Min, N, Max, Groups) ->
+ case select_by_keylen(Min-10, N, Max+10, Groups) of
+ {ok,{Sz,GPs}} ->
+ {ok, {Sz,lists:nth(crypto:rand_uniform(1, 1+length(GPs)), GPs)}};
+ Other ->
+ Other
+ end.
+
+dh_gex_group_sizes()->
+ [KeyLen || {KeyLen,_} <- ?dh_default_groups].
+
+%% Select the one with K closest to N but within the interval [Min,Max]
+
+select_by_keylen(Min, N, Max, [{K,_Gs}|Groups]) when K < Min ->
+ select_by_keylen(Min, N, Max, Groups);
+select_by_keylen(Min, N, Max, [{K,Gs}|Groups]) when K =< Max ->
+ {ok, select_by_keylen(Min, N, Max, Groups, {K,Gs})};
+select_by_keylen(_Min, _N, _Max, _) ->
+ {error,no_group_found}.
+
+select_by_keylen(_Min, _N, Max, [{K,_Gs}|_Groups], GPprev) when K > Max ->
+ GPprev;
+select_by_keylen(Min, N, Max, [{K,Gs}|Groups], {Kprev,GsPrev}) ->
+ if
+ N == K -> {K,Gs};
+ N > K -> select_by_keylen(Min, N, Max, Groups, {K,Gs});
+ N < K, (K-N) < (N-Kprev) -> {K,Gs};
+ N < K -> {Kprev,GsPrev}
+ end;
+select_by_keylen(_Min, _N, _Max, [],GPprev) ->
+ %% is between Min and Max
+ GPprev.
+
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
begin_marker() ->