aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-05-21 20:22:16 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-05-21 20:22:16 +0000
commit5cf07901c5118a55c9d8e1c704283cfc744bb68b (patch)
tree3ae8c525f6c60519e5a90d2feeafe665257c9c97
parent515112f9d4874aaedd0c093f41c0ba3e0bf7f660 (diff)
downloadpostgresql-5cf07901c5118a55c9d8e1c704283cfc744bb68b.tar.gz
postgresql-5cf07901c5118a55c9d8e1c704283cfc744bb68b.zip
Fix errors in fortuna PRNG reseeding logic that could cause a predictable
session key to be selected by pgp_sym_encrypt() in some cases. This only affects non-OpenSSL-using builds. Marko Kreen
-rw-r--r--contrib/pgcrypto/fortuna.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/contrib/pgcrypto/fortuna.c b/contrib/pgcrypto/fortuna.c
index 1b13337301c..cf69cee28bc 100644
--- a/contrib/pgcrypto/fortuna.c
+++ b/contrib/pgcrypto/fortuna.c
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.5 2005/10/15 02:49:06 momjian Exp $
+ * $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.6 2006/05/21 20:22:16 tgl Exp $
*/
#include "postgres.h"
@@ -219,7 +219,7 @@ encrypt_counter(FState * st, uint8 *dst)
* microseconds.
*/
static int
-too_often(FState * st)
+enough_time_passed(FState * st)
{
int ok;
struct timeval tv;
@@ -227,13 +227,22 @@ too_often(FState * st)
gettimeofday(&tv, NULL);
+ /* check how much time has passed */
ok = 0;
- if (tv.tv_sec != last->tv_sec)
+ if (tv.tv_sec > last->tv_sec + 1)
ok = 1;
+ else if (tv.tv_sec == last->tv_sec + 1)
+ {
+ if (1000000 + tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
+ ok = 1;
+ }
else if (tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
ok = 1;
- memcpy(last, &tv, sizeof(tv));
+ /* reseed will happen, update last_reseed_time */
+ if (ok)
+ memcpy(last, &tv, sizeof(tv));
+
memset(&tv, 0, sizeof(tv));
return ok;
@@ -372,7 +381,7 @@ extract_data(FState * st, unsigned count, uint8 *dst)
unsigned block_nr = 0;
/* Can we reseed? */
- if (st->pool0_bytes >= POOL0_FILL && !too_often(st))
+ if (st->pool0_bytes >= POOL0_FILL && enough_time_passed(st))
reseed(st);
/* Is counter initialized? */