mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-23 13:55:13 +02:00
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
This commit is contained in:
parent
17877bc81d
commit
0fa3368322
24
kex.c
24
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.
|
* 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);
|
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
|
static int
|
||||||
kex_choose_conf(struct ssh *ssh)
|
kex_choose_conf(struct ssh *ssh)
|
||||||
{
|
{
|
||||||
@ -935,6 +947,16 @@ kex_choose_conf(struct ssh *ssh)
|
|||||||
free(ext);
|
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@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@openssh.com"))
|
||||||
|
kex->flags |= KEX_RSA_SHA2_512_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Algorithm Negotiation */
|
/* Algorithm Negotiation */
|
||||||
if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
|
if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
|
||||||
sprop[PROPOSAL_KEX_ALGS])) != 0) {
|
sprop[PROPOSAL_KEX_ALGS])) != 0) {
|
||||||
|
4
kex.h
4
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.
|
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||||
@ -109,6 +109,8 @@ enum kex_exchange {
|
|||||||
#define KEX_INIT_SENT 0x0001
|
#define KEX_INIT_SENT 0x0001
|
||||||
#define KEX_INITIAL 0x0002
|
#define KEX_INITIAL 0x0002
|
||||||
#define KEX_HAS_PUBKEY_HOSTBOUND 0x0004
|
#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 {
|
struct sshenc {
|
||||||
char *name;
|
char *name;
|
||||||
|
27
serverloop.c
27
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@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@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 *resp = NULL;
|
||||||
struct sshbuf *sigbuf = NULL;
|
struct sshbuf *sigbuf = NULL;
|
||||||
struct sshkey *key = NULL, *key_pub = NULL, *key_prv = 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 u_char *blob;
|
||||||
|
const char *sigalg, *kex_rsa_sigalg = NULL;
|
||||||
u_char *sig = 0;
|
u_char *sig = 0;
|
||||||
size_t blen, slen;
|
size_t blen, slen;
|
||||||
|
|
||||||
if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL)
|
if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL)
|
||||||
fatal_f("sshbuf_new");
|
fatal_f("sshbuf_new");
|
||||||
|
if (sshkey_type_plain(sshkey_type_from_name(
|
||||||
kexsigtype = sshkey_type_plain(
|
ssh->kex->hostkey_alg)) == KEY_RSA)
|
||||||
sshkey_type_from_name(ssh->kex->hostkey_alg));
|
kex_rsa_sigalg = ssh->kex->hostkey_alg;
|
||||||
while (ssh_packet_remaining(ssh) > 0) {
|
while (ssh_packet_remaining(ssh) > 0) {
|
||||||
sshkey_free(key);
|
sshkey_free(key);
|
||||||
key = NULL;
|
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
|
* For RSA keys, prefer to use the signature type negotiated
|
||||||
* during KEX to the default (SHA1).
|
* during KEX to the default (SHA1).
|
||||||
*/
|
*/
|
||||||
use_kexsigtype = kexsigtype == KEY_RSA &&
|
sigalg = NULL;
|
||||||
sshkey_type_plain(key->type) == KEY_RSA;
|
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,
|
if ((r = sshbuf_put_cstring(sigbuf,
|
||||||
"hostkeys-prove-00@openssh.com")) != 0 ||
|
"hostkeys-prove-00@openssh.com")) != 0 ||
|
||||||
(r = sshbuf_put_stringb(sigbuf,
|
(r = sshbuf_put_stringb(sigbuf,
|
||||||
ssh->kex->session_id)) != 0 ||
|
ssh->kex->session_id)) != 0 ||
|
||||||
(r = sshkey_puts(key, sigbuf)) != 0 ||
|
(r = sshkey_puts(key, sigbuf)) != 0 ||
|
||||||
(r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen,
|
(r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen,
|
||||||
sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
|
sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), sigalg)) != 0 ||
|
||||||
use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 ||
|
|
||||||
(r = sshbuf_put_string(resp, sig, slen)) != 0) {
|
(r = sshbuf_put_string(resp, sig, slen)) != 0) {
|
||||||
error_fr(r, "assemble signature");
|
error_fr(r, "assemble signature");
|
||||||
goto out;
|
goto out;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user