summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-04-29 23:57:08 +1000
committerDamien Miller <djm@mindrot.org>2000-04-29 23:57:08 +1000
commiteba71bab9bf01c0d688f829a8971f902732558df (patch)
treea9d5b50568bfc10cc50291fd3604debfaf3e3783 /ssh-keygen.c
parent8117111a3c1360727e3c54aad31aa045e7a7871b (diff)
- Merge big update to OpenSSH-2.0 from OpenBSD CVS
[README.openssh2] - interop w/ F-secure windows client - sync documentation - ssh_host_dsa_key not ssh_dsa_key [auth-rsa.c] - missing fclose [auth.c authfile.c compat.c dsa.c dsa.h hostfile.c key.c key.h radix.c] [readconf.c readconf.h ssh-add.c ssh-keygen.c ssh.c ssh.h sshconnect.c] [sshd.c uuencode.c uuencode.h authfile.h] - add DSA pubkey auth and other SSH2 fixes. use ssh-keygen -[xX] for trading keys with the real and the original SSH, directly from the people who invented the SSH protocol. [auth.c auth.h authfile.c sshconnect.c auth1.c auth2.c sshconnect.h] [sshconnect1.c sshconnect2.c] - split auth/sshconnect in one file per protocol version [sshconnect2.c] - remove debug [uuencode.c] - add trailing = [version.h] - OpenSSH-2.0 [ssh-keygen.1 ssh-keygen.c] - add -R flag: exit code indicates if RSA is alive [sshd.c] - remove unused silent if -Q is specified [ssh.h] - host key becomes /etc/ssh_host_dsa_key [readconf.c servconf.c ] - ssh/sshd default to proto 1 and 2 [uuencode.c] - remove debug [auth2.c ssh-keygen.c sshconnect2.c sshd.c] - xfree DSA blobs [auth2.c serverloop.c session.c] - cleanup logging for sshd/2, respect PasswordAuth no [sshconnect2.c] - less debug, respect .ssh/config [README.openssh2 channels.c channels.h] - clientloop.c session.c ssh.c - support for x11-fwding, client+server
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c350
1 files changed, 265 insertions, 85 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index f2484a4b1..0155949fd 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -7,20 +7,23 @@
7 */ 7 */
8 8
9#include "includes.h" 9#include "includes.h"
10RCSID("$Id: ssh-keygen.c,v 1.13 2000/04/16 01:18:46 damien Exp $"); 10RCSID("$Id: ssh-keygen.c,v 1.14 2000/04/29 13:57:12 damien Exp $");
11
12#include <openssl/evp.h>
13#include <openssl/pem.h>
14#include <openssl/rsa.h>
15#include <openssl/dsa.h>
11 16
12#include "rsa.h"
13#include "ssh.h" 17#include "ssh.h"
14#include "xmalloc.h" 18#include "xmalloc.h"
15#include "fingerprint.h" 19#include "fingerprint.h"
20#include "key.h"
21#include "rsa.h"
22#include "dsa.h"
23#include "authfile.h"
24#include "uuencode.h"
16 25
17/* Generated private key. */ 26/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */
18RSA *private_key;
19
20/* Generated public key. */
21RSA *public_key;
22
23/* Number of bits in the RSA key. This value can be changed on the command line. */
24int bits = 1024; 27int bits = 1024;
25 28
26/* 29/*
@@ -53,6 +56,12 @@ char *identity_new_passphrase = NULL;
53/* This is set to the new comment if given on the command line. */ 56/* This is set to the new comment if given on the command line. */
54char *identity_comment = NULL; 57char *identity_comment = NULL;
55 58
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
56/* argv0 */ 65/* argv0 */
57#ifdef HAVE___PROGNAME 66#ifdef HAVE___PROGNAME
58extern char *__progname; 67extern char *__progname;
@@ -60,6 +69,8 @@ extern char *__progname;
60const char *__progname = "ssh-keygen"; 69const char *__progname = "ssh-keygen";
61#endif /* HAVE___PROGNAME */ 70#endif /* HAVE___PROGNAME */
62 71
72char hostname[MAXHOSTNAMELEN];
73
63void 74void
64ask_filename(struct passwd *pw, const char *prompt) 75ask_filename(struct passwd *pw, const char *prompt)
65{ 76{
@@ -77,12 +88,140 @@ ask_filename(struct passwd *pw, const char *prompt)
77 have_identity = 1; 88 have_identity = 1;
78} 89}
79 90
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
80void 219void
81do_fingerprint(struct passwd *pw) 220do_fingerprint(struct passwd *pw)
82{ 221{
83 FILE *f; 222 FILE *f;
84 BIGNUM *e, *n; 223 BIGNUM *e, *n;
85 RSA *public_key; 224 Key *public;
86 char *comment = NULL, *cp, *ep, line[16*1024]; 225 char *comment = NULL, *cp, *ep, line[16*1024];
87 int i, skip = 0, num = 1, invalid = 1; 226 int i, skip = 0, num = 1, invalid = 1;
88 unsigned int ignore; 227 unsigned int ignore;
@@ -94,17 +233,16 @@ do_fingerprint(struct passwd *pw)
94 perror(identity_file); 233 perror(identity_file);
95 exit(1); 234 exit(1);
96 } 235 }
97 236 public = key_new(KEY_RSA);
98 public_key = RSA_new(); 237 if (load_public_key(identity_file, public, &comment)) {
99 if (load_public_key(identity_file, public_key, &comment)) { 238 printf("%d %s %s\n", BN_num_bits(public->rsa->n),
100 printf("%d %s %s\n", BN_num_bits(public_key->n), 239 key_fingerprint(public), comment);
101 fingerprint(public_key->e, public_key->n), 240 key_free(public);
102 comment);
103 RSA_free(public_key);
104 exit(0); 241 exit(0);
105 } 242 }
106 RSA_free(public_key); 243 key_free(public);
107 244
245 /* XXX */
108 f = fopen(identity_file, "r"); 246 f = fopen(identity_file, "r");
109 if (f != NULL) { 247 if (f != NULL) {
110 n = BN_new(); 248 n = BN_new();
@@ -172,7 +310,9 @@ do_change_passphrase(struct passwd *pw)
172 char *comment; 310 char *comment;
173 char *old_passphrase, *passphrase1, *passphrase2; 311 char *old_passphrase, *passphrase1, *passphrase2;
174 struct stat st; 312 struct stat st;
175 RSA *private_key; 313 Key *private;
314 Key *public;
315 int type = dsa_mode ? KEY_DSA : KEY_RSA;
176 316
177 if (!have_identity) 317 if (!have_identity)
178 ask_filename(pw, "Enter file in which the key is"); 318 ask_filename(pw, "Enter file in which the key is");
@@ -180,22 +320,26 @@ do_change_passphrase(struct passwd *pw)
180 perror(identity_file); 320 perror(identity_file);
181 exit(1); 321 exit(1);
182 } 322 }
183 public_key = RSA_new(); 323
184 if (!load_public_key(identity_file, public_key, NULL)) { 324 if (type == KEY_RSA) {
185 printf("%s is not a valid key file.\n", identity_file); 325 /* XXX this works currently only for RSA */
186 exit(1); 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);
187 } 333 }
188 /* Clear the public key since we are just about to load the whole file. */
189 RSA_free(public_key);
190 334
191 /* Try to load the file with empty passphrase. */ 335 /* Try to load the file with empty passphrase. */
192 private_key = RSA_new(); 336 private = key_new(type);
193 if (!load_private_key(identity_file, "", private_key, &comment)) { 337 if (!load_private_key(identity_file, "", private, &comment)) {
194 if (identity_passphrase) 338 if (identity_passphrase)
195 old_passphrase = xstrdup(identity_passphrase); 339 old_passphrase = xstrdup(identity_passphrase);
196 else 340 else
197 old_passphrase = read_passphrase("Enter old passphrase: ", 1); 341 old_passphrase = read_passphrase("Enter old passphrase: ", 1);
198 if (!load_private_key(identity_file, old_passphrase, private_key, &comment)) { 342 if (!load_private_key(identity_file, old_passphrase, private, &comment)) {
199 memset(old_passphrase, 0, strlen(old_passphrase)); 343 memset(old_passphrase, 0, strlen(old_passphrase));
200 xfree(old_passphrase); 344 xfree(old_passphrase);
201 printf("Bad passphrase.\n"); 345 printf("Bad passphrase.\n");
@@ -230,19 +374,19 @@ do_change_passphrase(struct passwd *pw)
230 } 374 }
231 375
232 /* Save the file using the new passphrase. */ 376 /* Save the file using the new passphrase. */
233 if (!save_private_key(identity_file, passphrase1, private_key, comment)) { 377 if (!save_private_key(identity_file, passphrase1, private, comment)) {
234 printf("Saving the key failed: %s: %s.\n", 378 printf("Saving the key failed: %s: %s.\n",
235 identity_file, strerror(errno)); 379 identity_file, strerror(errno));
236 memset(passphrase1, 0, strlen(passphrase1)); 380 memset(passphrase1, 0, strlen(passphrase1));
237 xfree(passphrase1); 381 xfree(passphrase1);
238 RSA_free(private_key); 382 key_free(private);
239 xfree(comment); 383 xfree(comment);
240 exit(1); 384 exit(1);
241 } 385 }
242 /* Destroy the passphrase and the copy of the key in memory. */ 386 /* Destroy the passphrase and the copy of the key in memory. */
243 memset(passphrase1, 0, strlen(passphrase1)); 387 memset(passphrase1, 0, strlen(passphrase1));
244 xfree(passphrase1); 388 xfree(passphrase1);
245 RSA_free(private_key); /* Destroys contents */ 389 key_free(private); /* Destroys contents */
246 xfree(comment); 390 xfree(comment);
247 391
248 printf("Your identification has been saved with the new passphrase.\n"); 392 printf("Your identification has been saved with the new passphrase.\n");
@@ -256,11 +400,11 @@ void
256do_change_comment(struct passwd *pw) 400do_change_comment(struct passwd *pw)
257{ 401{
258 char new_comment[1024], *comment; 402 char new_comment[1024], *comment;
259 RSA *private_key; 403 Key *private;
404 Key *public;
260 char *passphrase; 405 char *passphrase;
261 struct stat st; 406 struct stat st;
262 FILE *f; 407 FILE *f;
263 char *tmpbuf;
264 408
265 if (!have_identity) 409 if (!have_identity)
266 ask_filename(pw, "Enter file in which the key is"); 410 ask_filename(pw, "Enter file in which the key is");
@@ -272,14 +416,14 @@ do_change_comment(struct passwd *pw)
272 * Try to load the public key from the file the verify that it is 416 * Try to load the public key from the file the verify that it is
273 * readable and of the proper format. 417 * readable and of the proper format.
274 */ 418 */
275 public_key = RSA_new(); 419 public = key_new(KEY_RSA);
276 if (!load_public_key(identity_file, public_key, NULL)) { 420 if (!load_public_key(identity_file, public, NULL)) {
277 printf("%s is not a valid key file.\n", identity_file); 421 printf("%s is not a valid key file.\n", identity_file);
278 exit(1); 422 exit(1);
279 } 423 }
280 private_key = RSA_new();
281 424
282 if (load_private_key(identity_file, "", private_key, &comment)) 425 private = key_new(KEY_RSA);
426 if (load_private_key(identity_file, "", private, &comment))
283 passphrase = xstrdup(""); 427 passphrase = xstrdup("");
284 else { 428 else {
285 if (identity_passphrase) 429 if (identity_passphrase)
@@ -289,7 +433,7 @@ do_change_comment(struct passwd *pw)
289 else 433 else
290 passphrase = read_passphrase("Enter passphrase: ", 1); 434 passphrase = read_passphrase("Enter passphrase: ", 1);
291 /* Try to load using the passphrase. */ 435 /* Try to load using the passphrase. */
292 if (!load_private_key(identity_file, passphrase, private_key, &comment)) { 436 if (!load_private_key(identity_file, passphrase, private, &comment)) {
293 memset(passphrase, 0, strlen(passphrase)); 437 memset(passphrase, 0, strlen(passphrase));
294 xfree(passphrase); 438 xfree(passphrase);
295 printf("Bad passphrase.\n"); 439 printf("Bad passphrase.\n");
@@ -305,7 +449,7 @@ do_change_comment(struct passwd *pw)
305 fflush(stdout); 449 fflush(stdout);
306 if (!fgets(new_comment, sizeof(new_comment), stdin)) { 450 if (!fgets(new_comment, sizeof(new_comment), stdin)) {
307 memset(passphrase, 0, strlen(passphrase)); 451 memset(passphrase, 0, strlen(passphrase));
308 RSA_free(private_key); 452 key_free(private);
309 exit(1); 453 exit(1);
310 } 454 }
311 if (strchr(new_comment, '\n')) 455 if (strchr(new_comment, '\n'))
@@ -313,18 +457,18 @@ do_change_comment(struct passwd *pw)
313 } 457 }
314 458
315 /* Save the file using the new passphrase. */ 459 /* Save the file using the new passphrase. */
316 if (!save_private_key(identity_file, passphrase, private_key, new_comment)) { 460 if (!save_private_key(identity_file, passphrase, private, new_comment)) {
317 printf("Saving the key failed: %s: %s.\n", 461 printf("Saving the key failed: %s: %s.\n",
318 identity_file, strerror(errno)); 462 identity_file, strerror(errno));
319 memset(passphrase, 0, strlen(passphrase)); 463 memset(passphrase, 0, strlen(passphrase));
320 xfree(passphrase); 464 xfree(passphrase);
321 RSA_free(private_key); 465 key_free(private);
322 xfree(comment); 466 xfree(comment);
323 exit(1); 467 exit(1);
324 } 468 }
325 memset(passphrase, 0, strlen(passphrase)); 469 memset(passphrase, 0, strlen(passphrase));
326 xfree(passphrase); 470 xfree(passphrase);
327 RSA_free(private_key); 471 key_free(private);
328 472
329 strlcat(identity_file, ".pub", sizeof(identity_file)); 473 strlcat(identity_file, ".pub", sizeof(identity_file));
330 f = fopen(identity_file, "w"); 474 f = fopen(identity_file, "w");
@@ -332,13 +476,10 @@ do_change_comment(struct passwd *pw)
332 printf("Could not save your public key in %s\n", identity_file); 476 printf("Could not save your public key in %s\n", identity_file);
333 exit(1); 477 exit(1);
334 } 478 }
335 fprintf(f, "%d ", BN_num_bits(public_key->n)); 479 if (!key_write(public, f))
336 tmpbuf = BN_bn2dec(public_key->e); 480 fprintf(stderr, "write key failed");
337 fprintf(f, "%s ", tmpbuf); 481 key_free(public);
338 free(tmpbuf); 482 fprintf(f, " %s\n", new_comment);
339 tmpbuf = BN_bn2dec(public_key->n);
340 fprintf(f, "%s %s\n", tmpbuf, new_comment);
341 free(tmpbuf);
342 fclose(f); 483 fclose(f);
343 484
344 xfree(comment); 485 xfree(comment);
@@ -351,7 +492,7 @@ void
351usage(void) 492usage(void)
352{ 493{
353 printf("ssh-keygen version %s\n", SSH_VERSION); 494 printf("ssh-keygen version %s\n", SSH_VERSION);
354 printf("Usage: %s [-b bits] [-p] [-c] [-l] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname); 495 printf("Usage: %s [-b bits] [-p] [-c] [-l] [-x] [-X] [-y] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname);
355 exit(1); 496 exit(1);
356} 497}
357 498
@@ -363,29 +504,28 @@ main(int ac, char **av)
363{ 504{
364 char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2; 505 char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2;
365 struct passwd *pw; 506 struct passwd *pw;
366 char *tmpbuf;
367 int opt; 507 int opt;
368 struct stat st; 508 struct stat st;
369 FILE *f; 509 FILE *f;
370 char hostname[MAXHOSTNAMELEN]; 510 Key *private;
511 Key *public;
371 extern int optind; 512 extern int optind;
372 extern char *optarg; 513 extern char *optarg;
373 514
374 /* check if RSA support exists */ 515 OpenSSL_add_all_algorithms();
375 if (rsa_alive() == 0) { 516
376 fprintf(stderr,
377 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
378 __progname);
379 exit(1);
380 }
381 /* we need this for the home * directory. */ 517 /* we need this for the home * directory. */
382 pw = getpwuid(getuid()); 518 pw = getpwuid(getuid());
383 if (!pw) { 519 if (!pw) {
384 printf("You don't exist, go away!\n"); 520 printf("You don't exist, go away!\n");
385 exit(1); 521 exit(1);
386 } 522 }
523 if (gethostname(hostname, sizeof(hostname)) < 0) {
524 perror("gethostname");
525 exit(1);
526 }
387 527
388 while ((opt = getopt(ac, av, "qpclb:f:P:N:C:")) != EOF) { 528 while ((opt = getopt(ac, av, "dqpclRxXyb:f:P:N:C:")) != EOF) {
389 switch (opt) { 529 switch (opt) {
390 case 'b': 530 case 'b':
391 bits = atoi(optarg); 531 bits = atoi(optarg);
@@ -428,6 +568,29 @@ main(int ac, char **av)
428 quiet = 1; 568 quiet = 1;
429 break; 569 break;
430 570
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
431 case '?': 594 case '?':
432 default: 595 default:
433 usage(); 596 usage();
@@ -441,22 +604,44 @@ main(int ac, char **av)
441 printf("Can only have one of -p and -c.\n"); 604 printf("Can only have one of -p and -c.\n");
442 usage(); 605 usage();
443 } 606 }
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 }
444 if (print_fingerprint) 614 if (print_fingerprint)
445 do_fingerprint(pw); 615 do_fingerprint(pw);
446 if (change_passphrase) 616 if (change_passphrase)
447 do_change_passphrase(pw); 617 do_change_passphrase(pw);
448 if (change_comment) 618 if (change_comment)
449 do_change_comment(pw); 619 do_change_comment(pw);
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);
450 626
451 arc4random_stir(); 627 arc4random_stir();
452 628
453 if (quiet) 629 if (dsa_mode != 0) {
454 rsa_set_verbose(0); 630 if (!quiet)
455 631 printf("Generating DSA parameter and key.\n");
456 /* Generate the rsa key pair. */ 632 public = private = dsa_generate_key(bits);
457 private_key = RSA_new(); 633 if (private == NULL) {
458 public_key = RSA_new(); 634 fprintf(stderr, "dsa_generate_keys failed");
459 rsa_generate_key(private_key, public_key, bits); 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 }
460 645
461 if (!have_identity) 646 if (!have_identity)
462 ask_filename(pw, "Enter file in which to save the key"); 647 ask_filename(pw, "Enter file in which to save the key");
@@ -509,17 +694,13 @@ passphrase_again:
509 strlcpy(comment, identity_comment, sizeof(comment)); 694 strlcpy(comment, identity_comment, sizeof(comment));
510 } else { 695 } else {
511 /* Create default commend field for the passphrase. */ 696 /* Create default commend field for the passphrase. */
512 if (gethostname(hostname, sizeof(hostname)) < 0) {
513 perror("gethostname");
514 exit(1);
515 }
516 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); 697 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
517 } 698 }
518 699
519 /* Save the key with the given passphrase and comment. */ 700 /* Save the key with the given passphrase and comment. */
520 if (!save_private_key(identity_file, passphrase1, private_key, comment)) { 701 if (!save_private_key(identity_file, passphrase1, private, comment)) {
521 printf("Saving the key failed: %s: %s.\n", 702 printf("Saving the key failed: %s: %s.\n",
522 identity_file, strerror(errno)); 703 identity_file, strerror(errno));
523 memset(passphrase1, 0, strlen(passphrase1)); 704 memset(passphrase1, 0, strlen(passphrase1));
524 xfree(passphrase1); 705 xfree(passphrase1);
525 exit(1); 706 exit(1);
@@ -529,7 +710,9 @@ passphrase_again:
529 xfree(passphrase1); 710 xfree(passphrase1);
530 711
531 /* Clear the private key and the random number generator. */ 712 /* Clear the private key and the random number generator. */
532 RSA_free(private_key); 713 if (private != public) {
714 key_free(private);
715 }
533 arc4random_stir(); 716 arc4random_stir();
534 717
535 if (!quiet) 718 if (!quiet)
@@ -541,21 +724,18 @@ passphrase_again:
541 printf("Could not save your public key in %s\n", identity_file); 724 printf("Could not save your public key in %s\n", identity_file);
542 exit(1); 725 exit(1);
543 } 726 }
544 fprintf(f, "%d ", BN_num_bits(public_key->n)); 727 if (!key_write(public, f))
545 tmpbuf = BN_bn2dec(public_key->e); 728 fprintf(stderr, "write key failed");
546 fprintf(f, "%s ", tmpbuf); 729 fprintf(f, " %s\n", comment);
547 free(tmpbuf);
548 tmpbuf = BN_bn2dec(public_key->n);
549 fprintf(f, "%s %s\n", tmpbuf, comment);
550 free(tmpbuf);
551 fclose(f); 730 fclose(f);
552 731
553 if (!quiet) { 732 if (!quiet) {
554 printf("Your public key has been saved in %s.\n", identity_file); 733 printf("Your public key has been saved in %s.\n",
734 identity_file);
555 printf("The key fingerprint is:\n"); 735 printf("The key fingerprint is:\n");
556 printf("%d %s %s\n", BN_num_bits(public_key->n), 736 printf("%s %s\n", key_fingerprint(public), comment);
557 fingerprint(public_key->e, public_key->n),
558 comment);
559 } 737 }
738
739 key_free(public);
560 exit(0); 740 exit(0);
561} 741}