View | Details | Raw Unified | Return to bug 3375 | Differences between
and this patch

Collapse All | Expand All

(-)a/clientloop.c (-13 / +33 lines)
Lines 105-110 Link Here
105
#include "ssherr.h"
105
#include "ssherr.h"
106
#include "hostfile.h"
106
#include "hostfile.h"
107
107
108
/* Permitted RSA signature algorithms for UpdateHostkeys proofs */
109
#define HOSTKEY_PROOF_RSA_ALGS	"rsa-sha2-512,rsa-sha2-256"
110
108
/* import options */
111
/* import options */
109
extern Options options;
112
extern Options options;
110
113
Lines 2090-2097 client_global_hostkeys_private_confirm(struct ssh *ssh, int type, Link Here
2090
	struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2093
	struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2091
	size_t i, ndone;
2094
	size_t i, ndone;
2092
	struct sshbuf *signdata;
2095
	struct sshbuf *signdata;
2093
	int r, kexsigtype, use_kexsigtype;
2096
	int r, plaintype;
2094
	const u_char *sig;
2097
	const u_char *sig;
2098
	const char *rsa_kexalg = NULL;
2099
	char *alg = NULL;
2095
	size_t siglen;
2100
	size_t siglen;
2096
2101
2097
	if (ctx->nnew == 0)
2102
	if (ctx->nnew == 0)
Lines 2102-2110 client_global_hostkeys_private_confirm(struct ssh *ssh, int type, Link Here
2102
		hostkeys_update_ctx_free(ctx);
2107
		hostkeys_update_ctx_free(ctx);
2103
		return;
2108
		return;
2104
	}
2109
	}
2105
	kexsigtype = sshkey_type_plain(
2110
	if (sshkey_type_plain(sshkey_type_from_name(
2106
	    sshkey_type_from_name(ssh->kex->hostkey_alg));
2111
	    ssh->kex->hostkey_alg)) == KEY_RSA)
2107
2112
		rsa_kexalg = ssh->kex->hostkey_alg;
2108
	if ((signdata = sshbuf_new()) == NULL)
2113
	if ((signdata = sshbuf_new()) == NULL)
2109
		fatal_f("sshbuf_new failed");
2114
		fatal_f("sshbuf_new failed");
2110
	/*
2115
	/*
Lines 2115-2120 client_global_hostkeys_private_confirm(struct ssh *ssh, int type, Link Here
2115
	for (ndone = i = 0; i < ctx->nkeys; i++) {
2120
	for (ndone = i = 0; i < ctx->nkeys; i++) {
2116
		if (ctx->keys_match[i])
2121
		if (ctx->keys_match[i])
2117
			continue;
2122
			continue;
2123
		plaintype = sshkey_type_plain(ctx->keys[i]->type);
2118
		/* Prepare data to be signed: session ID, unique string, key */
2124
		/* Prepare data to be signed: session ID, unique string, key */
2119
		sshbuf_reset(signdata);
2125
		sshbuf_reset(signdata);
2120
		if ( (r = sshbuf_put_cstring(signdata,
2126
		if ( (r = sshbuf_put_cstring(signdata,
Lines 2128-2146 client_global_hostkeys_private_confirm(struct ssh *ssh, int type, Link Here
2128
			error_fr(r, "parse sig");
2134
			error_fr(r, "parse sig");
2129
			goto out;
2135
			goto out;
2130
		}
2136
		}
2137
		if ((r = sshkey_get_sigtype(sig, siglen, &alg)) != 0) {
2138
			error_fr(r, "server gave unintelligible signature "
2139
			    "for %s key %zu", sshkey_type(ctx->keys[i]), i);
2140
			goto out;
2141
		}
2131
		/*
2142
		/*
2132
		 * For RSA keys, prefer to use the signature type negotiated
2143
		 * Special case for RSA keys: if a RSA hostkey was negotiated,
2133
		 * during KEX to the default (SHA1).
2144
		 * then use its signature type for verification of RSA hostkey
2145
		 * proofs. Otherwise, accept only RSA-SHA256/512 signatures.
2134
		 */
2146
		 */
2135
		use_kexsigtype = kexsigtype == KEY_RSA &&
2147
		if (plaintype == KEY_RSA && rsa_kexalg == NULL &&
2136
		    sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA;
2148
		    match_pattern_list(alg, HOSTKEY_PROOF_RSA_ALGS, 0) != 1) {
2137
		debug3_f("verify %s key %zu using %s sigalg",
2149
			debug_f("server used untrusted RSA signature algorithm "
2138
		    sshkey_type(ctx->keys[i]), i,
2150
			    "%s for key %zu, disregarding", alg, i);
2139
		    use_kexsigtype ? ssh->kex->hostkey_alg : "default");
2151
			free(alg);
2152
			/* zap the key from the list */
2153
			sshkey_free(ctx->keys[i]);
2154
			ctx->keys[i] = NULL;
2155
			ndone++;
2156
			continue;
2157
		}
2158
		debug3_f("verify %s key %zu using sigalg %s",
2159
		    sshkey_type(ctx->keys[i]), i, alg);
2160
		free(alg);
2140
		if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
2161
		if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
2141
		    sshbuf_ptr(signdata), sshbuf_len(signdata),
2162
		    sshbuf_ptr(signdata), sshbuf_len(signdata),
2142
		    use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0,
2163
		    plaintype == KEY_RSA ? rsa_kexalg : NULL, 0, NULL)) != 0) {
2143
		    NULL)) != 0) {
2144
			error_fr(r, "server gave bad signature for %s key %zu",
2164
			error_fr(r, "server gave bad signature for %s key %zu",
2145
			    sshkey_type(ctx->keys[i]), i);
2165
			    sshkey_type(ctx->keys[i]), i);
2146
			goto out;
2166
			goto out;
(-)a/hostfile.c (-1 / +1 lines)
Lines 635-641 hostfile_replace_entries(const char *filename, const char *host, const char *ip, Link Here
635
	/* Re-add the requested keys */
635
	/* Re-add the requested keys */
636
	want = HKF_MATCH_HOST | (ip == NULL ? 0 : HKF_MATCH_IP);
636
	want = HKF_MATCH_HOST | (ip == NULL ? 0 : HKF_MATCH_IP);
637
	for (i = 0; i < nkeys; i++) {
637
	for (i = 0; i < nkeys; i++) {
638
		if ((want & ctx.match_keys[i]) == want)
638
		if (keys[i] == NULL || (want & ctx.match_keys[i]) == want)
639
			continue;
639
			continue;
640
		if ((fp = sshkey_fingerprint(keys[i], hash_alg,
640
		if ((fp = sshkey_fingerprint(keys[i], hash_alg,
641
		    SSH_FP_DEFAULT)) == NULL) {
641
		    SSH_FP_DEFAULT)) == NULL) {

Return to bug 3375