Zoltan Fridrich fd0d5a
diff --color -rup a/sshconnect2.c b/sshconnect2.c
Zoltan Fridrich fd0d5a
--- a/sshconnect2.c	2022-07-11 17:00:02.618575727 +0200
Zoltan Fridrich fd0d5a
+++ b/sshconnect2.c	2022-07-11 17:03:05.096085690 +0200
Zoltan Fridrich fd0d5a
@@ -2288,9 +2288,9 @@ userauth_hostbased(struct ssh *ssh)
Zoltan Fridrich fd0d5a
 			if (authctxt->sensitive->keys[i] == NULL ||
Zoltan Fridrich fd0d5a
 			    authctxt->sensitive->keys[i]->type == KEY_UNSPEC)
Zoltan Fridrich fd0d5a
 				continue;
Zoltan Fridrich fd0d5a
-			if (match_pattern_list(
Zoltan Fridrich fd0d5a
+			if (!sshkey_match_keyname_to_sigalgs(
Zoltan Fridrich fd0d5a
 			    sshkey_ssh_name(authctxt->sensitive->keys[i]),
Zoltan Fridrich fd0d5a
-			    authctxt->active_ktype, 0) != 1)
Zoltan Fridrich fd0d5a
+			    authctxt->active_ktype))
Zoltan Fridrich fd0d5a
 				continue;
Zoltan Fridrich fd0d5a
 			/* we take and free the key */
Zoltan Fridrich fd0d5a
 			private = authctxt->sensitive->keys[i];
Zoltan Fridrich fd0d5a
@@ -2316,7 +2316,8 @@ userauth_hostbased(struct ssh *ssh)
Zoltan Fridrich fd0d5a
 		error_f("sshkey_fingerprint failed");
Zoltan Fridrich fd0d5a
 		goto out;
Zoltan Fridrich fd0d5a
 	}
Zoltan Fridrich fd0d5a
-	debug_f("trying hostkey %s %s", sshkey_ssh_name(private), fp);
Zoltan Fridrich fd0d5a
+	debug_f("trying hostkey %s %s using sigalg %s",
Zoltan Fridrich fd0d5a
+		sshkey_ssh_name(private), fp, authctxt->active_ktype);
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
 	/* figure out a name for the client host */
Zoltan Fridrich fd0d5a
 	lname = get_local_name(ssh_packet_get_connection_in(ssh));
Zoltan Fridrich fd0d5a
diff --color -rup a/sshkey.c b/sshkey.c
Zoltan Fridrich fd0d5a
--- a/sshkey.c	2022-07-11 17:00:02.609575554 +0200
Zoltan Fridrich fd0d5a
+++ b/sshkey.c	2022-07-11 17:12:30.905976443 +0200
Zoltan Fridrich fd0d5a
@@ -252,6 +252,29 @@ sshkey_ecdsa_nid_from_name(const char *n
Zoltan Fridrich fd0d5a
 	return -1;
Zoltan Fridrich fd0d5a
 }
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
+int
Zoltan Fridrich fd0d5a
+sshkey_match_keyname_to_sigalgs(const char *keyname, const char *sigalgs)
Zoltan Fridrich fd0d5a
+{
Zoltan Fridrich fd0d5a
+	int ktype;
Zoltan Fridrich fd0d5a
+
Zoltan Fridrich fd0d5a
+	if (sigalgs == NULL || *sigalgs == '\0' ||
Zoltan Fridrich fd0d5a
+	    (ktype = sshkey_type_from_name(keyname)) == KEY_UNSPEC)
Zoltan Fridrich fd0d5a
+		return 0;
Zoltan Fridrich fd0d5a
+	else if (ktype == KEY_RSA) {
Zoltan Fridrich fd0d5a
+		return match_pattern_list("ssh-rsa", sigalgs, 0) == 1 ||
Zoltan Fridrich fd0d5a
+		    match_pattern_list("rsa-sha2-256", sigalgs, 0) == 1 ||
Zoltan Fridrich fd0d5a
+		    match_pattern_list("rsa-sha2-512", sigalgs, 0) == 1;
Zoltan Fridrich fd0d5a
+	} else if (ktype == KEY_RSA_CERT) {
Zoltan Fridrich fd0d5a
+		return match_pattern_list("ssh-rsa-cert-v01@openssh.com",
Zoltan Fridrich fd0d5a
+		    sigalgs, 0) == 1 ||
Zoltan Fridrich fd0d5a
+		    match_pattern_list("rsa-sha2-256-cert-v01@openssh.com",
Zoltan Fridrich fd0d5a
+		    sigalgs, 0) == 1 ||
Zoltan Fridrich fd0d5a
+		    match_pattern_list("rsa-sha2-512-cert-v01@openssh.com",
Zoltan Fridrich fd0d5a
+		    sigalgs, 0) == 1;
Zoltan Fridrich fd0d5a
+	} else
Zoltan Fridrich fd0d5a
+		return match_pattern_list(keyname, sigalgs, 0) == 1;
Zoltan Fridrich fd0d5a
+}
Zoltan Fridrich fd0d5a
+
Zoltan Fridrich fd0d5a
 char *
Zoltan Fridrich fd0d5a
 sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
Zoltan Fridrich fd0d5a
 {
Zoltan Fridrich fd0d5a
diff --color -rup a/sshkey.h b/sshkey.h
Zoltan Fridrich fd0d5a
--- a/sshkey.h	2022-07-11 17:00:02.603575438 +0200
Zoltan Fridrich fd0d5a
+++ b/sshkey.h	2022-07-11 17:13:01.052556879 +0200
Zoltan Fridrich fd0d5a
@@ -194,6 +194,10 @@ int	 sshkey_is_cert(const struct sshkey
Zoltan Fridrich fd0d5a
 int	 sshkey_is_sk(const struct sshkey *);
Zoltan Fridrich fd0d5a
 int	 sshkey_type_is_cert(int);
Zoltan Fridrich fd0d5a
 int	 sshkey_type_plain(int);
Zoltan Fridrich fd0d5a
+
Zoltan Fridrich fd0d5a
+/* Returns non-zero if key name match sigalgs pattern list. (handles RSA) */
Zoltan Fridrich fd0d5a
+int	 sshkey_match_keyname_to_sigalgs(const char *, const char *);
Zoltan Fridrich fd0d5a
+
Zoltan Fridrich fd0d5a
 int	 sshkey_to_certified(struct sshkey *);
Zoltan Fridrich fd0d5a
 int	 sshkey_drop_cert(struct sshkey *);
Zoltan Fridrich fd0d5a
 int	 sshkey_cert_copy(const struct sshkey *, struct sshkey *);
Zoltan Fridrich fd0d5a
diff --color -rup a/ssh-keysign.c b/ssh-keysign.c
Zoltan Fridrich fd0d5a
--- a/ssh-keysign.c	2021-08-20 06:03:49.000000000 +0200
Zoltan Fridrich fd0d5a
+++ b/ssh-keysign.c	2022-07-11 17:00:23.306973667 +0200
Zoltan Fridrich fd0d5a
@@ -62,7 +62,7 @@
Zoltan Fridrich fd0d5a
 extern char *__progname;
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
 static int
Zoltan Fridrich fd0d5a
-valid_request(struct passwd *pw, char *host, struct sshkey **ret,
Zoltan Fridrich fd0d5a
+valid_request(struct passwd *pw, char *host, struct sshkey **ret, char **pkalgp,
Zoltan Fridrich fd0d5a
     u_char *data, size_t datalen)
Zoltan Fridrich fd0d5a
 {
Zoltan Fridrich fd0d5a
 	struct sshbuf *b;
Zoltan Fridrich fd0d5a
@@ -75,6 +75,8 @@ valid_request(struct passwd *pw, char *h
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
 	if (ret != NULL)
Zoltan Fridrich fd0d5a
 		*ret = NULL;
Zoltan Fridrich fd0d5a
+	if (pkalgp != NULL)
Zoltan Fridrich fd0d5a
+		*pkalgp = NULL;
Zoltan Fridrich fd0d5a
 	fail = 0;
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
 	if ((b = sshbuf_from(data, datalen)) == NULL)
Zoltan Fridrich fd0d5a
@@ -122,8 +124,6 @@ valid_request(struct passwd *pw, char *h
Zoltan Fridrich fd0d5a
 		fail++;
Zoltan Fridrich fd0d5a
 	} else if (key->type != pktype)
Zoltan Fridrich fd0d5a
 		fail++;
Zoltan Fridrich fd0d5a
-	free(pkalg);
Zoltan Fridrich fd0d5a
-	free(pkblob);
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
 	/* client host name, handle trailing dot */
Zoltan Fridrich fd0d5a
 	if ((r = sshbuf_get_cstring(b, &p, &len)) != 0)
Zoltan Fridrich fd0d5a
@@ -154,8 +154,19 @@ valid_request(struct passwd *pw, char *h
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
 	if (fail)
Zoltan Fridrich fd0d5a
 		sshkey_free(key);
Zoltan Fridrich fd0d5a
-	else if (ret != NULL)
Zoltan Fridrich fd0d5a
-		*ret = key;
Zoltan Fridrich fd0d5a
+	else {
Zoltan Fridrich fd0d5a
+		if (ret != NULL) {
Zoltan Fridrich fd0d5a
+			*ret = key;
Zoltan Fridrich fd0d5a
+			key = NULL;
Zoltan Fridrich fd0d5a
+		}
Zoltan Fridrich fd0d5a
+		if (pkalgp != NULL) {
Zoltan Fridrich fd0d5a
+			*pkalgp = pkalg;
Zoltan Fridrich fd0d5a
+			pkalg = NULL;
Zoltan Fridrich fd0d5a
+		}
Zoltan Fridrich fd0d5a
+	}
Zoltan Fridrich fd0d5a
+	sshkey_free(key);
Zoltan Fridrich fd0d5a
+	free(pkalg);
Zoltan Fridrich fd0d5a
+	free(pkblob);
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
 	return (fail ? -1 : 0);
Zoltan Fridrich fd0d5a
 }
Zoltan Fridrich fd0d5a
@@ -170,7 +181,7 @@ main(int argc, char **argv)
Zoltan Fridrich fd0d5a
 	struct passwd *pw;
Zoltan Fridrich fd0d5a
 	int r, key_fd[NUM_KEYTYPES], i, found, version = 2, fd;
Zoltan Fridrich fd0d5a
 	u_char *signature, *data, rver;
Zoltan Fridrich fd0d5a
-	char *host, *fp;
Zoltan Fridrich fd0d5a
+	char *host, *fp, *pkalg;
Zoltan Fridrich fd0d5a
 	size_t slen, dlen;
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
 	if (pledge("stdio rpath getpw dns id", NULL) != 0)
Zoltan Fridrich fd0d5a
@@ -258,7 +269,7 @@ main(int argc, char **argv)
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
 	if ((r = sshbuf_get_string(b, &data, &dlen)) != 0)
Zoltan Fridrich fd0d5a
 		fatal_r(r, "%s: buffer error", __progname);
Zoltan Fridrich fd0d5a
-	if (valid_request(pw, host, &key, data, dlen) < 0)
Zoltan Fridrich fd0d5a
+	if (valid_request(pw, host, &key, &pkalg, data, dlen) < 0)
Zoltan Fridrich fd0d5a
 		fatal("%s: not a valid request", __progname);
Zoltan Fridrich fd0d5a
 	free(host);
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
@@ -279,7 +290,7 @@ main(int argc, char **argv)
Zoltan Fridrich fd0d5a
 	}
Zoltan Fridrich fd0d5a
 
Zoltan Fridrich fd0d5a
 	if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen,
Zoltan Fridrich fd0d5a
-	    NULL, NULL, NULL, 0)) != 0)
Zoltan Fridrich fd0d5a
+	    pkalg, NULL, NULL, 0)) != 0)
Zoltan Fridrich fd0d5a
 		fatal_r(r, "%s: sshkey_sign failed", __progname);
Zoltan Fridrich fd0d5a
 	free(data);
Zoltan Fridrich fd0d5a