summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c158
1 files changed, 81 insertions, 77 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 21b61b44b..596da76fb 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -14,7 +14,7 @@ Identity and host key generation and maintenance.
14*/ 14*/
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: ssh-keygen.c,v 1.6 1999/11/20 06:02:56 damien Exp $"); 17RCSID("$Id: ssh-keygen.c,v 1.7 1999/11/21 07:31:57 damien Exp $");
18 18
19#include "rsa.h" 19#include "rsa.h"
20#include "ssh.h" 20#include "ssh.h"
@@ -50,8 +50,9 @@ int quiet = 0;
50/* Flag indicating that we just want to see the key fingerprint */ 50/* Flag indicating that we just want to see the key fingerprint */
51int print_fingerprint = 0; 51int print_fingerprint = 0;
52 52
53/* This is set to the identity file name if given on the command line. */ 53/* The identity file name, given on the command line or entered by the user. */
54char *identity_file = NULL; 54char identity_file[1024];
55int have_identity = 0;
55 56
56/* This is set to the passphrase if given on the command line. */ 57/* This is set to the passphrase if given on the command line. */
57char *identity_passphrase = NULL; 58char *identity_passphrase = NULL;
@@ -62,51 +63,46 @@ char *identity_new_passphrase = NULL;
62/* This is set to the new comment if given on the command line. */ 63/* This is set to the new comment if given on the command line. */
63char *identity_comment = NULL; 64char *identity_comment = NULL;
64 65
65/* Perform changing a passphrase. The argument is the passwd structure 66/* argv0 */
66 for the current user. */ 67extern char *__progname;
67 68
68char * 69void
69get_filename(struct passwd *pw, const char *prompt) 70ask_filename(struct passwd *pw, const char *prompt)
70{ 71{
71 char buf[1024], default_file[1024]; 72 char buf[1024];
72 73 snprintf(identity_file, sizeof(identity_file), "%s/%s",
73 /* Read key file name. */ 74 pw->pw_dir, SSH_CLIENT_IDENTITY);
74 if (identity_file != NULL) { 75 printf("%s (%s): ", prompt, identity_file);
75 return xstrdup(identity_file); 76 fflush(stdout);
76 } else { 77 if (fgets(buf, sizeof(buf), stdin) == NULL)
77 snprintf(default_file, sizeof default_file, "%s/%s", 78 exit(1);
78 pw->pw_dir, SSH_CLIENT_IDENTITY); 79 if (strchr(buf, '\n'))
79 printf("%s (%s): ", prompt, default_file); 80 *strchr(buf, '\n') = 0;
80 fflush(stdout); 81 if (strcmp(buf, "") != 0)
81 if (fgets(buf, sizeof(buf), stdin) == NULL) 82 strlcpy(identity_file, buf, sizeof(identity_file));
82 exit(1); 83 have_identity = 1;
83 if (strchr(buf, '\n'))
84 *strchr(buf, '\n') = 0;
85 if (strcmp(buf, "") == 0)
86 return xstrdup(default_file);
87 }
88 return xstrdup(buf);
89} 84}
90 85
91void 86void
92do_fingerprint(struct passwd *pw) 87do_fingerprint(struct passwd *pw)
93{ 88{
94 char *file, *comment; 89 char *comment;
95 RSA *public_key; 90 RSA *public_key;
96 struct stat st; 91 struct stat st;
97 92
98 file = get_filename(pw, "Enter file in which the key is"); 93 if (!have_identity)
99 if (stat(file, &st) < 0) 94 ask_filename(pw, "Enter file in which the key is");
95 if (stat(identity_file, &st) < 0)
100 { 96 {
101 perror(file); 97 perror(identity_file);
102 exit(1); 98 exit(1);
103 } 99 }
104 public_key = RSA_new(); 100 public_key = RSA_new();
105 if (!load_public_key(file, public_key, &comment)) { 101 if (!load_public_key(identity_file, public_key, &comment)) {
106 char *cp, line[1024]; 102 char *cp, line[1024];
107 BIGNUM *e, *n; 103 BIGNUM *e, *n;
108 int dummy, invalid = 0; 104 int dummy, invalid = 0;
109 FILE *f = fopen(file, "r"); 105 FILE *f = fopen(identity_file, "r");
110 n = BN_new(); 106 n = BN_new();
111 e = BN_new(); 107 e = BN_new();
112 if (f && fgets(line, sizeof(line), f)) { 108 if (f && fgets(line, sizeof(line), f)) {
@@ -123,7 +119,7 @@ do_fingerprint(struct passwd *pw)
123 invalid = 1; 119 invalid = 1;
124 } 120 }
125 if (invalid) { 121 if (invalid) {
126 printf("%s is not a valid key file.\n", file); 122 printf("%s is not a valid key file.\n", identity_file);
127 BN_free(e); 123 BN_free(e);
128 BN_free(n); 124 BN_free(n);
129 exit(1); 125 exit(1);
@@ -137,29 +133,32 @@ do_fingerprint(struct passwd *pw)
137 exit(0); 133 exit(0);
138} 134}
139 135
136/* Perform changing a passphrase. The argument is the passwd structure
137 for the current user. */
140 138
141void 139void
142do_change_passphrase(struct passwd *pw) 140do_change_passphrase(struct passwd *pw)
143{ 141{
144 char *file, *comment; 142 char *comment;
145 char *old_passphrase, *passphrase1, *passphrase2; 143 char *old_passphrase, *passphrase1, *passphrase2;
146 struct stat st; 144 struct stat st;
147 RSA *private_key; 145 RSA *private_key;
148 146
149 file = get_filename(pw, "Enter file in which the key is"); 147 if (!have_identity)
148 ask_filename(pw, "Enter file in which the key is");
150 /* Check if the file exists. */ 149 /* Check if the file exists. */
151 if (stat(file, &st) < 0) 150 if (stat(identity_file, &st) < 0)
152 { 151 {
153 perror(file); 152 perror(identity_file);
154 exit(1); 153 exit(1);
155 } 154 }
156 155
157 /* Try to load the public key from the file the verify that it is 156 /* Try to load the public key from the file the verify that it is
158 readable and of the proper format. */ 157 readable and of the proper format. */
159 public_key = RSA_new(); 158 public_key = RSA_new();
160 if (!load_public_key(file, public_key, NULL)) 159 if (!load_public_key(identity_file, public_key, NULL))
161 { 160 {
162 printf("%s is not a valid key file.\n", file); 161 printf("%s is not a valid key file.\n", identity_file);
163 exit(1); 162 exit(1);
164 } 163 }
165 /* Clear the public key since we are just about to load the whole file. */ 164 /* Clear the public key since we are just about to load the whole file. */
@@ -167,14 +166,14 @@ do_change_passphrase(struct passwd *pw)
167 166
168 /* Try to load the file with empty passphrase. */ 167 /* Try to load the file with empty passphrase. */
169 private_key = RSA_new(); 168 private_key = RSA_new();
170 if (!load_private_key(file, "", private_key, &comment)) { 169 if (!load_private_key(identity_file, "", private_key, &comment)) {
171 /* Read passphrase from the user. */ 170 /* Read passphrase from the user. */
172 if (identity_passphrase) 171 if (identity_passphrase)
173 old_passphrase = xstrdup(identity_passphrase); 172 old_passphrase = xstrdup(identity_passphrase);
174 else 173 else
175 old_passphrase = read_passphrase("Enter old passphrase: ", 1); 174 old_passphrase = read_passphrase("Enter old passphrase: ", 1);
176 /* Try to load using the passphrase. */ 175 /* Try to load using the passphrase. */
177 if (!load_private_key(file, old_passphrase, private_key, &comment)) 176 if (!load_private_key(identity_file, old_passphrase, private_key, &comment))
178 { 177 {
179 memset(old_passphrase, 0, strlen(old_passphrase)); 178 memset(old_passphrase, 0, strlen(old_passphrase));
180 xfree(old_passphrase); 179 xfree(old_passphrase);
@@ -215,10 +214,10 @@ do_change_passphrase(struct passwd *pw)
215 } 214 }
216 215
217 /* Save the file using the new passphrase. */ 216 /* Save the file using the new passphrase. */
218 if (!save_private_key(file, passphrase1, private_key, comment)) 217 if (!save_private_key(identity_file, passphrase1, private_key, comment))
219 { 218 {
220 printf("Saving the key failed: %s: %s.\n", 219 printf("Saving the key failed: %s: %s.\n",
221 file, strerror(errno)); 220 identity_file, strerror(errno));
222 memset(passphrase1, 0, strlen(passphrase1)); 221 memset(passphrase1, 0, strlen(passphrase1));
223 xfree(passphrase1); 222 xfree(passphrase1);
224 RSA_free(private_key); 223 RSA_free(private_key);
@@ -240,33 +239,34 @@ do_change_passphrase(struct passwd *pw)
240void 239void
241do_change_comment(struct passwd *pw) 240do_change_comment(struct passwd *pw)
242{ 241{
243 char new_comment[1024], *file, *comment; 242 char new_comment[1024], *comment;
244 RSA *private_key; 243 RSA *private_key;
245 char *passphrase; 244 char *passphrase;
246 struct stat st; 245 struct stat st;
247 FILE *f; 246 FILE *f;
248 char *tmpbuf; 247 char *tmpbuf;
249 248
250 file = get_filename(pw, "Enter file in which the key is"); 249 if (!have_identity)
250 ask_filename(pw, "Enter file in which the key is");
251 /* Check if the file exists. */ 251 /* Check if the file exists. */
252 if (stat(file, &st) < 0) 252 if (stat(identity_file, &st) < 0)
253 { 253 {
254 perror(file); 254 perror(identity_file);
255 exit(1); 255 exit(1);
256 } 256 }
257 257
258 /* Try to load the public key from the file the verify that it is 258 /* Try to load the public key from the file the verify that it is
259 readable and of the proper format. */ 259 readable and of the proper format. */
260 public_key = RSA_new(); 260 public_key = RSA_new();
261 if (!load_public_key(file, public_key, NULL)) 261 if (!load_public_key(identity_file, public_key, NULL))
262 { 262 {
263 printf("%s is not a valid key file.\n", file); 263 printf("%s is not a valid key file.\n", identity_file);
264 exit(1); 264 exit(1);
265 } 265 }
266 266
267 private_key = RSA_new(); 267 private_key = RSA_new();
268 /* Try to load the file with empty passphrase. */ 268 /* Try to load the file with empty passphrase. */
269 if (load_private_key(file, "", private_key, &comment)) 269 if (load_private_key(identity_file, "", private_key, &comment))
270 passphrase = xstrdup(""); 270 passphrase = xstrdup("");
271 else 271 else
272 { 272 {
@@ -279,7 +279,7 @@ do_change_comment(struct passwd *pw)
279 else 279 else
280 passphrase = read_passphrase("Enter passphrase: ", 1); 280 passphrase = read_passphrase("Enter passphrase: ", 1);
281 /* Try to load using the passphrase. */ 281 /* Try to load using the passphrase. */
282 if (!load_private_key(file, passphrase, private_key, &comment)) 282 if (!load_private_key(identity_file, passphrase, private_key, &comment))
283 { 283 {
284 memset(passphrase, 0, strlen(passphrase)); 284 memset(passphrase, 0, strlen(passphrase));
285 xfree(passphrase); 285 xfree(passphrase);
@@ -310,10 +310,10 @@ do_change_comment(struct passwd *pw)
310 } 310 }
311 311
312 /* Save the file using the new passphrase. */ 312 /* Save the file using the new passphrase. */
313 if (!save_private_key(file, passphrase, private_key, new_comment)) 313 if (!save_private_key(identity_file, passphrase, private_key, new_comment))
314 { 314 {
315 printf("Saving the key failed: %s: %s.\n", 315 printf("Saving the key failed: %s: %s.\n",
316 file, strerror(errno)); 316 identity_file, strerror(errno));
317 memset(passphrase, 0, strlen(passphrase)); 317 memset(passphrase, 0, strlen(passphrase));
318 xfree(passphrase); 318 xfree(passphrase);
319 RSA_free(private_key); 319 RSA_free(private_key);
@@ -328,11 +328,11 @@ do_change_comment(struct passwd *pw)
328 328
329 /* Save the public key in text format in a file with the same name but 329 /* Save the public key in text format in a file with the same name but
330 .pub appended. */ 330 .pub appended. */
331 strcat(file, ".pub"); 331 strlcat(identity_file, ".pub", sizeof(identity_file));
332 f = fopen(file, "w"); 332 f = fopen(identity_file, "w");
333 if (!f) 333 if (!f)
334 { 334 {
335 printf("Could not save your public key in %s\n", file); 335 printf("Could not save your public key in %s\n", identity_file);
336 exit(1); 336 exit(1);
337 } 337 }
338 fprintf(f, "%d ", BN_num_bits(public_key->n)); 338 fprintf(f, "%d ", BN_num_bits(public_key->n));
@@ -350,6 +350,14 @@ do_change_comment(struct passwd *pw)
350 exit(0); 350 exit(0);
351} 351}
352 352
353void
354usage(void)
355{
356 printf("ssh-keygen version %s\n", SSH_VERSION);
357 printf("Usage: %s [-b bits] [-p] [-c] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname);
358 exit(1);
359}
360
353/* Main program for key management. */ 361/* Main program for key management. */
354 362
355int 363int
@@ -357,7 +365,7 @@ main(int ac, char **av)
357{ 365{
358 char buf[16384], buf2[1024], *passphrase1, *passphrase2; 366 char buf[16384], buf2[1024], *passphrase1, *passphrase2;
359 struct passwd *pw; 367 struct passwd *pw;
360 char *file, *tmpbuf; 368 char *tmpbuf;
361 int opt; 369 int opt;
362 struct stat st; 370 struct stat st;
363 FILE *f; 371 FILE *f;
@@ -416,7 +424,8 @@ main(int ac, char **av)
416 break; 424 break;
417 425
418 case 'f': 426 case 'f':
419 identity_file = optarg; 427 strlcpy(identity_file, optarg, sizeof(identity_file));
428 have_identity = 1;
420 break; 429 break;
421 430
422 case 'P': 431 case 'P':
@@ -437,20 +446,18 @@ main(int ac, char **av)
437 446
438 case '?': 447 case '?':
439 default: 448 default:
440 printf("ssh-keygen version %s\n", SSH_VERSION); 449 usage();
441 printf("Usage: %s [-b bits] [-p] [-c] [-f file] [-P pass] [-N new-pass] [-C comment]\n", av[0]);
442 exit(1);
443 } 450 }
444 } 451 }
445 if (optind < ac) 452 if (optind < ac)
446 { 453 {
447 printf("Too many arguments.\n"); 454 printf("Too many arguments.\n");
448 exit(1); 455 usage();
449 } 456 }
450 if (change_passphrase && change_comment) 457 if (change_passphrase && change_comment)
451 { 458 {
452 printf("Can only have one of -p and -c.\n"); 459 printf("Can only have one of -p and -c.\n");
453 exit(1); 460 usage();
454 } 461 }
455 462
456 if (print_fingerprint) 463 if (print_fingerprint)
@@ -476,14 +483,13 @@ main(int ac, char **av)
476 public_key = RSA_new(); 483 public_key = RSA_new();
477 rsa_generate_key(private_key, public_key, bits); 484 rsa_generate_key(private_key, public_key, bits);
478 485
479 ask_file_again: 486 if (!have_identity)
480 487 ask_filename(pw, "Enter file in which to save the key");
481 file = get_filename(pw, "Enter file in which to save the key");
482 488
483 /* If the file aready exists, ask the user to confirm. */ 489 /* If the file aready exists, ask the user to confirm. */
484 if (stat(file, &st) >= 0) 490 if (stat(identity_file, &st) >= 0)
485 { 491 {
486 printf("%s already exists.\n", file); 492 printf("%s already exists.\n", identity_file);
487 printf("Overwrite (y/n)? "); 493 printf("Overwrite (y/n)? ");
488 fflush(stdout); 494 fflush(stdout);
489 if (fgets(buf2, sizeof(buf2), stdin) == NULL) 495 if (fgets(buf2, sizeof(buf2), stdin) == NULL)
@@ -536,14 +542,13 @@ main(int ac, char **av)
536 } 542 }
537 543
538 /* Save the key with the given passphrase and comment. */ 544 /* Save the key with the given passphrase and comment. */
539 if (!save_private_key(file, passphrase1, private_key, buf2)) 545 if (!save_private_key(identity_file, passphrase1, private_key, buf2))
540 { 546 {
541 printf("Saving the key failed: %s: %s.\n", 547 printf("Saving the key failed: %s: %s.\n",
542 file, strerror(errno)); 548 identity_file, strerror(errno));
543 memset(passphrase1, 0, strlen(passphrase1)); 549 memset(passphrase1, 0, strlen(passphrase1));
544 xfree(passphrase1); 550 xfree(passphrase1);
545 xfree(file); 551 exit(1);
546 goto ask_file_again;
547 } 552 }
548 /* Clear the passphrase. */ 553 /* Clear the passphrase. */
549 memset(passphrase1, 0, strlen(passphrase1)); 554 memset(passphrase1, 0, strlen(passphrase1));
@@ -554,7 +559,7 @@ main(int ac, char **av)
554 arc4random_stir(); 559 arc4random_stir();
555 560
556 if (!quiet) 561 if (!quiet)
557 printf("Your identification has been saved in %s.\n", file); 562 printf("Your identification has been saved in %s.\n", identity_file);
558 563
559 /* Display the public key on the screen. */ 564 /* Display the public key on the screen. */
560 if (!quiet) { 565 if (!quiet) {
@@ -570,12 +575,11 @@ main(int ac, char **av)
570 575
571 /* Save the public key in text format in a file with the same name but 576 /* Save the public key in text format in a file with the same name but
572 .pub appended. */ 577 .pub appended. */
573 file = xrealloc(file, strlen(file) + 5); 578 strlcat(identity_file, ".pub", sizeof(identity_file));
574 strcat(file, ".pub"); 579 f = fopen(identity_file, "w");
575 f = fopen(file, "w");
576 if (!f) 580 if (!f)
577 { 581 {
578 printf("Could not save your public key in %s\n", file); 582 printf("Could not save your public key in %s\n", identity_file);
579 exit(1); 583 exit(1);
580 } 584 }
581 fprintf(f, "%d ", BN_num_bits(public_key->n)); 585 fprintf(f, "%d ", BN_num_bits(public_key->n));
@@ -588,7 +592,7 @@ main(int ac, char **av)
588 fclose(f); 592 fclose(f);
589 593
590 if (!quiet) 594 if (!quiet)
591 printf("Your public key has been saved in %s\n", file); 595 printf("Your public key has been saved in %s\n", identity_file);
592 596
593 exit(0); 597 exit(0);
594} 598}