diff --git a/src/kex.c b/src/kex.c index d9d0c7e5..44d60f59 100644 --- a/src/kex.c +++ b/src/kex.c @@ -38,6 +38,7 @@ #include "libssh/curve25519.h" #include "libssh/knownhosts.h" #include "libssh/misc.h" +#include "libssh/pki.h" #ifdef HAVE_LIBGCRYPT # define BLOWFISH "blowfish-cbc," @@ -619,6 +620,8 @@ char *ssh_client_select_hostkeys(ssh_session session) "ecdsa-sha2-nistp521", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp256", + "rsa-sha2-512", + "rsa-sha2-256", "ssh-rsa", #ifdef HAVE_DSA "ssh-dss", @@ -644,29 +647,30 @@ char *ssh_client_select_hostkeys(ssh_session session) for (i = 0; preferred_hostkeys[i] != NULL; ++i) { bool found = false; + /* This is a signature type: We list also the SHA2 extensions */ + enum ssh_keytypes_e base_preferred = + ssh_key_type_from_signature_name(preferred_hostkeys[i]); for (it = ssh_list_get_iterator(algo_list); it != NULL; it = it->next) { const char *algo = ssh_iterator_value(const char *, it); - int cmp; - int ok; + /* This is always key type so we do not have to care for the + * SHA2 extension */ + enum ssh_keytypes_e base_algo = ssh_key_type_from_name(algo); - cmp = strcmp(preferred_hostkeys[i], algo); - if (cmp == 0) { - ok = ssh_verify_existing_algo(SSH_HOSTKEYS, algo); - if (ok) { - if (needcomma) { - strncat(methods_buffer, - ",", - sizeof(methods_buffer) - strlen(methods_buffer) - 1); - } + if (base_preferred == base_algo) { + /* Matching the keys already verified it is a known type */ + if (needcomma) { strncat(methods_buffer, - algo, + ",", sizeof(methods_buffer) - strlen(methods_buffer) - 1); - needcomma = 1; - found = true; } + strncat(methods_buffer, + preferred_hostkeys[i], + sizeof(methods_buffer) - strlen(methods_buffer) - 1); + needcomma = 1; + found = true; } } /* Collect the rest of the algorithms in other buffer, that will @@ -728,10 +732,10 @@ int ssh_set_client_kex(ssh_session session) memset(client->methods, 0, KEX_METHODS_SIZE * sizeof(char **)); /* first check if we have specific host key methods */ - if(session->opts.wanted_methods[SSH_HOSTKEYS] == NULL){ + if (session->opts.wanted_methods[SSH_HOSTKEYS] == NULL) { /* Only if no override */ session->opts.wanted_methods[SSH_HOSTKEYS] = - ssh_client_select_hostkeys(session); + ssh_client_select_hostkeys(session); } for (i = 0; i < KEX_METHODS_SIZE; i++) { diff --git a/tests/unittests/torture_knownhosts_parsing.c b/tests/unittests/torture_knownhosts_parsing.c index 148c5da8..a7a0d99d 100644 --- a/tests/unittests/torture_knownhosts_parsing.c +++ b/tests/unittests/torture_knownhosts_parsing.c @@ -310,8 +310,9 @@ torture_knownhosts_algorithms(void **state) const char *knownhosts_file = *state; char *algo_list = NULL; ssh_session session; - const char *expect = "ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521," - "ecdsa-sha2-nistp384,ecdsa-sha2-nistp256" + const char *expect = "ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa," + "ecdsa-sha2-nistp521,ecdsa-sha2-nistp384," + "ecdsa-sha2-nistp256" #ifdef HAVE_DSA ",ssh-dss" #endif @@ -339,8 +340,9 @@ torture_knownhosts_algorithms_global(void **state) const char *knownhosts_file = *state; char *algo_list = NULL; ssh_session session; - const char *expect = "ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521," - "ecdsa-sha2-nistp384,ecdsa-sha2-nistp256" + const char *expect = "ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa," + "ecdsa-sha2-nistp521,ecdsa-sha2-nistp384," + "ecdsa-sha2-nistp256" #ifdef HAVE_DSA ",ssh-dss" #endif