diff options
author | djm@openbsd.org <djm@openbsd.org> | 2017-12-18 23:16:23 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-12-19 15:21:37 +1100 |
commit | 7860731ef190b52119fa480f8064ab03c44a120a (patch) | |
tree | 758274280fa590762fac827aae5b9aa3ee56c946 | |
parent | 966ef478339ad5e631fb684d2a8effe846ce3fd4 (diff) |
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
-rw-r--r-- | clientloop.c | 15 | ||||
-rw-r--r-- | serverloop.c | 14 |
2 files changed, 23 insertions, 6 deletions
diff --git a/clientloop.c b/clientloop.c index 3ce5d930e..c187ae570 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -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 $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1893,7 +1893,7 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type, | |||
1893 | struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; | 1893 | struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; |
1894 | size_t i, ndone; | 1894 | size_t i, ndone; |
1895 | struct sshbuf *signdata; | 1895 | struct sshbuf *signdata; |
1896 | int r; | 1896 | int r, kexsigtype, use_kexsigtype; |
1897 | const u_char *sig; | 1897 | const u_char *sig; |
1898 | size_t siglen; | 1898 | size_t siglen; |
1899 | 1899 | ||
@@ -1905,6 +1905,9 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type, | |||
1905 | hostkeys_update_ctx_free(ctx); | 1905 | hostkeys_update_ctx_free(ctx); |
1906 | return; | 1906 | return; |
1907 | } | 1907 | } |
1908 | kexsigtype = sshkey_type_plain( | ||
1909 | sshkey_type_from_name(ssh->kex->hostkey_alg)); | ||
1910 | |||
1908 | if ((signdata = sshbuf_new()) == NULL) | 1911 | if ((signdata = sshbuf_new()) == NULL) |
1909 | fatal("%s: sshbuf_new failed", __func__); | 1912 | fatal("%s: sshbuf_new failed", __func__); |
1910 | /* Don't want to accidentally accept an unbound signature */ | 1913 | /* Don't want to accidentally accept an unbound signature */ |
@@ -1933,9 +1936,15 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type, | |||
1933 | __func__, ssh_err(r)); | 1936 | __func__, ssh_err(r)); |
1934 | goto out; | 1937 | goto out; |
1935 | } | 1938 | } |
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; | ||
1936 | if ((r = sshkey_verify(ctx->keys[i], sig, siglen, | 1945 | if ((r = sshkey_verify(ctx->keys[i], sig, siglen, |
1937 | sshbuf_ptr(signdata), sshbuf_len(signdata), | 1946 | sshbuf_ptr(signdata), sshbuf_len(signdata), |
1938 | ssh->kex->hostkey_alg, 0)) != 0) { | 1947 | use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0) { |
1939 | error("%s: server gave bad signature for %s key %zu", | 1948 | error("%s: server gave bad signature for %s key %zu", |
1940 | __func__, sshkey_type(ctx->keys[i]), i); | 1949 | __func__, sshkey_type(ctx->keys[i]), i); |
1941 | goto out; | 1950 | goto out; |
diff --git a/serverloop.c b/serverloop.c index fb2980568..615921c38 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -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 $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -671,7 +671,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) | |||
671 | struct sshbuf *resp = NULL; | 671 | struct sshbuf *resp = NULL; |
672 | struct sshbuf *sigbuf = NULL; | 672 | struct sshbuf *sigbuf = NULL; |
673 | struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; | 673 | 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; |
675 | const u_char *blob; | 675 | const u_char *blob; |
676 | u_char *sig = 0; | 676 | u_char *sig = 0; |
677 | size_t blen, slen; | 677 | size_t blen, slen; |
@@ -679,6 +679,8 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) | |||
679 | if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) | 679 | if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) |
680 | fatal("%s: sshbuf_new", __func__); | 680 | fatal("%s: sshbuf_new", __func__); |
681 | 681 | ||
682 | kexsigtype = sshkey_type_plain( | ||
683 | sshkey_type_from_name(ssh->kex->hostkey_alg)); | ||
682 | while (ssh_packet_remaining(ssh) > 0) { | 684 | while (ssh_packet_remaining(ssh) > 0) { |
683 | sshkey_free(key); | 685 | sshkey_free(key); |
684 | key = NULL; | 686 | key = NULL; |
@@ -709,6 +711,12 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) | |||
709 | sshbuf_reset(sigbuf); | 711 | sshbuf_reset(sigbuf); |
710 | free(sig); | 712 | free(sig); |
711 | sig = NULL; | 713 | 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; | ||
712 | if ((r = sshbuf_put_cstring(sigbuf, | 720 | if ((r = sshbuf_put_cstring(sigbuf, |
713 | "hostkeys-prove-00@openssh.com")) != 0 || | 721 | "hostkeys-prove-00@openssh.com")) != 0 || |
714 | (r = sshbuf_put_string(sigbuf, | 722 | (r = sshbuf_put_string(sigbuf, |
@@ -716,7 +724,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) | |||
716 | (r = sshkey_puts(key, sigbuf)) != 0 || | 724 | (r = sshkey_puts(key, sigbuf)) != 0 || |
717 | (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, | 725 | (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, |
718 | sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), | 726 | sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), |
719 | ssh->kex->hostkey_alg, 0)) != 0 || | 727 | use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0 || |
720 | (r = sshbuf_put_string(resp, sig, slen)) != 0) { | 728 | (r = sshbuf_put_string(resp, sig, slen)) != 0) { |
721 | error("%s: couldn't prepare signature: %s", | 729 | error("%s: couldn't prepare signature: %s", |
722 | __func__, ssh_err(r)); | 730 | __func__, ssh_err(r)); |