aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssh/src/ssh_transport.erl
diff options
context:
space:
mode:
authorHenrik Nord <[email protected]>2015-06-02 09:00:04 +0200
committerHenrik Nord <[email protected]>2015-06-02 09:00:04 +0200
commit21b8941d83516e381000387c47758bc7f040ae8b (patch)
tree2499b8b04c15a5ba2777a54921af7e4f9916676d /lib/ssh/src/ssh_transport.erl
parentf3fefbae24a2569a13b538d80d0e99129963ebef (diff)
parentc1df511623b9a2a98d4d3862ae612c1ca9837da7 (diff)
downloadotp-21b8941d83516e381000387c47758bc7f040ae8b.tar.gz
otp-21b8941d83516e381000387c47758bc7f040ae8b.tar.bz2
otp-21b8941d83516e381000387c47758bc7f040ae8b.zip
Merge tag 'OTP-17.5.6' into maint
=== OTP-17.5.6 === Changed Applications: - inets-5.10.9 - ssh-3.2.4 - ssl-6.0.1 Unchanged Applications: - asn1-3.0.4 - common_test-1.10.1 - compiler-5.0.4 - cosEvent-2.1.15 - cosEventDomain-1.1.14 - cosFileTransfer-1.1.16 - cosNotification-1.1.21 - cosProperty-1.1.17 - cosTime-1.1.14 - cosTransactions-1.2.14 - crypto-3.5 - debugger-4.0.3 - dialyzer-2.7.4 - diameter-1.9.2 - edoc-0.7.16 - eldap-1.1.1 - erl_docgen-0.3.7 - erl_interface-3.7.20 - erts-6.4.1 - et-1.5 - eunit-2.2.9 - gs-1.5.16 - hipe-3.11.3 - ic-4.3.6 - jinterface-1.5.12 - kernel-3.2 - megaco-3.17.3 - mnesia-4.12.5 - observer-2.0.4 - odbc-2.10.22 - orber-3.7.1 - os_mon-2.3.1 - ose-1.0.2 - otp_mibs-1.0.10 - parsetools-2.0.12 - percept-0.8.10 - public_key-0.23 - reltool-0.6.6 - runtime_tools-1.8.16 - sasl-2.4.1 - snmp-5.1.2 - stdlib-2.4 - syntax_tools-1.6.18 - test_server-3.8.1 - tools-2.7.2 - typer-0.9.8 - webtool-0.8.10 - wx-1.3.3 - xmerl-1.3.7
Diffstat (limited to 'lib/ssh/src/ssh_transport.erl')
-rw-r--r--lib/ssh/src/ssh_transport.erl59
1 files changed, 41 insertions, 18 deletions
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 8669be570e..6c0873fd9e 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -240,20 +240,30 @@ key_exchange_first_msg('diffie-hellman-group-exchange-sha1', Ssh0) ->
handle_kexdh_init(#ssh_msg_kexdh_init{e = E}, Ssh0) ->
{G, P} = dh_group1(),
- {Private, Public} = dh_gen_key(G, P, 1024),
- K = ssh_math:ipow(E, Private, P),
- 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),
-
- {ok, SshPacket, Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}},
- shared_secret = K,
- exchanged_hash = H,
- session_id = sid(Ssh1, H)}}.
+ if
+ 1=<E, E=<(P-1) ->
+ {Private, Public} = dh_gen_key(G, P, 1024),
+ K = ssh_math:ipow(E, Private, P),
+ 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),
+
+ {ok, SshPacket, Ssh1#ssh{keyex_key = {{Private, Public}, {G, P}},
+ shared_secret = K,
+ exchanged_hash = H,
+ session_id = sid(Ssh1, H)}};
+ true ->
+ Error = {error,bad_e_from_peer},
+ Disconnect = #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'f' out of bounds",
+ language = "en"},
+ throw({Error, Disconnect})
+ end.
handle_kex_dh_gex_group(#ssh_msg_kex_dh_gex_group{p = P, g = G}, Ssh0) ->
{Private, Public} = dh_gen_key(G,P,1024),
@@ -277,7 +287,7 @@ handle_new_keys(#ssh_msg_newkeys{}, Ssh0) ->
%% %% Select algorithms
handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey, f = F,
h_sig = H_SIG},
- #ssh{keyex_key = {{Private, Public}, {_G, P}}} = Ssh0) ->
+ #ssh{keyex_key = {{Private, Public}, {_G, P}}} = Ssh0) when 1=<F, F=<(P-1)->
K = ssh_math:ipow(F, Private, P),
H = kex_h(Ssh0, HostKey, Public, F, K),
@@ -293,7 +303,15 @@ handle_kexdh_reply(#ssh_msg_kexdh_reply{public_host_key = HostKey, f = F,
description = "Key exchange failed",
language = "en"},
throw({Error, Disconnect})
- end.
+ end;
+handle_kexdh_reply(#ssh_msg_kexdh_reply{}, _SSH) ->
+ Error = {error,bad_f_from_peer},
+ Disconnect = #ssh_msg_disconnect{
+ code = ?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ description = "Key exchange failed, 'f' out of bounds",
+ language = "en"},
+ throw({Error, Disconnect}).
+
handle_kex_dh_gex_request(#ssh_msg_kex_dh_gex_request{min = _Min,
n = _NBits,
@@ -519,10 +537,15 @@ alg_final(SSH0) ->
{ok,SSH6} = decompress_final(SSH5),
SSH6.
-select_all(CL, SL) ->
+select_all(CL, SL) when length(CL) + length(SL) < 50 ->
A = CL -- SL, %% algortihms only used by client
%% algorithms used by client and server (client pref)
- lists:map(fun(ALG) -> list_to_atom(ALG) end, (CL -- A)).
+ lists:map(fun(ALG) -> list_to_atom(ALG) end, (CL -- A));
+select_all(_CL, _SL) ->
+ throw(#ssh_msg_disconnect{code = ?SSH_DISCONNECT_PROTOCOL_ERROR,
+ description = "Too many algorithms",
+ language = "en"}).
+
select([], []) ->
none;