diff --git a/include/libssh/kex.h b/include/libssh/kex.h index 3e9b69b5..58a9c555 100644 --- a/include/libssh/kex.h +++ b/include/libssh/kex.h @@ -43,6 +43,7 @@ char **ssh_space_tokenize(const char *chain); int ssh_get_kex1(ssh_session session); char *ssh_find_matching(const char *in_d, const char *what_d); const char *ssh_kex_get_supported_method(uint32_t algo); +const char *ssh_kex_get_default_methods(uint32_t algo); const char *ssh_kex_get_description(uint32_t algo); #endif /* KEX_H_ */ diff --git a/include/libssh/pki.h b/include/libssh/pki.h index 0a3823f3..621378ad 100644 --- a/include/libssh/pki.h +++ b/include/libssh/pki.h @@ -138,4 +138,5 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session, ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key); ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key); +int ssh_key_algorithm_allowed(ssh_session session, const char *type); #endif /* PKI_H_ */ diff --git a/src/kex.c b/src/kex.c index 475b0ec8..ee36bb31 100644 --- a/src/kex.c +++ b/src/kex.c @@ -235,6 +235,15 @@ char **ssh_space_tokenize(const char *chain){ return tokens; } +const char *ssh_kex_get_default_methods(uint32_t algo) +{ + if (algo >= KEX_METHODS_SIZE) { + return NULL; + } + + return default_methods[algo]; +} + const char *ssh_kex_get_supported_method(uint32_t algo) { if (algo >= KEX_METHODS_SIZE) { return NULL; diff --git a/src/pki.c b/src/pki.c index d894762c..69d76c27 100644 --- a/src/pki.c +++ b/src/pki.c @@ -271,6 +271,27 @@ static enum ssh_digest_e ssh_key_hash_from_name(const char *name) /* we do not care for others now */ return SSH_DIGEST_AUTO; } +/** + * @brief Checks the given key against the configured allowed + * public key algorithm types + * + * @param[in] session The SSH session + * @parma[in] type The key algorithm to check + * @returns 1 if the key algorithm is allowed 0 otherwise + */ +int ssh_key_algorithm_allowed(ssh_session session, const char *type) +{ + const char *allowed_list; + + allowed_list = session->opts.pubkey_accepted_types; + if (allowed_list == NULL) { + allowed_list = ssh_kex_get_default_methods(SSH_HOSTKEYS); + } + + SSH_LOG(SSH_LOG_DEBUG, "Checking %s with list <%s>", type, allowed_list); + return ssh_match_group(allowed_list, type); +} + /** * @brief Convert a key type to a hash type. This is usually unambiguous * for all the key types, unless the SHA2 extension (RFC 8332) is @@ -285,15 +306,15 @@ static enum ssh_digest_e ssh_key_hash_from_name(const char *name) static enum ssh_digest_e ssh_key_type_to_hash(ssh_session session, enum ssh_keytypes_e type) { - /* TODO this should also reflect supported key types specified in - * configuration (ssh_config PubkeyAcceptedKeyTypes) */ switch (type) { case SSH_KEYTYPE_RSA: - if (session->extensions & SSH_EXT_SIG_RSA_SHA512) { + if (ssh_key_algorithm_allowed(session, "rsa-sha2-512") && + (session->extensions & SSH_EXT_SIG_RSA_SHA512)) { return SSH_DIGEST_SHA512; } - if (session->extensions & SSH_EXT_SIG_RSA_SHA256) { + if (ssh_key_algorithm_allowed(session, "rsa-sha2-256") && + (session->extensions & SSH_EXT_SIG_RSA_SHA256)) { return SSH_DIGEST_SHA256; }