Skip to content

Commit 7860731

Browse files
committed
upstream commit
unbreak hostkey rotation; attempting to sign with a desired signature algorithm of kex->hostkey_alg is incorrect when the key type isn't capable of making those signatures. ok markus@ OpenBSD-Commit-ID: 35ae46864e1f5859831ec0d115ee5ea50953a906
1 parent 966ef47 commit 7860731

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

clientloop.c

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: clientloop.c,v 1.308 2017/12/18 02:25:15 djm Exp $ */
1+
/* $OpenBSD: clientloop.c,v 1.309 2017/12/18 23:16:23 djm Exp $ */
22
/*
33
* Author: Tatu Ylonen <[email protected]>
44
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
@@ -1893,7 +1893,7 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
18931893
struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
18941894
size_t i, ndone;
18951895
struct sshbuf *signdata;
1896-
int r;
1896+
int r, kexsigtype, use_kexsigtype;
18971897
const u_char *sig;
18981898
size_t siglen;
18991899

@@ -1905,6 +1905,9 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
19051905
hostkeys_update_ctx_free(ctx);
19061906
return;
19071907
}
1908+
kexsigtype = sshkey_type_plain(
1909+
sshkey_type_from_name(ssh->kex->hostkey_alg));
1910+
19081911
if ((signdata = sshbuf_new()) == NULL)
19091912
fatal("%s: sshbuf_new failed", __func__);
19101913
/* Don't want to accidentally accept an unbound signature */
@@ -1933,9 +1936,15 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
19331936
__func__, ssh_err(r));
19341937
goto out;
19351938
}
1939+
/*
1940+
* For RSA keys, prefer to use the signature type negotiated
1941+
* during KEX to the default (SHA1).
1942+
*/
1943+
use_kexsigtype = kexsigtype == KEY_RSA &&
1944+
sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA;
19361945
if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
19371946
sshbuf_ptr(signdata), sshbuf_len(signdata),
1938-
ssh->kex->hostkey_alg, 0)) != 0) {
1947+
use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0) {
19391948
error("%s: server gave bad signature for %s key %zu",
19401949
__func__, sshkey_type(ctx->keys[i]), i);
19411950
goto out;

serverloop.c

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: serverloop.c,v 1.201 2017/12/18 02:25:15 djm Exp $ */
1+
/* $OpenBSD: serverloop.c,v 1.202 2017/12/18 23:16:24 djm Exp $ */
22
/*
33
* Author: Tatu Ylonen <[email protected]>
44
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
@@ -671,14 +671,16 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
671671
struct sshbuf *resp = NULL;
672672
struct sshbuf *sigbuf = NULL;
673673
struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
674-
int r, ndx, success = 0;
674+
int r, ndx, kexsigtype, use_kexsigtype, success = 0;
675675
const u_char *blob;
676676
u_char *sig = 0;
677677
size_t blen, slen;
678678

679679
if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL)
680680
fatal("%s: sshbuf_new", __func__);
681681

682+
kexsigtype = sshkey_type_plain(
683+
sshkey_type_from_name(ssh->kex->hostkey_alg));
682684
while (ssh_packet_remaining(ssh) > 0) {
683685
sshkey_free(key);
684686
key = NULL;
@@ -709,14 +711,20 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
709711
sshbuf_reset(sigbuf);
710712
free(sig);
711713
sig = NULL;
714+
/*
715+
* For RSA keys, prefer to use the signature type negotiated
716+
* during KEX to the default (SHA1).
717+
*/
718+
use_kexsigtype = kexsigtype == KEY_RSA &&
719+
sshkey_type_plain(key->type) == KEY_RSA;
712720
if ((r = sshbuf_put_cstring(sigbuf,
713721
"[email protected]")) != 0 ||
714722
(r = sshbuf_put_string(sigbuf,
715723
ssh->kex->session_id, ssh->kex->session_id_len)) != 0 ||
716724
(r = sshkey_puts(key, sigbuf)) != 0 ||
717725
(r = ssh->kex->sign(key_prv, key_pub, &sig, &slen,
718726
sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
719-
ssh->kex->hostkey_alg, 0)) != 0 ||
727+
use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0 ||
720728
(r = sshbuf_put_string(resp, sig, slen)) != 0) {
721729
error("%s: couldn't prepare signature: %s",
722730
__func__, ssh_err(r));

0 commit comments

Comments
 (0)