]> git.wh0rd.org - ICEs.git/blame - 505182/ssh-keygen.i
more
[ICEs.git] / 505182 / ssh-keygen.i
CommitLineData
bd3239d2
MF
1typedef unsigned int __u_int;
2typedef unsigned long int __u_long;
3__extension__ typedef unsigned int __uid_t;
4__extension__ typedef long int __time_t;
5__extension__ typedef int __ssize_t;
6typedef __u_int u_int;
7typedef __u_long u_long;
8typedef __ssize_t ssize_t;
9typedef __time_t time_t;
10typedef unsigned int size_t;
11typedef unsigned int u_int32_t __attribute__ ((__mode__(__SI__)));
12typedef unsigned int u_int64_t __attribute__ ((__mode__(__DI__)));
13struct stat {
14};
15extern int *__errno_location(void) __attribute__ ((__nothrow__, __leaf__))
16 __attribute__ ((__const__));
17struct passwd {
18 char *pw_name;
19 __uid_t pw_uid;
20 char *pw_dir;
21};
22typedef struct _IO_FILE FILE;
23extern struct _IO_FILE *stdin;
24extern struct _IO_FILE *stdout;
25extern struct _IO_FILE *stderr;
26typedef struct {
27} Buffer;
28typedef struct bignum_st BIGNUM;
29extern ssize_t write(int __fd, const void *__buf, size_t __n)
30 __attribute__ ((__warn_unused_result__));
31typedef struct Key Key;
32enum types {
33 KEY_RSA1, KEY_RSA, KEY_DSA, KEY_ECDSA, KEY_ED25519, KEY_RSA_CERT,
34 KEY_DSA_CERT, KEY_ECDSA_CERT, KEY_ED25519_CERT, KEY_RSA_CERT_V00,
35 KEY_DSA_CERT_V00, KEY_UNSPEC
36};
37enum fp_type {
38 SSH_FP_SHA1, SSH_FP_MD5, SSH_FP_SHA256
39};
40enum fp_rep {
41 SSH_FP_HEX, SSH_FP_BUBBLEBABBLE, SSH_FP_RANDOMART
42};
43struct KeyCert {
44 u_int64_t serial;
45 char *key_id;
46 u_int nprincipals;
47 char **principals;
48 u_int64_t valid_after, valid_before;
49 Buffer critical;
50 Buffer extensions;
51 Key *signature_key;
52};
53struct Key {
54 int type;
55 struct KeyCert *cert;
56};
57typedef enum {
58 SYSLOG_FACILITY_DAEMON, SYSLOG_FACILITY_USER, SYSLOG_FACILITY_AUTH,
59 SYSLOG_FACILITY_LOCAL0, SYSLOG_FACILITY_LOCAL1,
60 SYSLOG_FACILITY_LOCAL2, SYSLOG_FACILITY_LOCAL3,
61 SYSLOG_FACILITY_LOCAL4, SYSLOG_FACILITY_LOCAL5,
62 SYSLOG_FACILITY_LOCAL6, SYSLOG_FACILITY_LOCAL7,
63 SYSLOG_FACILITY_NOT_SET = -1
64} SyslogFacility;
65typedef enum {
66 SYSLOG_LEVEL_QUIET, SYSLOG_LEVEL_FATAL, SYSLOG_LEVEL_ERROR,
67 SYSLOG_LEVEL_INFO, SYSLOG_LEVEL_VERBOSE, SYSLOG_LEVEL_DEBUG1,
68 SYSLOG_LEVEL_DEBUG2, SYSLOG_LEVEL_DEBUG3, SYSLOG_LEVEL_NOT_SET = -1
69} LogLevel;
70u_int32_t bits = 0;
71int change_passphrase = 0;
72int change_comment = 0;
73int quiet = 0;
74int log_level = SYSLOG_LEVEL_INFO;
75int hash_hosts = 0;
76int find_host = 0;
77int delete_host = 0;
78int show_cert = 0;
79int print_fingerprint = 0;
80int print_bubblebabble = 0;
81char identity_file[1024];
82int have_identity = 0;
83char *identity_passphrase = ((void *)0);
84char *identity_new_passphrase = ((void *)0);
85char *identity_comment = ((void *)0);
86char *ca_key_path = ((void *)0);
87unsigned long long cert_serial = 0;
88u_int cert_key_type = 1;
89char *cert_key_id = ((void *)0);
90char *cert_principals = ((void *)0);
91u_int32_t certflags_flags = ((1) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4));
92int convert_to = 0;
93int convert_from = 0;
94enum {
95 FMT_RFC4716, FMT_PKCS8, FMT_PEM
96} convert_format = FMT_RFC4716;
97int print_public = 0;
98int print_generic = 0;
99char *key_type_name = ((void *)0);
100char *pkcs11provider = ((void *)0);
101int use_new_format = 0;
102char *new_format_cipher = ((void *)0);
103int rounds = 0;
104extern char *__progname;
105char hostname[64];
106static void do_download(struct passwd *pw)
107{
108 Key **keys = ((void *)0);
109 int i, nkeys;
110 enum fp_rep rep;
111 enum fp_type fptype;
112 char *fp, *ra;
113 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
114 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
115 pkcs11_init(0);
116 nkeys = pkcs11_add_provider(pkcs11provider, ((void *)0), &keys);
117 if (nkeys <= 0)
118 fatal("cannot read public key from pkcs11");
119 for (i = 0; i < nkeys; i++) {
120 if (print_fingerprint) {
121 fp = key_fingerprint(keys[i], fptype, rep);
122 ra = key_fingerprint(keys[i], SSH_FP_MD5,
123 SSH_FP_RANDOMART);
124 printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), fp,
125 key_type(keys[i]));
126 if (log_level >= SYSLOG_LEVEL_VERBOSE)
127 printf("%s\n", ra);
128 free(ra);
129 free(fp);
130 key_write(keys[i], stdout);
131 fprintf(stdout, "\n");
132 }
133 key_free(keys[i]);
134 }
135 free(keys);
136 exit(0);
137}
138
139static void do_fingerprint(struct passwd *pw)
140{
141 FILE *f;
142 Key *public;
143 char *comment = ((void *)0), *cp, *ep, line[16 * 1024], *fp, *ra;
144 int i, skip = 0, num = 0, invalid = 1;
145 enum fp_rep rep;
146 enum fp_type fptype;
147 struct stat st;
148 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
149 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
150 if (!have_identity)
151 ask_filename(pw, "Enter file in which the key is");
152 if (stat(identity_file, &st) < 0) {
153 perror(identity_file);
154 exit(1);
155 }
156 public = key_load_public(identity_file, &comment);
157 if (public != ((void *)0)) {
158 fp = key_fingerprint(public, fptype, rep);
159 ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
160 printf("%u %s %s (%s)\n", key_size(public), fp, comment,
161 key_type(public));
162 if (log_level >= SYSLOG_LEVEL_VERBOSE)
163 printf("%s\n", ra);
164 key_free(public);
165 free(comment);
166 free(ra);
167 free(fp);
168 exit(0);
169 }
170 if (comment) {
171 free(comment);
172 }
173 if ((f = fopen(identity_file, "r")) == ((void *)0))
174 fatal("%s: %s: %s", __progname, identity_file,
175 strerror((*__errno_location())));
176 while (fgets(line, sizeof(line), f)) {
177 if ((cp =
178 (__extension__
179 (__builtin_constant_p('\n') && !__builtin_constant_p(line)
180 && ('\n') == '\0' ? (char *)__rawmemchr(line,
181 '\n') :
182 __builtin_strchr(line, '\n')))) == ((void *)0)) {
183 error("line %d too long: %.40s...", num + 1, line);
184 skip = 1;
185 }
186 num++;
187 if (skip) {
188 continue;
189 }
190 *cp = '\0';
191 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ;
192 if (!*cp || *cp == '\n' || *cp == '#')
193 continue;
194 i = strtol(cp, &ep, 10);
195 if (i == 0 || ep == ((void *)0) || (*ep != ' ' && *ep != '\t')) {
196 int quoted = 0;
197 comment = cp;
198 for (;
199 *cp && (quoted || (*cp != ' ' && *cp != '\t'));
200 cp++) {
201 if (*cp == '\\' && cp[1] == '"')
202 cp++;
203 else if (*cp == '"')
204 quoted = !quoted;
205 }
206 if (!*cp)
207 continue;
208 *cp++ = '\0';
209 }
210 ep = cp;
211 public = key_new(KEY_RSA1);
212 if (key_read(public, &cp) != 1) {
213 cp = ep;
214 key_free(public);
215 public = key_new(KEY_UNSPEC);
216 if (key_read(public, &cp) != 1) {
217 key_free(public);
218 }
219 }
220 comment = *cp ? cp : comment;
221 fp = key_fingerprint(public, fptype, rep);
222 ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
223 printf("%u %s %s (%s)\n", key_size(public), fp,
224 comment ? comment : "no comment", key_type(public));
225 if (log_level >= SYSLOG_LEVEL_VERBOSE)
226 printf("%s\n", ra);
227 free(ra);
228 free(fp);
229 key_free(public);
230 invalid = 0;
231 }
232 fclose(f);
233 if (invalid) {
234 printf("%s is not a public key file.\n", identity_file);
235 exit(1);
236 }
237}
238
239static void do_gen_all_hostkeys(struct passwd *pw)
240{
241 struct {
242 char *key_type;
243 char *key_type_display;
244 char *path;
245 } key_types[] = {
246 {
247 "rsa1", "RSA1", "/etc/ssh" "/ssh_host_key"}
248 , {
249 "rsa", "RSA", "/etc/ssh" "/ssh_host_rsa_key"}
250 , {
251 ((void *)0), ((void *)0), ((void *)0)}
252 };
253 int first = 0;
254 struct stat st;
255 Key *private, *public;
256 char comment[1024];
257 int i, type, fd;
258 FILE *f;
259 for (i = 0; key_types[i].key_type; i++) {
260 if (stat(key_types[i].path, &st) == 0)
261 continue;
262 if ((*__errno_location()) != 2) {
263 printf("Could not stat %s: %s", key_types[i].path,
264 strerror((*__errno_location())));
265 }
266 if (first == 0) {
267 first = 1;
268 printf("%s: generating new host keys: ", __progname);
269 }
270 printf("%s ", key_types[i].key_type_display);
271 fflush(stdout);
272 type = key_type_from_name(key_types[i].key_type);
273 strlcpy(identity_file, key_types[i].path,
274 sizeof(identity_file));
275 bits = 0;
276 type_bits_valid(type, &bits);
277 private = key_generate(type, bits);
278 if (private == ((void *)0)) {
279 fprintf(stderr, "key_generate failed\n");
280 }
281 public = key_from_private(private);
282 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
283 hostname);
284 if (!key_save_private
285 (private, identity_file, "", comment, use_new_format,
286 new_format_cipher, rounds)) {
287 printf("Saving the key failed: %s.\n", identity_file);
288 key_free(private);
289 key_free(public);
290 }
291 key_free(private);
292 strlcat(identity_file, ".pub", sizeof(identity_file));
293 fd = open(identity_file, 01 | 00000400 | 01000, 0644);
294 if (fd == -1) {
295 printf("Could not save your public key in %s\n",
296 identity_file);
297 key_free(public);
298 }
299 f = fdopen(fd, "w");
300 if (f == ((void *)0)) {
301 printf("fdopen %s failed\n", identity_file);
302 key_free(public);
303 }
304 if (!key_write(public, f)) {
305 fprintf(stderr, "write key failed\n");
306 key_free(public);
307 }
308 fprintf(f, " %s\n", comment);
309 fclose(f);
310 key_free(public);
311 }
312 if (first != 0)
313 printf("\n");
314}
315
316static void do_known_hosts(struct passwd *pw, const char *name)
317{
318 FILE *in, *out = stdout;
319 Key *pub;
320 char *cp, *cp2, *kp, *kp2;
321 char line[16 * 1024], tmp[4096], old[4096];
322 int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
323 int ca;
324 int found_key = 0;
325 if (!have_identity) {
326 cp = tilde_expand_filename("~/" ".ssh" "/known_hosts",
327 pw->pw_uid);
328 if (strlcpy(identity_file, cp, sizeof(identity_file)) >=
329 sizeof(identity_file))
330 fatal("Specified known hosts path too long");
331 free(cp);
332 }
333 if ((in = fopen(identity_file, "r")) == ((void *)0))
334 fatal("%s: %s: %s", __progname, identity_file,
335 strerror((*__errno_location())));
336 if (!find_host && (hash_hosts || delete_host)) {
337 if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp)
338 || strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp)
339 || strlcpy(old, identity_file, sizeof(old)) >= sizeof(old)
340 || strlcat(old, ".old", sizeof(old)) >= sizeof(old))
341 fatal("known_hosts path too long");
342 umask(077);
343 if ((c = mkstemp(tmp)) == -1)
344 fatal("mkstemp: %s", strerror((*__errno_location())));
345 if ((out = fdopen(c, "w")) == ((void *)0)) {
346 c = (*__errno_location());
347 unlink(tmp);
348 fatal("fdopen: %s", strerror(c));
349 }
350 inplace = 1;
351 }
352 while (fgets(line, sizeof(line), in)) {
353 if ((cp =
354 (__extension__
355 (__builtin_constant_p('\n') && !__builtin_constant_p(line)
356 && ('\n') == '\0' ? (char *)__rawmemchr(line,
357 '\n') :
358 __builtin_strchr(line, '\n')))) == ((void *)0)) {
359 error("line %d too long: %.40s...", num + 1, line);
360 skip = 1;
361 invalid = 1;
362 continue;
363 }
364 num++;
365 if (skip) {
366 continue;
367 }
368 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ;
369 if (!*cp || *cp == '\n' || *cp == '#') {
370 if (inplace)
371 fprintf(out, "%s\n", cp);
372 }
373 if (strncasecmp
374 (cp, "@cert-authority", sizeof("@cert-authority") - 1) == 0
375 && (cp[sizeof("@cert-authority") - 1] == ' '
376 || cp[sizeof("@cert-authority") - 1] == '\t')) {
377 ca = 1;
378 cp += sizeof("@cert-authority");
379 } else
380 ca = 0;
381 for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++) ;
382 if (*kp == '\0' || *(kp + 1) == '\0') {
383 error("line %d missing key: %.40s...", num, line);
384 }
385 *kp++ = '\0';
386 pub = key_new(KEY_RSA1);
387 if (key_read(pub, &kp) != 1) {
388 kp = kp2;
389 key_free(pub);
390 pub = key_new(KEY_UNSPEC);
391 if (key_read(pub, &kp) != 1) {
392 error("line %d invalid key: %.40s...", num,
393 line);
394 key_free(pub);
395 }
396 }
397 if (*cp == '|') {
398 if (find_host || delete_host) {
399 cp2 = host_hash(name, cp, strlen(cp));
400 if (cp2 == ((void *)0)) {
401 error("line %d: invalid hashed "
402 "name: %.64s...", num, line);
403 }
404 c = (__extension__( {
405 size_t __s1_len, __s2_len;
406 (__builtin_constant_p(cp2)
407 && __builtin_constant_p(cp)
408 && (__s1_len =
409 strlen(cp2), __s2_len =
410 strlen(cp),
411 (!((size_t)
412 (const void *)((cp2)
413 + 1) -
414 (size_t) (const void
415 *)(cp2) ==
416 1) || __s1_len >= 4)
417 &&
418 (!((size_t)
419 (const void *)((cp) +
420 1) -
421 (size_t) (const void
422 *)(cp) ==
423 1)
424 || __s2_len >=
425 4)) ?
426 __builtin_strcmp(cp2,
427 cp)
428 : (__builtin_constant_p(cp2)
429 &&
430 ((size_t) (const void *)
431 ((cp2) + 1) -
432 (size_t) (const void
433 *)(cp2) == 1)
434 && (__s1_len =
435 strlen(cp2),
436 __s1_len <
437 4)
438 ? (__builtin_constant_p
439 (cp)
440 &&
441 ((size_t)
442 (const void *)((cp) +
443 1) -
444 (size_t) (const void
445 *)(cp) ==
446 1) ?
447 __builtin_strcmp(cp2,
448 cp)
449 : (__extension__( {
450 const
451 unsigned
452 char
453 *__s2
454 =
455 (const
456 unsigned
457 char
458 *)
459 (const
460 char
461 *)
462 (cp);
463 register
464 int
465 __result
466 =
467 (((const unsigned char *)(const char *)(cp2))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) {
468 }
469 __result;}
470 ))):
471 (__builtin_constant_p(cp)
472 &&
473 ((size_t) (const void *)
474 ((cp) + 1) -
475 (size_t) (const void
476 *)(cp) == 1)
477 && (__s2_len =
478 strlen(cp),
479 __s2_len <
480 4)
481 ? (__builtin_constant_p
482 (cp2)
483 &&
484 ((size_t)
485 (const void *)((cp2)
486 +
487 1) -
488 (size_t) (const void
489 *)(cp2) ==
490 1) ?
491 __builtin_strcmp(cp2,
492 cp)
493 : (__extension__( {
494 const
495 unsigned
496 char
497 *__s1
498 =
499 (const
500 unsigned
501 char
502 *)
503 (const
504 char
505 *)
506 (cp2);
507 register
508 int
509 __result
510 =
511 __s1
512 [0]
513 -
514 ((const unsigned char *)(const char *)(cp))[0]; __result;}
515 ))):
516 __builtin_strcmp(cp2,
517 cp))));}
518 ) == 0) ;
519 if (find_host && c) {
520 if (!quiet)
521 printf("# Host %s found: "
522 "line %d type %s%s\n",
523 name, num, key_type(pub),
524 ca ? " (CA key)" : "");
525 printhost(out, cp, pub, ca, 0);
526 found_key = 1;
527 }
528 if (delete_host) {
529 if (!c && !ca)
530 printhost(out, cp, pub, ca, 0);
531 else
532 printf("# Host %s found: "
533 "line %d type %s\n",
534 name, num,
535 key_type(pub));
536 }
537 } else if (hash_hosts)
538 printhost(out, cp, pub, ca, 0);
539 if (find_host || delete_host) {
540 c = (match_hostname(name, cp, strlen(cp)) == 1);
541 if (find_host && c) {
542 if (!quiet)
543 printf("# Host %s found: "
544 "line %d type %s%s\n",
545 name, num, key_type(pub),
546 ca ? " (CA key)" : "");
547 printhost(out, name, pub, ca, hash_hosts
548 && !ca);
549 }
550 if (delete_host) {
551 if (!c && !ca)
552 printhost(out, cp, pub, ca, 0);
553 else
554 printf("# Host %s found: "
555 "line %d type %s\n",
556 name, num,
557 key_type(pub));
558 }
559 } else if (hash_hosts) {
560 for (cp2 = __extension__( {
561 char __r0, __r1, __r2;
562 (__builtin_constant_p
563 (",")
564 &&
565 ((size_t)
566 (const void *)((",")
567 + 1) -
568 (size_t) (const void
569 *)(",") ==
570 1)
571 && (__r0 =
572 ((const char
573 *)(","))[0],
574 ((const char
575 *)(","))[0] !=
576 '\0') ? ((__r1 =
577 ((const
578 char
579 *)
580 (","))
581 [1],
582 ((const
583 char
584 *)
585 (","))
586 [1] ==
587 '\0') ?
588 __strsep_1c
589 (&cp,
590 __r0)
591 : ((__r2
592 =
593 ((const char *)(","))[2], __r2 == '\0') ? __strsep_2c(&cp, __r0, __r1) : (((const char *)(","))[3] == '\0' ? __strsep_3c(&cp, __r0, __r1, __r2) : __strsep_g(&cp, ",")))) : __strsep_g(&cp, ","));}
594 ); cp2 != ((void *)0) && *cp2 != '\0';
595 cp2 = __extension__( {
596 char __r0, __r1, __r2;
597 (__builtin_constant_p
598 (",")
599 &&
600 ((size_t)
601 (const void *)((",")
602 + 1) -
603 (size_t) (const void
604 *)(",") ==
605 1)
606 && (__r0 =
607 ((const char
608 *)(","))[0],
609 ((const char
610 *)(","))[0] !=
611 '\0') ? ((__r1 =
612 ((const
613 char
614 *)
615 (","))
616 [1],
617 ((const
618 char
619 *)
620 (","))
621 [1] ==
622 '\0') ?
623 __strsep_1c
624 (&cp,
625 __r0)
626 : ((__r2
627 =
628 ((const char *)(","))[2], __r2 == '\0') ? __strsep_2c(&cp, __r0, __r1) : (((const char *)(","))[3] == '\0' ? __strsep_3c(&cp, __r0, __r1, __r2) : __strsep_g(&cp, ",")))) : __strsep_g(&cp, ","));}
629 )) {
630 if (ca) {
631 fprintf(stderr,
632 "Warning: "
633 "ignoring CA key for host: "
634 "%.64s\n", cp2);
635 printhost(out, cp2, pub, ca, 0);
636 } else if (__extension__( {
637 char __r0,
638 __r1, __r2;
639 (__builtin_constant_p
640 ("*?!")
641 &&
642 ((size_t)
643 (const void
644 *)(("*?!") +
645 1) -
646 (size_t)
647 (const void
648 *)("*?!") ==
649 1)
650 ? ((__builtin_constant_p(cp2) && ((size_t) (const void *)((cp2) + 1) - (size_t) (const void *)(cp2) == 1)) ? __builtin_strcspn(cp2, "*?!") : ((__r0 = ((const char *)("*?!"))[0], __r0 == '\0') ? strlen(cp2) : ((__r1 = ((const char *)("*?!"))[1], __r1 == '\0') ? __strcspn_c1(cp2, __r0) : ((__r2 = ((const char *)("*?!"))[2], __r2 == '\0') ? __strcspn_c2(cp2, __r0, __r1) : (((const char *)("*?!"))[3] == '\0' ? __strcspn_c3(cp2, __r0, __r1, __r2) : __builtin_strcspn(cp2, "*?!")))))) : __builtin_strcspn(cp2, "*?!"));}
651 ) != strlen(cp2)) {
652 fprintf(stderr,
653 "Warning: "
654 "ignoring host name with "
655 "metacharacters: %.64s\n",
656 cp2);
657 printhost(out, cp2, pub, ca, 0);
658 } else
659 printhost(out, cp2, pub, ca, 1);
660 }
661 has_unhashed = 1;
662 }
663 }
664 key_free(pub);
665 }
666 fclose(in);
667 if (invalid) {
668 fprintf(stderr, "%s is not a valid known_hosts file.\n",
669 identity_file);
670 if (inplace) {
671 fprintf(stderr,
672 "Not replacing existing known_hosts "
673 "file because of errors\n");
674 fclose(out);
675 unlink(tmp);
676 }
677 exit(1);
678 }
679 if (inplace) {
680 fclose(out);
681 if (unlink(old) == -1 && (*__errno_location()) != 2)
682 fatal("unlink %.100s: %s", old,
683 strerror((*__errno_location())));
684 if (link(identity_file, old) == -1)
685 fatal("link %.100s to %.100s: %s", identity_file, old,
686 strerror((*__errno_location())));
687 if (rename(tmp, identity_file) == -1) {
688 error("rename\"%s\" to \"%s\": %s", tmp, identity_file,
689 strerror((*__errno_location())));
690 unlink(tmp);
691 unlink(old);
692 exit(1);
693 }
694 fprintf(stderr, "%s updated.\n", identity_file);
695 fprintf(stderr, "Original contents retained as %s\n", old);
696 if (has_unhashed) {
697 fprintf(stderr,
698 "WARNING: %s contains unhashed " "entries\n",
699 old);
700 fprintf(stderr,
701 "Delete this file to ensure privacy "
702 "of hostnames\n");
703 }
704 }
705 exit(find_host && !found_key);
706}
707
708static void do_change_passphrase(struct passwd *pw)
709{
710 char *comment;
711 char *old_passphrase, *passphrase1, *passphrase2;
712 struct stat st;
713 Key *private;
714 if (!have_identity)
715 ask_filename(pw, "Enter file in which the key is");
716 if (stat(identity_file, &st) < 0) {
717 perror(identity_file);
718 exit(1);
719 }
720 private = key_load_private(identity_file, "", &comment);
721 if (private == ((void *)0)) {
722 if (identity_passphrase)
723 old_passphrase = xstrdup(identity_passphrase);
724 else
725 old_passphrase =
726 read_passphrase("Enter old passphrase: ", 0x0002);
727 private =
728 key_load_private(identity_file, old_passphrase, &comment);
729 explicit_bzero(old_passphrase, strlen(old_passphrase));
730 free(old_passphrase);
731 if (private == ((void *)0)) {
732 printf("Bad passphrase.\n");
733 exit(1);
734 }
735 }
736 printf("Key has comment '%s'\n", comment);
737 if (identity_new_passphrase) {
738 passphrase1 = xstrdup(identity_new_passphrase);
739 } else {
740 passphrase1 =
741 read_passphrase("Enter new passphrase (empty for no "
742 "passphrase): ", 0x0002);
743 passphrase2 =
744 read_passphrase("Enter same passphrase again: ", 0x0002);
745 if (__extension__( {
746 size_t __s1_len, __s2_len;
747 (__builtin_constant_p(passphrase1)
748 && __builtin_constant_p(passphrase2)
749 && (__s1_len =
750 strlen(passphrase1), __s2_len =
751 strlen(passphrase2),
752 (!((size_t) (const void *)
753 ((passphrase1) + 1) -
754 (size_t) (const void *)(passphrase1)
755 == 1) || __s1_len >= 4)
756 &&
757 (!((size_t) (const void *)
758 ((passphrase2) + 1) -
759 (size_t) (const void *)(passphrase2)
760 == 1)
761 || __s2_len >=
762 4)) ? __builtin_strcmp(passphrase1,
763 passphrase2)
764 : (__builtin_constant_p(passphrase1)
765 &&
766 ((size_t) (const void *)
767 ((passphrase1) + 1) -
768 (size_t) (const void *)(passphrase1) ==
769 1)
770 && (__s1_len =
771 strlen(passphrase1),
772 __s1_len <
773 4)
774 ? (__builtin_constant_p(passphrase2)
775 &&
776 ((size_t) (const void *)
777 ((passphrase2) + 1) -
778 (size_t) (const void *)(passphrase2)
779 == 1) ? __builtin_strcmp(passphrase1,
780 passphrase2)
781 : (__extension__( {
782 const unsigned char
783 *__s2 =
784 (const unsigned char
785 *)(const char
786 *)(passphrase2);
787 register int __result
788 =
789 (((const unsigned char
790 *)(const char
791 *)(passphrase1))
792 [0] - __s2[0]);
793 __result;}
794 ))): (__builtin_constant_p(passphrase2)
795 &&
796 ((size_t) (const void *)
797 ((passphrase2) + 1) -
798 (size_t) (const void
799 *)(passphrase2) == 1)
800 && (__s2_len =
801 strlen(passphrase2),
802 __s2_len <
803 4)
804 ? (__builtin_constant_p
805 (passphrase1)
806 &&
807 ((size_t) (const void *)
808 ((passphrase1) + 1) -
809 (size_t) (const void
810 *)(passphrase1) ==
811 1) ?
812 __builtin_strcmp(passphrase1,
813 passphrase2)
814 : (__extension__( {
815 const unsigned
816 char *__s1 =
817 (const unsigned
818 char *)(const
819 char
820 *)
821 (passphrase1);
822 register int
823 __result =
824 __s1[0] -
825 ((const
826 unsigned char
827 *)(const char
828 *)
829 (passphrase2))
830 [0];
831 if (__s2_len >
832 0
833 && __result
834 == 0) {
835 }
836 __result;}
837 ))): __builtin_strcmp(passphrase1,
838 passphrase2))));}
839 ) != 0) {
840 explicit_bzero(passphrase1, strlen(passphrase1));
841 explicit_bzero(passphrase2, strlen(passphrase2));
842 free(passphrase1);
843 free(passphrase2);
844 printf("Pass phrases do not match. Try again.\n");
845 exit(1);
846 }
847 explicit_bzero(passphrase2, strlen(passphrase2));
848 free(passphrase2);
849 }
850 if (!key_save_private
851 (private, identity_file, passphrase1, comment, use_new_format,
852 new_format_cipher, rounds)) {
853 printf("Saving the key failed: %s.\n", identity_file);
854 explicit_bzero(passphrase1, strlen(passphrase1));
855 free(passphrase1);
856 key_free(private);
857 free(comment);
858 exit(1);
859 }
860 explicit_bzero(passphrase1, strlen(passphrase1));
861 free(passphrase1);
862 key_free(private);
863 free(comment);
864 printf("Your identification has been saved with the new passphrase.\n");
865 exit(0);
866}
867
868static void do_change_comment(struct passwd *pw)
869{
870 char new_comment[1024], *comment, *passphrase;
871 Key *private;
872 Key *public;
873 struct stat st;
874 FILE *f;
875 int fd;
876 if (!have_identity)
877 ask_filename(pw, "Enter file in which the key is");
878 if (stat(identity_file, &st) < 0) {
879 perror(identity_file);
880 exit(1);
881 }
882 private = key_load_private(identity_file, "", &comment);
883 if (private == ((void *)0)) {
884 if (identity_passphrase)
885 passphrase = xstrdup(identity_passphrase);
886 else if (identity_new_passphrase)
887 passphrase = xstrdup(identity_new_passphrase);
888 else
889 passphrase =
890 read_passphrase("Enter passphrase: ", 0x0002);
891 private = key_load_private(identity_file, passphrase, &comment);
892 if (private == ((void *)0)) {
893 explicit_bzero(passphrase, strlen(passphrase));
894 free(passphrase);
895 printf("Bad passphrase.\n");
896 exit(1);
897 }
898 passphrase = xstrdup("");
899 }
900 if (private->type != KEY_RSA1) {
901 fprintf(stderr, "Comments are only supported for RSA1 keys.\n");
902 key_free(private);
903 exit(1);
904 }
905 printf("Key now has comment '%s'\n", comment);
906 if (identity_comment) {
907 strlcpy(new_comment, identity_comment, sizeof(new_comment));
908 printf("Enter new comment: ");
909 fflush(stdout);
910 if (!fgets(new_comment, sizeof(new_comment), stdin)) {
911 explicit_bzero(passphrase, strlen(passphrase));
912 key_free(private);
913 exit(1);
914 }
915 new_comment[__extension__( {
916 char __r0, __r1, __r2;
917 (__builtin_constant_p("\n")
918 &&
919 ((size_t) (const void *)(("\n") + 1)
920 - (size_t) (const void *)("\n") ==
921 1)
922 ? ((__builtin_constant_p(new_comment)
923 &&
924 ((size_t) (const void *)
925 ((new_comment) + 1) -
926 (size_t) (const void
927 *)(new_comment) ==
928 1)) ?
929 __builtin_strcspn(new_comment,
930 "\n") : ((__r0 =
931 ((const char *)("\n"))[0], __r0 == '\0') ? strlen(new_comment) : ((__r1 = ((const char *)("\n"))[1], __r1 == '\0') ? __strcspn_c1(new_comment, __r0) : ((__r2 = ((const char *)("\n"))[2], __r2 == '\0') ? __strcspn_c2(new_comment, __r0, __r1) : (((const char *)("\n"))[3] == '\0' ? __strcspn_c3(new_comment, __r0, __r1, __r2) : __builtin_strcspn(new_comment, "\n")))))) : __builtin_strcspn(new_comment, "\n"));}
932 )] = '\0';
933 }
934 if (!key_save_private
935 (private, identity_file, passphrase, new_comment, use_new_format,
936 new_format_cipher, rounds)) {
937 printf("Saving the key failed: %s.\n", identity_file);
938 explicit_bzero(passphrase, strlen(passphrase));
939 free(passphrase);
940 key_free(private);
941 free(comment);
942 exit(1);
943 }
944 explicit_bzero(passphrase, strlen(passphrase));
945 free(passphrase);
946 public = key_from_private(private);
947 key_free(private);
948 strlcat(identity_file, ".pub", sizeof(identity_file));
949 fd = open(identity_file, 01 | 00000400 | 01000, 0644);
950 if (fd == -1) {
951 printf("Could not save your public key in %s\n", identity_file);
952 exit(1);
953 }
954 f = fdopen(fd, "w");
955 if (f == ((void *)0)) {
956 printf("fdopen %s failed\n", identity_file);
957 exit(1);
958 }
959 if (!key_write(public, f))
960 fprintf(stderr, "write key failed\n");
961 key_free(public);
962 fprintf(f, " %s\n", new_comment);
963 fclose(f);
964 free(comment);
965 printf("The comment in your key file has been changed.\n");
966 exit(0);
967}
968
969static const char *fmt_validity(u_int64_t valid_from, u_int64_t valid_to)
970{
971 char from[32], to[32];
972 static char ret[64];
973 time_t tt;
974 struct tm *tm;
975 *from = *to = '\0';
976 if (valid_from == 0 && valid_to == 0xffffffffffffffffULL)
977 return "forever";
978 if (valid_from != 0) {
979 tt = valid_from > 2147483647 ? 2147483647 : valid_from;
980 tm = localtime(&tt);
981 strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm);
982 }
983 if (valid_to != 0xffffffffffffffffULL) {
984 tt = valid_to > 2147483647 ? 2147483647 : valid_to;
985 tm = localtime(&tt);
986 strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm);
987 }
988 if (valid_from == 0) {
989 snprintf(ret, sizeof(ret), "before %s", to);
990 }
991 if (valid_to == 0xffffffffffffffffULL) {
992 snprintf(ret, sizeof(ret), "after %s", from);
993 }
994 snprintf(ret, sizeof(ret), "from %s to %s", from, to);
995}
996
997static void do_show_cert(struct passwd *pw)
998{
999 Key *key;
1000 struct stat st;
1001 char *key_fp, *ca_fp;
1002 u_int i, v00;
1003 if (!have_identity)
1004 ask_filename(pw, "Enter file in which the key is");
1005 if (stat(identity_file, &st) < 0)
1006 fatal("%s: %s: %s", __progname, identity_file,
1007 strerror((*__errno_location())));
1008 if ((key = key_load_public(identity_file, ((void *)0))) == ((void *)0))
1009 fatal("%s is not a public key", identity_file);
1010 if (!key_is_cert(key))
1011 fatal("%s is not a certificate", identity_file);
1012 v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
1013 key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
1014 ca_fp =
1015 key_fingerprint(key->cert->signature_key, SSH_FP_MD5, SSH_FP_HEX);
1016 printf("%s:\n", identity_file);
1017 printf(" Type: %s %s certificate\n", key_ssh_name(key),
1018 key_cert_type(key));
1019 printf(" Public key: %s %s\n", key_type(key), key_fp);
1020 printf(" Signing CA: %s %s\n",
1021 key_type(key->cert->signature_key), ca_fp);
1022 printf(" Key ID: \"%s\"\n", key->cert->key_id);
1023 if (!v00) {
1024 printf(" Serial: %llu\n",
1025 (unsigned long long)key->cert->serial);
1026 }
1027 printf(" Valid: %s\n",
1028 fmt_validity(key->cert->valid_after, key->cert->valid_before));
1029 printf(" Principals: ");
1030 if (key->cert->nprincipals == 0)
1031 printf("(none)\n");
1032 else {
1033 for (i = 0; i < key->cert->nprincipals; i++)
1034 printf("\n %s",
1035 key->cert->principals[i]);
1036 printf("\n");
1037 }
1038 printf(" Critical Options: ");
1039 if (buffer_len(&key->cert->critical) == 0)
1040 printf("(none)\n");
1041 else {
1042 printf("\n");
1043 show_options(&key->cert->critical, v00, 1);
1044 }
1045 if (!v00) {
1046 printf(" Extensions: ");
1047 if (buffer_len(&key->cert->extensions) == 0)
1048 printf("(none)\n");
1049 else {
1050 printf("\n");
1051 show_options(&key->cert->extensions, v00, 0);
1052 }
1053 }
1054 exit(0);
1055}
1056
1057static void do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
1058{
1059 struct ssh_krl *krl;
1060 struct stat sb;
1061 Key *ca = ((void *)0);
1062 int fd, i;
1063 char *tmp;
1064 Buffer kbuf;
1065 if (*identity_file == '\0')
1066 fatal("KRL generation requires an output file");
1067 if (stat(identity_file, &sb) == -1) {
1068 if ((*__errno_location()) != 2)
1069 fatal("Cannot access KRL \"%s\": %s", identity_file,
1070 strerror((*__errno_location())));
1071 if (updating)
1072 fatal("KRL \"%s\" does not exist", identity_file);
1073 }
1074 if (ca_key_path != ((void *)0)) {
1075 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1076 if ((ca = key_load_public(tmp, ((void *)0))) == ((void *)0))
1077 fatal("Cannot load CA public key %s", tmp);
1078 free(tmp);
1079 }
1080 if (updating)
1081 load_krl(identity_file, &krl);
1082 else if ((krl = ssh_krl_init()) == ((void *)0))
1083 fatal("couldn't create KRL");
1084 if (cert_serial != 0)
1085 ssh_krl_set_version(krl, cert_serial);
1086 if (identity_comment != ((void *)0))
1087 ssh_krl_set_comment(krl, identity_comment);
1088 for (i = 0; i < argc; i++)
1089 update_krl_from_file(pw, argv[i], ca, krl);
1090 buffer_init(&kbuf);
1091 if (ssh_krl_to_blob(krl, &kbuf, ((void *)0), 0) != 0)
1092 fatal("Couldn't generate KRL");
1093 if ((fd = open(identity_file, 01 | 00000400 | 01000, 0644)) == -1)
1094 fatal("open %s: %s", identity_file,
1095 strerror((*__errno_location())));
1096 if (atomicio
1097 ((ssize_t(*)(int, void *, size_t))write, fd, buffer_ptr(&kbuf),
1098 buffer_len(&kbuf)) != buffer_len(&kbuf))
1099 fatal("write %s: %s", identity_file,
1100 strerror((*__errno_location())));
1101 close(fd);
1102 buffer_free(&kbuf);
1103 ssh_krl_free(krl);
1104 if (ca != ((void *)0))
1105 key_free(ca);
1106}
1107
1108static void usage(void)
1109{
1110 exit(1);
1111}
1112
1113int main(int argc, char **argv)
1114{
1115 char dotsshdir[4096], comment[1024], *passphrase1, *passphrase2;
1116 char *checkpoint = ((void *)0);
1117 char out_file[4096], *ep, *rr_hostname = ((void *)0);
1118 Key *private, *public;
1119 struct passwd *pw;
1120 struct stat st;
1121 int opt, type, fd;
1122 u_int32_t memory = 0, generator_wanted = 0;
1123 int do_gen_candidates = 0, do_screen_candidates = 0;
1124 int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
1125 unsigned long start_lineno = 0, lines_to_process = 0;
1126 BIGNUM *start = ((void *)0);
1127 FILE *f;
1128 const char *errstr;
1129 extern char *BSDoptarg;
1130 sanitise_stdfd();
1131 __progname = ssh_get_progname(argv[0]);
1132 ssh_OpenSSL_add_all_algorithms();
1133 log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
1134 seed_rng();
1135 pw = getpwuid(getuid());
1136 if (!pw) {
1137 printf("No user exists for uid %lu\n", (u_long) getuid());
1138 exit(1);
1139 }
1140 if (gethostname(hostname, sizeof(hostname)) < 0) {
1141 perror("gethostname");
1142 exit(1);
1143 }
1144 while ((opt =
1145 BSDgetopt(argc, argv,
1146 "ABHLQXceghiklopquvxy"
1147 "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:a:b:f:g:j:m:n:r:s:t:z:"))
1148 != -1) {
1149 switch (opt) {
1150 case 'A':
1151 gen_all_hostkeys = 1;
1152 case 'b':
1153 bits =
1154 (u_int32_t) strtonum(BSDoptarg, 256, 32768,
1155 &errstr);
1156 if (errstr)
1157 fatal("Bits has bad value %s (%s)", BSDoptarg,
1158 errstr);
1159 case 'F':
1160 find_host = 1;
1161 rr_hostname = BSDoptarg;
1162 break;
1163 case 'H':
1164 hash_hosts = 1;
1165 case 'I':
1166 cert_key_id = BSDoptarg;
1167 case 'J':
1168 lines_to_process = strtoul(BSDoptarg, ((void *)0), 10);
1169 case 'j':
1170 start_lineno = strtoul(BSDoptarg, ((void *)0), 10);
1171 case 'R':
1172 delete_host = 1;
1173 rr_hostname = BSDoptarg;
1174 break;
1175 case 'L':
1176 show_cert = 1;
1177 case 'l':
1178 print_fingerprint = 1;
1179 case 'B':
1180 print_bubblebabble = 1;
1181 case 'm':
1182 if (strcasecmp(BSDoptarg, "RFC4716") == 0
1183 || strcasecmp(BSDoptarg, "ssh2") == 0) {
1184 convert_format = FMT_RFC4716;
1185 }
1186 if (strcasecmp(BSDoptarg, "PKCS8") == 0) {
1187 convert_format = FMT_PKCS8;
1188 }
1189 if (strcasecmp(BSDoptarg, "PEM") == 0) {
1190 convert_format = FMT_PEM;
1191 }
1192 fatal("Unsupported conversion format \"%s\"",
1193 BSDoptarg);
1194 case 'n':
1195 cert_principals = BSDoptarg;
1196 case 'o':
1197 use_new_format = 1;
1198 case 'p':
1199 change_passphrase = 1;
1200 case 'c':
1201 change_comment = 1;
1202 case 'f':
1203 if (strlcpy
1204 (identity_file, BSDoptarg,
1205 sizeof(identity_file)) >= sizeof(identity_file))
1206 fatal("Identity filename too long");
1207 have_identity = 1;
1208 case 'g':
1209 print_generic = 1;
1210 case 'P':
1211 identity_passphrase = BSDoptarg;
1212 case 'N':
1213 identity_new_passphrase = BSDoptarg;
1214 case 'Q':
1215 check_krl = 1;
1216 case 'O':
1217 add_cert_option(BSDoptarg);
1218 case 'Z':
1219 new_format_cipher = BSDoptarg;
1220 case 'C':
1221 identity_comment = BSDoptarg;
1222 case 'q':
1223 quiet = 1;
1224 case 'e':
1225 case 'x':
1226 convert_to = 1;
1227 case 'h':
1228 cert_key_type = 2;
1229 certflags_flags = 0;
1230 case 'k':
1231 gen_krl = 1;
1232 case 'i':
1233 case 'X':
1234 convert_from = 1;
1235 case 'y':
1236 print_public = 1;
1237 case 's':
1238 ca_key_path = BSDoptarg;
1239 case 't':
1240 key_type_name = BSDoptarg;
1241 case 'D':
1242 pkcs11provider = BSDoptarg;
1243 case 'u':
1244 update_krl = 1;
1245 case 'v':
1246 if (log_level == SYSLOG_LEVEL_INFO)
1247 log_level = SYSLOG_LEVEL_DEBUG1;
1248 else {
1249 if (log_level >= SYSLOG_LEVEL_DEBUG1
1250 && log_level < SYSLOG_LEVEL_DEBUG3)
1251 log_level++;
1252 }
1253 case 'r':
1254 rr_hostname = BSDoptarg;
1255 case 'W':
1256 generator_wanted =
1257 (u_int32_t) strtonum(BSDoptarg, 1,
1258 (2147483647 * 2U + 1U),
1259 &errstr);
1260 if (errstr)
1261 fatal
1262 ("Desired generator has bad value: %s (%s)",
1263 BSDoptarg, errstr);
1264 case 'a':
1265 rounds =
1266 (int)strtonum(BSDoptarg, 1, 2147483647, &errstr);
1267 if (errstr)
1268 fatal("Invalid number: %s (%s)", BSDoptarg,
1269 errstr);
1270 case 'M':
1271 memory =
1272 (u_int32_t) strtonum(BSDoptarg, 1,
1273 (2147483647 * 2U + 1U),
1274 &errstr);
1275 if (errstr)
1276 fatal("Memory limit is %s: %s", errstr,
1277 BSDoptarg);
1278 case 'G':
1279 do_gen_candidates = 1;
1280 if (strlcpy(out_file, BSDoptarg, sizeof(out_file)) >=
1281 sizeof(out_file))
1282 fatal("Output filename too long");
1283 case 'T':
1284 do_screen_candidates = 1;
1285 if (strlcpy(out_file, BSDoptarg, sizeof(out_file)) >=
1286 sizeof(out_file))
1287 fatal("Output filename too long");
1288 case 'K':
1289 if (strlen(BSDoptarg) >= 4096)
1290 fatal("Checkpoint filename too long");
1291 checkpoint = xstrdup(BSDoptarg);
1292 break;
1293 case 'S':
1294 if (BN_hex2bn(&start, BSDoptarg) == 0)
1295 fatal("Invalid start point.");
1296 case 'V':
1297 parse_cert_times(BSDoptarg);
1298 case 'z':
1299 (*__errno_location()) = 0;
1300 cert_serial = strtoull(BSDoptarg, &ep, 10);
1301 if (*BSDoptarg < '0' || *BSDoptarg > '9' || *ep != '\0'
1302 || ((*__errno_location()) == 34
1303 && cert_serial ==
1304 (9223372036854775807LL * 2ULL + 1)))
1305 fatal("Invalid serial number \"%s\"",
1306 BSDoptarg);
1307 case '?':
1308 default:
1309 usage();
1310 }
1311 }
1312 log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
1313 if (ca_key_path != ((void *)0)) {
1314 if (argc < 1 && !gen_krl) {
1315 printf("Too few arguments.\n");
1316 usage();
1317 }
1318 } else if (argc > 0 && !gen_krl && !check_krl) {
1319 printf("Too many arguments.\n");
1320 }
1321 if (change_passphrase && change_comment) {
1322 printf("Can only have one of -p and -c.\n");
1323 usage();
1324 }
1325 if (print_fingerprint && (delete_host || hash_hosts)) {
1326 printf("Cannot use -l with -H or -R.\n");
1327 usage();
1328 }
1329 if (gen_krl) {
1330 do_gen_krl(pw, update_krl, argc, argv);
1331 return (0);
1332 }
1333 if (check_krl) {
1334 do_check_krl(pw, argc, argv);
1335 }
1336 if (ca_key_path != ((void *)0)) {
1337 if (cert_key_id == ((void *)0))
1338 fatal("Must specify key id (-I) when certifying");
1339 do_ca_sign(pw, argc, argv);
1340 }
1341 if (show_cert)
1342 do_show_cert(pw);
1343 if (delete_host || hash_hosts || find_host)
1344 do_known_hosts(pw, rr_hostname);
1345 if (pkcs11provider != ((void *)0))
1346 do_download(pw);
1347 if (print_fingerprint || print_bubblebabble)
1348 do_fingerprint(pw);
1349 if (change_passphrase)
1350 do_change_passphrase(pw);
1351 if (change_comment)
1352 do_change_comment(pw);
1353 if (convert_to)
1354 do_convert_to(pw);
1355 if (convert_from)
1356 do_convert_from(pw);
1357 if (print_public)
1358 do_print_public(pw);
1359 if (rr_hostname != ((void *)0)) {
1360 unsigned int n = 0;
1361 if (have_identity) {
1362 n = do_print_resource_record(pw, identity_file,
1363 rr_hostname);
1364 if (n == 0) {
1365 perror(identity_file);
1366 exit(1);
1367 }
1368 exit(0);
1369 } else {
1370 n += do_print_resource_record(pw,
1371 "/etc/ssh"
1372 "/ssh_host_rsa_key",
1373 rr_hostname);
1374 n += do_print_resource_record(pw,
1375 "/etc/ssh"
1376 "/ssh_host_dsa_key",
1377 rr_hostname);
1378 n += do_print_resource_record(pw,
1379 "/etc/ssh"
1380 "/ssh_host_ecdsa_key",
1381 rr_hostname);
1382 if (n == 0)
1383 fatal("no keys found.");
1384 exit(0);
1385 }
1386 }
1387 if (do_gen_candidates) {
1388 FILE *out = fopen(out_file, "w");
1389 if (out == ((void *)0)) {
1390 error("Couldn't open modulus candidate file \"%s\": %s",
1391 out_file, strerror((*__errno_location())));
1392 }
1393 if (bits == 0)
1394 bits = 2048;
1395 if (gen_candidates(out, memory, bits, start) != 0)
1396 fatal("modulus candidate generation failed");
1397 }
1398 if (do_screen_candidates) {
1399 FILE *in;
1400 FILE *out = fopen(out_file, "a");
1401 if (have_identity && __extension__( {
1402 size_t __s1_len, __s2_len;
1403 (__builtin_constant_p
1404 (identity_file)
1405 && __builtin_constant_p("-")
1406 && (__s1_len =
1407 strlen(identity_file),
1408 __s2_len =
1409 strlen("-"),
1410 (!((size_t)
1411 (const void
1412 *)((identity_file) +
1413 1) -
1414 (size_t) (const void
1415 *)
1416 (identity_file) == 1)
1417 || __s1_len >= 4)
1418 &&
1419 (!((size_t)
1420 (const void *)(("-")
1421 + 1) -
1422 (size_t) (const void
1423 *)("-") ==
1424 1)
1425 || __s2_len >=
1426 4)) ?
1427 __builtin_strcmp
1428 (identity_file,
1429 "-")
1430 : (__builtin_constant_p
1431 (identity_file)
1432 &&
1433 ((size_t) (const void *)
1434 ((identity_file) + 1) -
1435 (size_t) (const void
1436 *)
1437 (identity_file) == 1)
1438 && (__s1_len =
1439 strlen
1440 (identity_file),
1441 __s1_len <
1442 4)
1443 ? (__builtin_constant_p
1444 ("-")
1445 &&
1446 ((size_t)
1447 (const void *)(("-")
1448 + 1) -
1449 (size_t) (const void
1450 *)("-") ==
1451 1) ?
1452 __builtin_strcmp
1453 (identity_file,
1454 "-")
1455 : (__extension__( {
1456 const
1457 unsigned
1458 char
1459 *__s2
1460 =
1461 (const
1462 unsigned
1463 char
1464 *)
1465 (const
1466 char
1467 *)
1468 ("-");
1469 register
1470 int
1471 __result
1472 =
1473 (((const unsigned char *)(const char *)(identity_file))[0] - __s2[0]); __result;}
1474 ))):
1475 (__builtin_constant_p
1476 ("-")
1477 &&
1478 ((size_t) (const void *)
1479 (("-") + 1) -
1480 (size_t) (const void
1481 *)("-") == 1)
1482 && (__s2_len =
1483 strlen("-"),
1484 __s2_len <
1485 4)
1486 ? (__builtin_constant_p
1487 (identity_file)
1488 &&
1489 ((size_t)
1490 (const void
1491 *)((identity_file)
1492 + 1) -
1493 (size_t) (const void
1494 *)
1495 (identity_file) ==
1496 1) ?
1497 __builtin_strcmp
1498 (identity_file,
1499 "-")
1500 : (__extension__( {
1501 const
1502 unsigned
1503 char
1504 *__s1
1505 =
1506 (const
1507 unsigned
1508 char
1509 *)
1510 (const
1511 char
1512 *)
1513 (identity_file);
1514 register
1515 int
1516 __result
1517 =
1518 __s1
1519 [0]
1520 -
1521 ((const unsigned char *)(const char *)("-"))[0]; if (__s2_len > 0 && __result == 0) {
1522 __result
1523 =
1524 (__s1
1525 [1]
1526 -
1527 ((const unsigned char *)(const char *)("-"))[1]);}
1528 __result;}
1529 ))):
1530 __builtin_strcmp
1531 (identity_file,
1532 "-"))));}
1533 ) != 0) {
1534 if ((in = fopen(identity_file, "r")) == ((void *)0)) {
1535 fatal("Couldn't open modulus candidate "
1536 "file \"%s\": %s", identity_file,
1537 strerror((*__errno_location())));
1538 }
1539 } else
1540 in = stdin;
1541 if (out == ((void *)0)) {
1542 fatal("Couldn't open moduli file \"%s\": %s", out_file,
1543 strerror((*__errno_location())));
1544 }
1545 if (prime_test
1546 (in, out, rounds == 0 ? 100 : rounds, generator_wanted,
1547 checkpoint, start_lineno, lines_to_process) != 0)
1548 fatal("modulus screening failed");
1549 }
1550 if (gen_all_hostkeys) {
1551 do_gen_all_hostkeys(pw);
1552 }
1553 if (key_type_name == ((void *)0))
1554 key_type_name = "rsa";
1555 type = key_type_from_name(key_type_name);
1556 type_bits_valid(type, &bits);
1557 if (!quiet)
1558 printf("Generating public/private %s key pair.\n",
1559 key_type_name);
1560 private = key_generate(type, bits);
1561 if (private == ((void *)0)) {
1562 fprintf(stderr, "key_generate failed\n");
1563 exit(1);
1564 }
1565 public = key_from_private(private);
1566 if (!have_identity)
1567 ask_filename(pw, "Enter file in which to save the key");
1568 snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, ".ssh");
1569 if (strstr(identity_file, dotsshdir) != ((void *)0)) {
1570 if (stat(dotsshdir, &st) < 0) {
1571 if ((*__errno_location()) != 2) {
1572 error("Could not stat %s: %s", dotsshdir,
1573 strerror((*__errno_location())));
1574 } else if (mkdir(dotsshdir, 0700) < 0) {
1575 error("Could not create directory '%s': %s",
1576 dotsshdir,
1577 strerror((*__errno_location())));
1578 } else if (!quiet)
1579 printf("Created directory '%s'.\n", dotsshdir);
1580 }
1581 }
1582 if (stat(identity_file, &st) >= 0) {
1583 char yesno[3];
1584 printf("%s already exists.\n", identity_file);
1585 printf("Overwrite (y/n)? ");
1586 fflush(stdout);
1587 if (fgets(yesno, sizeof(yesno), stdin) == ((void *)0))
1588 exit(1);
1589 if (yesno[0] != 'y' && yesno[0] != 'Y')
1590 exit(1);
1591 }
1592 if (identity_passphrase)
1593 passphrase1 = xstrdup(identity_passphrase);
1594 else if (identity_new_passphrase)
1595 passphrase1 = xstrdup(identity_new_passphrase);
1596 else {
1597 passphrase_again:passphrase1 =
1598 read_passphrase("Enter passphrase (empty for no "
1599 "passphrase): ", 0x0002);
1600 passphrase2 =
1601 read_passphrase("Enter same passphrase again: ", 0x0002);
1602 if (__extension__( {
1603 size_t __s1_len, __s2_len;
1604 (__builtin_constant_p(passphrase1)
1605 && __builtin_constant_p(passphrase2)
1606 && (__s1_len =
1607 strlen(passphrase1), __s2_len =
1608 strlen(passphrase2),
1609 (!((size_t) (const void *)
1610 ((passphrase1) + 1) -
1611 (size_t) (const void *)(passphrase1)
1612 == 1) || __s1_len >= 4)
1613 &&
1614 (!((size_t) (const void *)
1615 ((passphrase2) + 1) -
1616 (size_t) (const void *)(passphrase2)
1617 == 1)
1618 || __s2_len >=
1619 4)) ? __builtin_strcmp(passphrase1,
1620 passphrase2)
1621 : (__builtin_constant_p(passphrase1)
1622 &&
1623 ((size_t) (const void *)
1624 ((passphrase1) + 1) -
1625 (size_t) (const void *)(passphrase1) ==
1626 1)
1627 && (__s1_len =
1628 strlen(passphrase1),
1629 __s1_len <
1630 4)
1631 ? (__builtin_constant_p(passphrase2)
1632 &&
1633 ((size_t) (const void *)
1634 ((passphrase2) + 1) -
1635 (size_t) (const void *)(passphrase2)
1636 == 1) ? __builtin_strcmp(passphrase1,
1637 passphrase2)
1638 : (__extension__( {
1639 const unsigned char
1640 *__s2 =
1641 (const unsigned char
1642 *)(const char
1643 *)(passphrase2);
1644 register int __result
1645 =
1646 (((const unsigned char
1647 *)(const char
1648 *)(passphrase1))
1649 [0] - __s2[0]);
1650 __result;}
1651 ))): (__builtin_constant_p(passphrase2)
1652 &&
1653 ((size_t) (const void *)
1654 ((passphrase2) + 1) -
1655 (size_t) (const void
1656 *)(passphrase2) == 1)
1657 && (__s2_len =
1658 strlen(passphrase2),
1659 __s2_len <
1660 4)
1661 ? (__builtin_constant_p
1662 (passphrase1)
1663 &&
1664 ((size_t) (const void *)
1665 ((passphrase1) + 1) -
1666 (size_t) (const void
1667 *)(passphrase1) ==
1668 1) ?
1669 __builtin_strcmp(passphrase1,
1670 passphrase2)
1671 : (__extension__( {
1672 const unsigned
1673 char *__s1 =
1674 (const unsigned
1675 char *)(const
1676 char
1677 *)
1678 (passphrase1);
1679 register int
1680 __result =
1681 __s1[0] -
1682 ((const
1683 unsigned char
1684 *)(const char
1685 *)
1686 (passphrase2))
1687 [0]; __result;}
1688 ))): __builtin_strcmp(passphrase1,
1689 passphrase2))));}
1690 ) != 0) {
1691 explicit_bzero(passphrase1, strlen(passphrase1));
1692 explicit_bzero(passphrase2, strlen(passphrase2));
1693 free(passphrase1);
1694 free(passphrase2);
1695 printf("Passphrases do not match. Try again.\n");
1696 }
1697 explicit_bzero(passphrase2, strlen(passphrase2));
1698 free(passphrase2);
1699 }
1700 if (identity_comment) {
1701 strlcpy(comment, identity_comment, sizeof(comment));
1702 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
1703 hostname);
1704 }
1705 if (!key_save_private
1706 (private, identity_file, passphrase1, comment, use_new_format,
1707 new_format_cipher, rounds)) {
1708 printf("Saving the key failed: %s.\n", identity_file);
1709 explicit_bzero(passphrase1, strlen(passphrase1));
1710 free(passphrase1);
1711 exit(1);
1712 }
1713 explicit_bzero(passphrase1, strlen(passphrase1));
1714 free(passphrase1);
1715 if (!quiet)
1716 printf("Your identification has been saved in %s.\n",
1717 identity_file);
1718 strlcat(identity_file, ".pub", sizeof(identity_file));
1719 if (!key_write(public, f))
1720 fprintf(stderr, "write key failed\n");
1721 fprintf(f, " %s\n", comment);
1722 fclose(f);
1723 if (!quiet) {
1724 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
1725 char *ra =
1726 key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
1727 printf("Your public key has been saved in %s.\n",
1728 identity_file);
1729 printf("The key fingerprint is:\n");
1730 printf("%s %s\n", fp, comment);
1731 printf("The key's randomart image is:\n");
1732 printf("%s\n", ra);
1733 free(ra);
1734 free(fp);
1735 }
1736}