]> andersk Git - openssh.git/blame - ssh-keygen.c
- Merge big update to OpenSSH-2.0 from OpenBSD CVS
[openssh.git] / ssh-keygen.c
CommitLineData
8efc0c15 1/*
5260325f 2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5 * Created: Mon Mar 27 02:26:40 1995 ylo
6 * Identity and host key generation and maintenance.
7 */
8efc0c15 8
9#include "includes.h"
10RCSID("$Id$");
11
a306f2dd 12#include <openssl/evp.h>
13#include <openssl/pem.h>
14#include <openssl/rsa.h>
15#include <openssl/dsa.h>
16
8efc0c15 17#include "ssh.h"
18#include "xmalloc.h"
f095fcc7 19#include "fingerprint.h"
a306f2dd 20#include "key.h"
21#include "rsa.h"
22#include "dsa.h"
23#include "authfile.h"
24#include "uuencode.h"
8efc0c15 25
a306f2dd 26/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */
8efc0c15 27int bits = 1024;
28
aa3378df 29/*
30 * Flag indicating that we just want to change the passphrase. This can be
31 * set on the command line.
32 */
8efc0c15 33int change_passphrase = 0;
34
aa3378df 35/*
36 * Flag indicating that we just want to change the comment. This can be set
37 * on the command line.
38 */
8efc0c15 39int change_comment = 0;
40
41int quiet = 0;
42
f095fcc7 43/* Flag indicating that we just want to see the key fingerprint */
44int print_fingerprint = 0;
45
5ad13cd7 46/* The identity file name, given on the command line or entered by the user. */
47char identity_file[1024];
48int have_identity = 0;
8efc0c15 49
50/* This is set to the passphrase if given on the command line. */
51char *identity_passphrase = NULL;
52
53/* This is set to the new passphrase if given on the command line. */
54char *identity_new_passphrase = NULL;
55
56/* This is set to the new comment if given on the command line. */
57char *identity_comment = NULL;
58
a306f2dd 59/* Dump public key file in format used by real and the original SSH 2 */
60int convert_to_ssh2 = 0;
61int convert_from_ssh2 = 0;
62int print_public = 0;
63int dsa_mode = 0;
64
5ad13cd7 65/* argv0 */
5260325f 66#ifdef HAVE___PROGNAME
5ad13cd7 67extern char *__progname;
5260325f 68#else /* HAVE___PROGNAME */
69const char *__progname = "ssh-keygen";
70#endif /* HAVE___PROGNAME */
8efc0c15 71
a306f2dd 72char hostname[MAXHOSTNAMELEN];
73
5ad13cd7 74void
75ask_filename(struct passwd *pw, const char *prompt)
8efc0c15 76{
5260325f 77 char buf[1024];
78 snprintf(identity_file, sizeof(identity_file), "%s/%s",
79 pw->pw_dir, SSH_CLIENT_IDENTITY);
80 printf("%s (%s): ", prompt, identity_file);
81 fflush(stdout);
82 if (fgets(buf, sizeof(buf), stdin) == NULL)
83 exit(1);
84 if (strchr(buf, '\n'))
85 *strchr(buf, '\n') = 0;
86 if (strcmp(buf, "") != 0)
87 strlcpy(identity_file, buf, sizeof(identity_file));
88 have_identity = 1;
f095fcc7 89}
8efc0c15 90
a306f2dd 91int
92try_load_key(char *filename, Key *k)
93{
94 int success = 1;
95 if (!load_private_key(filename, "", k, NULL)) {
96 char *pass = read_passphrase("Enter passphrase: ", 1);
97 if (!load_private_key(filename, pass, k, NULL)) {
98 success = 0;
99 }
100 memset(pass, 0, strlen(pass));
101 xfree(pass);
102 }
103 return success;
104}
105
106#define SSH_COM_MAGIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----"
107#define SSH_COM_MAGIC_END "---- END SSH2 PUBLIC KEY ----"
108
109void
110do_convert_to_ssh2(struct passwd *pw)
111{
112 Key *k;
113 int len;
114 unsigned char *blob;
115 struct stat st;
116
117 if (!have_identity)
118 ask_filename(pw, "Enter file in which the key is");
119 if (stat(identity_file, &st) < 0) {
120 perror(identity_file);
121 exit(1);
122 }
123 k = key_new(KEY_DSA);
124 if (!try_load_key(identity_file, k)) {
125 fprintf(stderr, "load failed\n");
126 exit(1);
127 }
128 dsa_make_key_blob(k, &blob, &len);
129 fprintf(stdout, SSH_COM_MAGIC_BEGIN "\n");
130 fprintf(stdout,
131 "Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n",
132 BN_num_bits(k->dsa->p),
133 pw->pw_name, hostname);
134 dump_base64(stdout, blob, len);
135 fprintf(stdout, SSH_COM_MAGIC_END "\n");
136 key_free(k);
137 xfree(blob);
138 exit(0);
139}
140
141void
142do_convert_from_ssh2(struct passwd *pw)
143{
144 Key *k;
145 int blen;
146 char line[1024], *p;
147 char blob[8096];
148 char encoded[8096];
149 struct stat st;
150 FILE *fp;
151
152 if (!have_identity)
153 ask_filename(pw, "Enter file in which the key is");
154 if (stat(identity_file, &st) < 0) {
155 perror(identity_file);
156 exit(1);
157 }
158 fp = fopen(identity_file, "r");
159 if (fp == NULL) {
160 perror(identity_file);
161 exit(1);
162 }
163 encoded[0] = '\0';
164 while (fgets(line, sizeof(line), fp)) {
165 if (strncmp(line, "----", 4) == 0 ||
166 strstr(line, ": ") != NULL) {
167 fprintf(stderr, "ignore: %s", line);
168 continue;
169 }
170 if (!(p = strchr(line, '\n'))) {
171 fprintf(stderr, "input line too long.\n");
172 exit(1);
173 }
174 *p = '\0';
175 strlcat(encoded, line, sizeof(encoded));
176 }
177 blen = uudecode(encoded, (unsigned char *)blob, sizeof(blob));
178 if (blen < 0) {
179 fprintf(stderr, "uudecode failed.\n");
180 exit(1);
181 }
182 k = dsa_key_from_blob(blob, blen);
183 if (!key_write(k, stdout))
184 fprintf(stderr, "key_write failed");
185 key_free(k);
186 fprintf(stdout, "\n");
187 fclose(fp);
188 exit(0);
189}
190
191void
192do_print_public(struct passwd *pw)
193{
194 Key *k;
195 int len;
196 unsigned char *blob;
197 struct stat st;
198
199 if (!have_identity)
200 ask_filename(pw, "Enter file in which the key is");
201 if (stat(identity_file, &st) < 0) {
202 perror(identity_file);
203 exit(1);
204 }
205 k = key_new(KEY_DSA);
206 if (!try_load_key(identity_file, k)) {
207 fprintf(stderr, "load failed\n");
208 exit(1);
209 }
210 dsa_make_key_blob(k, &blob, &len);
211 if (!key_write(k, stdout))
212 fprintf(stderr, "key_write failed");
213 key_free(k);
214 xfree(blob);
215 fprintf(stdout, "\n");
216 exit(0);
217}
218
f095fcc7 219void
220do_fingerprint(struct passwd *pw)
221{
c8d54615 222 FILE *f;
223 BIGNUM *e, *n;
a306f2dd 224 Key *public;
c8d54615 225 char *comment = NULL, *cp, *ep, line[16*1024];
226 int i, skip = 0, num = 1, invalid = 1;
610cd5c6 227 unsigned int ignore;
5260325f 228 struct stat st;
229
230 if (!have_identity)
231 ask_filename(pw, "Enter file in which the key is");
232 if (stat(identity_file, &st) < 0) {
233 perror(identity_file);
234 exit(1);
235 }
a306f2dd 236 public = key_new(KEY_RSA);
237 if (load_public_key(identity_file, public, &comment)) {
238 printf("%d %s %s\n", BN_num_bits(public->rsa->n),
239 key_fingerprint(public), comment);
240 key_free(public);
c8d54615 241 exit(0);
242 }
a306f2dd 243 key_free(public);
c8d54615 244
a306f2dd 245 /* XXX */
c8d54615 246 f = fopen(identity_file, "r");
247 if (f != NULL) {
5260325f 248 n = BN_new();
249 e = BN_new();
c8d54615 250 while (fgets(line, sizeof(line), f)) {
251 i = strlen(line) - 1;
252 if (line[i] != '\n') {
253 error("line %d too long: %.40s...", num, line);
254 skip = 1;
255 continue;
256 }
257 num++;
258 if (skip) {
259 skip = 0;
260 continue;
261 }
262 line[i] = '\0';
263
264 /* Skip leading whitespace, empty and comment lines. */
265 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
266 ;
267 if (!*cp || *cp == '\n' || *cp == '#')
268 continue ;
269 i = strtol(cp, &ep, 10);
270 if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
271 int quoted = 0;
272 comment = cp;
273 for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
274 if (*cp == '\\' && cp[1] == '"')
275 cp++; /* Skip both */
276 else if (*cp == '"')
277 quoted = !quoted;
278 }
279 if (!*cp)
280 continue;
281 *cp++ = '\0';
282 }
283 ep = cp;
610cd5c6 284 if (auth_rsa_read_key(&cp, &ignore, e, n)) {
c8d54615 285 invalid = 0;
286 comment = *cp ? cp : comment;
287 printf("%d %s %s\n", BN_num_bits(n),
288 fingerprint(e, n),
289 comment ? comment : "no comment");
5260325f 290 }
5260325f 291 }
c8d54615 292 BN_free(e);
293 BN_free(n);
294 fclose(f);
295 }
296 if (invalid) {
297 printf("%s is not a valid key file.\n", identity_file);
298 exit(1);
5260325f 299 }
5260325f 300 exit(0);
f095fcc7 301}
302
5260325f 303/*
304 * Perform changing a passphrase. The argument is the passwd structure
305 * for the current user.
306 */
f095fcc7 307void
308do_change_passphrase(struct passwd *pw)
309{
5260325f 310 char *comment;
311 char *old_passphrase, *passphrase1, *passphrase2;
312 struct stat st;
a306f2dd 313 Key *private;
314 Key *public;
315 int type = dsa_mode ? KEY_DSA : KEY_RSA;
5260325f 316
317 if (!have_identity)
318 ask_filename(pw, "Enter file in which the key is");
5260325f 319 if (stat(identity_file, &st) < 0) {
320 perror(identity_file);
321 exit(1);
322 }
a306f2dd 323
324 if (type == KEY_RSA) {
325 /* XXX this works currently only for RSA */
326 public = key_new(type);
327 if (!load_public_key(identity_file, public, NULL)) {
328 printf("%s is not a valid key file.\n", identity_file);
329 exit(1);
330 }
331 /* Clear the public key since we are just about to load the whole file. */
332 key_free(public);
5260325f 333 }
5260325f 334
335 /* Try to load the file with empty passphrase. */
a306f2dd 336 private = key_new(type);
337 if (!load_private_key(identity_file, "", private, &comment)) {
5260325f 338 if (identity_passphrase)
339 old_passphrase = xstrdup(identity_passphrase);
340 else
341 old_passphrase = read_passphrase("Enter old passphrase: ", 1);
a306f2dd 342 if (!load_private_key(identity_file, old_passphrase, private, &comment)) {
5260325f 343 memset(old_passphrase, 0, strlen(old_passphrase));
344 xfree(old_passphrase);
345 printf("Bad passphrase.\n");
346 exit(1);
347 }
5260325f 348 memset(old_passphrase, 0, strlen(old_passphrase));
349 xfree(old_passphrase);
350 }
351 printf("Key has comment '%s'\n", comment);
352
353 /* Ask the new passphrase (twice). */
354 if (identity_new_passphrase) {
355 passphrase1 = xstrdup(identity_new_passphrase);
356 passphrase2 = NULL;
357 } else {
358 passphrase1 =
359 read_passphrase("Enter new passphrase (empty for no passphrase): ", 1);
360 passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
361
362 /* Verify that they are the same. */
363 if (strcmp(passphrase1, passphrase2) != 0) {
364 memset(passphrase1, 0, strlen(passphrase1));
365 memset(passphrase2, 0, strlen(passphrase2));
366 xfree(passphrase1);
367 xfree(passphrase2);
368 printf("Pass phrases do not match. Try again.\n");
369 exit(1);
370 }
371 /* Destroy the other copy. */
372 memset(passphrase2, 0, strlen(passphrase2));
373 xfree(passphrase2);
8efc0c15 374 }
8efc0c15 375
5260325f 376 /* Save the file using the new passphrase. */
a306f2dd 377 if (!save_private_key(identity_file, passphrase1, private, comment)) {
5260325f 378 printf("Saving the key failed: %s: %s.\n",
379 identity_file, strerror(errno));
380 memset(passphrase1, 0, strlen(passphrase1));
381 xfree(passphrase1);
a306f2dd 382 key_free(private);
5260325f 383 xfree(comment);
384 exit(1);
385 }
386 /* Destroy the passphrase and the copy of the key in memory. */
387 memset(passphrase1, 0, strlen(passphrase1));
388 xfree(passphrase1);
a306f2dd 389 key_free(private); /* Destroys contents */
5260325f 390 xfree(comment);
391
392 printf("Your identification has been saved with the new passphrase.\n");
393 exit(0);
394}
8efc0c15 395
5260325f 396/*
397 * Change the comment of a private key file.
398 */
8efc0c15 399void
400do_change_comment(struct passwd *pw)
401{
5260325f 402 char new_comment[1024], *comment;
a306f2dd 403 Key *private;
404 Key *public;
5260325f 405 char *passphrase;
406 struct stat st;
407 FILE *f;
5260325f 408
409 if (!have_identity)
410 ask_filename(pw, "Enter file in which the key is");
5260325f 411 if (stat(identity_file, &st) < 0) {
412 perror(identity_file);
413 exit(1);
414 }
aa3378df 415 /*
416 * Try to load the public key from the file the verify that it is
417 * readable and of the proper format.
418 */
a306f2dd 419 public = key_new(KEY_RSA);
420 if (!load_public_key(identity_file, public, NULL)) {
5260325f 421 printf("%s is not a valid key file.\n", identity_file);
422 exit(1);
8efc0c15 423 }
aa3378df 424
a306f2dd 425 private = key_new(KEY_RSA);
426 if (load_private_key(identity_file, "", private, &comment))
5260325f 427 passphrase = xstrdup("");
428 else {
5260325f 429 if (identity_passphrase)
430 passphrase = xstrdup(identity_passphrase);
431 else if (identity_new_passphrase)
432 passphrase = xstrdup(identity_new_passphrase);
433 else
434 passphrase = read_passphrase("Enter passphrase: ", 1);
435 /* Try to load using the passphrase. */
a306f2dd 436 if (!load_private_key(identity_file, passphrase, private, &comment)) {
5260325f 437 memset(passphrase, 0, strlen(passphrase));
438 xfree(passphrase);
439 printf("Bad passphrase.\n");
440 exit(1);
441 }
442 }
443 printf("Key now has comment '%s'\n", comment);
444
445 if (identity_comment) {
446 strlcpy(new_comment, identity_comment, sizeof(new_comment));
447 } else {
448 printf("Enter new comment: ");
449 fflush(stdout);
450 if (!fgets(new_comment, sizeof(new_comment), stdin)) {
451 memset(passphrase, 0, strlen(passphrase));
a306f2dd 452 key_free(private);
5260325f 453 exit(1);
454 }
5260325f 455 if (strchr(new_comment, '\n'))
456 *strchr(new_comment, '\n') = 0;
457 }
458
459 /* Save the file using the new passphrase. */
a306f2dd 460 if (!save_private_key(identity_file, passphrase, private, new_comment)) {
5260325f 461 printf("Saving the key failed: %s: %s.\n",
462 identity_file, strerror(errno));
463 memset(passphrase, 0, strlen(passphrase));
464 xfree(passphrase);
a306f2dd 465 key_free(private);
5260325f 466 xfree(comment);
467 exit(1);
8efc0c15 468 }
5260325f 469 memset(passphrase, 0, strlen(passphrase));
470 xfree(passphrase);
a306f2dd 471 key_free(private);
5260325f 472
5260325f 473 strlcat(identity_file, ".pub", sizeof(identity_file));
474 f = fopen(identity_file, "w");
475 if (!f) {
476 printf("Could not save your public key in %s\n", identity_file);
477 exit(1);
478 }
a306f2dd 479 if (!key_write(public, f))
480 fprintf(stderr, "write key failed");
481 key_free(public);
482 fprintf(f, " %s\n", new_comment);
5260325f 483 fclose(f);
484
485 xfree(comment);
486
487 printf("The comment in your key file has been changed.\n");
488 exit(0);
8efc0c15 489}
490
5ad13cd7 491void
492usage(void)
493{
5260325f 494 printf("ssh-keygen version %s\n", SSH_VERSION);
a306f2dd 495 printf("Usage: %s [-b bits] [-p] [-c] [-l] [-x] [-X] [-y] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname);
5260325f 496 exit(1);
5ad13cd7 497}
498
5260325f 499/*
500 * Main program for key management.
501 */
8efc0c15 502int
503main(int ac, char **av)
504{
5260325f 505 char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2;
506 struct passwd *pw;
5260325f 507 int opt;
508 struct stat st;
509 FILE *f;
a306f2dd 510 Key *private;
511 Key *public;
5260325f 512 extern int optind;
513 extern char *optarg;
514
a306f2dd 515 OpenSSL_add_all_algorithms();
516
aa3378df 517 /* we need this for the home * directory. */
5260325f 518 pw = getpwuid(getuid());
519 if (!pw) {
520 printf("You don't exist, go away!\n");
521 exit(1);
522 }
a306f2dd 523 if (gethostname(hostname, sizeof(hostname)) < 0) {
524 perror("gethostname");
525 exit(1);
526 }
aa3378df 527
a306f2dd 528 while ((opt = getopt(ac, av, "dqpclRxXyb:f:P:N:C:")) != EOF) {
5260325f 529 switch (opt) {
530 case 'b':
531 bits = atoi(optarg);
532 if (bits < 512 || bits > 32768) {
533 printf("Bits has bad value.\n");
534 exit(1);
535 }
536 break;
537
538 case 'l':
539 print_fingerprint = 1;
540 break;
541
542 case 'p':
543 change_passphrase = 1;
544 break;
545
546 case 'c':
547 change_comment = 1;
548 break;
549
550 case 'f':
551 strlcpy(identity_file, optarg, sizeof(identity_file));
552 have_identity = 1;
553 break;
554
555 case 'P':
556 identity_passphrase = optarg;
557 break;
558
559 case 'N':
560 identity_new_passphrase = optarg;
561 break;
562
563 case 'C':
564 identity_comment = optarg;
565 break;
566
567 case 'q':
568 quiet = 1;
569 break;
570
a306f2dd 571 case 'R':
572 if (rsa_alive() == 0)
573 exit(1);
574 else
575 exit(0);
576 break;
577
578 case 'x':
579 convert_to_ssh2 = 1;
580 break;
581
582 case 'X':
583 convert_from_ssh2 = 1;
584 break;
585
586 case 'y':
587 print_public = 1;
588 break;
589
590 case 'd':
591 dsa_mode = 1;
592 break;
593
5260325f 594 case '?':
595 default:
596 usage();
597 }
598 }
599 if (optind < ac) {
600 printf("Too many arguments.\n");
601 usage();
602 }
603 if (change_passphrase && change_comment) {
604 printf("Can only have one of -p and -c.\n");
605 usage();
606 }
a306f2dd 607 /* check if RSA support is needed and exists */
608 if (dsa_mode == 0 && rsa_alive() == 0) {
609 fprintf(stderr,
610 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
611 __progname);
612 exit(1);
613 }
5260325f 614 if (print_fingerprint)
615 do_fingerprint(pw);
5260325f 616 if (change_passphrase)
617 do_change_passphrase(pw);
5260325f 618 if (change_comment)
619 do_change_comment(pw);
a306f2dd 620 if (convert_to_ssh2)
621 do_convert_to_ssh2(pw);
622 if (convert_from_ssh2)
623 do_convert_from_ssh2(pw);
624 if (print_public)
625 do_print_public(pw);
5260325f 626
627 arc4random_stir();
628
a306f2dd 629 if (dsa_mode != 0) {
630 if (!quiet)
631 printf("Generating DSA parameter and key.\n");
632 public = private = dsa_generate_key(bits);
633 if (private == NULL) {
634 fprintf(stderr, "dsa_generate_keys failed");
635 exit(1);
636 }
637 } else {
638 if (quiet)
639 rsa_set_verbose(0);
640 /* Generate the rsa key pair. */
641 public = key_new(KEY_RSA);
642 private = key_new(KEY_RSA);
643 rsa_generate_key(private->rsa, public->rsa, bits);
644 }
5260325f 645
646 if (!have_identity)
647 ask_filename(pw, "Enter file in which to save the key");
648
649 /* Create ~/.ssh directory if it doesn\'t already exist. */
650 snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, SSH_USER_DIR);
651 if (strstr(identity_file, dotsshdir) != NULL &&
652 stat(dotsshdir, &st) < 0) {
653 if (mkdir(dotsshdir, 0755) < 0)
654 error("Could not create directory '%s'.", dotsshdir);
655 else if (!quiet)
656 printf("Created directory '%s'.\n", dotsshdir);
657 }
658 /* If the file already exists, ask the user to confirm. */
659 if (stat(identity_file, &st) >= 0) {
660 char yesno[3];
661 printf("%s already exists.\n", identity_file);
662 printf("Overwrite (y/n)? ");
663 fflush(stdout);
664 if (fgets(yesno, sizeof(yesno), stdin) == NULL)
665 exit(1);
666 if (yesno[0] != 'y' && yesno[0] != 'Y')
667 exit(1);
668 }
669 /* Ask for a passphrase (twice). */
670 if (identity_passphrase)
671 passphrase1 = xstrdup(identity_passphrase);
672 else if (identity_new_passphrase)
673 passphrase1 = xstrdup(identity_new_passphrase);
674 else {
675passphrase_again:
676 passphrase1 =
677 read_passphrase("Enter passphrase (empty for no passphrase): ", 1);
678 passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
679 if (strcmp(passphrase1, passphrase2) != 0) {
680 /* The passphrases do not match. Clear them and retry. */
681 memset(passphrase1, 0, strlen(passphrase1));
682 memset(passphrase2, 0, strlen(passphrase2));
683 xfree(passphrase1);
684 xfree(passphrase2);
685 printf("Passphrases do not match. Try again.\n");
686 goto passphrase_again;
687 }
688 /* Clear the other copy of the passphrase. */
689 memset(passphrase2, 0, strlen(passphrase2));
690 xfree(passphrase2);
691 }
692
5260325f 693 if (identity_comment) {
694 strlcpy(comment, identity_comment, sizeof(comment));
695 } else {
6ae2364d 696 /* Create default commend field for the passphrase. */
5260325f 697 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
698 }
699
700 /* Save the key with the given passphrase and comment. */
a306f2dd 701 if (!save_private_key(identity_file, passphrase1, private, comment)) {
5260325f 702 printf("Saving the key failed: %s: %s.\n",
a306f2dd 703 identity_file, strerror(errno));
5260325f 704 memset(passphrase1, 0, strlen(passphrase1));
705 xfree(passphrase1);
706 exit(1);
707 }
708 /* Clear the passphrase. */
709 memset(passphrase1, 0, strlen(passphrase1));
710 xfree(passphrase1);
711
712 /* Clear the private key and the random number generator. */
a306f2dd 713 if (private != public) {
714 key_free(private);
715 }
5260325f 716 arc4random_stir();
717
718 if (!quiet)
719 printf("Your identification has been saved in %s.\n", identity_file);
720
5260325f 721 strlcat(identity_file, ".pub", sizeof(identity_file));
722 f = fopen(identity_file, "w");
723 if (!f) {
724 printf("Could not save your public key in %s\n", identity_file);
725 exit(1);
726 }
a306f2dd 727 if (!key_write(public, f))
728 fprintf(stderr, "write key failed");
729 fprintf(f, " %s\n", comment);
5260325f 730 fclose(f);
731
732 if (!quiet) {
a306f2dd 733 printf("Your public key has been saved in %s.\n",
734 identity_file);
5260325f 735 printf("The key fingerprint is:\n");
a306f2dd 736 printf("%s %s\n", key_fingerprint(public), comment);
8efc0c15 737 }
a306f2dd 738
739 key_free(public);
5260325f 740 exit(0);
8efc0c15 741}
This page took 0.176574 seconds and 5 git commands to generate.