mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Enforce acceptable range for Diffie-Hellman server value.
Florent Daigniere of Matta points out that RFC 4253 actually _requires_ us to refuse to accept out-of-range values, though it isn't completely clear to me why this should be a MUST on the receiving end. Matta considers this to be a security vulnerability, on the grounds that if a server should accidentally send an obviously useless value such as 1 then we will fail to reject it and agree a key that an eavesdropper could also figure out. Their id for this vulnerability is MATTA-2015-002.
This commit is contained in:
parent
db9385b3ce
commit
174476813f
7
ssh.c
7
ssh.c
@ -6645,6 +6645,13 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
||||
}
|
||||
ssh_pkt_getstring(pktin, &s->sigdata, &s->siglen);
|
||||
|
||||
{
|
||||
const char *err = dh_validate_f(ssh->kex_ctx, s->f);
|
||||
if (err) {
|
||||
bombout(("key exchange reply failed validation: %s", err));
|
||||
crStopV;
|
||||
}
|
||||
}
|
||||
s->K = dh_find_K(ssh->kex_ctx, s->f);
|
||||
|
||||
/* We assume everything from now on will be quick, and it might
|
||||
|
1
ssh.h
1
ssh.h
@ -536,6 +536,7 @@ void *dh_setup_group(const struct ssh_kex *kex);
|
||||
void *dh_setup_gex(Bignum pval, Bignum gval);
|
||||
void dh_cleanup(void *);
|
||||
Bignum dh_create_e(void *, int nbits);
|
||||
const char *dh_validate_f(void *handle, Bignum f);
|
||||
Bignum dh_find_K(void *, Bignum f);
|
||||
|
||||
int loadrsakey(const Filename *filename, struct RSAKey *key,
|
||||
|
23
sshdh.c
23
sshdh.c
@ -218,6 +218,29 @@ Bignum dh_create_e(void *handle, int nbits)
|
||||
return ctx->e;
|
||||
}
|
||||
|
||||
/*
|
||||
* DH stage 2-epsilon: given a number f, validate it to ensure it's in
|
||||
* range. (RFC 4253 section 8: "Values of 'e' or 'f' that are not in
|
||||
* the range [1, p-1] MUST NOT be sent or accepted by either side."
|
||||
* Also, we rule out 1 and p-1 too, since that's easy to do and since
|
||||
* they lead to obviously weak keys that even a passive eavesdropper
|
||||
* can figure out.)
|
||||
*/
|
||||
const char *dh_validate_f(void *handle, Bignum f)
|
||||
{
|
||||
struct dh_ctx *ctx = (struct dh_ctx *)handle;
|
||||
if (bignum_cmp(f, One) <= 0) {
|
||||
return "f value received is too small";
|
||||
} else {
|
||||
Bignum pm1 = bigsub(ctx->p, One);
|
||||
int cmp = bignum_cmp(f, pm1);
|
||||
freebn(pm1);
|
||||
if (cmp >= 0)
|
||||
return "f value received is too large";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* DH stage 2: given a number f, compute K = f^x mod p.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user