From 68de26a4b0ea762b3cbb2f2bc837afde441ebefd Mon Sep 17 00:00:00 2001 From: djm Date: Tue, 30 Apr 2024 02:10:49 +0000 Subject: [PATCH] add explict check for server hostkey type against HostkeyAlgorithms. Allows HostkeyAlgorithms to disable implicit fallback from certificate keys to plain keys. ok markus@ --- usr.bin/ssh/clientloop.c | 23 ++--------------------- usr.bin/ssh/sshconnect.c | 32 +++++++++++++++++++++++++++++++- usr.bin/ssh/sshconnect.h | 6 +++++- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index 31eaa9500f1..c4b37a7a4db 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.403 2024/02/21 05:57:34 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.404 2024/04/30 02:10:49 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -2426,25 +2426,6 @@ client_global_hostkeys_prove_confirm(struct ssh *ssh, int type, client_repledge(); } -/* - * Returns non-zero if the key is accepted by HostkeyAlgorithms. - * Made slightly less trivial by the multiple RSA signature algorithm names. - */ -static int -key_accepted_by_hostkeyalgs(const struct sshkey *key) -{ - const char *ktype = sshkey_ssh_name(key); - const char *hostkeyalgs = options.hostkeyalgorithms; - - if (key->type == KEY_UNSPEC) - return 0; - if (key->type == KEY_RSA && - (match_pattern_list("rsa-sha2-256", hostkeyalgs, 0) == 1 || - match_pattern_list("rsa-sha2-512", hostkeyalgs, 0) == 1)) - return 1; - return match_pattern_list(ktype, hostkeyalgs, 0) == 1; -} - /* * Handle hostkeys-00@openssh.com global request to inform the client of all * the server's hostkeys. The keys are checked against the user's @@ -2489,7 +2470,7 @@ client_input_hostkeys(struct ssh *ssh) debug3_f("received %s key %s", sshkey_type(key), fp); free(fp); - if (!key_accepted_by_hostkeyalgs(key)) { + if (!hostkey_accepted_by_hostkeyalgs(key)) { debug3_f("%s key not permitted by " "HostkeyAlgorithms", sshkey_ssh_name(key)); continue; diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c index 8ff922852b5..4cc597c4947 100644 --- a/usr.bin/ssh/sshconnect.c +++ b/usr.bin/ssh/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.367 2024/04/23 13:34:50 jsg Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.368 2024/04/30 02:10:49 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -45,6 +45,7 @@ #include "sshconnect.h" #include "hostfile.h" #include "log.h" +#include "match.h" #include "misc.h" #include "readconf.h" #include "atomicio.h" @@ -679,6 +680,29 @@ try_tilde_unexpand(const char *path) return ret; } +/* + * Returns non-zero if the key is accepted by HostkeyAlgorithms. + * Made slightly less trivial by the multiple RSA signature algorithm names. + */ +int +hostkey_accepted_by_hostkeyalgs(const struct sshkey *key) +{ + const char *ktype = sshkey_ssh_name(key); + const char *hostkeyalgs = options.hostkeyalgorithms; + + if (key->type == KEY_UNSPEC) + return 0; + if (key->type == KEY_RSA && + (match_pattern_list("rsa-sha2-256", hostkeyalgs, 0) == 1 || + match_pattern_list("rsa-sha2-512", hostkeyalgs, 0) == 1)) + return 1; + if (key->type == KEY_RSA_CERT && + (match_pattern_list("rsa-sha2-512-cert-v01@openssh.com", hostkeyalgs, 0) == 1 || + match_pattern_list("rsa-sha2-256-cert-v01@openssh.com", hostkeyalgs, 0) == 1)) + return 1; + return match_pattern_list(ktype, hostkeyalgs, 0) == 1; +} + static int hostkeys_find_by_key_cb(struct hostkey_foreach_line *l, void *_ctx) { @@ -979,6 +1003,12 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, } retry: + if (!hostkey_accepted_by_hostkeyalgs(host_key)) { + error("host key %s not permitted by HostkeyAlgorithms", + sshkey_ssh_name(host_key)); + goto fail; + } + /* Reload these as they may have changed on cert->key downgrade */ want_cert = sshkey_is_cert(host_key); type = sshkey_type(host_key); diff --git a/usr.bin/ssh/sshconnect.h b/usr.bin/ssh/sshconnect.h index 79d35cc195d..8b0466f299e 100644 --- a/usr.bin/ssh/sshconnect.h +++ b/usr.bin/ssh/sshconnect.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.h,v 1.47 2023/10/12 02:18:18 djm Exp $ */ +/* $OpenBSD: sshconnect.h,v 1.48 2024/04/30 02:10:49 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -24,6 +24,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +struct sshkey; + typedef struct Sensitive Sensitive; struct Sensitive { struct sshkey **keys; @@ -94,3 +96,5 @@ void maybe_add_key_to_agent(const char *, struct sshkey *, void load_hostkeys_command(struct hostkeys *, const char *, const char *, const struct ssh_conn_info *, const struct sshkey *, const char *); + +int hostkey_accepted_by_hostkeyalgs(const struct sshkey *); -- 2.20.1