From 3507ea008839ad68dc16060a2696e3efde551684 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Thu, 18 May 2017 20:33:14 +0200 Subject: ssh: fix the rsa-sha2-* hostkey verify error --- lib/public_key/src/pubkey_ssh.erl | 18 ++++++++---------- lib/ssh/src/ssh_message.erl | 4 ++-- lib/ssh/src/ssh_transport.erl | 18 +++++++++++------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/lib/public_key/src/pubkey_ssh.erl b/lib/public_key/src/pubkey_ssh.erl index 6974afa992..9bda76d670 100644 --- a/lib/public_key/src/pubkey_ssh.erl +++ b/lib/public_key/src/pubkey_ssh.erl @@ -408,10 +408,11 @@ comma_list_encode([Option | Rest], Acc) -> comma_list_encode(Rest, Acc ++ "," ++ Option). -%% An experimental fix adding the signature algorithm name as the last element in a tuple... - ssh2_pubkey_encode(#'RSAPublicKey'{modulus = N, publicExponent = E}) -> ssh2_pubkey_encode({#'RSAPublicKey'{modulus = N, publicExponent = E}, 'ssh-rsa'}); + +ssh2_pubkey_encode({Key, 'rsa-sha2-256'}) -> ssh2_pubkey_encode({Key, 'ssh-rsa'}); +ssh2_pubkey_encode({Key, 'rsa-sha2-512'}) -> ssh2_pubkey_encode({Key, 'ssh-rsa'}); ssh2_pubkey_encode({#'RSAPublicKey'{modulus = N, publicExponent = E}, SignAlg}) -> SignAlgName = list_to_binary(atom_to_list(SignAlg)), StrLen = size(SignAlgName), @@ -448,16 +449,12 @@ ssh2_pubkey_encode(Key={#'ECPoint'{point = Q}, {namedCurve,OID}}) -> ssh2_pubkey_decode(Bin = <>) -> ssh2_pubkey_decode(Type, Bin). -%% An experimental fix with the Signature Algorithm Name -ssh2_pubkey_decode(SignAlgName, +ssh2_pubkey_decode(<<"rsa-sha2-256">>, Bin) -> ssh2_pubkey_decode(<<"ssh-rsa">>, Bin); +ssh2_pubkey_decode(<<"rsa-sha2-512">>, Bin) -> ssh2_pubkey_decode(<<"ssh-rsa">>, Bin); +ssh2_pubkey_decode(<<"ssh-rsa">>, <>) - when SignAlgName == <<"ssh-rsa">> ; - SignAlgName == <<"rsa-sha2-256">> ; - SignAlgName == <<"rsa-sha2-384">> ; - SignAlgName == <<"rsa-sha2-512">> - -> + ?UINT32(SizeN), N:SizeN/binary>>) -> #'RSAPublicKey'{modulus = erlint(SizeN, N), publicExponent = erlint(SizeE, E)}; @@ -471,6 +468,7 @@ ssh2_pubkey_decode(<<"ssh-dss">>, #'Dss-Parms'{p = erlint(SizeP, P), q = erlint(SizeQ, Q), g = erlint(SizeG, G)}}; + ssh2_pubkey_decode(<<"ecdsa-sha2-",Id/binary>>, <>, Acc, N) -> %%% Signature decode/encode %%% -decode_signature(<>) -> - Signature. +decode_signature(<>) -> + {binary_to_list(Alg), Signature}. encode_signature({#'RSAPublicKey'{},Sign}, Signature) -> diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl index 1a15798080..412f5de9de 100644 --- a/lib/ssh/src/ssh_transport.erl +++ b/lib/ssh/src/ssh_transport.erl @@ -776,16 +776,20 @@ extract_public_key(#'ECPrivateKey'{parameters = {namedCurve,OID}, {#'ECPoint'{point=Q}, {namedCurve,OID}}. -verify_host_key(#ssh{algorithms=Alg}=SSH, PublicKey, Digest, Signature) -> - case verify(Digest, sha(Alg#alg.hkey), Signature, PublicKey) of - false -> - {error, bad_signature}; - true -> - known_host_key(SSH, PublicKey, public_algo(PublicKey)) +verify_host_key(#ssh{algorithms=Alg}=SSH, PublicKey, Digest, {AlgStr,Signature}) -> + case atom_to_list(Alg#alg.hkey) of + AlgStr -> + case verify(Digest, sha(Alg#alg.hkey), Signature, PublicKey) of + false -> + {error, bad_signature}; + true -> + known_host_key(SSH, PublicKey, public_algo(PublicKey)) + end; + _ -> + {error, bad_signature_name} end. - accepted_host(Ssh, PeerName, Public, Opts) -> case ?GET_OPT(silently_accept_hosts, Opts) of -- cgit v1.2.3