summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2024-04-30 02:10:49 +0000
committerDamien Miller <djm@mindrot.org>2024-04-30 12:22:35 +1000
commit80fb0eb21551aed3aebb009ab20aeffeb01e44e0 (patch)
tree6b4515c412eb94b024bed884c920eeaf983fbd69
parent5b28096d31ff7d80748fc845553a4aef5bb05d86 (diff)
upstream: add explict check for server hostkey type against
HostkeyAlgorithms. Allows HostkeyAlgorithms to disable implicit fallback from certificate keys to plain keys. ok markus@ OpenBSD-Commit-ID: 364087e4a395ff9b2f42bf3aefdb2090bb23643a
-rw-r--r--clientloop.c23
-rw-r--r--sshconnect.c32
-rw-r--r--sshconnect.h6
3 files changed, 38 insertions, 23 deletions
diff --git a/clientloop.c b/clientloop.c
index 8ec36af9..be8bb5fc 100644
--- a/clientloop.c
+++ b/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 <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2442,25 +2442,6 @@ client_global_hostkeys_prove_confirm(struct ssh *ssh, int type,
}
/*
- * 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
* HostkeyAlgorithms preference before they are accepted.
@@ -2504,7 +2485,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/sshconnect.c b/sshconnect.c
index 1e94967d..7cf6b638 100644
--- a/sshconnect.c
+++ b/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 <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -57,6 +57,7 @@
#include "sshkey.h"
#include "sshconnect.h"
#include "log.h"
+#include "match.h"
#include "misc.h"
#include "readconf.h"
#include "atomicio.h"
@@ -717,6 +718,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)
{
@@ -1017,6 +1041,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/sshconnect.h b/sshconnect.h
index 79d35cc1..8b0466f2 100644
--- a/sshconnect.h
+++ b/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 *);