summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/moduli.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/moduli.c')
-rw-r--r--crypto/openssh/moduli.c81
1 files changed, 77 insertions, 4 deletions
diff --git a/crypto/openssh/moduli.c b/crypto/openssh/moduli.c
index 2964a8b..5267bb9 100644
--- a/crypto/openssh/moduli.c
+++ b/crypto/openssh/moduli.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: moduli.c,v 1.22 2010/11/10 01:33:07 djm Exp $ */
+/* $OpenBSD: moduli.c,v 1.26 2012/07/06 00:41:59 dtucker Exp $ */
/*
* Copyright 1994 Phil Karn <karn@qualcomm.com>
* Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
@@ -39,16 +39,19 @@
#include "includes.h"
+#include <sys/param.h>
#include <sys/types.h>
#include <openssl/bn.h>
#include <openssl/dh.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
+#include <unistd.h>
#include "xmalloc.h"
#include "dh.h"
@@ -137,7 +140,8 @@ static u_int32_t largebits, largememory; /* megabytes */
static BIGNUM *largebase;
int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
-int prime_test(FILE *, FILE *, u_int32_t, u_int32_t);
+int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long,
+ unsigned long);
/*
* print moduli out in consistent form,
@@ -438,6 +442,52 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start)
return (ret);
}
+static void
+write_checkpoint(char *cpfile, u_int32_t lineno)
+{
+ FILE *fp;
+ char tmp[MAXPATHLEN];
+ int r;
+
+ r = snprintf(tmp, sizeof(tmp), "%s.XXXXXXXXXX", cpfile);
+ if (r == -1 || r >= MAXPATHLEN) {
+ logit("write_checkpoint: temp pathname too long");
+ return;
+ }
+ if ((r = mkstemp(tmp)) == -1) {
+ logit("mkstemp(%s): %s", tmp, strerror(errno));
+ return;
+ }
+ if ((fp = fdopen(r, "w")) == NULL) {
+ logit("write_checkpoint: fdopen: %s", strerror(errno));
+ close(r);
+ return;
+ }
+ if (fprintf(fp, "%lu\n", (unsigned long)lineno) > 0 && fclose(fp) == 0
+ && rename(tmp, cpfile) == 0)
+ debug3("wrote checkpoint line %lu to '%s'",
+ (unsigned long)lineno, cpfile);
+ else
+ logit("failed to write to checkpoint file '%s': %s", cpfile,
+ strerror(errno));
+}
+
+static unsigned long
+read_checkpoint(char *cpfile)
+{
+ FILE *fp;
+ unsigned long lineno = 0;
+
+ if ((fp = fopen(cpfile, "r")) == NULL)
+ return 0;
+ if (fscanf(fp, "%lu\n", &lineno) < 1)
+ logit("Failed to load checkpoint from '%s'", cpfile);
+ else
+ logit("Loaded checkpoint from '%s' line %lu", cpfile, lineno);
+ fclose(fp);
+ return lineno;
+}
+
/*
* perform a Miller-Rabin primality test
* on the list of candidates
@@ -445,13 +495,15 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start)
* The result is a list of so-call "safe" primes
*/
int
-prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
+prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted,
+ char *checkpoint_file, unsigned long start_lineno, unsigned long num_lines)
{
BIGNUM *q, *p, *a;
BN_CTX *ctx;
char *cp, *lp;
u_int32_t count_in = 0, count_out = 0, count_possible = 0;
u_int32_t generator_known, in_tests, in_tries, in_type, in_size;
+ unsigned long last_processed = 0, end_lineno;
time_t time_start, time_stop;
int res;
@@ -472,10 +524,28 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
debug2("%.24s Final %u Miller-Rabin trials (%x generator)",
ctime(&time_start), trials, generator_wanted);
+ if (checkpoint_file != NULL)
+ last_processed = read_checkpoint(checkpoint_file);
+ if (start_lineno > last_processed)
+ last_processed = start_lineno;
+ if (num_lines == 0)
+ end_lineno = ULONG_MAX;
+ else
+ end_lineno = last_processed + num_lines;
+ debug2("process line %lu to line %lu", last_processed, end_lineno);
+
res = 0;
lp = xmalloc(QLINESIZE + 1);
- while (fgets(lp, QLINESIZE + 1, in) != NULL) {
+ while (fgets(lp, QLINESIZE + 1, in) != NULL && count_in < end_lineno) {
count_in++;
+ if (checkpoint_file != NULL) {
+ if (count_in <= last_processed) {
+ debug3("skipping line %u, before checkpoint",
+ count_in);
+ continue;
+ }
+ write_checkpoint(checkpoint_file, count_in);
+ }
if (strlen(lp) < 14 || *lp == '!' || *lp == '#') {
debug2("%10u: comment or short line", count_in);
continue;
@@ -644,6 +714,9 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
BN_free(q);
BN_CTX_free(ctx);
+ if (checkpoint_file != NULL)
+ unlink(checkpoint_file);
+
logit("%.24s Found %u safe primes of %u candidates in %ld seconds",
ctime(&time_stop), count_out, count_possible,
(long) (time_stop - time_start));
OpenPOWER on IntegriCloud