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