blob: f2484a4b16e0821460a87c12f4738ef81d36cf51 [file] [log] [blame]
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001/*
Damien Miller95def091999-11-25 00:26:21 +11002 * 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 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +10008
9#include "includes.h"
Damien Miller4af51302000-04-16 11:18:38 +100010RCSID("$Id: ssh-keygen.c,v 1.13 2000/04/16 01:18:46 damien Exp $");
Damien Millerd4a8b7e1999-10-27 13:42:43 +100011
12#include "rsa.h"
13#include "ssh.h"
14#include "xmalloc.h"
Damien Miller10f6f6b1999-11-17 17:29:08 +110015#include "fingerprint.h"
Damien Millerd4a8b7e1999-10-27 13:42:43 +100016
17/* Generated private key. */
18RSA *private_key;
19
20/* Generated public key. */
21RSA *public_key;
22
Damien Miller5428f641999-11-25 11:54:57 +110023/* Number of bits in the RSA key. This value can be changed on the command line. */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100024int bits = 1024;
25
Damien Miller5428f641999-11-25 11:54:57 +110026/*
27 * Flag indicating that we just want to change the passphrase. This can be
28 * set on the command line.
29 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100030int change_passphrase = 0;
31
Damien Miller5428f641999-11-25 11:54:57 +110032/*
33 * Flag indicating that we just want to change the comment. This can be set
34 * on the command line.
35 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100036int change_comment = 0;
37
38int quiet = 0;
39
Damien Miller10f6f6b1999-11-17 17:29:08 +110040/* Flag indicating that we just want to see the key fingerprint */
41int print_fingerprint = 0;
42
Damien Miller431f66b1999-11-21 18:31:57 +110043/* The identity file name, given on the command line or entered by the user. */
44char identity_file[1024];
45int have_identity = 0;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100046
47/* This is set to the passphrase if given on the command line. */
48char *identity_passphrase = NULL;
49
50/* This is set to the new passphrase if given on the command line. */
51char *identity_new_passphrase = NULL;
52
53/* This is set to the new comment if given on the command line. */
54char *identity_comment = NULL;
55
Damien Miller431f66b1999-11-21 18:31:57 +110056/* argv0 */
Damien Miller95def091999-11-25 00:26:21 +110057#ifdef HAVE___PROGNAME
Damien Miller431f66b1999-11-21 18:31:57 +110058extern char *__progname;
Damien Miller95def091999-11-25 00:26:21 +110059#else /* HAVE___PROGNAME */
60const char *__progname = "ssh-keygen";
61#endif /* HAVE___PROGNAME */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100062
Damien Miller431f66b1999-11-21 18:31:57 +110063void
64ask_filename(struct passwd *pw, const char *prompt)
Damien Millerd4a8b7e1999-10-27 13:42:43 +100065{
Damien Miller95def091999-11-25 00:26:21 +110066 char buf[1024];
67 snprintf(identity_file, sizeof(identity_file), "%s/%s",
68 pw->pw_dir, SSH_CLIENT_IDENTITY);
69 printf("%s (%s): ", prompt, identity_file);
70 fflush(stdout);
71 if (fgets(buf, sizeof(buf), stdin) == NULL)
72 exit(1);
73 if (strchr(buf, '\n'))
74 *strchr(buf, '\n') = 0;
75 if (strcmp(buf, "") != 0)
76 strlcpy(identity_file, buf, sizeof(identity_file));
77 have_identity = 1;
Damien Miller10f6f6b1999-11-17 17:29:08 +110078}
Damien Millerd4a8b7e1999-10-27 13:42:43 +100079
Damien Miller10f6f6b1999-11-17 17:29:08 +110080void
81do_fingerprint(struct passwd *pw)
82{
Damien Miller98c7ad62000-03-09 21:27:49 +110083 FILE *f;
84 BIGNUM *e, *n;
Damien Miller95def091999-11-25 00:26:21 +110085 RSA *public_key;
Damien Miller98c7ad62000-03-09 21:27:49 +110086 char *comment = NULL, *cp, *ep, line[16*1024];
87 int i, skip = 0, num = 1, invalid = 1;
Damien Miller7684ee12000-03-17 23:40:15 +110088 unsigned int ignore;
Damien Miller95def091999-11-25 00:26:21 +110089 struct stat st;
Damien Miller10f6f6b1999-11-17 17:29:08 +110090
Damien Miller95def091999-11-25 00:26:21 +110091 if (!have_identity)
92 ask_filename(pw, "Enter file in which the key is");
93 if (stat(identity_file, &st) < 0) {
94 perror(identity_file);
95 exit(1);
96 }
Damien Miller98c7ad62000-03-09 21:27:49 +110097
Damien Miller95def091999-11-25 00:26:21 +110098 public_key = RSA_new();
Damien Miller98c7ad62000-03-09 21:27:49 +110099 if (load_public_key(identity_file, public_key, &comment)) {
100 printf("%d %s %s\n", BN_num_bits(public_key->n),
101 fingerprint(public_key->e, public_key->n),
102 comment);
103 RSA_free(public_key);
104 exit(0);
105 }
106 RSA_free(public_key);
107
108 f = fopen(identity_file, "r");
109 if (f != NULL) {
Damien Miller95def091999-11-25 00:26:21 +1100110 n = BN_new();
111 e = BN_new();
Damien Miller98c7ad62000-03-09 21:27:49 +1100112 while (fgets(line, sizeof(line), f)) {
113 i = strlen(line) - 1;
114 if (line[i] != '\n') {
115 error("line %d too long: %.40s...", num, line);
116 skip = 1;
117 continue;
Damien Miller95def091999-11-25 00:26:21 +1100118 }
Damien Miller98c7ad62000-03-09 21:27:49 +1100119 num++;
120 if (skip) {
121 skip = 0;
122 continue;
123 }
124 line[i] = '\0';
125
126 /* Skip leading whitespace, empty and comment lines. */
127 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
128 ;
129 if (!*cp || *cp == '\n' || *cp == '#')
130 continue ;
131 i = strtol(cp, &ep, 10);
132 if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {
133 int quoted = 0;
134 comment = cp;
135 for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
136 if (*cp == '\\' && cp[1] == '"')
137 cp++; /* Skip both */
138 else if (*cp == '"')
139 quoted = !quoted;
140 }
141 if (!*cp)
142 continue;
143 *cp++ = '\0';
144 }
145 ep = cp;
Damien Miller7684ee12000-03-17 23:40:15 +1100146 if (auth_rsa_read_key(&cp, &ignore, e, n)) {
Damien Miller98c7ad62000-03-09 21:27:49 +1100147 invalid = 0;
148 comment = *cp ? cp : comment;
149 printf("%d %s %s\n", BN_num_bits(n),
150 fingerprint(e, n),
151 comment ? comment : "no comment");
152 }
Damien Miller95def091999-11-25 00:26:21 +1100153 }
Damien Miller98c7ad62000-03-09 21:27:49 +1100154 BN_free(e);
155 BN_free(n);
156 fclose(f);
Damien Miller95def091999-11-25 00:26:21 +1100157 }
Damien Miller98c7ad62000-03-09 21:27:49 +1100158 if (invalid) {
159 printf("%s is not a valid key file.\n", identity_file);
160 exit(1);
161 }
Damien Miller95def091999-11-25 00:26:21 +1100162 exit(0);
Damien Miller10f6f6b1999-11-17 17:29:08 +1100163}
164
Damien Miller95def091999-11-25 00:26:21 +1100165/*
166 * Perform changing a passphrase. The argument is the passwd structure
167 * for the current user.
168 */
Damien Miller10f6f6b1999-11-17 17:29:08 +1100169void
170do_change_passphrase(struct passwd *pw)
171{
Damien Miller95def091999-11-25 00:26:21 +1100172 char *comment;
173 char *old_passphrase, *passphrase1, *passphrase2;
174 struct stat st;
175 RSA *private_key;
Damien Miller10f6f6b1999-11-17 17:29:08 +1100176
Damien Miller95def091999-11-25 00:26:21 +1100177 if (!have_identity)
178 ask_filename(pw, "Enter file in which the key is");
Damien Miller95def091999-11-25 00:26:21 +1100179 if (stat(identity_file, &st) < 0) {
180 perror(identity_file);
181 exit(1);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000182 }
Damien Miller95def091999-11-25 00:26:21 +1100183 public_key = RSA_new();
184 if (!load_public_key(identity_file, public_key, NULL)) {
185 printf("%s is not a valid key file.\n", identity_file);
186 exit(1);
187 }
188 /* Clear the public key since we are just about to load the whole file. */
189 RSA_free(public_key);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000190
Damien Miller95def091999-11-25 00:26:21 +1100191 /* Try to load the file with empty passphrase. */
192 private_key = RSA_new();
193 if (!load_private_key(identity_file, "", private_key, &comment)) {
Damien Miller95def091999-11-25 00:26:21 +1100194 if (identity_passphrase)
195 old_passphrase = xstrdup(identity_passphrase);
196 else
197 old_passphrase = read_passphrase("Enter old passphrase: ", 1);
Damien Miller95def091999-11-25 00:26:21 +1100198 if (!load_private_key(identity_file, old_passphrase, private_key, &comment)) {
199 memset(old_passphrase, 0, strlen(old_passphrase));
200 xfree(old_passphrase);
201 printf("Bad passphrase.\n");
202 exit(1);
203 }
Damien Miller95def091999-11-25 00:26:21 +1100204 memset(old_passphrase, 0, strlen(old_passphrase));
205 xfree(old_passphrase);
206 }
207 printf("Key has comment '%s'\n", comment);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000208
Damien Miller95def091999-11-25 00:26:21 +1100209 /* Ask the new passphrase (twice). */
210 if (identity_new_passphrase) {
211 passphrase1 = xstrdup(identity_new_passphrase);
212 passphrase2 = NULL;
213 } else {
214 passphrase1 =
215 read_passphrase("Enter new passphrase (empty for no passphrase): ", 1);
216 passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
217
218 /* Verify that they are the same. */
219 if (strcmp(passphrase1, passphrase2) != 0) {
220 memset(passphrase1, 0, strlen(passphrase1));
221 memset(passphrase2, 0, strlen(passphrase2));
222 xfree(passphrase1);
223 xfree(passphrase2);
224 printf("Pass phrases do not match. Try again.\n");
225 exit(1);
226 }
227 /* Destroy the other copy. */
228 memset(passphrase2, 0, strlen(passphrase2));
229 xfree(passphrase2);
230 }
231
232 /* Save the file using the new passphrase. */
233 if (!save_private_key(identity_file, passphrase1, private_key, comment)) {
234 printf("Saving the key failed: %s: %s.\n",
235 identity_file, strerror(errno));
236 memset(passphrase1, 0, strlen(passphrase1));
237 xfree(passphrase1);
238 RSA_free(private_key);
239 xfree(comment);
240 exit(1);
241 }
242 /* Destroy the passphrase and the copy of the key in memory. */
243 memset(passphrase1, 0, strlen(passphrase1));
244 xfree(passphrase1);
245 RSA_free(private_key); /* Destroys contents */
246 xfree(comment);
247
248 printf("Your identification has been saved with the new passphrase.\n");
249 exit(0);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000250}
251
Damien Miller95def091999-11-25 00:26:21 +1100252/*
253 * Change the comment of a private key file.
254 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000255void
256do_change_comment(struct passwd *pw)
257{
Damien Miller95def091999-11-25 00:26:21 +1100258 char new_comment[1024], *comment;
259 RSA *private_key;
260 char *passphrase;
261 struct stat st;
262 FILE *f;
263 char *tmpbuf;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000264
Damien Miller95def091999-11-25 00:26:21 +1100265 if (!have_identity)
266 ask_filename(pw, "Enter file in which the key is");
Damien Miller95def091999-11-25 00:26:21 +1100267 if (stat(identity_file, &st) < 0) {
268 perror(identity_file);
269 exit(1);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000270 }
Damien Miller5428f641999-11-25 11:54:57 +1100271 /*
272 * Try to load the public key from the file the verify that it is
273 * readable and of the proper format.
274 */
Damien Miller95def091999-11-25 00:26:21 +1100275 public_key = RSA_new();
276 if (!load_public_key(identity_file, public_key, NULL)) {
277 printf("%s is not a valid key file.\n", identity_file);
278 exit(1);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000279 }
Damien Miller95def091999-11-25 00:26:21 +1100280 private_key = RSA_new();
Damien Miller5428f641999-11-25 11:54:57 +1100281
Damien Miller95def091999-11-25 00:26:21 +1100282 if (load_private_key(identity_file, "", private_key, &comment))
283 passphrase = xstrdup("");
284 else {
Damien Miller95def091999-11-25 00:26:21 +1100285 if (identity_passphrase)
286 passphrase = xstrdup(identity_passphrase);
287 else if (identity_new_passphrase)
288 passphrase = xstrdup(identity_new_passphrase);
289 else
290 passphrase = read_passphrase("Enter passphrase: ", 1);
291 /* Try to load using the passphrase. */
292 if (!load_private_key(identity_file, passphrase, private_key, &comment)) {
293 memset(passphrase, 0, strlen(passphrase));
294 xfree(passphrase);
295 printf("Bad passphrase.\n");
296 exit(1);
297 }
298 }
299 printf("Key now has comment '%s'\n", comment);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000300
Damien Miller95def091999-11-25 00:26:21 +1100301 if (identity_comment) {
302 strlcpy(new_comment, identity_comment, sizeof(new_comment));
303 } else {
304 printf("Enter new comment: ");
305 fflush(stdout);
306 if (!fgets(new_comment, sizeof(new_comment), stdin)) {
307 memset(passphrase, 0, strlen(passphrase));
308 RSA_free(private_key);
309 exit(1);
310 }
Damien Miller95def091999-11-25 00:26:21 +1100311 if (strchr(new_comment, '\n'))
312 *strchr(new_comment, '\n') = 0;
313 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000314
Damien Miller95def091999-11-25 00:26:21 +1100315 /* Save the file using the new passphrase. */
316 if (!save_private_key(identity_file, passphrase, private_key, new_comment)) {
317 printf("Saving the key failed: %s: %s.\n",
318 identity_file, strerror(errno));
319 memset(passphrase, 0, strlen(passphrase));
320 xfree(passphrase);
321 RSA_free(private_key);
322 xfree(comment);
323 exit(1);
324 }
Damien Miller95def091999-11-25 00:26:21 +1100325 memset(passphrase, 0, strlen(passphrase));
326 xfree(passphrase);
327 RSA_free(private_key);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000328
Damien Miller95def091999-11-25 00:26:21 +1100329 strlcat(identity_file, ".pub", sizeof(identity_file));
330 f = fopen(identity_file, "w");
331 if (!f) {
332 printf("Could not save your public key in %s\n", identity_file);
333 exit(1);
334 }
335 fprintf(f, "%d ", BN_num_bits(public_key->n));
336 tmpbuf = BN_bn2dec(public_key->e);
337 fprintf(f, "%s ", tmpbuf);
338 free(tmpbuf);
339 tmpbuf = BN_bn2dec(public_key->n);
340 fprintf(f, "%s %s\n", tmpbuf, new_comment);
341 free(tmpbuf);
342 fclose(f);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000343
Damien Miller95def091999-11-25 00:26:21 +1100344 xfree(comment);
345
346 printf("The comment in your key file has been changed.\n");
347 exit(0);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000348}
349
Damien Miller431f66b1999-11-21 18:31:57 +1100350void
351usage(void)
352{
Damien Miller95def091999-11-25 00:26:21 +1100353 printf("ssh-keygen version %s\n", SSH_VERSION);
Damien Miller98c7ad62000-03-09 21:27:49 +1100354 printf("Usage: %s [-b bits] [-p] [-c] [-l] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname);
Damien Miller95def091999-11-25 00:26:21 +1100355 exit(1);
Damien Miller431f66b1999-11-21 18:31:57 +1100356}
357
Damien Miller95def091999-11-25 00:26:21 +1100358/*
359 * Main program for key management.
360 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000361int
362main(int ac, char **av)
363{
Damien Miller95def091999-11-25 00:26:21 +1100364 char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2;
365 struct passwd *pw;
366 char *tmpbuf;
367 int opt;
368 struct stat st;
369 FILE *f;
370 char hostname[MAXHOSTNAMELEN];
371 extern int optind;
372 extern char *optarg;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000373
Damien Miller95def091999-11-25 00:26:21 +1100374 /* check if RSA support exists */
375 if (rsa_alive() == 0) {
Damien Miller95def091999-11-25 00:26:21 +1100376 fprintf(stderr,
377 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
378 __progname);
379 exit(1);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000380 }
Damien Miller5428f641999-11-25 11:54:57 +1100381 /* we need this for the home * directory. */
Damien Miller95def091999-11-25 00:26:21 +1100382 pw = getpwuid(getuid());
383 if (!pw) {
384 printf("You don't exist, go away!\n");
385 exit(1);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000386 }
Damien Miller5428f641999-11-25 11:54:57 +1100387
Damien Miller95def091999-11-25 00:26:21 +1100388 while ((opt = getopt(ac, av, "qpclb:f:P:N:C:")) != EOF) {
389 switch (opt) {
390 case 'b':
391 bits = atoi(optarg);
392 if (bits < 512 || bits > 32768) {
393 printf("Bits has bad value.\n");
394 exit(1);
395 }
396 break;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000397
Damien Miller95def091999-11-25 00:26:21 +1100398 case 'l':
399 print_fingerprint = 1;
400 break;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000401
Damien Miller95def091999-11-25 00:26:21 +1100402 case 'p':
403 change_passphrase = 1;
404 break;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000405
Damien Miller95def091999-11-25 00:26:21 +1100406 case 'c':
407 change_comment = 1;
408 break;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000409
Damien Miller95def091999-11-25 00:26:21 +1100410 case 'f':
411 strlcpy(identity_file, optarg, sizeof(identity_file));
412 have_identity = 1;
413 break;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000414
Damien Miller95def091999-11-25 00:26:21 +1100415 case 'P':
416 identity_passphrase = optarg;
417 break;
418
419 case 'N':
420 identity_new_passphrase = optarg;
421 break;
422
423 case 'C':
424 identity_comment = optarg;
425 break;
426
427 case 'q':
428 quiet = 1;
429 break;
430
431 case '?':
432 default:
433 usage();
434 }
435 }
436 if (optind < ac) {
437 printf("Too many arguments.\n");
438 usage();
439 }
440 if (change_passphrase && change_comment) {
441 printf("Can only have one of -p and -c.\n");
442 usage();
443 }
444 if (print_fingerprint)
445 do_fingerprint(pw);
Damien Miller95def091999-11-25 00:26:21 +1100446 if (change_passphrase)
447 do_change_passphrase(pw);
Damien Miller95def091999-11-25 00:26:21 +1100448 if (change_comment)
449 do_change_comment(pw);
450
451 arc4random_stir();
452
453 if (quiet)
454 rsa_set_verbose(0);
455
456 /* Generate the rsa key pair. */
457 private_key = RSA_new();
458 public_key = RSA_new();
459 rsa_generate_key(private_key, public_key, bits);
460
461 if (!have_identity)
462 ask_filename(pw, "Enter file in which to save the key");
463
464 /* Create ~/.ssh directory if it doesn\'t already exist. */
465 snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, SSH_USER_DIR);
466 if (strstr(identity_file, dotsshdir) != NULL &&
467 stat(dotsshdir, &st) < 0) {
468 if (mkdir(dotsshdir, 0755) < 0)
469 error("Could not create directory '%s'.", dotsshdir);
470 else if (!quiet)
471 printf("Created directory '%s'.\n", dotsshdir);
472 }
473 /* If the file already exists, ask the user to confirm. */
474 if (stat(identity_file, &st) >= 0) {
475 char yesno[3];
476 printf("%s already exists.\n", identity_file);
477 printf("Overwrite (y/n)? ");
478 fflush(stdout);
479 if (fgets(yesno, sizeof(yesno), stdin) == NULL)
480 exit(1);
481 if (yesno[0] != 'y' && yesno[0] != 'Y')
482 exit(1);
483 }
484 /* Ask for a passphrase (twice). */
485 if (identity_passphrase)
486 passphrase1 = xstrdup(identity_passphrase);
487 else if (identity_new_passphrase)
488 passphrase1 = xstrdup(identity_new_passphrase);
489 else {
490passphrase_again:
491 passphrase1 =
492 read_passphrase("Enter passphrase (empty for no passphrase): ", 1);
493 passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
494 if (strcmp(passphrase1, passphrase2) != 0) {
495 /* The passphrases do not match. Clear them and retry. */
496 memset(passphrase1, 0, strlen(passphrase1));
497 memset(passphrase2, 0, strlen(passphrase2));
498 xfree(passphrase1);
499 xfree(passphrase2);
500 printf("Passphrases do not match. Try again.\n");
501 goto passphrase_again;
502 }
503 /* Clear the other copy of the passphrase. */
504 memset(passphrase2, 0, strlen(passphrase2));
505 xfree(passphrase2);
506 }
507
Damien Miller95def091999-11-25 00:26:21 +1100508 if (identity_comment) {
509 strlcpy(comment, identity_comment, sizeof(comment));
510 } else {
Damien Miller4af51302000-04-16 11:18:38 +1000511 /* Create default commend field for the passphrase. */
Damien Miller95def091999-11-25 00:26:21 +1100512 if (gethostname(hostname, sizeof(hostname)) < 0) {
513 perror("gethostname");
514 exit(1);
515 }
516 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
517 }
518
519 /* Save the key with the given passphrase and comment. */
520 if (!save_private_key(identity_file, passphrase1, private_key, comment)) {
521 printf("Saving the key failed: %s: %s.\n",
522 identity_file, strerror(errno));
523 memset(passphrase1, 0, strlen(passphrase1));
524 xfree(passphrase1);
525 exit(1);
526 }
527 /* Clear the passphrase. */
528 memset(passphrase1, 0, strlen(passphrase1));
529 xfree(passphrase1);
530
531 /* Clear the private key and the random number generator. */
532 RSA_free(private_key);
533 arc4random_stir();
534
535 if (!quiet)
536 printf("Your identification has been saved in %s.\n", identity_file);
537
Damien Miller95def091999-11-25 00:26:21 +1100538 strlcat(identity_file, ".pub", sizeof(identity_file));
539 f = fopen(identity_file, "w");
540 if (!f) {
541 printf("Could not save your public key in %s\n", identity_file);
542 exit(1);
543 }
544 fprintf(f, "%d ", BN_num_bits(public_key->n));
545 tmpbuf = BN_bn2dec(public_key->e);
546 fprintf(f, "%s ", tmpbuf);
547 free(tmpbuf);
548 tmpbuf = BN_bn2dec(public_key->n);
549 fprintf(f, "%s %s\n", tmpbuf, comment);
550 free(tmpbuf);
551 fclose(f);
552
553 if (!quiet) {
554 printf("Your public key has been saved in %s.\n", identity_file);
555 printf("The key fingerprint is:\n");
556 printf("%d %s %s\n", BN_num_bits(public_key->n),
557 fingerprint(public_key->e, public_key->n),
558 comment);
559 }
560 exit(0);
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000561}