|
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; |