summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2011-10-18 16:05:19 +1100
committerDamien Miller <djm@mindrot.org>2011-10-18 16:05:19 +1100
commit390d0561fccfba5e2e97105f75b70b32aab59578 (patch)
treec1baadb7c116489ef2a6260d06fac81d66208c3e
parentd3e6990c4ca1e6c8ad9e66f5e57a2b4545dbc940 (diff)
- dtucker@cvs.openbsd.org 2011/10/16 11:02:46
[moduli.c ssh-keygen.1 ssh-keygen.c] Add optional checkpoints for moduli screening. feedback & ok deraadt
-rw-r--r--ChangeLog3
-rw-r--r--moduli.c69
-rw-r--r--ssh-keygen.113
-rw-r--r--ssh-keygen.c16
4 files changed, 92 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 1d00c68cb..9f33f53bb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,9 @@
3 - djm@cvs.openbsd.org 2011/10/04 14:17:32 3 - djm@cvs.openbsd.org 2011/10/04 14:17:32
4 [sftp-glob.c] 4 [sftp-glob.c]
5 silence error spam for "ls */foo" in directory with files; bz#1683 5 silence error spam for "ls */foo" in directory with files; bz#1683
6 - dtucker@cvs.openbsd.org 2011/10/16 11:02:46
7 [moduli.c ssh-keygen.1 ssh-keygen.c]
8 Add optional checkpoints for moduli screening. feedback & ok deraadt
6 9
720111001 1020111001
8 - (dtucker) [openbsd-compat/mktemp.c] Fix compiler warning. ok djm 11 - (dtucker) [openbsd-compat/mktemp.c] Fix compiler warning. ok djm
diff --git a/moduli.c b/moduli.c
index 2964a8b3d..f734d1c28 100644
--- a/moduli.c
+++ b/moduli.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: moduli.c,v 1.22 2010/11/10 01:33:07 djm Exp $ */ 1/* $OpenBSD: moduli.c,v 1.23 2011/10/16 11:02:46 dtucker Exp $ */
2/* 2/*
3 * Copyright 1994 Phil Karn <karn@qualcomm.com> 3 * Copyright 1994 Phil Karn <karn@qualcomm.com>
4 * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com> 4 * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
@@ -49,6 +49,7 @@
49#include <string.h> 49#include <string.h>
50#include <stdarg.h> 50#include <stdarg.h>
51#include <time.h> 51#include <time.h>
52#include <unistd.h>
52 53
53#include "xmalloc.h" 54#include "xmalloc.h"
54#include "dh.h" 55#include "dh.h"
@@ -137,7 +138,7 @@ static u_int32_t largebits, largememory; /* megabytes */
137static BIGNUM *largebase; 138static BIGNUM *largebase;
138 139
139int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); 140int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
140int prime_test(FILE *, FILE *, u_int32_t, u_int32_t); 141int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *);
141 142
142/* 143/*
143 * print moduli out in consistent form, 144 * print moduli out in consistent form,
@@ -438,6 +439,52 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start)
438 return (ret); 439 return (ret);
439} 440}
440 441
442static void
443write_checkpoint(char *cpfile, u_int32_t lineno)
444{
445 FILE *fp;
446 char tmpfile[MAXPATHLEN];
447 int r;
448
449 r = snprintf(tmpfile, sizeof(tmpfile), "%s.XXXXXXXXXX", cpfile);
450 if (r == -1 || r >= MAXPATHLEN) {
451 logit("write_checkpoint: temp pathname too long");
452 return;
453 }
454 if ((r = mkstemp(tmpfile)) == -1) {
455 logit("mkstemp(%s): %s", tmpfile, strerror(errno));
456 return;
457 }
458 if ((fp = fdopen(r, "w")) == NULL) {
459 logit("write_checkpoint: fdopen: %s", strerror(errno));
460 close(r);
461 return;
462 }
463 if (fprintf(fp, "%lu\n", (unsigned long)lineno) > 0 && fclose(fp) == 0
464 && rename(tmpfile, cpfile) == 0)
465 debug3("wrote checkpoint line %lu to '%s'",
466 (unsigned long)lineno, cpfile);
467 else
468 logit("failed to write to checkpoint file '%s': %s", cpfile,
469 strerror(errno));
470}
471
472static unsigned long
473read_checkpoint(char *cpfile)
474{
475 FILE *fp;
476 unsigned long lineno = 0;
477
478 if ((fp = fopen(cpfile, "r")) == NULL)
479 return 0;
480 if (fscanf(fp, "%lu\n", &lineno) < 1)
481 logit("Failed to load checkpoint from '%s'", cpfile);
482 else
483 logit("Loaded checkpoint from '%s' line %lu", cpfile, lineno);
484 fclose(fp);
485 return lineno;
486}
487
441/* 488/*
442 * perform a Miller-Rabin primality test 489 * perform a Miller-Rabin primality test
443 * on the list of candidates 490 * on the list of candidates
@@ -445,13 +492,15 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start)
445 * The result is a list of so-call "safe" primes 492 * The result is a list of so-call "safe" primes
446 */ 493 */
447int 494int
448prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) 495prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted,
496 char *checkpoint_file)
449{ 497{
450 BIGNUM *q, *p, *a; 498 BIGNUM *q, *p, *a;
451 BN_CTX *ctx; 499 BN_CTX *ctx;
452 char *cp, *lp; 500 char *cp, *lp;
453 u_int32_t count_in = 0, count_out = 0, count_possible = 0; 501 u_int32_t count_in = 0, count_out = 0, count_possible = 0;
454 u_int32_t generator_known, in_tests, in_tries, in_type, in_size; 502 u_int32_t generator_known, in_tests, in_tries, in_type, in_size;
503 unsigned long last_processed = 0;
455 time_t time_start, time_stop; 504 time_t time_start, time_stop;
456 int res; 505 int res;
457 506
@@ -472,10 +521,21 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
472 debug2("%.24s Final %u Miller-Rabin trials (%x generator)", 521 debug2("%.24s Final %u Miller-Rabin trials (%x generator)",
473 ctime(&time_start), trials, generator_wanted); 522 ctime(&time_start), trials, generator_wanted);
474 523
524 if (checkpoint_file != NULL)
525 last_processed = read_checkpoint(checkpoint_file);
526
475 res = 0; 527 res = 0;
476 lp = xmalloc(QLINESIZE + 1); 528 lp = xmalloc(QLINESIZE + 1);
477 while (fgets(lp, QLINESIZE + 1, in) != NULL) { 529 while (fgets(lp, QLINESIZE + 1, in) != NULL) {
478 count_in++; 530 count_in++;
531 if (checkpoint_file != NULL) {
532 if (count_in <= last_processed) {
533 debug3("skipping line %u, before checkpoint",
534 count_in);
535 continue;
536 }
537 write_checkpoint(checkpoint_file, count_in);
538 }
479 if (strlen(lp) < 14 || *lp == '!' || *lp == '#') { 539 if (strlen(lp) < 14 || *lp == '!' || *lp == '#') {
480 debug2("%10u: comment or short line", count_in); 540 debug2("%10u: comment or short line", count_in);
481 continue; 541 continue;
@@ -644,6 +704,9 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted)
644 BN_free(q); 704 BN_free(q);
645 BN_CTX_free(ctx); 705 BN_CTX_free(ctx);
646 706
707 if (checkpoint_file != NULL)
708 unlink(checkpoint_file);
709
647 logit("%.24s Found %u safe primes of %u candidates in %ld seconds", 710 logit("%.24s Found %u safe primes of %u candidates in %ld seconds",
648 ctime(&time_stop), count_out, count_possible, 711 ctime(&time_stop), count_out, count_possible,
649 (long) (time_stop - time_start)); 712 (long) (time_stop - time_start));
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index 528fcd39d..41da2077b 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keygen.1,v 1.107 2011/09/07 02:18:31 deraadt Exp $ 1.\" $OpenBSD: ssh-keygen.1,v 1.108 2011/10/16 11:02:46 dtucker Exp $
2.\" 2.\"
3.\" Author: Tatu Ylonen <ylo@cs.hut.fi> 3.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,7 +35,7 @@
35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37.\" 37.\"
38.Dd $Mdocdate: September 7 2011 $ 38.Dd $Mdocdate: October 16 2011 $
39.Dt SSH-KEYGEN 1 39.Dt SSH-KEYGEN 1
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -104,6 +104,7 @@
104.Fl f Ar input_file 104.Fl f Ar input_file
105.Op Fl v 105.Op Fl v
106.Op Fl a Ar num_trials 106.Op Fl a Ar num_trials
107.Op Fl K Ar checkpt
107.Op Fl W Ar generator 108.Op Fl W Ar generator
108.Nm ssh-keygen 109.Nm ssh-keygen
109.Fl s Ar ca_key 110.Fl s Ar ca_key
@@ -296,6 +297,14 @@ in the format specified by the
296.Fl m 297.Fl m
297option and print an OpenSSH compatible private 298option and print an OpenSSH compatible private
298(or public) key to stdout. 299(or public) key to stdout.
300.It Fl K Ar checkpt
301Write the last line processed to the file
302.Ar checkpt
303while performing DH candidate screening using the
304.Fl T
305option.
306This will be used to skip lines in the input file that have already been
307processed if the job is restarted.
299This option allows importing keys from other software, including several 308This option allows importing keys from other software, including several
300commercial SSH implementations. 309commercial SSH implementations.
301The default import format is 310The default import format is
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 4b6218b10..bd15cccff 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.210 2011/04/18 00:46:05 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.211 2011/10/16 11:02:46 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -154,7 +154,7 @@ char hostname[MAXHOSTNAMELEN];
154 154
155/* moduli.c */ 155/* moduli.c */
156int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); 156int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *);
157int prime_test(FILE *, FILE *, u_int32_t, u_int32_t); 157int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *);
158 158
159static void 159static void
160type_bits_valid(int type, u_int32_t *bitsp) 160type_bits_valid(int type, u_int32_t *bitsp)
@@ -1881,6 +1881,7 @@ usage(void)
1881 fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n"); 1881 fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n");
1882 fprintf(stderr, " -g Use generic DNS resource record format.\n"); 1882 fprintf(stderr, " -g Use generic DNS resource record format.\n");
1883 fprintf(stderr, " -H Hash names in known_hosts file.\n"); 1883 fprintf(stderr, " -H Hash names in known_hosts file.\n");
1884 fprintf(stderr, " -K checkpt Write checkpoints to this file.\n");
1884 fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n"); 1885 fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n");
1885 fprintf(stderr, " -I key_id Key identifier to include in certificate.\n"); 1886 fprintf(stderr, " -I key_id Key identifier to include in certificate.\n");
1886 fprintf(stderr, " -i Import foreign format to OpenSSH key file.\n"); 1887 fprintf(stderr, " -i Import foreign format to OpenSSH key file.\n");
@@ -1916,6 +1917,7 @@ int
1916main(int argc, char **argv) 1917main(int argc, char **argv)
1917{ 1918{
1918 char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; 1919 char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
1920 char *checkpoint = NULL;
1919 char out_file[MAXPATHLEN], *rr_hostname = NULL; 1921 char out_file[MAXPATHLEN], *rr_hostname = NULL;
1920 Key *private, *public; 1922 Key *private, *public;
1921 struct passwd *pw; 1923 struct passwd *pw;
@@ -1952,7 +1954,7 @@ main(int argc, char **argv)
1952 exit(1); 1954 exit(1);
1953 } 1955 }
1954 1956
1955 while ((opt = getopt(argc, argv, "AegiqpclBHLhvxXyF:b:f:t:D:I:P:m:N:n:" 1957 while ((opt = getopt(argc, argv, "AegiqpclBHLhvxXyF:b:f:t:D:I:K:P:m:N:n:"
1956 "O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) { 1958 "O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) {
1957 switch (opt) { 1959 switch (opt) {
1958 case 'A': 1960 case 'A':
@@ -2103,6 +2105,11 @@ main(int argc, char **argv)
2103 sizeof(out_file)) 2105 sizeof(out_file))
2104 fatal("Output filename too long"); 2106 fatal("Output filename too long");
2105 break; 2107 break;
2108 case 'K':
2109 if (strlen(optarg) >= MAXPATHLEN)
2110 fatal("Checkpoint filename too long");
2111 checkpoint = xstrdup(optarg);
2112 break;
2106 case 'S': 2113 case 'S':
2107 /* XXX - also compare length against bits */ 2114 /* XXX - also compare length against bits */
2108 if (BN_hex2bn(&start, optarg) == 0) 2115 if (BN_hex2bn(&start, optarg) == 0)
@@ -2225,7 +2232,8 @@ main(int argc, char **argv)
2225 fatal("Couldn't open moduli file \"%s\": %s", 2232 fatal("Couldn't open moduli file \"%s\": %s",
2226 out_file, strerror(errno)); 2233 out_file, strerror(errno));
2227 } 2234 }
2228 if (prime_test(in, out, trials, generator_wanted) != 0) 2235 if (prime_test(in, out, trials, generator_wanted, checkpoint)
2236 != 0)
2229 fatal("modulus screening failed"); 2237 fatal("modulus screening failed");
2230 return (0); 2238 return (0);
2231 } 2239 }