Dmitry Belyavskiy ebbbfc
diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c
Dmitry Belyavskiy ebbbfc
--- openssh-8.7p1/compat.c.sshrsacheck	2023-01-12 13:29:06.338710923 +0100
Dmitry Belyavskiy ebbbfc
+++ openssh-8.7p1/compat.c	2023-01-12 13:29:06.357711165 +0100
Dmitry Belyavskiy ebbbfc
@@ -43,6 +43,7 @@ void
Dmitry Belyavskiy ebbbfc
 compat_banner(struct ssh *ssh, const char *version)
Dmitry Belyavskiy ebbbfc
 {
Dmitry Belyavskiy ebbbfc
 	int i;
Dmitry Belyavskiy ebbbfc
+	int forbid_ssh_rsa = 0;
Dmitry Belyavskiy ebbbfc
 	static struct {
Dmitry Belyavskiy ebbbfc
 		char	*pat;
Dmitry Belyavskiy ebbbfc
 		int	bugs;
Dmitry Belyavskiy ebbbfc
@@ -145,16 +146,21 @@ compat_banner(struct ssh *ssh, const cha
Dmitry Belyavskiy ebbbfc
 	};
Dmitry Belyavskiy ebbbfc
 
Dmitry Belyavskiy ebbbfc
 	/* process table, return first match */
Dmitry Belyavskiy ebbbfc
+	forbid_ssh_rsa = (ssh->compat & SSH_RH_RSASIGSHA);
Dmitry Belyavskiy ebbbfc
 	ssh->compat = 0;
Dmitry Belyavskiy ebbbfc
 	for (i = 0; check[i].pat; i++) {
Dmitry Belyavskiy ebbbfc
 		if (match_pattern_list(version, check[i].pat, 0) == 1) {
Dmitry Belyavskiy ebbbfc
 			debug_f("match: %s pat %s compat 0x%08x",
Dmitry Belyavskiy ebbbfc
 			    version, check[i].pat, check[i].bugs);
Dmitry Belyavskiy ebbbfc
 			ssh->compat = check[i].bugs;
Dmitry Belyavskiy ebbbfc
+	if (forbid_ssh_rsa)
Dmitry Belyavskiy ebbbfc
+		ssh->compat |= SSH_RH_RSASIGSHA;
Dmitry Belyavskiy ebbbfc
 			return;
Dmitry Belyavskiy ebbbfc
 		}
Dmitry Belyavskiy ebbbfc
 	}
Dmitry Belyavskiy ebbbfc
 	debug_f("no match: %s", version);
Dmitry Belyavskiy ebbbfc
+	if (forbid_ssh_rsa)
Dmitry Belyavskiy ebbbfc
+		ssh->compat |= SSH_RH_RSASIGSHA;
Dmitry Belyavskiy ebbbfc
 }
Dmitry Belyavskiy ebbbfc
 
Dmitry Belyavskiy ebbbfc
 /* Always returns pointer to allocated memory, caller must free. */
Dmitry Belyavskiy ebbbfc
diff -up openssh-8.7p1/compat.h.sshrsacheck openssh-8.7p1/compat.h
Dmitry Belyavskiy ebbbfc
--- openssh-8.7p1/compat.h.sshrsacheck	2021-08-20 06:03:49.000000000 +0200
Dmitry Belyavskiy ebbbfc
+++ openssh-8.7p1/compat.h	2023-01-12 13:29:06.358711178 +0100
Dmitry Belyavskiy ebbbfc
@@ -30,7 +30,7 @@
Dmitry Belyavskiy ebbbfc
 #define SSH_BUG_UTF8TTYMODE	0x00000001
Dmitry Belyavskiy ebbbfc
 #define SSH_BUG_SIGTYPE		0x00000002
Dmitry Belyavskiy ebbbfc
 #define SSH_BUG_SIGTYPE74	0x00000004
Dmitry Belyavskiy ebbbfc
-/* #define unused		0x00000008 */
Dmitry Belyavskiy ebbbfc
+#define SSH_RH_RSASIGSHA	0x00000008
Dmitry Belyavskiy ebbbfc
 #define SSH_OLD_SESSIONID	0x00000010
Dmitry Belyavskiy ebbbfc
 /* #define unused		0x00000020 */
Dmitry Belyavskiy ebbbfc
 #define SSH_BUG_DEBUG		0x00000040
Dmitry Belyavskiy ebbbfc
diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c
Dmitry Belyavskiy ebbbfc
--- openssh-8.7p1/serverloop.c.sshrsacheck	2023-01-12 14:57:08.118400073 +0100
Dmitry Belyavskiy ebbbfc
+++ openssh-8.7p1/serverloop.c	2023-01-12 14:59:17.330470518 +0100
Dmitry Belyavskiy ebbbfc
@@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh *
Dmitry Belyavskiy ebbbfc
 			else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
Dmitry Belyavskiy ebbbfc
 				sigalg = "rsa-sha2-256";
Dmitry Belyavskiy ebbbfc
 		}
Dmitry Belyavskiy ebbbfc
+		if (ssh->compat & SSH_RH_RSASIGSHA && sigalg == NULL) {
Dmitry Belyavskiy ebbbfc
+			sigalg = "rsa-sha2-512";
Dmitry Belyavskiy ebbbfc
+			debug3_f("SHA1 signature is not supported, falling back to %s", sigalg);
Dmitry Belyavskiy ebbbfc
+		}
Dmitry Belyavskiy ebbbfc
 		debug3_f("sign %s key (index %d) using sigalg %s",
Dmitry Belyavskiy ebbbfc
 		sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
Dmitry Belyavskiy ebbbfc
 		if ((r = sshbuf_put_cstring(sigbuf,
Dmitry Belyavskiy ebbbfc
diff -up openssh-8.7p1/sshd.c.sshrsacheck openssh-8.7p1/sshd.c
Dmitry Belyavskiy ebbbfc
--- openssh-8.7p1/sshd.c.sshrsacheck	2023-01-12 13:29:06.355711140 +0100
Dmitry Belyavskiy ebbbfc
+++ openssh-8.7p1/sshd.c	2023-01-12 13:29:06.358711178 +0100
Dmitry Belyavskiy ebbbfc
@@ -1640,6 +1651,7 @@ main(int ac, char **av)
Dmitry Belyavskiy ebbbfc
 	int keytype;
Dmitry Belyavskiy ebbbfc
 	Authctxt *authctxt;
Dmitry Belyavskiy ebbbfc
 	struct connection_info *connection_info = NULL;
Dmitry Belyavskiy ebbbfc
+	int forbid_ssh_rsa = 0;
Dmitry Belyavskiy ebbbfc
 
Dmitry Belyavskiy ebbbfc
 #ifdef HAVE_SECUREWARE
Dmitry Belyavskiy ebbbfc
 	(void)set_auth_parameters(ac, av);
Dmitry Belyavskiy ebbbfc
@@ -1938,6 +1950,19 @@ main(int ac, char **av)
Dmitry Belyavskiy ebbbfc
 		    key = NULL;
Dmitry Belyavskiy ebbbfc
 		    continue;
Dmitry Belyavskiy ebbbfc
 		}
Dmitry Belyavskiy ebbbfc
+		if (sshkey_type_plain(key->type) == KEY_RSA || sshkey_type_plain(key->type) == KEY_RSA_CERT) {
Dmitry Belyavskiy ebbbfc
+		    size_t sign_size = 0;
Dmitry Belyavskiy ebbbfc
+		    u_char *tmp = NULL;
Dmitry Belyavskiy ebbbfc
+		    u_char data[] = "Test SHA1 vector";
Dmitry Belyavskiy ebbbfc
+		    int res;
Dmitry Belyavskiy ebbbfc
+
Dmitry Belyavskiy ebbbfc
+		    res = ssh_rsa_sign(key, &tmp, &sign_size, data, sizeof(data), NULL);
Dmitry Belyavskiy ebbbfc
+		    free(tmp);
Dmitry Belyavskiy ebbbfc
+		    if (res == SSH_ERR_LIBCRYPTO_ERROR) {
Dmitry Belyavskiy ebbbfc
+			logit_f("sshd: ssh-rsa algorithm is disabled");
Dmitry Belyavskiy ebbbfc
+		    	forbid_ssh_rsa = 1;
Dmitry Belyavskiy ebbbfc
+		    }
Dmitry Belyavskiy ebbbfc
+		}
Dmitry Belyavskiy ebbbfc
 		if (sshkey_is_sk(key) &&
Dmitry Belyavskiy ebbbfc
 		    key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
Dmitry Belyavskiy ebbbfc
 			debug("host key %s requires user presence, ignoring",
Dmitry Belyavskiy ebbbfc
@@ -2275,6 +2306,9 @@ main(int ac, char **av)
Dmitry Belyavskiy ebbbfc
 
Dmitry Belyavskiy ebbbfc
 	check_ip_options(ssh);
Dmitry Belyavskiy ebbbfc
 
Dmitry Belyavskiy ebbbfc
+	if (forbid_ssh_rsa)
Dmitry Belyavskiy ebbbfc
+		ssh->compat |= SSH_RH_RSASIGSHA;
Dmitry Belyavskiy ebbbfc
+
Dmitry Belyavskiy ebbbfc
 	/* Prepare the channels layer */
Dmitry Belyavskiy ebbbfc
 	channel_init_channels(ssh);
Dmitry Belyavskiy ebbbfc
 	channel_set_af(ssh, options.address_family);