From 5e2443ff1f07cb8cd7e6dd7d8cb044283c788478 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Wed, 6 May 2015 20:49:07 +0100 Subject: [PATCH] Fix SSH-1 RSA key handling in Pageant. The auxiliary values (the two primes and the inverse of one mod the other) were being read into the key structure wrongly, causing crt_modpow() in sshrsa.c to give the wrong answers where straight modpow would not have. This must have been broken ever since I implemented the RSA CRT optimisation in 2011. And nobody has noticed, which is a good sign for the phasing out of SSH-1 :-) I only spotted it myself because I was testing all the Pageant message types in the course of implementing the new logging. --- pageant.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pageant.c b/pageant.c index 220d0ca1..33d0d305 100644 --- a/pageant.c +++ b/pageant.c @@ -580,6 +580,10 @@ void *pageant_handle_msg(const void *msg, int msglen, int *outlen, } p += n; + /* SSH-1 names p and q the other way round, i.e. we have + * the inverse of p mod q and not of q mod p. We swap the + * names, because our internal RSA wants iqmp. */ + n = ssh1_read_bignum(p, msgend - p, &key->iqmp); /* p^-1 mod q */ if (n < 0) { freersakey(key); @@ -589,7 +593,7 @@ void *pageant_handle_msg(const void *msg, int msglen, int *outlen, } p += n; - n = ssh1_read_bignum(p, msgend - p, &key->p); /* p */ + n = ssh1_read_bignum(p, msgend - p, &key->q); /* p */ if (n < 0) { freersakey(key); sfree(key); @@ -598,7 +602,7 @@ void *pageant_handle_msg(const void *msg, int msglen, int *outlen, } p += n; - n = ssh1_read_bignum(p, msgend - p, &key->q); /* q */ + n = ssh1_read_bignum(p, msgend - p, &key->p); /* q */ if (n < 0) { freersakey(key); sfree(key);