aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src/ssh_transport.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssh/src/ssh_transport.erl')
-rw-r--r--lib/ssh/src/ssh_transport.erl266
1 files changed, 141 insertions, 125 deletions
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index a6438e69d4..0c999b96cc 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -44,7 +44,8 @@
handle_kexdh_reply/2,
handle_kex_ecdh_init/2,
handle_kex_ecdh_reply/2,
- unpack/3, decompress/2, ssh_packet/2, pack/2, msg_data/1,
+ extract_public_key/1,
+ unpack/3, decompress/2, ssh_packet/2, pack/2, pack/3, msg_data/1,
sign/3, verify/4]).
%%%----------------------------------------------------------------------------
@@ -65,8 +66,8 @@ default_algorithms() -> [{K,default_algorithms(K)} || K <- algo_classes()].
algo_classes() -> [kex, public_key, cipher, mac, compression].
-default_algorithms(kex) ->
- supported_algorithms(kex, []); %% Just to have a call to supported_algorithms/2
+%% default_algorithms(kex) -> % Example of how to disable an algorithm
+%% supported_algorithms(kex, ['ecdh-sha2-nistp521']);
default_algorithms(Alg) ->
supported_algorithms(Alg).
@@ -117,11 +118,11 @@ supported_algorithms(compression) ->
'zlib'
]).
-supported_algorithms(Key, [{client2server,BL1},{server2client,BL2}]) ->
- [{client2server,As1},{server2client,As2}] = supported_algorithms(Key),
- [{client2server,As1--BL1},{server2client,As2--BL2}];
-supported_algorithms(Key, BlackList) ->
- supported_algorithms(Key) -- BlackList.
+%% Dialyzer complains when not called...supported_algorithms(Key, [{client2server,BL1},{server2client,BL2}]) ->
+%% Dialyzer complains when not called... [{client2server,As1},{server2client,As2}] = supported_algorithms(Key),
+%% Dialyzer complains when not called... [{client2server,As1--BL1},{server2client,As2--BL2}];
+%% Dialyzer complains when not called...supported_algorithms(Key, BlackList) ->
+%% Dialyzer complains when not called... supported_algorithms(Key) -- BlackList.
select_crypto_supported(L) ->
Sup = [{ec_curve,crypto_supported_curves()} | crypto:supports()],
@@ -328,9 +329,7 @@ verify_algorithm(#alg{encrypt = undefined}) -> false;
verify_algorithm(#alg{decrypt = undefined}) -> false;
verify_algorithm(#alg{compress = undefined}) -> false;
verify_algorithm(#alg{decompress = undefined}) -> false;
-
-verify_algorithm(#alg{kex = Kex}) -> lists:member(Kex, supported_algorithms(kex));
-verify_algorithm(_) -> false.
+verify_algorithm(#alg{kex = Kex}) -> lists:member(Kex, supported_algorithms(kex)).
%%%----------------------------------------------------------------
%%%
@@ -380,13 +379,15 @@ handle_kexdh_init(#ssh_msg_kexdh_init{e = E},
1=<E, E=<(P-1) ->
{Public, Private} = generate_key(dh, [P,G]),
K = compute_key(dh, E, Private, [P,G]),
- Key = get_host_key(Ssh0),
- H = kex_h(Ssh0, Key, E, Public, K),
- H_SIG = sign_host_key(Ssh0, Key, H),
- {SshPacket, Ssh1} = ssh_packet(#ssh_msg_kexdh_reply{public_host_key = Key,
- f = Public,
- h_sig = H_SIG
- }, Ssh0),
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, MyPubHostKey, E, Public, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
+ {SshPacket, Ssh1} =
+ ssh_packet(#ssh_msg_kexdh_reply{public_host_key = MyPubHostKey,
+ f = Public,
+ h_sig = H_SIG
+ }, Ssh0),
{ok, SshPacket, Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}},
shared_secret = K,
exchanged_hash = H,
@@ -401,7 +402,7 @@ handle_kexdh_init(#ssh_msg_kexdh_init{e = E},
})
end.
-handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey,
+handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = PeerPubHostKey,
f = F,
h_sig = H_SIG},
#ssh{keyex_key = {{Private, Public}, {G, P}}} = Ssh0) ->
@@ -409,9 +410,9 @@ handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey,
if
1=<F, F=<(P-1)->
K = compute_key(dh, F, Private, [P,G]),
- H = kex_h(Ssh0, HostKey, Public, F, K),
+ H = kex_h(Ssh0, PeerPubHostKey, Public, F, K),
- case verify_host_key(Ssh0, HostKey, H, H_SIG) of
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
ok ->
{SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
{ok, SshPacket, Ssh#ssh{shared_secret = K,
@@ -440,19 +441,29 @@ handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey,
%%%
%%% diffie-hellman-group-exchange-sha1
%%%
-handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = Min,
+handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = Min0,
n = NBits,
- max = Max},
- Ssh0=#ssh{opts=Opts}) when Min=<NBits, NBits=<Max ->
+ max = Max0},
+ Ssh0=#ssh{opts=Opts}) when Min0=<NBits, NBits=<Max0 ->
%% server
- {G, P} = dh_gex_group(Min, NBits, Max, proplists:get_value(dh_gex_groups,Opts)),
- {Public, Private} = generate_key(dh, [P,G]),
- {SshPacket, Ssh} =
- ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
- {ok, SshPacket,
- Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
- keyex_info = {Min, Max, NBits}
- }};
+ {Min, Max} = adjust_gex_min_max(Min0, Max0, Opts),
+ case public_key:dh_gex_group(Min, NBits, Max,
+ proplists:get_value(dh_gex_groups,Opts)) of
+ {ok, {_Sz, {G,P}}} ->
+ {Public, Private} = generate_key(dh, [P,G]),
+ {SshPacket, Ssh} =
+ ssh_packet(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0),
+ {ok, SshPacket,
+ Ssh#ssh{keyex_key = {{Private, Public}, {G, P}},
+ keyex_info = {Min, Max, NBits}
+ }};
+ {error,_} ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group found",
+ language = ""})
+ end;
+
handle_kex_dh_gex_request(_, _) ->
throw({{error,bad_ssh_msg_kex_dh_gex_request},
#ssh_msg_disconnect{
@@ -461,6 +472,26 @@ handle_kex_dh_gex_request(_, _) ->
language = ""}
}).
+
+adjust_gex_min_max(Min0, Max0, Opts) ->
+ case proplists:get_value(dh_gex_limits, Opts) of
+ undefined ->
+ {Min0, Max0};
+ {Min1, Max1} ->
+ Min2 = max(Min0, Min1),
+ Max2 = min(Max0, Max1),
+ if
+ Min2 =< Max2 ->
+ {Min2, Max2};
+ Max2 < Min2 ->
+ throw(#ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "No possible diffie-hellman-group-exchange group possible",
+ language = ""})
+ end
+ end.
+
+
handle_kex_dh_gex_group(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0) ->
%% client
{Public, Private} = generate_key(dh, [P,G]),
@@ -480,11 +511,12 @@ handle_kex_dh_gex_init(#ssh_msg_kex_dh_gex_init{e = E},
K = compute_key(dh, E, Private, [P,G]),
if
1<K, K<(P-1) ->
- HostKey = get_host_key(Ssh0),
- H = kex_h(Ssh0, HostKey, Min, NBits, Max, P, G, E, Public, K),
- H_SIG = sign_host_key(Ssh0, HostKey, H),
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, MyPubHostKey, Min, NBits, Max, P, G, E, Public, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
{SshPacket, Ssh} =
- ssh_packet(#ssh_msg_kex_dh_gex_reply{public_host_key = HostKey,
+ ssh_packet(#ssh_msg_kex_dh_gex_reply{public_host_key = MyPubHostKey,
f = Public,
h_sig = H_SIG}, Ssh0),
{ok, SshPacket, Ssh#ssh{shared_secret = K,
@@ -508,7 +540,7 @@ handle_kex_dh_gex_init(#ssh_msg_kex_dh_gex_init{e = E},
})
end.
-handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = HostKey,
+handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = PeerPubHostKey,
f = F,
h_sig = H_SIG},
#ssh{keyex_key = {{Private, Public}, {G, P}},
@@ -520,9 +552,9 @@ handle_kex_dh_gex_reply(#ssh_msg_kex_dh_gex_reply{public_host_key = HostKey,
K = compute_key(dh, F, Private, [P,G]),
if
1<K, K<(P-1) ->
- H = kex_h(Ssh0, HostKey, Min, NBits, Max, P, G, Public, F, K),
+ H = kex_h(Ssh0, PeerPubHostKey, Min, NBits, Max, P, G, Public, F, K),
- case verify_host_key(Ssh0, HostKey, H, H_SIG) of
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
ok ->
{SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
{ok, SshPacket, Ssh#ssh{shared_secret = K,
@@ -561,24 +593,26 @@ handle_kex_ecdh_init(#ssh_msg_kex_ecdh_init{q_c = PeerPublic},
Ssh0 = #ssh{algorithms = #alg{kex=Kex}}) ->
%% at server
Curve = ecdh_curve(Kex),
- case ecdh_validate_public_key(PeerPublic, Curve) of
- true ->
- {MyPublic, MyPrivate} = generate_key(ecdh, Curve),
- K = compute_key(ecdh, PeerPublic, MyPrivate, Curve),
- HostKey = get_host_key(Ssh0),
- H = kex_h(Ssh0, Curve, HostKey, PeerPublic, MyPublic, K),
- H_SIG = sign_host_key(Ssh0, HostKey, H),
+ {MyPublic, MyPrivate} = generate_key(ecdh, Curve),
+ try
+ compute_key(ecdh, PeerPublic, MyPrivate, Curve)
+ of
+ K ->
+ MyPrivHostKey = get_host_key(Ssh0),
+ MyPubHostKey = extract_public_key(MyPrivHostKey),
+ H = kex_h(Ssh0, Curve, MyPubHostKey, PeerPublic, MyPublic, K),
+ H_SIG = sign_host_key(Ssh0, MyPrivHostKey, H),
{SshPacket, Ssh1} =
- ssh_packet(#ssh_msg_kex_ecdh_reply{public_host_key = HostKey,
+ ssh_packet(#ssh_msg_kex_ecdh_reply{public_host_key = MyPubHostKey,
q_s = MyPublic,
h_sig = H_SIG},
Ssh0),
{ok, SshPacket, Ssh1#ssh{keyex_key = {{MyPublic,MyPrivate},Curve},
shared_secret = K,
exchanged_hash = H,
- session_id = sid(Ssh1, H)}};
-
- false ->
+ session_id = sid(Ssh1, H)}}
+ catch
+ _:_ ->
throw({{error,invalid_peer_public_key},
#ssh_msg_disconnect{
code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
@@ -587,17 +621,18 @@ handle_kex_ecdh_init(#ssh_msg_kex_ecdh_init{q_c = PeerPublic},
})
end.
-handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = HostKey,
+handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = PeerPubHostKey,
q_s = PeerPublic,
h_sig = H_SIG},
#ssh{keyex_key = {{MyPublic,MyPrivate}, Curve}} = Ssh0
) ->
%% at client
- case ecdh_validate_public_key(PeerPublic, Curve) of
- true ->
- K = compute_key(ecdh, PeerPublic, MyPrivate, Curve),
- H = kex_h(Ssh0, Curve, HostKey, MyPublic, PeerPublic, K),
- case verify_host_key(Ssh0, HostKey, H, H_SIG) of
+ try
+ compute_key(ecdh, PeerPublic, MyPrivate, Curve)
+ of
+ K ->
+ H = kex_h(Ssh0, Curve, PeerPubHostKey, MyPublic, PeerPublic, K),
+ case verify_host_key(Ssh0, PeerPubHostKey, H, H_SIG) of
ok ->
{SshPacket, Ssh} = ssh_packet(#ssh_msg_newkeys{}, Ssh0),
{ok, SshPacket, Ssh#ssh{shared_secret = K,
@@ -610,9 +645,9 @@ handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = HostKey,
description = "Key exchange failed",
language = ""}
})
- end;
-
- false ->
+ end
+ catch
+ _:_ ->
throw({{error,invalid_peer_public_key},
#ssh_msg_disconnect{
code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
@@ -622,8 +657,6 @@ handle_kex_ecdh_reply(#ssh_msg_kex_ecdh_reply{public_host_key = HostKey,
end.
-ecdh_validate_public_key(_, _) -> true. % FIXME: Far too many false positives :)
-
%%%----------------------------------------------------------------
handle_new_keys(#ssh_msg_newkeys{}, Ssh0) ->
try install_alg(Ssh0) of
@@ -659,13 +692,20 @@ get_host_key(SSH) ->
sign_host_key(_Ssh, PrivateKey, H) ->
sign(H, sign_host_key_sha(PrivateKey), PrivateKey).
-sign_host_key_sha(#'ECPrivateKey'{parameters = {namedCurve, ?'secp256r1'}}) -> sha256;
-sign_host_key_sha(#'ECPrivateKey'{parameters = {namedCurve, ?'secp384r1'}}) -> sha384;
-sign_host_key_sha(#'ECPrivateKey'{parameters = {namedCurve, ?'secp521r1'}}) -> sha512;
+sign_host_key_sha(#'ECPrivateKey'{parameters = {namedCurve,OID}}) -> sha(OID);
sign_host_key_sha(#'RSAPrivateKey'{}) -> sha;
sign_host_key_sha(#'DSAPrivateKey'{}) -> sha.
+extract_public_key(#'RSAPrivateKey'{modulus = N, publicExponent = E}) ->
+ #'RSAPublicKey'{modulus = N, publicExponent = E};
+extract_public_key(#'DSAPrivateKey'{y = Y, p = P, q = Q, g = G}) ->
+ {Y, #'Dss-Parms'{p=P, q=Q, g=G}};
+extract_public_key(#'ECPrivateKey'{parameters = {namedCurve,OID},
+ publicKey = Q}) ->
+ {#'ECPoint'{point=Q}, {namedCurve,OID}}.
+
+
verify_host_key(SSH, PublicKey, Digest, Signature) ->
case verify(Digest, host_key_sha(PublicKey), Signature, PublicKey) of
false ->
@@ -674,14 +714,16 @@ verify_host_key(SSH, PublicKey, Digest, Signature) ->
known_host_key(SSH, PublicKey, public_algo(PublicKey))
end.
-host_key_sha(#'RSAPublicKey'{}) -> sha;
-host_key_sha({_, #'Dss-Parms'{}}) -> sha;
-host_key_sha({#'ECPoint'{},Id}) -> sha(list_to_atom(binary_to_list(Id))).
+host_key_sha(#'RSAPublicKey'{}) -> sha;
+host_key_sha({_, #'Dss-Parms'{}}) -> sha;
+host_key_sha({#'ECPoint'{},{namedCurve,OID}}) -> sha(OID).
public_algo(#'RSAPublicKey'{}) -> 'ssh-rsa';
public_algo({_, #'Dss-Parms'{}}) -> 'ssh-dss';
-public_algo({#'ECPoint'{},Id}) -> list_to_atom("ecdsa-sha2-" ++ binary_to_list(Id)).
+public_algo({#'ECPoint'{},{namedCurve,OID}}) ->
+ Curve = public_key:oid2ssh_curvename(OID),
+ list_to_atom("ecdsa-sha2-" ++ binary_to_list(Curve)).
accepted_host(Ssh, PeerName, Opts) ->
@@ -863,11 +905,18 @@ ssh_packet(Msg, Ssh) ->
BinMsg = ssh_message:encode(Msg),
pack(BinMsg, Ssh).
+pack(Data, Ssh=#ssh{}) ->
+ pack(Data, Ssh, 0).
+
+%%% Note: pack/3 is only to be called from tests that wants
+%%% to deliberetly send packets with wrong PacketLength!
+%%% Use pack/2 for all other purposes!
pack(Data0, #ssh{encrypt_block_size = BlockSize,
send_sequence = SeqNum, send_mac = MacAlg,
send_mac_key = MacKey,
random_length_padding = RandomLengthPadding}
- = Ssh0) when is_binary(Data0) ->
+ = Ssh0,
+ PacketLenDeviationForTests) when is_binary(Data0) ->
{Ssh1, Data} = compress(Ssh0, Data0),
PL = (BlockSize - ((4 + 1 + size(Data)) rem BlockSize)) rem BlockSize,
MinPaddingLen = if PL < 4 -> PL + BlockSize;
@@ -880,7 +929,7 @@ pack(Data0, #ssh{encrypt_block_size = BlockSize,
end,
PaddingLen = MinPaddingLen + ExtraPaddingLen,
Padding = ssh_bits:random(PaddingLen),
- PacketLen = 1 + PaddingLen + size(Data),
+ PacketLen = 1 + PaddingLen + size(Data) + PacketLenDeviationForTests,
PacketData = <<?UINT32(PacketLen),?BYTE(PaddingLen),
Data/binary, Padding/binary>>,
{Ssh2, EncPacket} = encrypt(Ssh1, PacketData),
@@ -933,17 +982,12 @@ verify(PlainText, Hash, Sig, {_, #'Dss-Parms'{}} = Key) ->
<<R:160/big-unsigned-integer, S:160/big-unsigned-integer>> = Sig,
Signature = public_key:der_encode('Dss-Sig-Value', #'Dss-Sig-Value'{r = R, s = S}),
public_key:verify(PlainText, Hash, Signature, Key);
-verify(PlainText, Hash, Sig, {ECPoint=#'ECPoint'{}, Param}) ->
- C = case Param of
- <<"nistp256">> -> {namedCurve, ?'secp256r1'};
- <<"nistp384">> -> {namedCurve, ?'secp384r1'};
- <<"nistp521">> -> {namedCurve, ?'secp521r1'}
- end,
+verify(PlainText, Hash, Sig, {#'ECPoint'{},_} = Key) ->
<<?UINT32(Rlen),R:Rlen/big-signed-integer-unit:8,
?UINT32(Slen),S:Slen/big-signed-integer-unit:8>> = Sig,
Sval = #'ECDSA-Sig-Value'{r=R, s=S},
DerEncodedSig = public_key:der_encode('ECDSA-Sig-Value',Sval),
- public_key:verify(PlainText, Hash, DerEncodedSig, {ECPoint,C});
+ public_key:verify(PlainText, Hash, DerEncodedSig, Key);
verify(PlainText, Hash, Sig, Key) ->
public_key:verify(PlainText, Hash, Sig, Key).
@@ -1336,52 +1380,58 @@ hash(K, H, Ki, N, HASH) ->
hash(K, H, <<Ki/binary, Kj/binary>>, N-128, HASH).
kex_h(SSH, Key, E, F, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = ssh_bits:encode([SSH#ssh.c_version, SSH#ssh.s_version,
SSH#ssh.c_keyinit, SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), E,F,K],
+ KeyBin, E,F,K],
[string,string,binary,binary,binary,
mpint,mpint,mpint]),
crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).
%% crypto:hash(sha,L).
kex_h(SSH, Curve, Key, Q_c, Q_s, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = ssh_bits:encode([SSH#ssh.c_version, SSH#ssh.s_version,
SSH#ssh.c_keyinit, SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), Q_c, Q_s, K],
+ KeyBin, Q_c, Q_s, K],
[string,string,binary,binary,binary,
mpint,mpint,mpint]),
crypto:hash(sha(Curve), L).
kex_h(SSH, Key, Min, NBits, Max, Prime, Gen, E, F, K) ->
L = if Min==-1; Max==-1 ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
Ts = [string,string,binary,binary,binary,
uint32,
mpint,mpint,mpint,mpint,mpint],
ssh_bits:encode([SSH#ssh.c_version,SSH#ssh.s_version,
SSH#ssh.c_keyinit,SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), NBits, Prime, Gen, E,F,K],
+ KeyBin, NBits, Prime, Gen, E,F,K],
Ts);
true ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
Ts = [string,string,binary,binary,binary,
uint32,uint32,uint32,
mpint,mpint,mpint,mpint,mpint],
ssh_bits:encode([SSH#ssh.c_version,SSH#ssh.s_version,
SSH#ssh.c_keyinit,SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), Min, NBits, Max,
+ KeyBin, Min, NBits, Max,
Prime, Gen, E,F,K], Ts)
end,
crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).
-sha('nistp256') -> sha256;
-sha('secp256r1')-> sha256;
-sha('nistp384') -> sha384;
-sha('secp384r1')-> sha384;
-sha('nistp521') -> sha512;
-sha('secp521r1')-> sha512;
+
+sha(secp256r1) -> sha256;
+sha(secp384r1) -> sha384;
+sha(secp521r1) -> sha512;
sha('diffie-hellman-group1-sha1') -> sha;
sha('diffie-hellman-group14-sha1') -> sha;
sha('diffie-hellman-group-exchange-sha1') -> sha;
-sha('diffie-hellman-group-exchange-sha256') -> sha256.
+sha('diffie-hellman-group-exchange-sha256') -> sha256;
+sha(?'secp256r1') -> sha(secp256r1);
+sha(?'secp384r1') -> sha(secp384r1);
+sha(?'secp521r1') -> sha(secp521r1).
+
mac_key_size('hmac-sha1') -> 20*8;
mac_key_size('hmac-sha1-96') -> 20*8;
@@ -1408,44 +1458,10 @@ peer_name({Host, _}) ->
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-dh_group('diffie-hellman-group1-sha1') -> element(2, ?dh_group1);
-dh_group('diffie-hellman-group14-sha1') -> element(2, ?dh_group14).
-
-dh_gex_default_groups() -> ?dh_default_groups.
-
-
-dh_gex_group(Min, N, Max, undefined) ->
- dh_gex_group(Min, N, Max, dh_gex_default_groups());
-dh_gex_group(Min, N, Max, Groups) ->
- %% First try to find an exact match. If not an exact match, select the largest possible.
- {_Size,Group} =
- lists:foldl(
- fun(_, {I,G}) when I==N ->
- %% If we have an exact match already: use that one
- {I,G};
- ({I,G}, _) when I==N ->
- %% If we now found an exact match: use that very one
- {I,G};
- ({I,G}, {Imax,_Gmax}) when Min=<I,I=<Max, % a) {I,G} fullfills the requirements
- I>Imax -> % b) {I,G} is larger than current max
- %% A group within the limits and better than the one we have
- {I,G};
- (_, IGmax) ->
- %% Keep the one we have
- IGmax
- end, {-1,undefined}, Groups),
-
- case Group of
- undefined ->
- throw(#ssh_msg_disconnect{
- code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
- description = "No possible diffie-hellman-group-exchange group found",
- language = ""});
- _ ->
- Group
- end.
-
+dh_group('diffie-hellman-group1-sha1') -> ?dh_group1;
+dh_group('diffie-hellman-group14-sha1') -> ?dh_group14.
+%%%----------------------------------------------------------------
generate_key(Algorithm, Args) ->
{Public,Private} = crypto:generate_key(Algorithm, Args),
{crypto:bytes_to_integer(Public), crypto:bytes_to_integer(Private)}.