diff options
author | Hans Nilsson <[email protected]> | 2017-04-26 16:52:05 +0200 |
---|---|---|
committer | Hans Nilsson <[email protected]> | 2017-04-26 19:01:30 +0200 |
commit | 9bcd621df2abf35394cd9f68b42c446d3ab83f11 (patch) | |
tree | 5814ee10161852278b46aa3b0ec03b4f4d0f3bb2 | |
parent | 98fa13854707fc1f4aecb6d2f7bc167f478bdd6f (diff) | |
download | otp-9bcd621df2abf35394cd9f68b42c446d3ab83f11.tar.gz otp-9bcd621df2abf35394cd9f68b42c446d3ab83f11.tar.bz2 otp-9bcd621df2abf35394cd9f68b42c446d3ab83f11.zip |
ssh: Codenomicon/Defensics fixes
-rw-r--r-- | lib/ssh/src/ssh_auth.erl | 24 | ||||
-rw-r--r-- | lib/ssh/src/ssh_connection_handler.erl | 13 | ||||
-rw-r--r-- | lib/ssh/src/ssh_transport.erl | 27 |
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; |