vishalmishra434 / rpms / openssh

Forked from rpms/openssh a month ago
Clone
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/compat.c.sshrsacheck	2023-01-12 13:29:06.338710923 +0100
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/compat.c	2023-01-12 13:29:06.357711165 +0100
Dmitry Belyavskiy 1506e0
@@ -43,6 +43,7 @@ void
Dmitry Belyavskiy 1506e0
 compat_banner(struct ssh *ssh, const char *version)
Dmitry Belyavskiy 1506e0
 {
Dmitry Belyavskiy 1506e0
 	int i;
Dmitry Belyavskiy 1506e0
+	int forbid_ssh_rsa = 0;
Dmitry Belyavskiy 1506e0
 	static struct {
Dmitry Belyavskiy 1506e0
 		char	*pat;
Dmitry Belyavskiy 1506e0
 		int	bugs;
Dmitry Belyavskiy 1506e0
@@ -145,16 +146,21 @@ compat_banner(struct ssh *ssh, const cha
Dmitry Belyavskiy 1506e0
 	};
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 	/* process table, return first match */
Dmitry Belyavskiy 1506e0
+	forbid_ssh_rsa = (ssh->compat & SSH_RH_RSASIGSHA);
Dmitry Belyavskiy 1506e0
 	ssh->compat = 0;
Dmitry Belyavskiy 1506e0
 	for (i = 0; check[i].pat; i++) {
Dmitry Belyavskiy 1506e0
 		if (match_pattern_list(version, check[i].pat, 0) == 1) {
Dmitry Belyavskiy 1506e0
 			debug_f("match: %s pat %s compat 0x%08x",
Dmitry Belyavskiy 1506e0
 			    version, check[i].pat, check[i].bugs);
Dmitry Belyavskiy 1506e0
 			ssh->compat = check[i].bugs;
Dmitry Belyavskiy 1506e0
+	if (forbid_ssh_rsa)
Dmitry Belyavskiy 1506e0
+		ssh->compat |= SSH_RH_RSASIGSHA;
Dmitry Belyavskiy 1506e0
 			return;
Dmitry Belyavskiy 1506e0
 		}
Dmitry Belyavskiy 1506e0
 	}
Dmitry Belyavskiy 1506e0
 	debug_f("no match: %s", version);
Dmitry Belyavskiy 1506e0
+	if (forbid_ssh_rsa)
Dmitry Belyavskiy 1506e0
+		ssh->compat |= SSH_RH_RSASIGSHA;
Dmitry Belyavskiy 1506e0
 }
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 /* Always returns pointer to allocated memory, caller must free. */
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/compat.h.sshrsacheck openssh-8.7p1/compat.h
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/compat.h.sshrsacheck	2021-08-20 06:03:49.000000000 +0200
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/compat.h	2023-01-12 13:29:06.358711178 +0100
Dmitry Belyavskiy 1506e0
@@ -30,7 +30,7 @@
Dmitry Belyavskiy 1506e0
 #define SSH_BUG_UTF8TTYMODE	0x00000001
Dmitry Belyavskiy 1506e0
 #define SSH_BUG_SIGTYPE		0x00000002
Dmitry Belyavskiy 1506e0
 #define SSH_BUG_SIGTYPE74	0x00000004
Dmitry Belyavskiy 1506e0
-/* #define unused		0x00000008 */
Dmitry Belyavskiy 1506e0
+#define SSH_RH_RSASIGSHA	0x00000008
Dmitry Belyavskiy 1506e0
 #define SSH_OLD_SESSIONID	0x00000010
Dmitry Belyavskiy 1506e0
 /* #define unused		0x00000020 */
Dmitry Belyavskiy 1506e0
 #define SSH_BUG_DEBUG		0x00000040
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/monitor.c.sshrsacheck openssh-8.7p1/monitor.c
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/monitor.c.sshrsacheck	2023-01-20 13:07:54.279676981 +0100
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/monitor.c	2023-01-20 15:01:07.007821379 +0100
Dmitry Belyavskiy 1506e0
@@ -660,11 +660,12 @@ mm_answer_sign(struct ssh *ssh, int sock
Dmitry Belyavskiy 1506e0
 	struct sshkey *key;
Dmitry Belyavskiy 1506e0
 	struct sshbuf *sigbuf = NULL;
Dmitry Belyavskiy 1506e0
 	u_char *p = NULL, *signature = NULL;
Dmitry Belyavskiy 1506e0
-	char *alg = NULL;
Dmitry Belyavskiy 1506e0
+	char *alg = NULL, *effective_alg;
Dmitry Belyavskiy 1506e0
 	size_t datlen, siglen, alglen;
Dmitry Belyavskiy 1506e0
 	int r, is_proof = 0;
Dmitry Belyavskiy 1506e0
 	u_int keyid, compat;
Dmitry Belyavskiy 1506e0
 	const char proof_req[] = "hostkeys-prove-00@openssh.com";
Dmitry Belyavskiy 1506e0
+	const char safe_rsa[]  = "rsa-sha2-256";
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 	debug3_f("entering");
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
@@ -719,18 +720,30 @@ mm_answer_sign(struct ssh *ssh, int sock
Dmitry Belyavskiy 1506e0
 	}
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 	if ((key = get_hostkey_by_index(keyid)) != NULL) {
Dmitry Belyavskiy 1506e0
-		if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg,
Dmitry Belyavskiy 1506e0
+		if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
Dmitry Belyavskiy 1506e0
+				&& (sshkey_type_plain(key->type) == KEY_RSA)) {
Dmitry Belyavskiy 1506e0
+			effective_alg = safe_rsa;
Dmitry Belyavskiy 1506e0
+		} else {
Dmitry Belyavskiy 1506e0
+			effective_alg = alg;
Dmitry Belyavskiy 1506e0
+		}
Dmitry Belyavskiy 1506e0
+		if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, effective_alg,
Dmitry Belyavskiy 1506e0
 		    options.sk_provider, NULL, compat)) != 0)
Dmitry Belyavskiy 1506e0
 			fatal_fr(r, "sign");
Dmitry Belyavskiy 1506e0
 	} else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL &&
Dmitry Belyavskiy 1506e0
 	    auth_sock > 0) {
Dmitry Belyavskiy 1506e0
+		if (ssh->compat & SSH_RH_RSASIGSHA && strcmp(alg, "ssh-rsa") == 0
Dmitry Belyavskiy 1506e0
+				&& (sshkey_type_plain(key->type) == KEY_RSA)) {
Dmitry Belyavskiy 1506e0
+			effective_alg = safe_rsa;
Dmitry Belyavskiy 1506e0
+		} else {
Dmitry Belyavskiy 1506e0
+			effective_alg = alg;
Dmitry Belyavskiy 1506e0
+		}
Dmitry Belyavskiy 1506e0
 		if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen,
Dmitry Belyavskiy 1506e0
-		    p, datlen, alg, compat)) != 0)
Dmitry Belyavskiy 1506e0
+		    p, datlen, effective_alg, compat)) != 0)
Dmitry Belyavskiy 1506e0
 			fatal_fr(r, "agent sign");
Dmitry Belyavskiy 1506e0
 	} else
Dmitry Belyavskiy 1506e0
 		fatal_f("no hostkey from index %d", keyid);
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
-	debug3_f("%s %s signature len=%zu", alg,
Dmitry Belyavskiy 1506e0
+	debug3_f("%s (effective: %s) %s signature len=%zu", alg, effective_alg,
Dmitry Belyavskiy 1506e0
 	    is_proof ? "hostkey proof" : "KEX", siglen);
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 	sshbuf_reset(m);
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck openssh-8.7p1/regress/cert-userkey.sh
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/regress/cert-userkey.sh.sshrsacheck	2023-01-25 14:26:52.885963113 +0100
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/regress/cert-userkey.sh	2023-01-25 14:27:25.757219800 +0100
Dmitry Belyavskiy 1506e0
@@ -7,7 +7,8 @@ rm -f $OBJ/authorized_keys_$USER $OBJ/us
Dmitry Belyavskiy 1506e0
 cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
Dmitry Belyavskiy 1506e0
 cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
-PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
Dmitry Belyavskiy 1506e0
+#ssh-dss keys are incompatible with DEFAULT crypto policy
Dmitry Belyavskiy 1506e0
+PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss' | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'`
Dmitry Belyavskiy 1506e0
 EXTRA_TYPES=""
Dmitry Belyavskiy 1506e0
 rsa=""
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/regress/Makefile.sshrsacheck openssh-8.7p1/regress/Makefile
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/regress/Makefile.sshrsacheck	2023-01-20 13:07:54.169676051 +0100
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/regress/Makefile	2023-01-20 13:07:54.290677074 +0100
Dmitry Belyavskiy 1506e0
@@ -2,7 +2,8 @@
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 tests:		prep file-tests t-exec unit
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
-REGRESS_TARGETS=	t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12
Dmitry Belyavskiy 1506e0
+#ssh-dss tests will not pass on DEFAULT crypto-policy because of SHA1, skipping
Dmitry Belyavskiy 1506e0
+REGRESS_TARGETS=	t1 t2 t3 t4 t5 t7 t8 t9 t10 t11 t12
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 # File based tests
Dmitry Belyavskiy 1506e0
 file-tests: $(REGRESS_TARGETS)
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/regress/test-exec.sh.sshrsacheck openssh-8.7p1/regress/test-exec.sh
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/regress/test-exec.sh.sshrsacheck	2023-01-25 14:24:54.778040819 +0100
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/regress/test-exec.sh	2023-01-25 14:26:39.500858590 +0100
Dmitry Belyavskiy 1506e0
@@ -581,8 +581,9 @@ maybe_filter_sk() {
Dmitry Belyavskiy 1506e0
 	fi
Dmitry Belyavskiy 1506e0
 }
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
-SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk`
Dmitry Belyavskiy 1506e0
-SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk`
Dmitry Belyavskiy 1506e0
+#ssh-dss keys are incompatible with DEFAULT crypto policy
Dmitry Belyavskiy 1506e0
+SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'`
Dmitry Belyavskiy 1506e0
+SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk | grep -v 'ssh-dss'`
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 for t in ${SSH_KEYTYPES}; do
Dmitry Belyavskiy 1506e0
 	# generate user key
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck openssh-8.7p1/regress/unittests/kex/test_kex.c
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/regress/unittests/kex/test_kex.c.sshrsacheck	2023-01-26 13:34:52.645743677 +0100
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/regress/unittests/kex/test_kex.c	2023-01-26 13:36:56.220745823 +0100
Dmitry Belyavskiy 1506e0
@@ -97,7 +97,8 @@ do_kex_with_key(char *kex, int keytype,
Dmitry Belyavskiy 1506e0
 	memcpy(kex_params.proposal, myproposal, sizeof(myproposal));
Dmitry Belyavskiy 1506e0
 	if (kex != NULL)
Dmitry Belyavskiy 1506e0
 		kex_params.proposal[PROPOSAL_KEX_ALGS] = kex;
Dmitry Belyavskiy 1506e0
-	keyname = strdup(sshkey_ssh_name(private));
Dmitry Belyavskiy 1506e0
+	keyname = (strcmp(sshkey_ssh_name(private), "ssh-rsa")) ?
Dmitry Belyavskiy 1506e0
+		strdup(sshkey_ssh_name(private)) : strdup("rsa-sha2-256");
Dmitry Belyavskiy 1506e0
 	ASSERT_PTR_NE(keyname, NULL);
Dmitry Belyavskiy 1506e0
 	kex_params.proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = keyname;
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0);
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_file.c
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/regress/unittests/sshkey/test_file.c.sshrsacheck	2023-01-26 12:04:55.946343408 +0100
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/regress/unittests/sshkey/test_file.c	2023-01-26 12:06:35.235164432 +0100
Dmitry Belyavskiy 1506e0
@@ -110,6 +110,7 @@ sshkey_file_tests(void)
Dmitry Belyavskiy 1506e0
 	sshkey_free(k2);
Dmitry Belyavskiy 1506e0
 	TEST_DONE();
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
+	/* Skip this test, SHA1 signatures are not supported
Dmitry Belyavskiy 1506e0
 	TEST_START("load RSA cert with SHA1 signature");
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha1"), &k2), 0);
Dmitry Belyavskiy 1506e0
 	ASSERT_PTR_NE(k2, NULL);
Dmitry Belyavskiy 1506e0
@@ -117,7 +118,7 @@ sshkey_file_tests(void)
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1);
Dmitry Belyavskiy 1506e0
 	ASSERT_STRING_EQ(k2->cert->signature_type, "ssh-rsa");
Dmitry Belyavskiy 1506e0
 	sshkey_free(k2);
Dmitry Belyavskiy 1506e0
-	TEST_DONE();
Dmitry Belyavskiy 1506e0
+	TEST_DONE(); */
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 	TEST_START("load RSA cert with SHA512 signature");
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1_sha512"), &k2), 0);
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c.sshrsacheck	2023-01-26 12:10:37.533168013 +0100
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/regress/unittests/sshkey/test_fuzz.c	2023-01-26 12:15:35.637631860 +0100
Dmitry Belyavskiy 1506e0
@@ -333,13 +333,14 @@ sshkey_fuzz_tests(void)
Dmitry Belyavskiy 1506e0
 	TEST_DONE();
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 #ifdef WITH_OPENSSL
Dmitry Belyavskiy 1506e0
+	/* Skip this test, SHA1 signatures are not supported
Dmitry Belyavskiy 1506e0
 	TEST_START("fuzz RSA sig");
Dmitry Belyavskiy 1506e0
 	buf = load_file("rsa_1");
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
Dmitry Belyavskiy 1506e0
 	sshbuf_free(buf);
Dmitry Belyavskiy 1506e0
 	sig_fuzz(k1, "ssh-rsa");
Dmitry Belyavskiy 1506e0
 	sshkey_free(k1);
Dmitry Belyavskiy 1506e0
-	TEST_DONE();
Dmitry Belyavskiy 1506e0
+	TEST_DONE();*/
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 	TEST_START("fuzz RSA SHA256 sig");
Dmitry Belyavskiy 1506e0
 	buf = load_file("rsa_1");
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c.sshrsacheck	2023-01-26 11:02:52.339413463 +0100
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/regress/unittests/sshkey/test_sshkey.c	2023-01-26 11:58:42.324253896 +0100
Dmitry Belyavskiy 1506e0
@@ -60,6 +60,9 @@ build_cert(struct sshbuf *b, struct sshk
Dmitry Belyavskiy 1506e0
 	u_char *sigblob;
Dmitry Belyavskiy 1506e0
 	size_t siglen;
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
+	/* ssh-rsa implies SHA1, forbidden in DEFAULT cp */
Dmitry Belyavskiy 1506e0
+	int expected = (sig_alg == NULL || strcmp(sig_alg, "ssh-rsa") == 0) ? SSH_ERR_LIBCRYPTO_ERROR : 0;
Dmitry Belyavskiy 1506e0
+
Dmitry Belyavskiy 1506e0
 	ca_buf = sshbuf_new();
Dmitry Belyavskiy 1506e0
 	ASSERT_PTR_NE(ca_buf, NULL);
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0);
Dmitry Belyavskiy 1506e0
@@ -101,8 +104,9 @@ build_cert(struct sshbuf *b, struct sshk
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen,
Dmitry Belyavskiy 1506e0
-	    sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), 0);
Dmitry Belyavskiy 1506e0
-	ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
Dmitry Belyavskiy 1506e0
+	    sshbuf_ptr(b), sshbuf_len(b), sig_alg, NULL, NULL, 0), expected);
Dmitry Belyavskiy 1506e0
+	if (expected == 0)
Dmitry Belyavskiy 1506e0
+		ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 	free(sigblob);
Dmitry Belyavskiy 1506e0
 	sshbuf_free(ca_buf);
Dmitry Belyavskiy 1506e0
@@ -119,16 +123,22 @@ signature_test(struct sshkey *k, struct
Dmitry Belyavskiy 1506e0
 {
Dmitry Belyavskiy 1506e0
 	size_t len;
Dmitry Belyavskiy 1506e0
 	u_char *sig;
Dmitry Belyavskiy 089d79
+	/* ssh-rsa implies SHA1, forbidden in DEFAULT cp in RHEL, permitted in Fedora */
Dmitry Belyavskiy 089d79
+	int expected = (sig_alg && strcmp(sig_alg, "ssh-rsa") == 0) ? sshkey_sign(k, &sig, &len, d, l, sig_alg, NULL, NULL, 0) : 0;
Dmitry Belyavskiy 1506e0
+	if (k && (sshkey_type_plain(k->type) == KEY_DSA || sshkey_type_plain(k->type) == KEY_DSA_CERT))
Dmitry Belyavskiy 089d79
+		expected = sshkey_sign(k, &sig, &len, d, l, sig_alg, NULL, NULL, 0);
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg,
Dmitry Belyavskiy 1506e0
-	    NULL, NULL, 0), 0);
Dmitry Belyavskiy 1506e0
-	ASSERT_SIZE_T_GT(len, 8);
Dmitry Belyavskiy 1506e0
-	ASSERT_PTR_NE(sig, NULL);
Dmitry Belyavskiy 1506e0
-	ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
Dmitry Belyavskiy 1506e0
-	ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
Dmitry Belyavskiy 1506e0
-	/* Fuzz test is more comprehensive, this is just a smoke test */
Dmitry Belyavskiy 1506e0
-	sig[len - 5] ^= 0x10;
Dmitry Belyavskiy 1506e0
-	ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
Dmitry Belyavskiy 1506e0
+	    NULL, NULL, 0), expected);
Dmitry Belyavskiy 1506e0
+	if (expected == 0) {
Dmitry Belyavskiy 1506e0
+		ASSERT_SIZE_T_GT(len, 8);
Dmitry Belyavskiy 1506e0
+		ASSERT_PTR_NE(sig, NULL);
Dmitry Belyavskiy 1506e0
+		ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
Dmitry Belyavskiy 1506e0
+		ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, NULL, 0, NULL), 0);
Dmitry Belyavskiy 1506e0
+		/* Fuzz test is more comprehensive, this is just a smoke test */
Dmitry Belyavskiy 1506e0
+		sig[len - 5] ^= 0x10;
Dmitry Belyavskiy 1506e0
+		ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, NULL, 0, NULL), 0);
Dmitry Belyavskiy 1506e0
+	}
Dmitry Belyavskiy 1506e0
 	free(sig);
Dmitry Belyavskiy 1506e0
 }
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 1506e0
@@ -514,7 +524,7 @@ sshkey_tests(void)
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
Dmitry Belyavskiy 1506e0
 	    NULL), 0);
Dmitry Belyavskiy 1506e0
 	k3 = get_private("rsa_1");
Dmitry Belyavskiy 1506e0
-	build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL);
Dmitry Belyavskiy 1506e0
+	build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, "rsa-sha2-256");
Dmitry Belyavskiy 1506e0
 	ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
Dmitry Belyavskiy 1506e0
 	    SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
Dmitry Belyavskiy 1506e0
 	ASSERT_PTR_EQ(k4, NULL);
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/serverloop.c.sshrsacheck	2023-01-12 14:57:08.118400073 +0100
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/serverloop.c	2023-01-12 14:59:17.330470518 +0100
Dmitry Belyavskiy f561c6
@@ -80,6 +80,7 @@
Dmitry Belyavskiy f561c6
 #include "auth-options.h"
Dmitry Belyavskiy f561c6
 #include "serverloop.h"
Dmitry Belyavskiy f561c6
 #include "ssherr.h"
Dmitry Belyavskiy f561c6
+#include "compat.h"
Dmitry Belyavskiy f561c6
 
Dmitry Belyavskiy f561c6
 extern ServerOptions options;
Dmitry Belyavskiy f561c6
 
Dmitry Belyavskiy 1506e0
@@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh *
Dmitry Belyavskiy 1506e0
 			else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
Dmitry Belyavskiy 1506e0
 				sigalg = "rsa-sha2-256";
Dmitry Belyavskiy 1506e0
 		}
Dmitry Belyavskiy 1506e0
+		if (ssh->compat & SSH_RH_RSASIGSHA && sigalg == NULL) {
Dmitry Belyavskiy 1506e0
+			sigalg = "rsa-sha2-512";
Dmitry Belyavskiy 1506e0
+			debug3_f("SHA1 signature is not supported, falling back to %s", sigalg);
Dmitry Belyavskiy 1506e0
+		}
Dmitry Belyavskiy 1506e0
 		debug3_f("sign %s key (index %d) using sigalg %s",
Dmitry Belyavskiy 1506e0
 		    sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
Dmitry Belyavskiy 1506e0
 		if ((r = sshbuf_put_cstring(sigbuf,
Dmitry Belyavskiy 1506e0
diff -up openssh-8.7p1/sshconnect2.c.sshrsacheck openssh-8.7p1/sshconnect2.c
Dmitry Belyavskiy 1506e0
--- openssh-8.7p1/sshconnect2.c.sshrsacheck	2023-01-25 15:33:29.140353651 +0100
Dmitry Belyavskiy 1506e0
+++ openssh-8.7p1/sshconnect2.c	2023-01-25 15:59:34.225364883 +0100
Dmitry Belyavskiy 1506e0
@@ -1461,6 +1464,14 @@ identity_sign(struct identity *id, u_cha
Dmitry Belyavskiy 1506e0
 			retried = 1;
Dmitry Belyavskiy 1506e0
 			goto retry_pin;
Dmitry Belyavskiy 1506e0
 		}
Dmitry Belyavskiy 1506e0
+		if ((r == SSH_ERR_LIBCRYPTO_ERROR) && strcmp("ssh-rsa", alg)) {
Dmitry Belyavskiy 1506e0
+			char rsa_safe_alg[] = "rsa-sha2-512";
Dmitry Belyavskiy 1506e0
+			debug3_f("trying to fallback to algorithm %s", rsa_safe_alg);
Dmitry Belyavskiy 1506e0
+
Dmitry Belyavskiy 1506e0
+			if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen,
Dmitry Belyavskiy 1506e0
+			rsa_safe_alg, options.sk_provider, pin, compat)) != 0)
Dmitry Belyavskiy 1506e0
+				debug_fr(r, "sshkey_sign - RSA fallback");
Dmitry Belyavskiy 1506e0
+		}
Dmitry Belyavskiy 1506e0
 		goto out;
Dmitry Belyavskiy 1506e0
 	}
Dmitry Belyavskiy 1506e0
 
Dmitry Belyavskiy 089d79
diff -up openssh-8.7p1/ssh-rsa.c.sshrsacheck openssh-8.7p1/ssh-rsa.c
Dmitry Belyavskiy 089d79
--- openssh-8.7p1/ssh-rsa.c.sshrsacheck	2023-01-20 13:07:54.180676144 +0100
Dmitry Belyavskiy 089d79
+++ openssh-8.7p1/ssh-rsa.c	2023-01-20 13:07:54.290677074 +0100
Dmitry Belyavskiy 089d79
@@ -254,7 +254,8 @@ ssh_rsa_verify(const struct sshkey *key,
Dmitry Belyavskiy 089d79
 			ret = SSH_ERR_INVALID_ARGUMENT;
Dmitry Belyavskiy 089d79
 			goto out;
Dmitry Belyavskiy 1506e0
 		}
Dmitry Belyavskiy 089d79
-		if (hash_alg != want_alg) {
Dmitry Belyavskiy 089d79
+		if (hash_alg != want_alg && want_alg != SSH_DIGEST_SHA1) {
Dmitry Belyavskiy 089d79
+			debug_f("Unexpected digest algorithm: got %d, wanted %d", hash_alg, want_alg);
Dmitry Belyavskiy 089d79
 			ret = SSH_ERR_SIGNATURE_INVALID;
Dmitry Belyavskiy 089d79
 			goto out;
Dmitry Belyavskiy 089d79
 		}
Dmitry Belyavskiy 089d79
diff -up openssh-9.8p1/sshd-session.c.xxx openssh-9.8p1/sshd-session.c
Dmitry Belyavskiy 089d79
--- openssh-9.8p1/sshd-session.c.xxx	2024-07-23 15:08:14.794350818 +0200
Dmitry Belyavskiy 089d79
+++ openssh-9.8p1/sshd-session.c	2024-07-23 15:40:21.658456636 +0200
Dmitry Belyavskiy 089d79
@@ -1305,6 +1305,27 @@ main(int ac, char **av)
Dmitry Belyavskiy 089d79
 
Dmitry Belyavskiy 089d79
 	check_ip_options(ssh);
Dmitry Belyavskiy 089d79
 
Dmitry Belyavskiy 089d79
+	{
Dmitry Belyavskiy 089d79
+		struct sshkey *rsakey = NULL;
Dmitry Belyavskiy 089d79
+		rsakey = get_hostkey_private_by_type(KEY_RSA, 0, ssh);
Dmitry Belyavskiy 089d79
+		if (rsakey == NULL)
Dmitry Belyavskiy 089d79
+			rsakey = get_hostkey_private_by_type(KEY_RSA_CERT, 0, ssh);
Dmitry Belyavskiy 1506e0
+
Dmitry Belyavskiy 089d79
+		if (rsakey != NULL) {
Dmitry Belyavskiy 1506e0
+		    size_t sign_size = 0;
Dmitry Belyavskiy 1506e0
+		    u_char *tmp = NULL;
Dmitry Belyavskiy 1506e0
+		    u_char data[] = "Test SHA1 vector";
Dmitry Belyavskiy 1506e0
+		    int res;
Dmitry Belyavskiy 1506e0
+
Dmitry Belyavskiy 089d79
+		    res = sshkey_sign(rsakey, &tmp, &sign_size, data, sizeof(data), NULL, NULL, NULL, 0);
Dmitry Belyavskiy 1506e0
+		    free(tmp);
Dmitry Belyavskiy 1506e0
+		    if (res == SSH_ERR_LIBCRYPTO_ERROR) {
Dmitry Belyavskiy 089d79
+			verbose_f("SHA1 in signatures is disabled for RSA keys");
Dmitry Belyavskiy 089d79
+		    	ssh->compat |= SSH_RH_RSASIGSHA;
Dmitry Belyavskiy 1506e0
+		    }
Dmitry Belyavskiy 1506e0
+		}
Dmitry Belyavskiy 089d79
+	}
Dmitry Belyavskiy 1506e0
+
Dmitry Belyavskiy 1506e0
 	/* Prepare the channels layer */
Dmitry Belyavskiy 1506e0
 	channel_init_channels(ssh);
Dmitry Belyavskiy 1506e0
 	channel_set_af(ssh, options.address_family);