[openssh-commits] [openssh] 05/12: upstream: correctly match ECDSA signature algorithms against

git+noreply at mindrot.org git+noreply at mindrot.org
Thu Apr 2 20:26:20 AEDT 2026


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch V_10_3
in repository openssh.

commit fd1c7e131f331942d20f42f31e79912d570081fa
Author: djm at openbsd.org <djm at openbsd.org>
AuthorDate: Thu Apr 2 07:48:13 2026 +0000

    upstream: correctly match ECDSA signature algorithms against
    
    algorithm allowlists: HostKeyAlgorithms, PubkeyAcceptedAlgorithms and
    HostbasedAcceptedAlgorithms.
    
    Previously, if any ECDSA type (say "ecdsa-sha2-nistp521") was
    present in one of these lists, then all ECDSA algorithms would
    be permitted.
    
    Reported by Christos Papakonstantinou of Cantina and Spearbit.
    
    OpenBSD-Commit-ID: c790e2687c35989ae34a00e709be935c55b16a86
---
 auth2-hostbased.c  |  9 +++++----
 auth2-pubkey.c     |  9 +++++----
 auth2-pubkeyfile.c | 26 +++++++++++++++-----------
 sshconnect2.c      | 28 ++++++++++++++++++----------
 4 files changed, 43 insertions(+), 29 deletions(-)

diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index e2ed8b3eb..8a1acdec3 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-hostbased.c,v 1.56 2025/12/22 01:49:03 djm Exp $ */
+/* $OpenBSD: auth2-hostbased.c,v 1.57 2026/04/02 07:48:13 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -96,9 +96,10 @@ userauth_hostbased(struct ssh *ssh, const char *method)
 		error_f("cannot decode key: %s", pkalg);
 		goto done;
 	}
-	if (key->type != pktype) {
-		error_f("type mismatch for decoded key "
-		    "(received %d, expected %d)", key->type, pktype);
+	if (key->type != pktype || (sshkey_type_plain(pktype) == KEY_ECDSA &&
+	    sshkey_ecdsa_nid_from_name(pkalg) != key->ecdsa_nid)) {
+		error_f("key type mismatch for decoded key "
+		    "(received %s, expected %s)", sshkey_ssh_name(key), pkalg);
 		goto done;
 	}
 	if (match_pattern_list(pkalg, options.hostbased_accepted_algos, 0) != 1) {
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index be378f266..e446ef412 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-pubkey.c,v 1.125 2025/12/22 01:49:03 djm Exp $ */
+/* $OpenBSD: auth2-pubkey.c,v 1.126 2026/04/02 07:48:13 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
@@ -148,9 +148,10 @@ userauth_pubkey(struct ssh *ssh, const char *method)
 		error_f("cannot decode key: %s", pkalg);
 		goto done;
 	}
-	if (key->type != pktype) {
-		error_f("type mismatch for decoded key "
-		    "(received %d, expected %d)", key->type, pktype);
+	if (key->type != pktype || (sshkey_type_plain(pktype) == KEY_ECDSA &&
+	    sshkey_ecdsa_nid_from_name(pkalg) != key->ecdsa_nid)) {
+		error_f("key type mismatch for decoded key "
+		    "(received %s, expected %s)", sshkey_ssh_name(key), pkalg);
 		goto done;
 	}
 	if (auth2_key_already_used(authctxt, key)) {
diff --git a/auth2-pubkeyfile.c b/auth2-pubkeyfile.c
index 896ea1996..e729cc50a 100644
--- a/auth2-pubkeyfile.c
+++ b/auth2-pubkeyfile.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-pubkeyfile.c,v 1.7 2025/12/22 01:49:03 djm Exp $ */
+/* $OpenBSD: auth2-pubkeyfile.c,v 1.8 2026/04/02 07:48:13 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
@@ -50,6 +50,7 @@
 #include "authfile.h"
 #include "match.h"
 #include "ssherr.h"
+#include "xmalloc.h"
 
 int
 auth_authorise_keyopts(struct passwd *pw, struct sshauthopt *opts,
@@ -146,20 +147,23 @@ auth_authorise_keyopts(struct passwd *pw, struct sshauthopt *opts,
 static int
 match_principals_option(const char *principal_list, struct sshkey_cert *cert)
 {
-	char *result;
+	char *list, *olist, *entry;
 	u_int i;
 
-	/* XXX percent_expand() sequences for authorized_principals? */
-
-	for (i = 0; i < cert->nprincipals; i++) {
-		if ((result = match_list(cert->principals[i],
-		    principal_list, NULL)) != NULL) {
-			debug3("matched principal from key options \"%.100s\"",
-			    result);
-			free(result);
-			return 1;
+	olist = list = xstrdup(principal_list);
+	for (;;) {
+		if ((entry = strsep(&list, ",")) == NULL || *entry == '\0')
+			break;
+		for (i = 0; i < cert->nprincipals; i++) {
+			if (strcmp(entry, cert->principals[i]) == 0) {
+				debug3("matched principal from key i"
+				    "options \"%.100s\"", entry);
+				free(olist);
+				return 1;
+			}
 		}
 	}
+	free(olist);
 	return 0;
 }
 
diff --git a/sshconnect2.c b/sshconnect2.c
index e4f5bd0fd..478a9a52f 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.384 2026/03/03 09:57:25 dtucker Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.385 2026/04/02 07:48:13 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Damien Miller.  All rights reserved.
@@ -85,6 +85,7 @@ extern Options options;
 static char *xxx_host;
 static struct sockaddr *xxx_hostaddr;
 static const struct ssh_conn_info *xxx_conn_info;
+static int key_type_allowed(struct sshkey *, const char *);
 
 static int
 verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
@@ -94,6 +95,10 @@ verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
 	if ((r = sshkey_check_rsa_length(hostkey,
 	    options.required_rsa_size)) != 0)
 		fatal_r(r, "Bad server host key");
+	if (!key_type_allowed(hostkey, options.hostkeyalgorithms)) {
+		fatal("Server host key %s not in HostKeyAlgorithms",
+		    sshkey_ssh_name(hostkey));
+	}
 	if (verify_host_key(xxx_host, xxx_hostaddr, hostkey,
 	    xxx_conn_info) != 0)
 		fatal("Host key verification failed.");
@@ -1598,34 +1603,37 @@ load_identity_file(Identity *id)
 }
 
 static int
-key_type_allowed_by_config(struct sshkey *key)
+key_type_allowed(struct sshkey *key, const char *allowlist)
 {
-	if (match_pattern_list(sshkey_ssh_name(key),
-	    options.pubkey_accepted_algos, 0) == 1)
+	if (match_pattern_list(sshkey_ssh_name(key), allowlist, 0) == 1)
 		return 1;
 
 	/* RSA keys/certs might be allowed by alternate signature types */
 	switch (key->type) {
 	case KEY_RSA:
-		if (match_pattern_list("rsa-sha2-512",
-		    options.pubkey_accepted_algos, 0) == 1)
+		if (match_pattern_list("rsa-sha2-512", allowlist, 0) == 1)
 			return 1;
-		if (match_pattern_list("rsa-sha2-256",
-		    options.pubkey_accepted_algos, 0) == 1)
+		if (match_pattern_list("rsa-sha2-256", allowlist, 0) == 1)
 			return 1;
 		break;
 	case KEY_RSA_CERT:
 		if (match_pattern_list("rsa-sha2-512-cert-v01 at openssh.com",
-		    options.pubkey_accepted_algos, 0) == 1)
+		    allowlist, 0) == 1)
 			return 1;
 		if (match_pattern_list("rsa-sha2-256-cert-v01 at openssh.com",
-		    options.pubkey_accepted_algos, 0) == 1)
+		    allowlist, 0) == 1)
 			return 1;
 		break;
 	}
 	return 0;
 }
 
+static int
+key_type_allowed_by_config(struct sshkey *key)
+{
+	return key_type_allowed(key, options.pubkey_accepted_algos);
+}
+
 /* obtain a list of keys from the agent */
 static int
 get_agent_identities(struct ssh *ssh, int *agent_fdp,

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list