aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2017-04-26 16:52:05 +0200
committerHans Nilsson <[email protected]>2017-04-26 19:01:30 +0200
commit9bcd621df2abf35394cd9f68b42c446d3ab83f11 (patch)
tree5814ee10161852278b46aa3b0ec03b4f4d0f3bb2
parent98fa13854707fc1f4aecb6d2f7bc167f478bdd6f (diff)
downloadotp-9bcd621df2abf35394cd9f68b42c446d3ab83f11.tar.gz
otp-9bcd621df2abf35394cd9f68b42c446d3ab83f11.tar.bz2
otp-9bcd621df2abf35394cd9f68b42c446d3ab83f11.zip
ssh: Codenomicon/Defensics fixes
-rw-r--r--lib/ssh/src/ssh_auth.erl24
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl13
-rw-r--r--lib/ssh/src/ssh_transport.erl27
3 files changed, 36 insertions, 28 deletions
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl
index aadd1ad6dc..9eb11a53dc 100644
--- a/lib/ssh/src/ssh_auth.erl
+++ b/lib/ssh/src/ssh_auth.erl
@@ -296,8 +296,7 @@ handle_userauth_request(#ssh_msg_userauth_request{user = User,
userauth_supported_methods = Methods} = Ssh) ->
case verify_sig(SessionId, User, "ssh-connection",
- binary_to_list(BAlg),
- KeyBlob, SigWLen, Opts) of
+ BAlg, KeyBlob, SigWLen, Opts) of
true ->
{authorized, User,
ssh_transport:ssh_packet(
@@ -507,21 +506,18 @@ pre_verify_sig(User, KeyBlob, Opts) ->
false
end.
-verify_sig(SessionId, User, Service, Alg, KeyBlob, SigWLen, Opts) ->
+verify_sig(SessionId, User, Service, AlgBin, KeyBlob, SigWLen, Opts) ->
try
+ Alg = binary_to_list(AlgBin),
{KeyCb,KeyCbOpts} = ?GET_OPT(key_cb, Opts),
UserOpts = ?GET_OPT(user_options, Opts),
- Key0 = public_key:ssh_decode(KeyBlob, ssh2_pubkey), % or exception
- true = KeyCb:is_auth_key(Key0, User, [{key_cb_private,KeyCbOpts}|UserOpts]),
- Key0
- of
- Key ->
- PlainText = build_sig_data(SessionId, User, Service,
- KeyBlob, Alg),
- <<?UINT32(AlgSigLen), AlgSig:AlgSigLen/binary>> = SigWLen,
- <<?UINT32(AlgLen), _Alg:AlgLen/binary,
- ?UINT32(SigLen), Sig:SigLen/binary>> = AlgSig,
- ssh_transport:verify(PlainText, ssh_transport:sha(list_to_atom(Alg)), Sig, Key)
+ Key = public_key:ssh_decode(KeyBlob, ssh2_pubkey), % or exception
+ true = KeyCb:is_auth_key(Key, User, [{key_cb_private,KeyCbOpts}|UserOpts]),
+ PlainText = build_sig_data(SessionId, User, Service, KeyBlob, Alg),
+ <<?UINT32(AlgSigLen), AlgSig:AlgSigLen/binary>> = SigWLen,
+ <<?UINT32(AlgLen), _Alg:AlgLen/binary,
+ ?UINT32(SigLen), Sig:SigLen/binary>> = AlgSig,
+ ssh_transport:verify(PlainText, ssh_transport:sha(Alg), Sig, Key)
catch
_:_ ->
false
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 220b05e6b0..74e14a233f 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1710,6 +1710,7 @@ ext_info({"server-sig-algs",SigAlgs}, D0 = #data{ssh_params=#ssh{role=client}=Ss
SupportedAlgs = lists:map(fun erlang:atom_to_list/1, ssh_transport:supported_algorithms(public_key)),
Ssh = Ssh0#ssh{userauth_pubkeys =
[list_to_atom(SigAlg) || SigAlg <- string:tokens(SigAlgs,","),
+ %% length of SigAlg is implicitly checked by member:
lists:member(SigAlg, SupportedAlgs)
]},
D0#data{ssh_params = Ssh};
@@ -2008,12 +2009,14 @@ handshake(Pid, Ref, Timeout) ->
end.
update_inet_buffers(Socket) ->
- {ok, BufSzs0} = inet:getopts(Socket, [sndbuf,recbuf]),
- MinVal = 655360,
- case
- [{Tag,MinVal} || {Tag,Val} <- BufSzs0,
- Val < MinVal]
+ try
+ {ok, BufSzs0} = inet:getopts(Socket, [sndbuf,recbuf]),
+ MinVal = 655360,
+ [{Tag,MinVal} || {Tag,Val} <- BufSzs0,
+ Val < MinVal]
of
[] -> ok;
NewOpts -> inet:setopts(Socket, NewOpts)
+ catch
+ _:_ -> ok
end.
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 3cf1e60634..09b5d1ac81 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -1202,15 +1202,23 @@ sign(SigData, HashAlg, Key) ->
public_key:sign(SigData, HashAlg, Key).
verify(PlainText, HashAlg, 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, HashAlg, Signature, Key);
+ case Sig of
+ <<R:160/big-unsigned-integer, S:160/big-unsigned-integer>> ->
+ Signature = public_key:der_encode('Dss-Sig-Value', #'Dss-Sig-Value'{r = R, s = S}),
+ public_key:verify(PlainText, HashAlg, Signature, Key);
+ _ ->
+ false
+ end;
verify(PlainText, HashAlg, 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, HashAlg, DerEncodedSig, Key);
+ case Sig of
+ <<?UINT32(Rlen),R:Rlen/big-signed-integer-unit:8,
+ ?UINT32(Slen),S:Slen/big-signed-integer-unit:8>> ->
+ Sval = #'ECDSA-Sig-Value'{r=R, s=S},
+ DerEncodedSig = public_key:der_encode('ECDSA-Sig-Value',Sval),
+ public_key:verify(PlainText, HashAlg, DerEncodedSig, Key);
+ _ ->
+ false
+ end;
verify(PlainText, HashAlg, Sig, Key) ->
public_key:verify(PlainText, HashAlg, Sig, Key).
@@ -1795,7 +1803,8 @@ sha(?'secp384r1') -> sha(secp384r1);
sha(?'secp521r1') -> sha(secp521r1);
sha('ecdh-sha2-nistp256') -> sha(secp256r1);
sha('ecdh-sha2-nistp384') -> sha(secp384r1);
-sha('ecdh-sha2-nistp521') -> sha(secp521r1).
+sha('ecdh-sha2-nistp521') -> sha(secp521r1);
+sha(Str) when is_list(Str), length(Str)<50 -> sha(list_to_atom(Str)).
mac_key_bytes('hmac-sha1') -> 20;