X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/9275ca8aed9b69e7b62eab751342833eb637ff1d..60fe6ff72f12d19eed807bab77ffbe5ddeb87c66:/sshrsa.c diff --git a/sshrsa.c b/sshrsa.c index 9947ceff..fa5bfa25 100644 --- a/sshrsa.c +++ b/sshrsa.c @@ -153,10 +153,11 @@ void rsa_fingerprint(char *str, int len, struct RSAKey *key) { /* * Verify that the public data in an RSA key matches the private - * data. + * data. We also check the private data itself: we ensure that p > + * q and that iqmp really is the inverse of q mod p. */ int rsa_verify(struct RSAKey *key) { - Bignum n, ed, pm1, qm1, pm1qm1; + Bignum n, ed, pm1, qm1; int cmp; /* n must equal pq. */ @@ -166,21 +167,38 @@ int rsa_verify(struct RSAKey *key) { if (cmp != 0) return 0; - /* e * d must be congruent to 1, modulo (p-1)(q-1). */ + /* e * d must be congruent to 1, modulo (p-1) and modulo (q-1). */ pm1 = copybn(key->p); decbn(pm1); + ed = modmul(key->exponent, key->private_exponent, pm1); + cmp = bignum_cmp(ed, One); + sfree(ed); + if (cmp != 0) + return 0; + qm1 = copybn(key->q); decbn(qm1); - pm1qm1 = bigmul(pm1, qm1); - freebn(pm1); - freebn(qm1); - ed = modmul(key->exponent, key->private_exponent, pm1qm1); - sfree(pm1qm1); + ed = modmul(key->exponent, key->private_exponent, qm1); cmp = bignum_cmp(ed, One); sfree(ed); if (cmp != 0) return 0; + /* + * Ensure p > q. + */ + if (bignum_cmp(key->p, key->q) <= 0) + return 0; + + /* + * Ensure iqmp * q is congruent to 1, modulo p. + */ + n = modmul(key->iqmp, key->q, key->p); + cmp = bignum_cmp(n, One); + sfree(n); + if (cmp != 0) + return 0; + return 1; }