diff options
-rw-r--r-- | ssh-keygen.1 | 142 | ||||
-rw-r--r-- | ssh-keygen.c | 249 |
2 files changed, 228 insertions, 163 deletions
diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 67a57b9f7..9afb92943 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: ssh-keygen.1,v 1.183 2019/12/30 03:28:41 djm Exp $ | 1 | .\" $OpenBSD: ssh-keygen.1,v 1.184 2019/12/30 03:30:09 djm 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 |
@@ -99,20 +99,14 @@ | |||
99 | .Op Fl g | 99 | .Op Fl g |
100 | .Op Fl f Ar input_keyfile | 100 | .Op Fl f Ar input_keyfile |
101 | .Nm ssh-keygen | 101 | .Nm ssh-keygen |
102 | .Fl G Ar output_file | 102 | .Fl M Cm generate |
103 | .Op Fl v | 103 | .Op Fl O Ar option |
104 | .Op Fl b Ar bits | 104 | .Ar |
105 | .Op Fl M Ar memory | ||
106 | .Op Fl S Ar start_point | ||
107 | .Nm ssh-keygen | 105 | .Nm ssh-keygen |
106 | .Fl M Cm screen | ||
108 | .Fl f Ar input_file | 107 | .Fl f Ar input_file |
109 | .Fl T Ar output_file | 108 | .Op Fl O Ar option |
110 | .Op Fl v | 109 | .Ar |
111 | .Op Fl a Ar rounds | ||
112 | .Op Fl J Ar num_lines | ||
113 | .Op Fl j Ar start_line | ||
114 | .Op Fl K Ar checkpt | ||
115 | .Op Fl W Ar generator | ||
116 | .Nm ssh-keygen | 110 | .Nm ssh-keygen |
117 | .Fl I Ar certificate_identity | 111 | .Fl I Ar certificate_identity |
118 | .Fl s Ar ca_key | 112 | .Fl s Ar ca_key |
@@ -268,11 +262,6 @@ When saving a private key, this option specifies the number of KDF | |||
268 | (key derivation function) rounds used. | 262 | (key derivation function) rounds used. |
269 | Higher numbers result in slower passphrase verification and increased | 263 | Higher numbers result in slower passphrase verification and increased |
270 | resistance to brute-force password cracking (should the keys be stolen). | 264 | resistance to brute-force password cracking (should the keys be stolen). |
271 | .Pp | ||
272 | When screening DH-GEX candidates (using the | ||
273 | .Fl T | ||
274 | command), | ||
275 | this option specifies the number of primality tests to perform. | ||
276 | .It Fl B | 265 | .It Fl B |
277 | Show the bubblebabble digest of specified private or public key file. | 266 | Show the bubblebabble digest of specified private or public key file. |
278 | .It Fl b Ar bits | 267 | .It Fl b Ar bits |
@@ -333,12 +322,6 @@ used in conjunction with the | |||
333 | option to print found keys in a hashed format. | 322 | option to print found keys in a hashed format. |
334 | .It Fl f Ar filename | 323 | .It Fl f Ar filename |
335 | Specifies the filename of the key file. | 324 | Specifies the filename of the key file. |
336 | .It Fl G Ar output_file | ||
337 | Generate candidate primes for DH-GEX. | ||
338 | These primes must be screened for | ||
339 | safety (using the | ||
340 | .Fl T | ||
341 | option) before use. | ||
342 | .It Fl g | 325 | .It Fl g |
343 | Use generic DNS format when printing fingerprint resource records using the | 326 | Use generic DNS format when printing fingerprint resource records using the |
344 | .Fl r | 327 | .Fl r |
@@ -379,24 +362,6 @@ This option allows importing keys from other software, including several | |||
379 | commercial SSH implementations. | 362 | commercial SSH implementations. |
380 | The default import format is | 363 | The default import format is |
381 | .Dq RFC4716 . | 364 | .Dq RFC4716 . |
382 | .It Fl J Ar num_lines | ||
383 | Exit after screening the specified number of lines | ||
384 | while performing DH candidate screening using the | ||
385 | .Fl T | ||
386 | option. | ||
387 | .It Fl j Ar start_line | ||
388 | Start screening at the specified line number | ||
389 | while performing DH candidate screening using the | ||
390 | .Fl T | ||
391 | option. | ||
392 | .It Fl K Ar checkpt | ||
393 | Write the last line processed to the file | ||
394 | .Ar checkpt | ||
395 | while performing DH candidate screening using the | ||
396 | .Fl T | ||
397 | option. | ||
398 | This will be used to skip lines in the input file that have already been | ||
399 | processed if the job is restarted. | ||
400 | .It Fl k | 365 | .It Fl k |
401 | Generate a KRL file. | 366 | Generate a KRL file. |
402 | In this mode, | 367 | In this mode, |
@@ -419,9 +384,26 @@ If combined with | |||
419 | .Fl v , | 384 | .Fl v , |
420 | a visual ASCII art representation of the key is supplied with the | 385 | a visual ASCII art representation of the key is supplied with the |
421 | fingerprint. | 386 | fingerprint. |
422 | .It Fl M Ar memory | 387 | .It Fl M Cm generate |
423 | Specify the amount of memory to use (in megabytes) when generating | 388 | Generate candidate Diffie-Hellman Group Exchange (DH-GEX) parameters for |
424 | candidate moduli for DH-GEX. | 389 | eventual use by the |
390 | .Sq diffie-hellman-group-exchange-* | ||
391 | key exchange methods. | ||
392 | The numbers generated by this operation must be further screened before | ||
393 | use. | ||
394 | See the | ||
395 | .Sx MODULI GENERATION | ||
396 | section for more information. | ||
397 | .It Fl M Cm screen | ||
398 | Screen candidate parameters for Diffie-Hellman Group Exchange. | ||
399 | This will accept a list of candidate numbers and test that they are | ||
400 | safe (Sophie Germain) primes with acceptable group generators. | ||
401 | The results of this operation may be added to the | ||
402 | .Pa /etc/moduli | ||
403 | file. | ||
404 | See the | ||
405 | .Sx MODULI GENERATION | ||
406 | section for more information. | ||
425 | .It Fl m Ar key_format | 407 | .It Fl m Ar key_format |
426 | Specify a key format for key generation, the | 408 | Specify a key format for key generation, the |
427 | .Fl i | 409 | .Fl i |
@@ -457,10 +439,20 @@ Please see the | |||
457 | .Sx CERTIFICATES | 439 | .Sx CERTIFICATES |
458 | section for details. | 440 | section for details. |
459 | .It Fl O Ar option | 441 | .It Fl O Ar option |
460 | Specify a certificate option when signing a key. | 442 | Specify a key/value option. |
461 | See the | 443 | These are specific to the operation that |
444 | .Nm | ||
445 | has been requested to perform. | ||
446 | .Pp | ||
447 | When signing certificates, one of the options listed in the | ||
462 | .Sx CERTIFICATES | 448 | .Sx CERTIFICATES |
463 | section for a list of available certificate options. | 449 | section may be specified here. |
450 | .Pp | ||
451 | When performing moduli generation or screening, one of the options | ||
452 | listed in the | ||
453 | .Sx MODULI GENERATION | ||
454 | section may be specified. | ||
455 | .Pp | ||
464 | This option may be specified multiple times. | 456 | This option may be specified multiple times. |
465 | .It Fl P Ar passphrase | 457 | .It Fl P Ar passphrase |
466 | Provides the (old) passphrase. | 458 | Provides the (old) passphrase. |
@@ -489,8 +481,6 @@ option above). | |||
489 | Print the SSHFP fingerprint resource record named | 481 | Print the SSHFP fingerprint resource record named |
490 | .Ar hostname | 482 | .Ar hostname |
491 | for the specified public key file. | 483 | for the specified public key file. |
492 | .It Fl S Ar start | ||
493 | Specify start point (in hex) when generating candidate moduli for DH-GEX. | ||
494 | .It Fl s Ar ca_key | 484 | .It Fl s Ar ca_key |
495 | Certify (sign) a public key using the specified CA key. | 485 | Certify (sign) a public key using the specified CA key. |
496 | Please see the | 486 | Please see the |
@@ -504,10 +494,6 @@ by key ID or serial number. | |||
504 | See the | 494 | See the |
505 | .Sx KEY REVOCATION LISTS | 495 | .Sx KEY REVOCATION LISTS |
506 | section for details. | 496 | section for details. |
507 | .It Fl T Ar output_file | ||
508 | Test DH group exchange candidate primes (generated using the | ||
509 | .Fl G | ||
510 | option) for safety. | ||
511 | .It Fl t Cm dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa | 497 | .It Fl t Cm dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa |
512 | Specifies the type of key to create. | 498 | Specifies the type of key to create. |
513 | The possible values are | 499 | The possible values are |
@@ -583,8 +569,6 @@ Multiple | |||
583 | .Fl v | 569 | .Fl v |
584 | options increase the verbosity. | 570 | options increase the verbosity. |
585 | The maximum is 3. | 571 | The maximum is 3. |
586 | .It Fl W Ar generator | ||
587 | Specify desired generator when testing candidate moduli for DH-GEX. | ||
588 | .It Fl w Ar provider | 572 | .It Fl w Ar provider |
589 | Specifies a path to a library that will be used when creating | 573 | Specifies a path to a library that will be used when creating |
590 | FIDO authenticator-hosted keys, overriding the default of using | 574 | FIDO authenticator-hosted keys, overriding the default of using |
@@ -701,25 +685,25 @@ These candidate primes are then tested for suitability (a CPU-intensive | |||
701 | process). | 685 | process). |
702 | .Pp | 686 | .Pp |
703 | Generation of primes is performed using the | 687 | Generation of primes is performed using the |
704 | .Fl G | 688 | .Fl M Cm generate |
705 | option. | 689 | option. |
706 | The desired length of the primes may be specified by the | 690 | The desired length of the primes may be specified by the |
707 | .Fl b | 691 | .Fl O Cm bits |
708 | option. | 692 | option. |
709 | For example: | 693 | For example: |
710 | .Pp | 694 | .Pp |
711 | .Dl # ssh-keygen -G moduli-2048.candidates -b 2048 | 695 | .Dl # ssh-keygen -M generate -O bits=2048 moduli-2048.candidates |
712 | .Pp | 696 | .Pp |
713 | By default, the search for primes begins at a random point in the | 697 | By default, the search for primes begins at a random point in the |
714 | desired length range. | 698 | desired length range. |
715 | This may be overridden using the | 699 | This may be overridden using the |
716 | .Fl S | 700 | .Fl O Cm start |
717 | option, which specifies a different start point (in hex). | 701 | option, which specifies a different start point (in hex). |
718 | .Pp | 702 | .Pp |
719 | Once a set of candidates have been generated, they must be screened for | 703 | Once a set of candidates have been generated, they must be screened for |
720 | suitability. | 704 | suitability. |
721 | This may be performed using the | 705 | This may be performed using the |
722 | .Fl T | 706 | .Fl M Cm screen |
723 | option. | 707 | option. |
724 | In this mode | 708 | In this mode |
725 | .Nm | 709 | .Nm |
@@ -728,16 +712,16 @@ will read candidates from standard input (or a file specified using the | |||
728 | option). | 712 | option). |
729 | For example: | 713 | For example: |
730 | .Pp | 714 | .Pp |
731 | .Dl # ssh-keygen -T moduli-2048 -f moduli-2048.candidates | 715 | .Dl # ssh-keygen -M screen -f moduli-2048.candidates moduli-2048 |
732 | .Pp | 716 | .Pp |
733 | By default, each candidate will be subjected to 100 primality tests. | 717 | By default, each candidate will be subjected to 100 primality tests. |
734 | This may be overridden using the | 718 | This may be overridden using the |
735 | .Fl a | 719 | .Fl O Cm prime-tests |
736 | option. | 720 | option. |
737 | The DH generator value will be chosen automatically for the | 721 | The DH generator value will be chosen automatically for the |
738 | prime under consideration. | 722 | prime under consideration. |
739 | If a specific generator is desired, it may be requested using the | 723 | If a specific generator is desired, it may be requested using the |
740 | .Fl W | 724 | .Fl O Cm generator |
741 | option. | 725 | option. |
742 | Valid generator values are 2, 3, and 5. | 726 | Valid generator values are 2, 3, and 5. |
743 | .Pp | 727 | .Pp |
@@ -745,6 +729,36 @@ Screened DH groups may be installed in | |||
745 | .Pa /etc/moduli . | 729 | .Pa /etc/moduli . |
746 | It is important that this file contains moduli of a range of bit lengths and | 730 | It is important that this file contains moduli of a range of bit lengths and |
747 | that both ends of a connection share common moduli. | 731 | that both ends of a connection share common moduli. |
732 | .Pp | ||
733 | A number of options are available for moduli generation and screening via the | ||
734 | .Fl O | ||
735 | flag: | ||
736 | .Bl -tag -width Ds -compact | ||
737 | .Pp | ||
738 | .It Ic lines Ns = Ns Ar number | ||
739 | Exit after screening the specified number of lines while performing DH | ||
740 | candidate screening. | ||
741 | .Pp | ||
742 | .It Ic start-line Ns = Ns Ar line-number | ||
743 | Start screening at the specified line number while performing DH candidate | ||
744 | screening. | ||
745 | .Pp | ||
746 | .It Ic checkpoint Ns = Ns Ar filename | ||
747 | Write the last line processed to the specified file while performing DH | ||
748 | candidate screening. | ||
749 | This will be used to skip lines in the input file that have already been | ||
750 | processed if the job is restarted. | ||
751 | .Pp | ||
752 | .It Ic memory Ns = Ns Ar mbytes | ||
753 | Specify the amount of memory to use (in megabytes) when generating | ||
754 | candidate moduli for DH-GEX. | ||
755 | .Pp | ||
756 | .It Ic start Ns = Ns Ar hex-value | ||
757 | Specify start point (in hex) when generating candidate moduli for DH-GEX. | ||
758 | .Pp | ||
759 | .It Ic generator Ns = Ns Ar value | ||
760 | Specify desired generator (in decimal) when testing candidate moduli for DH-GEX. | ||
761 | .El | ||
748 | .Sh CERTIFICATES | 762 | .Sh CERTIFICATES |
749 | .Nm | 763 | .Nm |
750 | supports signing of keys to produce certificates that may be used for | 764 | supports signing of keys to produce certificates that may be used for |
diff --git a/ssh-keygen.c b/ssh-keygen.c index 43f2e1e82..447810fb1 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.375 2019/12/30 03:28:41 djm Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.376 2019/12/30 03:30:09 djm 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 |
@@ -162,10 +162,7 @@ static int private_key_format = SSHKEY_PRIVATE_OPENSSH; | |||
162 | /* Cipher for new-format private keys */ | 162 | /* Cipher for new-format private keys */ |
163 | static char *openssh_format_cipher = NULL; | 163 | static char *openssh_format_cipher = NULL; |
164 | 164 | ||
165 | /* | 165 | /* Number of KDF rounds to derive new format keys. */ |
166 | * Number of KDF rounds to derive new format keys / | ||
167 | * number of primality trials when screening moduli. | ||
168 | */ | ||
169 | static int rounds = 0; | 166 | static int rounds = 0; |
170 | 167 | ||
171 | /* argv0 */ | 168 | /* argv0 */ |
@@ -2759,6 +2756,122 @@ done: | |||
2759 | } | 2756 | } |
2760 | 2757 | ||
2761 | static void | 2758 | static void |
2759 | do_moduli_gen(const char *out_file, char **opts, size_t nopts) | ||
2760 | { | ||
2761 | #ifdef WITH_OPENSSL | ||
2762 | /* Moduli generation/screening */ | ||
2763 | u_int32_t memory = 0; | ||
2764 | BIGNUM *start = NULL; | ||
2765 | int moduli_bits = 0; | ||
2766 | FILE *out; | ||
2767 | size_t i; | ||
2768 | const char *errstr; | ||
2769 | |||
2770 | /* Parse options */ | ||
2771 | for (i = 0; i < nopts; i++) { | ||
2772 | if (strncmp(opts[i], "memory=", 7) == 0) { | ||
2773 | memory = (u_int32_t)strtonum(opts[i]+7, 1, | ||
2774 | UINT_MAX, &errstr); | ||
2775 | if (errstr) { | ||
2776 | fatal("Memory limit is %s: %s", | ||
2777 | errstr, opts[i]+7); | ||
2778 | } | ||
2779 | } else if (strncmp(opts[i], "start=", 6) == 0) { | ||
2780 | /* XXX - also compare length against bits */ | ||
2781 | if (BN_hex2bn(&start, opts[i]+6) == 0) | ||
2782 | fatal("Invalid start point."); | ||
2783 | } else if (strncmp(opts[i], "bits=", 5) == 0) { | ||
2784 | moduli_bits = (int)strtonum(opts[i]+5, 1, | ||
2785 | INT_MAX, &errstr); | ||
2786 | if (errstr) { | ||
2787 | fatal("Invalid number: %s (%s)", | ||
2788 | opts[i]+12, errstr); | ||
2789 | } | ||
2790 | } else { | ||
2791 | fatal("Option \"%s\" is unsupported for moduli " | ||
2792 | "generation", opts[i]); | ||
2793 | } | ||
2794 | } | ||
2795 | |||
2796 | if ((out = fopen(out_file, "w")) == NULL) { | ||
2797 | fatal("Couldn't open modulus candidate file \"%s\": %s", | ||
2798 | out_file, strerror(errno)); | ||
2799 | } | ||
2800 | setvbuf(out, NULL, _IOLBF, 0); | ||
2801 | |||
2802 | if (moduli_bits == 0) | ||
2803 | moduli_bits = DEFAULT_BITS; | ||
2804 | if (gen_candidates(out, memory, moduli_bits, start) != 0) | ||
2805 | fatal("modulus candidate generation failed"); | ||
2806 | #else /* WITH_OPENSSL */ | ||
2807 | fatal("Moduli generation is not supported"); | ||
2808 | #endif /* WITH_OPENSSL */ | ||
2809 | } | ||
2810 | |||
2811 | static void | ||
2812 | do_moduli_screen(const char *out_file, char **opts, size_t nopts) | ||
2813 | { | ||
2814 | #ifdef WITH_OPENSSL | ||
2815 | /* Moduli generation/screening */ | ||
2816 | char *checkpoint = NULL; | ||
2817 | u_int32_t generator_wanted = 0; | ||
2818 | unsigned long start_lineno = 0, lines_to_process = 0; | ||
2819 | int prime_tests = 0; | ||
2820 | FILE *out, *in = stdin; | ||
2821 | size_t i; | ||
2822 | const char *errstr; | ||
2823 | |||
2824 | /* Parse options */ | ||
2825 | for (i = 0; i < nopts; i++) { | ||
2826 | if (strncmp(opts[i], "lines=", 6) == 0) { | ||
2827 | lines_to_process = strtoul(opts[i]+6, NULL, 10); | ||
2828 | } else if (strncmp(opts[i], "start-line=", 11) == 0) { | ||
2829 | start_lineno = strtoul(opts[i]+11, NULL, 10); | ||
2830 | } else if (strncmp(opts[i], "checkpoint=", 11) == 0) { | ||
2831 | checkpoint = xstrdup(opts[i]+11); | ||
2832 | } else if (strncmp(opts[i], "generator=", 10) == 0) { | ||
2833 | generator_wanted = (u_int32_t)strtonum( | ||
2834 | opts[i]+10, 1, UINT_MAX, &errstr); | ||
2835 | if (errstr != NULL) { | ||
2836 | fatal("Generator invalid: %s (%s)", | ||
2837 | opts[i]+10, errstr); | ||
2838 | } | ||
2839 | } else if (strncmp(opts[i], "prime-tests=", 12) == 0) { | ||
2840 | prime_tests = (int)strtonum(opts[i]+12, 1, | ||
2841 | INT_MAX, &errstr); | ||
2842 | if (errstr) { | ||
2843 | fatal("Invalid number: %s (%s)", | ||
2844 | opts[i]+12, errstr); | ||
2845 | } | ||
2846 | } else { | ||
2847 | fatal("Option \"%s\" is unsupported for moduli " | ||
2848 | "screening", opts[i]); | ||
2849 | } | ||
2850 | } | ||
2851 | |||
2852 | if (have_identity && strcmp(identity_file, "-") != 0) { | ||
2853 | if ((in = fopen(identity_file, "r")) == NULL) { | ||
2854 | fatal("Couldn't open modulus candidate " | ||
2855 | "file \"%s\": %s", identity_file, | ||
2856 | strerror(errno)); | ||
2857 | } | ||
2858 | } | ||
2859 | |||
2860 | if ((out = fopen(out_file, "a")) == NULL) { | ||
2861 | fatal("Couldn't open moduli file \"%s\": %s", | ||
2862 | out_file, strerror(errno)); | ||
2863 | } | ||
2864 | setvbuf(out, NULL, _IOLBF, 0); | ||
2865 | if (prime_test(in, out, prime_tests == 0 ? 100 : prime_tests, | ||
2866 | generator_wanted, checkpoint, | ||
2867 | start_lineno, lines_to_process) != 0) | ||
2868 | fatal("modulus screening failed"); | ||
2869 | #else /* WITH_OPENSSL */ | ||
2870 | fatal("Moduli screening is not supported"); | ||
2871 | #endif /* WITH_OPENSSL */ | ||
2872 | } | ||
2873 | |||
2874 | static void | ||
2762 | usage(void) | 2875 | usage(void) |
2763 | { | 2876 | { |
2764 | fprintf(stderr, | 2877 | fprintf(stderr, |
@@ -2783,9 +2896,8 @@ usage(void) | |||
2783 | " ssh-keygen -R hostname [-f known_hosts_file]\n" | 2896 | " ssh-keygen -R hostname [-f known_hosts_file]\n" |
2784 | " ssh-keygen -r hostname [-g] [-f input_keyfile]\n" | 2897 | " ssh-keygen -r hostname [-g] [-f input_keyfile]\n" |
2785 | #ifdef WITH_OPENSSL | 2898 | #ifdef WITH_OPENSSL |
2786 | " ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n" | 2899 | " ssh-keygen -M generate [-O option] output\n" |
2787 | " ssh-keygen -f input_file -T output_file [-v] [-a rounds] [-J num_lines]\n" | 2900 | " ssh-keygen -M screen [-f input_file] [-O option] [-a rounds] output_file\n" |
2788 | " [-j start_line] [-K checkpt] [-W generator]\n" | ||
2789 | #endif | 2901 | #endif |
2790 | " ssh-keygen -I certificate_identity -s ca_key [-hU] [-D pkcs11_provider]\n" | 2902 | " ssh-keygen -I certificate_identity -s ca_key [-hU] [-D pkcs11_provider]\n" |
2791 | " [-n principals] [-O option] [-V validity_interval]\n" | 2903 | " [-n principals] [-O option] [-V validity_interval]\n" |
@@ -2819,6 +2931,7 @@ main(int argc, char **argv) | |||
2819 | int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; | 2931 | int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; |
2820 | int prefer_agent = 0, convert_to = 0, convert_from = 0; | 2932 | int prefer_agent = 0, convert_to = 0, convert_from = 0; |
2821 | int print_public = 0, print_generic = 0, cert_serial_autoinc = 0; | 2933 | int print_public = 0, print_generic = 0, cert_serial_autoinc = 0; |
2934 | int do_gen_candidates = 0, do_screen_candidates = 0; | ||
2822 | unsigned long long ull, cert_serial = 0; | 2935 | unsigned long long ull, cert_serial = 0; |
2823 | char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL; | 2936 | char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL; |
2824 | size_t i, nopts = 0; | 2937 | size_t i, nopts = 0; |
@@ -2828,14 +2941,6 @@ main(int argc, char **argv) | |||
2828 | const char *errstr; | 2941 | const char *errstr; |
2829 | int log_level = SYSLOG_LEVEL_INFO; | 2942 | int log_level = SYSLOG_LEVEL_INFO; |
2830 | char *sign_op = NULL; | 2943 | char *sign_op = NULL; |
2831 | #ifdef WITH_OPENSSL | ||
2832 | /* Moduli generation/screening */ | ||
2833 | char out_file[PATH_MAX], *checkpoint = NULL; | ||
2834 | u_int32_t memory = 0, generator_wanted = 0; | ||
2835 | int do_gen_candidates = 0, do_screen_candidates = 0; | ||
2836 | unsigned long start_lineno = 0, lines_to_process = 0; | ||
2837 | BIGNUM *start = NULL; | ||
2838 | #endif | ||
2839 | 2944 | ||
2840 | extern int optind; | 2945 | extern int optind; |
2841 | extern char *optarg; | 2946 | extern char *optarg; |
@@ -2860,10 +2965,10 @@ main(int argc, char **argv) | |||
2860 | 2965 | ||
2861 | sk_provider = getenv("SSH_SK_PROVIDER"); | 2966 | sk_provider = getenv("SSH_SK_PROVIDER"); |
2862 | 2967 | ||
2863 | /* Remaining character: d */ | 2968 | /* Remaining characters: dGjJKSTW */ |
2864 | while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvy" | 2969 | while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvy" |
2865 | "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Y:Z:" | 2970 | "C:D:E:F:I:M:N:O:P:R:V:Y:Z:" |
2866 | "a:b:f:g:j:m:n:r:s:t:w:x:z:")) != -1) { | 2971 | "a:b:f:g:m:n:r:s:t:w:x:z:")) != -1) { |
2867 | switch (opt) { | 2972 | switch (opt) { |
2868 | case 'A': | 2973 | case 'A': |
2869 | gen_all_hostkeys = 1; | 2974 | gen_all_hostkeys = 1; |
@@ -3053,50 +3158,14 @@ main(int argc, char **argv) | |||
3053 | (errno == ERANGE && cert_serial == ULLONG_MAX)) | 3158 | (errno == ERANGE && cert_serial == ULLONG_MAX)) |
3054 | fatal("Invalid serial number \"%s\"", optarg); | 3159 | fatal("Invalid serial number \"%s\"", optarg); |
3055 | break; | 3160 | break; |
3056 | #ifdef WITH_OPENSSL | ||
3057 | /* Moduli generation/screening */ | ||
3058 | case 'G': | ||
3059 | do_gen_candidates = 1; | ||
3060 | if (strlcpy(out_file, optarg, sizeof(out_file)) >= | ||
3061 | sizeof(out_file)) | ||
3062 | fatal("Output filename too long"); | ||
3063 | break; | ||
3064 | case 'J': | ||
3065 | lines_to_process = strtoul(optarg, NULL, 10); | ||
3066 | break; | ||
3067 | case 'j': | ||
3068 | start_lineno = strtoul(optarg, NULL, 10); | ||
3069 | break; | ||
3070 | case 'K': | ||
3071 | if (strlen(optarg) >= PATH_MAX) | ||
3072 | fatal("Checkpoint filename too long"); | ||
3073 | checkpoint = xstrdup(optarg); | ||
3074 | break; | ||
3075 | case 'M': | 3161 | case 'M': |
3076 | memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, | 3162 | if (strcmp(optarg, "generate") == 0) |
3077 | &errstr); | 3163 | do_gen_candidates = 1; |
3078 | if (errstr) | 3164 | else if (strcmp(optarg, "screen") == 0) |
3079 | fatal("Memory limit is %s: %s", errstr, optarg); | 3165 | do_screen_candidates = 1; |
3080 | break; | 3166 | else |
3081 | case 'S': | 3167 | fatal("Unsupported moduli option %s", optarg); |
3082 | /* XXX - also compare length against bits */ | ||
3083 | if (BN_hex2bn(&start, optarg) == 0) | ||
3084 | fatal("Invalid start point."); | ||
3085 | break; | ||
3086 | case 'T': | ||
3087 | do_screen_candidates = 1; | ||
3088 | if (strlcpy(out_file, optarg, sizeof(out_file)) >= | ||
3089 | sizeof(out_file)) | ||
3090 | fatal("Output filename too long"); | ||
3091 | break; | ||
3092 | case 'W': | ||
3093 | generator_wanted = (u_int32_t)strtonum(optarg, 1, | ||
3094 | UINT_MAX, &errstr); | ||
3095 | if (errstr != NULL) | ||
3096 | fatal("Desired generator invalid: %s (%s)", | ||
3097 | optarg, errstr); | ||
3098 | break; | 3168 | break; |
3099 | #endif /* WITH_OPENSSL */ | ||
3100 | case '?': | 3169 | case '?': |
3101 | default: | 3170 | default: |
3102 | usage(); | 3171 | usage(); |
@@ -3163,7 +3232,8 @@ main(int argc, char **argv) | |||
3163 | error("Too few arguments."); | 3232 | error("Too few arguments."); |
3164 | usage(); | 3233 | usage(); |
3165 | } | 3234 | } |
3166 | } else if (argc > 0 && !gen_krl && !check_krl) { | 3235 | } else if (argc > 0 && !gen_krl && !check_krl && |
3236 | !do_gen_candidates && !do_screen_candidates) { | ||
3167 | error("Too many arguments."); | 3237 | error("Too many arguments."); |
3168 | usage(); | 3238 | usage(); |
3169 | } | 3239 | } |
@@ -3176,13 +3246,21 @@ main(int argc, char **argv) | |||
3176 | usage(); | 3246 | usage(); |
3177 | } | 3247 | } |
3178 | if (gen_krl) { | 3248 | if (gen_krl) { |
3249 | #ifdef WITH_OPENSSL | ||
3179 | do_gen_krl(pw, update_krl, ca_key_path, | 3250 | do_gen_krl(pw, update_krl, ca_key_path, |
3180 | cert_serial, identity_comment, argc, argv); | 3251 | cert_serial, identity_comment, argc, argv); |
3181 | return (0); | 3252 | return (0); |
3253 | #else | ||
3254 | fatal("KRL generation not supported"); | ||
3255 | #endif | ||
3182 | } | 3256 | } |
3183 | if (check_krl) { | 3257 | if (check_krl) { |
3258 | #ifdef WITH_OPENSSL | ||
3184 | do_check_krl(pw, argc, argv); | 3259 | do_check_krl(pw, argc, argv); |
3185 | return (0); | 3260 | return (0); |
3261 | #else | ||
3262 | fatal("KRL checking not supported"); | ||
3263 | #endif | ||
3186 | } | 3264 | } |
3187 | if (ca_key_path != NULL) { | 3265 | if (ca_key_path != NULL) { |
3188 | if (cert_key_id == NULL) | 3266 | if (cert_key_id == NULL) |
@@ -3249,47 +3327,20 @@ main(int argc, char **argv) | |||
3249 | } | 3327 | } |
3250 | } | 3328 | } |
3251 | 3329 | ||
3252 | #ifdef WITH_OPENSSL | 3330 | if (do_gen_candidates || do_screen_candidates) { |
3331 | if (argc <= 0) | ||
3332 | fatal("No output file specified"); | ||
3333 | else if (argc > 1) | ||
3334 | fatal("Too many output files specified"); | ||
3335 | } | ||
3253 | if (do_gen_candidates) { | 3336 | if (do_gen_candidates) { |
3254 | FILE *out = fopen(out_file, "w"); | 3337 | do_moduli_gen(argv[0], opts, nopts); |
3255 | 3338 | return 0; | |
3256 | if (out == NULL) { | ||
3257 | error("Couldn't open modulus candidate file \"%s\": %s", | ||
3258 | out_file, strerror(errno)); | ||
3259 | return (1); | ||
3260 | } | ||
3261 | if (bits == 0) | ||
3262 | bits = DEFAULT_BITS; | ||
3263 | if (gen_candidates(out, memory, bits, start) != 0) | ||
3264 | fatal("modulus candidate generation failed"); | ||
3265 | |||
3266 | return (0); | ||
3267 | } | 3339 | } |
3268 | |||
3269 | if (do_screen_candidates) { | 3340 | if (do_screen_candidates) { |
3270 | FILE *in; | 3341 | do_moduli_screen(argv[0], opts, nopts); |
3271 | FILE *out = fopen(out_file, "a"); | 3342 | return 0; |
3272 | |||
3273 | if (have_identity && strcmp(identity_file, "-") != 0) { | ||
3274 | if ((in = fopen(identity_file, "r")) == NULL) { | ||
3275 | fatal("Couldn't open modulus candidate " | ||
3276 | "file \"%s\": %s", identity_file, | ||
3277 | strerror(errno)); | ||
3278 | } | ||
3279 | } else | ||
3280 | in = stdin; | ||
3281 | |||
3282 | if (out == NULL) { | ||
3283 | fatal("Couldn't open moduli file \"%s\": %s", | ||
3284 | out_file, strerror(errno)); | ||
3285 | } | ||
3286 | if (prime_test(in, out, rounds == 0 ? 100 : rounds, | ||
3287 | generator_wanted, checkpoint, | ||
3288 | start_lineno, lines_to_process) != 0) | ||
3289 | fatal("modulus screening failed"); | ||
3290 | return (0); | ||
3291 | } | 3343 | } |
3292 | #endif | ||
3293 | 3344 | ||
3294 | if (gen_all_hostkeys) { | 3345 | if (gen_all_hostkeys) { |
3295 | do_gen_all_hostkeys(pw); | 3346 | do_gen_all_hostkeys(pw); |