[openssh-commits] [openssh] 05/13: upstream: Fix signature algorithm selection logic for

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Jan 7 09:21:52 AEDT 2022


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

djm pushed a commit to branch master
in repository openssh.

commit 0fa33683223c76289470a954404047bc762be84c
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Thu Jan 6 21:55:23 2022 +0000

    upstream: Fix signature algorithm selection logic for
    
    UpdateHostkeys on the server side. The previous code tried to prefer RSA/SHA2
    for hostkey proofs of RSA keys, but missed some cases. This will use RSA/SHA2
    signatures for RSA keys if the client proposed these algorithms in initial
    KEX. bz3375
    
    Mostly by Dmitry Belyavskiy with some tweaks by me.
    
    ok markus@
    
    OpenBSD-Commit-ID: c17ba0c3236340d2c6a248158ebed042ac6a8029
---
 kex.c        | 24 +++++++++++++++++++++++-
 kex.h        |  4 +++-
 serverloop.c | 27 ++++++++++++++++++---------
 3 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/kex.c b/kex.c
index 29733cc0..26369097 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.170 2021/12/19 22:13:12 djm Exp $ */
+/* $OpenBSD: kex.c,v 1.171 2022/01/06 21:55:23 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
@@ -900,6 +900,18 @@ proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
 	return (1);
 }
 
+/* returns non-zero if proposal contains any algorithm from algs */
+static int
+has_any_alg(const char *proposal, const char *algs)
+{
+	char *cp;
+
+	if ((cp = match_list(proposal, algs, NULL)) == NULL)
+		return 0;
+	free(cp);
+	return 1;
+}
+
 static int
 kex_choose_conf(struct ssh *ssh)
 {
@@ -935,6 +947,16 @@ kex_choose_conf(struct ssh *ssh)
 		free(ext);
 	}
 
+	/* Check whether client supports rsa-sha2 algorithms */
+	if (kex->server && (kex->flags & KEX_INITIAL)) {
+		if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
+		    "rsa-sha2-256,rsa-sha2-256-cert-v01 at openssh.com"))
+			kex->flags |= KEX_RSA_SHA2_256_SUPPORTED;
+		if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS],
+		    "rsa-sha2-512,rsa-sha2-512-cert-v01 at openssh.com"))
+			kex->flags |= KEX_RSA_SHA2_512_SUPPORTED;
+	}
+
 	/* Algorithm Negotiation */
 	if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
 	    sprop[PROPOSAL_KEX_ALGS])) != 0) {
diff --git a/kex.h b/kex.h
index f644e599..c3532950 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.116 2021/12/19 22:12:54 djm Exp $ */
+/* $OpenBSD: kex.h,v 1.117 2022/01/06 21:55:23 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -109,6 +109,8 @@ enum kex_exchange {
 #define KEX_INIT_SENT			0x0001
 #define KEX_INITIAL			0x0002
 #define KEX_HAS_PUBKEY_HOSTBOUND	0x0004
+#define KEX_RSA_SHA2_256_SUPPORTED 	0x0008 /* only set in server for now */
+#define KEX_RSA_SHA2_512_SUPPORTED 	0x0010 /* only set in server for now */
 
 struct sshenc {
 	char	*name;
diff --git a/serverloop.c b/serverloop.c
index 1a744e1e..e31dbed5 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.229 2022/01/06 21:48:38 djm Exp $ */
+/* $OpenBSD: serverloop.c,v 1.230 2022/01/06 21:55:23 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -685,16 +685,17 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
 	struct sshbuf *resp = NULL;
 	struct sshbuf *sigbuf = NULL;
 	struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
-	int r, ndx, kexsigtype, use_kexsigtype, success = 0;
+	int r, ndx, success = 0;
 	const u_char *blob;
+	const char *sigalg, *kex_rsa_sigalg = NULL;
 	u_char *sig = 0;
 	size_t blen, slen;
 
 	if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL)
 		fatal_f("sshbuf_new");
-
-	kexsigtype = sshkey_type_plain(
-	    sshkey_type_from_name(ssh->kex->hostkey_alg));
+	if (sshkey_type_plain(sshkey_type_from_name(
+	    ssh->kex->hostkey_alg)) == KEY_RSA)
+		kex_rsa_sigalg = ssh->kex->hostkey_alg;
 	while (ssh_packet_remaining(ssh) > 0) {
 		sshkey_free(key);
 		key = NULL;
@@ -727,16 +728,24 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
 		 * For RSA keys, prefer to use the signature type negotiated
 		 * during KEX to the default (SHA1).
 		 */
-		use_kexsigtype = kexsigtype == KEY_RSA &&
-		    sshkey_type_plain(key->type) == KEY_RSA;
+		sigalg = NULL;
+		if (sshkey_type_plain(key->type) == KEY_RSA) {
+			if (kex_rsa_sigalg != NULL)
+				sigalg = kex_rsa_sigalg;
+			else if (ssh->kex->flags & KEX_RSA_SHA2_512_SUPPORTED)
+				sigalg = "rsa-sha2-512";
+			else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED)
+				sigalg = "rsa-sha2-256";
+		}
+		debug3_f("sign %s key (index %d) using sigalg %s",
+		    sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg);
 		if ((r = sshbuf_put_cstring(sigbuf,
 		    "hostkeys-prove-00 at openssh.com")) != 0 ||
 		    (r = sshbuf_put_stringb(sigbuf,
 		    ssh->kex->session_id)) != 0 ||
 		    (r = sshkey_puts(key, sigbuf)) != 0 ||
 		    (r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen,
-		    sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
-		    use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 ||
+		    sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), sigalg)) != 0 ||
 		    (r = sshbuf_put_string(resp, sig, slen)) != 0) {
 			error_fr(r, "assemble signature");
 			goto out;

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


More information about the openssh-commits mailing list