ssh-keygen.c revision 162852
1/* $OpenBSD: ssh-keygen.c,v 1.154 2006/08/03 03:34:42 deraadt Exp $ */ 2/* 3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5 * All rights reserved 6 * Identity and host key generation and maintenance. 7 * 8 * As far as I am concerned, the code I have written for this software 9 * can be used freely for any purpose. Any derived versions of this 10 * software must be clearly marked as such, and if the derived work is 11 * incompatible with the protocol description in the RFC file, it must be 12 * called by a name other than "ssh" or "Secure Shell". 13 */ 14 15#include "includes.h" 16 17#include <sys/types.h> 18#include <sys/socket.h> 19#include <sys/stat.h> 20#include <sys/param.h> 21 22#include <openssl/evp.h> 23#include <openssl/pem.h> 24 25#include <errno.h> 26#include <fcntl.h> 27#include <netdb.h> 28#ifdef HAVE_PATHS_H 29# include <paths.h> 30#endif 31#include <pwd.h> 32#include <stdarg.h> 33#include <stdio.h> 34#include <stdlib.h> 35#include <string.h> 36#include <unistd.h> 37 38#include "xmalloc.h" 39#include "key.h" 40#include "rsa.h" 41#include "authfile.h" 42#include "uuencode.h" 43#include "buffer.h" 44#include "pathnames.h" 45#include "log.h" 46#include "misc.h" 47#include "match.h" 48#include "hostfile.h" 49#include "dns.h" 50 51#ifdef SMARTCARD 52#include "scard.h" 53#endif 54 55/* Number of bits in the RSA/DSA key. This value can be set on the command line. */ 56#define DEFAULT_BITS 2048 57#define DEFAULT_BITS_DSA 1024 58u_int32_t bits = 0; 59 60/* 61 * Flag indicating that we just want to change the passphrase. This can be 62 * set on the command line. 63 */ 64int change_passphrase = 0; 65 66/* 67 * Flag indicating that we just want to change the comment. This can be set 68 * on the command line. 69 */ 70int change_comment = 0; 71 72int quiet = 0; 73 74/* Flag indicating that we want to hash a known_hosts file */ 75int hash_hosts = 0; 76/* Flag indicating that we want lookup a host in known_hosts file */ 77int find_host = 0; 78/* Flag indicating that we want to delete a host from a known_hosts file */ 79int delete_host = 0; 80 81/* Flag indicating that we just want to see the key fingerprint */ 82int print_fingerprint = 0; 83int print_bubblebabble = 0; 84 85/* The identity file name, given on the command line or entered by the user. */ 86char identity_file[1024]; 87int have_identity = 0; 88 89/* This is set to the passphrase if given on the command line. */ 90char *identity_passphrase = NULL; 91 92/* This is set to the new passphrase if given on the command line. */ 93char *identity_new_passphrase = NULL; 94 95/* This is set to the new comment if given on the command line. */ 96char *identity_comment = NULL; 97 98/* Dump public key file in format used by real and the original SSH 2 */ 99int convert_to_ssh2 = 0; 100int convert_from_ssh2 = 0; 101int print_public = 0; 102int print_generic = 0; 103 104char *key_type_name = NULL; 105 106/* argv0 */ 107extern char *__progname; 108 109char hostname[MAXHOSTNAMELEN]; 110 111/* moduli.c */ 112int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); 113int prime_test(FILE *, FILE *, u_int32_t, u_int32_t); 114 115static void 116ask_filename(struct passwd *pw, const char *prompt) 117{ 118 char buf[1024]; 119 char *name = NULL; 120 121 if (key_type_name == NULL) 122 name = _PATH_SSH_CLIENT_ID_RSA; 123 else { 124 switch (key_type_from_name(key_type_name)) { 125 case KEY_RSA1: 126 name = _PATH_SSH_CLIENT_IDENTITY; 127 break; 128 case KEY_DSA: 129 name = _PATH_SSH_CLIENT_ID_DSA; 130 break; 131 case KEY_RSA: 132 name = _PATH_SSH_CLIENT_ID_RSA; 133 break; 134 default: 135 fprintf(stderr, "bad key type"); 136 exit(1); 137 break; 138 } 139 } 140 snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name); 141 fprintf(stderr, "%s (%s): ", prompt, identity_file); 142 if (fgets(buf, sizeof(buf), stdin) == NULL) 143 exit(1); 144 if (strchr(buf, '\n')) 145 *strchr(buf, '\n') = 0; 146 if (strcmp(buf, "") != 0) 147 strlcpy(identity_file, buf, sizeof(identity_file)); 148 have_identity = 1; 149} 150 151static Key * 152load_identity(char *filename) 153{ 154 char *pass; 155 Key *prv; 156 157 prv = key_load_private(filename, "", NULL); 158 if (prv == NULL) { 159 if (identity_passphrase) 160 pass = xstrdup(identity_passphrase); 161 else 162 pass = read_passphrase("Enter passphrase: ", 163 RP_ALLOW_STDIN); 164 prv = key_load_private(filename, pass, NULL); 165 memset(pass, 0, strlen(pass)); 166 xfree(pass); 167 } 168 return prv; 169} 170 171#define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" 172#define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----" 173#define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----" 174#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb 175 176static void 177do_convert_to_ssh2(struct passwd *pw) 178{ 179 Key *k; 180 u_int len; 181 u_char *blob; 182 struct stat st; 183 184 if (!have_identity) 185 ask_filename(pw, "Enter file in which the key is"); 186 if (stat(identity_file, &st) < 0) { 187 perror(identity_file); 188 exit(1); 189 } 190 if ((k = key_load_public(identity_file, NULL)) == NULL) { 191 if ((k = load_identity(identity_file)) == NULL) { 192 fprintf(stderr, "load failed\n"); 193 exit(1); 194 } 195 } 196 if (k->type == KEY_RSA1) { 197 fprintf(stderr, "version 1 keys are not supported\n"); 198 exit(1); 199 } 200 if (key_to_blob(k, &blob, &len) <= 0) { 201 fprintf(stderr, "key_to_blob failed\n"); 202 exit(1); 203 } 204 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); 205 fprintf(stdout, 206 "Comment: \"%u-bit %s, converted from OpenSSH by %s@%s\"\n", 207 key_size(k), key_type(k), 208 pw->pw_name, hostname); 209 dump_base64(stdout, blob, len); 210 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); 211 key_free(k); 212 xfree(blob); 213 exit(0); 214} 215 216static void 217buffer_get_bignum_bits(Buffer *b, BIGNUM *value) 218{ 219 u_int bignum_bits = buffer_get_int(b); 220 u_int bytes = (bignum_bits + 7) / 8; 221 222 if (buffer_len(b) < bytes) 223 fatal("buffer_get_bignum_bits: input buffer too small: " 224 "need %d have %d", bytes, buffer_len(b)); 225 BN_bin2bn(buffer_ptr(b), bytes, value); 226 buffer_consume(b, bytes); 227} 228 229static Key * 230do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) 231{ 232 Buffer b; 233 Key *key = NULL; 234 char *type, *cipher; 235 u_char *sig, data[] = "abcde12345"; 236 int magic, rlen, ktype, i1, i2, i3, i4; 237 u_int slen; 238 u_long e; 239 240 buffer_init(&b); 241 buffer_append(&b, blob, blen); 242 243 magic = buffer_get_int(&b); 244 if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { 245 error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC); 246 buffer_free(&b); 247 return NULL; 248 } 249 i1 = buffer_get_int(&b); 250 type = buffer_get_string(&b, NULL); 251 cipher = buffer_get_string(&b, NULL); 252 i2 = buffer_get_int(&b); 253 i3 = buffer_get_int(&b); 254 i4 = buffer_get_int(&b); 255 debug("ignore (%d %d %d %d)", i1,i2,i3,i4); 256 if (strcmp(cipher, "none") != 0) { 257 error("unsupported cipher %s", cipher); 258 xfree(cipher); 259 buffer_free(&b); 260 xfree(type); 261 return NULL; 262 } 263 xfree(cipher); 264 265 if (strstr(type, "dsa")) { 266 ktype = KEY_DSA; 267 } else if (strstr(type, "rsa")) { 268 ktype = KEY_RSA; 269 } else { 270 buffer_free(&b); 271 xfree(type); 272 return NULL; 273 } 274 key = key_new_private(ktype); 275 xfree(type); 276 277 switch (key->type) { 278 case KEY_DSA: 279 buffer_get_bignum_bits(&b, key->dsa->p); 280 buffer_get_bignum_bits(&b, key->dsa->g); 281 buffer_get_bignum_bits(&b, key->dsa->q); 282 buffer_get_bignum_bits(&b, key->dsa->pub_key); 283 buffer_get_bignum_bits(&b, key->dsa->priv_key); 284 break; 285 case KEY_RSA: 286 e = buffer_get_char(&b); 287 debug("e %lx", e); 288 if (e < 30) { 289 e <<= 8; 290 e += buffer_get_char(&b); 291 debug("e %lx", e); 292 e <<= 8; 293 e += buffer_get_char(&b); 294 debug("e %lx", e); 295 } 296 if (!BN_set_word(key->rsa->e, e)) { 297 buffer_free(&b); 298 key_free(key); 299 return NULL; 300 } 301 buffer_get_bignum_bits(&b, key->rsa->d); 302 buffer_get_bignum_bits(&b, key->rsa->n); 303 buffer_get_bignum_bits(&b, key->rsa->iqmp); 304 buffer_get_bignum_bits(&b, key->rsa->q); 305 buffer_get_bignum_bits(&b, key->rsa->p); 306 rsa_generate_additional_parameters(key->rsa); 307 break; 308 } 309 rlen = buffer_len(&b); 310 if (rlen != 0) 311 error("do_convert_private_ssh2_from_blob: " 312 "remaining bytes in key blob %d", rlen); 313 buffer_free(&b); 314 315 /* try the key */ 316 key_sign(key, &sig, &slen, data, sizeof(data)); 317 key_verify(key, sig, slen, data, sizeof(data)); 318 xfree(sig); 319 return key; 320} 321 322static int 323get_line(FILE *fp, char *line, size_t len) 324{ 325 int c; 326 size_t pos = 0; 327 328 line[0] = '\0'; 329 while ((c = fgetc(fp)) != EOF) { 330 if (pos >= len - 1) { 331 fprintf(stderr, "input line too long.\n"); 332 exit(1); 333 } 334 switch (c) { 335 case '\r': 336 c = fgetc(fp); 337 if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) { 338 fprintf(stderr, "unget: %s\n", strerror(errno)); 339 exit(1); 340 } 341 return pos; 342 case '\n': 343 return pos; 344 } 345 line[pos++] = c; 346 line[pos] = '\0'; 347 } 348 if (c == EOF) 349 return -1; 350 return pos; 351} 352 353static void 354do_convert_from_ssh2(struct passwd *pw) 355{ 356 Key *k; 357 int blen; 358 u_int len; 359 char line[1024]; 360 u_char blob[8096]; 361 char encoded[8096]; 362 struct stat st; 363 int escaped = 0, private = 0, ok; 364 FILE *fp; 365 366 if (!have_identity) 367 ask_filename(pw, "Enter file in which the key is"); 368 if (stat(identity_file, &st) < 0) { 369 perror(identity_file); 370 exit(1); 371 } 372 fp = fopen(identity_file, "r"); 373 if (fp == NULL) { 374 perror(identity_file); 375 exit(1); 376 } 377 encoded[0] = '\0'; 378 while ((blen = get_line(fp, line, sizeof(line))) != -1) { 379 if (line[blen - 1] == '\\') 380 escaped++; 381 if (strncmp(line, "----", 4) == 0 || 382 strstr(line, ": ") != NULL) { 383 if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL) 384 private = 1; 385 if (strstr(line, " END ") != NULL) { 386 break; 387 } 388 /* fprintf(stderr, "ignore: %s", line); */ 389 continue; 390 } 391 if (escaped) { 392 escaped--; 393 /* fprintf(stderr, "escaped: %s", line); */ 394 continue; 395 } 396 strlcat(encoded, line, sizeof(encoded)); 397 } 398 len = strlen(encoded); 399 if (((len % 4) == 3) && 400 (encoded[len-1] == '=') && 401 (encoded[len-2] == '=') && 402 (encoded[len-3] == '=')) 403 encoded[len-3] = '\0'; 404 blen = uudecode(encoded, blob, sizeof(blob)); 405 if (blen < 0) { 406 fprintf(stderr, "uudecode failed.\n"); 407 exit(1); 408 } 409 k = private ? 410 do_convert_private_ssh2_from_blob(blob, blen) : 411 key_from_blob(blob, blen); 412 if (k == NULL) { 413 fprintf(stderr, "decode blob failed.\n"); 414 exit(1); 415 } 416 ok = private ? 417 (k->type == KEY_DSA ? 418 PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) : 419 PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) : 420 key_write(k, stdout); 421 if (!ok) { 422 fprintf(stderr, "key write failed"); 423 exit(1); 424 } 425 key_free(k); 426 if (!private) 427 fprintf(stdout, "\n"); 428 fclose(fp); 429 exit(0); 430} 431 432static void 433do_print_public(struct passwd *pw) 434{ 435 Key *prv; 436 struct stat st; 437 438 if (!have_identity) 439 ask_filename(pw, "Enter file in which the key is"); 440 if (stat(identity_file, &st) < 0) { 441 perror(identity_file); 442 exit(1); 443 } 444 prv = load_identity(identity_file); 445 if (prv == NULL) { 446 fprintf(stderr, "load failed\n"); 447 exit(1); 448 } 449 if (!key_write(prv, stdout)) 450 fprintf(stderr, "key_write failed"); 451 key_free(prv); 452 fprintf(stdout, "\n"); 453 exit(0); 454} 455 456#ifdef SMARTCARD 457static void 458do_upload(struct passwd *pw, const char *sc_reader_id) 459{ 460 Key *prv = NULL; 461 struct stat st; 462 int ret; 463 464 if (!have_identity) 465 ask_filename(pw, "Enter file in which the key is"); 466 if (stat(identity_file, &st) < 0) { 467 perror(identity_file); 468 exit(1); 469 } 470 prv = load_identity(identity_file); 471 if (prv == NULL) { 472 error("load failed"); 473 exit(1); 474 } 475 ret = sc_put_key(prv, sc_reader_id); 476 key_free(prv); 477 if (ret < 0) 478 exit(1); 479 logit("loading key done"); 480 exit(0); 481} 482 483static void 484do_download(struct passwd *pw, const char *sc_reader_id) 485{ 486 Key **keys = NULL; 487 int i; 488 489 keys = sc_get_keys(sc_reader_id, NULL); 490 if (keys == NULL) 491 fatal("cannot read public key from smartcard"); 492 for (i = 0; keys[i]; i++) { 493 key_write(keys[i], stdout); 494 key_free(keys[i]); 495 fprintf(stdout, "\n"); 496 } 497 xfree(keys); 498 exit(0); 499} 500#endif /* SMARTCARD */ 501 502static void 503do_fingerprint(struct passwd *pw) 504{ 505 FILE *f; 506 Key *public; 507 char *comment = NULL, *cp, *ep, line[16*1024], *fp; 508 int i, skip = 0, num = 1, invalid = 1; 509 enum fp_rep rep; 510 enum fp_type fptype; 511 struct stat st; 512 513 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; 514 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; 515 516 if (!have_identity) 517 ask_filename(pw, "Enter file in which the key is"); 518 if (stat(identity_file, &st) < 0) { 519 perror(identity_file); 520 exit(1); 521 } 522 public = key_load_public(identity_file, &comment); 523 if (public != NULL) { 524 fp = key_fingerprint(public, fptype, rep); 525 printf("%u %s %s\n", key_size(public), fp, comment); 526 key_free(public); 527 xfree(comment); 528 xfree(fp); 529 exit(0); 530 } 531 if (comment) { 532 xfree(comment); 533 comment = NULL; 534 } 535 536 f = fopen(identity_file, "r"); 537 if (f != NULL) { 538 while (fgets(line, sizeof(line), f)) { 539 i = strlen(line) - 1; 540 if (line[i] != '\n') { 541 error("line %d too long: %.40s...", num, line); 542 skip = 1; 543 continue; 544 } 545 num++; 546 if (skip) { 547 skip = 0; 548 continue; 549 } 550 line[i] = '\0'; 551 552 /* Skip leading whitespace, empty and comment lines. */ 553 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 554 ; 555 if (!*cp || *cp == '\n' || *cp == '#') 556 continue ; 557 i = strtol(cp, &ep, 10); 558 if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) { 559 int quoted = 0; 560 comment = cp; 561 for (; *cp && (quoted || (*cp != ' ' && 562 *cp != '\t')); cp++) { 563 if (*cp == '\\' && cp[1] == '"') 564 cp++; /* Skip both */ 565 else if (*cp == '"') 566 quoted = !quoted; 567 } 568 if (!*cp) 569 continue; 570 *cp++ = '\0'; 571 } 572 ep = cp; 573 public = key_new(KEY_RSA1); 574 if (key_read(public, &cp) != 1) { 575 cp = ep; 576 key_free(public); 577 public = key_new(KEY_UNSPEC); 578 if (key_read(public, &cp) != 1) { 579 key_free(public); 580 continue; 581 } 582 } 583 comment = *cp ? cp : comment; 584 fp = key_fingerprint(public, fptype, rep); 585 printf("%u %s %s\n", key_size(public), fp, 586 comment ? comment : "no comment"); 587 xfree(fp); 588 key_free(public); 589 invalid = 0; 590 } 591 fclose(f); 592 } 593 if (invalid) { 594 printf("%s is not a public key file.\n", identity_file); 595 exit(1); 596 } 597 exit(0); 598} 599 600static void 601print_host(FILE *f, char *name, Key *public, int hash) 602{ 603 if (hash && (name = host_hash(name, NULL, 0)) == NULL) 604 fatal("hash_host failed"); 605 fprintf(f, "%s ", name); 606 if (!key_write(public, f)) 607 fatal("key_write failed"); 608 fprintf(f, "\n"); 609} 610 611static void 612do_known_hosts(struct passwd *pw, const char *name) 613{ 614 FILE *in, *out = stdout; 615 Key *public; 616 char *cp, *cp2, *kp, *kp2; 617 char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; 618 int c, i, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; 619 620 if (!have_identity) { 621 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); 622 if (strlcpy(identity_file, cp, sizeof(identity_file)) >= 623 sizeof(identity_file)) 624 fatal("Specified known hosts path too long"); 625 xfree(cp); 626 have_identity = 1; 627 } 628 if ((in = fopen(identity_file, "r")) == NULL) 629 fatal("fopen: %s", strerror(errno)); 630 631 /* 632 * Find hosts goes to stdout, hash and deletions happen in-place 633 * A corner case is ssh-keygen -HF foo, which should go to stdout 634 */ 635 if (!find_host && (hash_hosts || delete_host)) { 636 if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) || 637 strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) || 638 strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) || 639 strlcat(old, ".old", sizeof(old)) >= sizeof(old)) 640 fatal("known_hosts path too long"); 641 umask(077); 642 if ((c = mkstemp(tmp)) == -1) 643 fatal("mkstemp: %s", strerror(errno)); 644 if ((out = fdopen(c, "w")) == NULL) { 645 c = errno; 646 unlink(tmp); 647 fatal("fdopen: %s", strerror(c)); 648 } 649 inplace = 1; 650 } 651 652 while (fgets(line, sizeof(line), in)) { 653 num++; 654 i = strlen(line) - 1; 655 if (line[i] != '\n') { 656 error("line %d too long: %.40s...", num, line); 657 skip = 1; 658 invalid = 1; 659 continue; 660 } 661 if (skip) { 662 skip = 0; 663 continue; 664 } 665 line[i] = '\0'; 666 667 /* Skip leading whitespace, empty and comment lines. */ 668 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 669 ; 670 if (!*cp || *cp == '\n' || *cp == '#') { 671 if (inplace) 672 fprintf(out, "%s\n", cp); 673 continue; 674 } 675 /* Find the end of the host name portion. */ 676 for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++) 677 ; 678 if (*kp == '\0' || *(kp + 1) == '\0') { 679 error("line %d missing key: %.40s...", 680 num, line); 681 invalid = 1; 682 continue; 683 } 684 *kp++ = '\0'; 685 kp2 = kp; 686 687 public = key_new(KEY_RSA1); 688 if (key_read(public, &kp) != 1) { 689 kp = kp2; 690 key_free(public); 691 public = key_new(KEY_UNSPEC); 692 if (key_read(public, &kp) != 1) { 693 error("line %d invalid key: %.40s...", 694 num, line); 695 key_free(public); 696 invalid = 1; 697 continue; 698 } 699 } 700 701 if (*cp == HASH_DELIM) { 702 if (find_host || delete_host) { 703 cp2 = host_hash(name, cp, strlen(cp)); 704 if (cp2 == NULL) { 705 error("line %d: invalid hashed " 706 "name: %.64s...", num, line); 707 invalid = 1; 708 continue; 709 } 710 c = (strcmp(cp2, cp) == 0); 711 if (find_host && c) { 712 printf("# Host %s found: " 713 "line %d type %s\n", name, 714 num, key_type(public)); 715 print_host(out, cp, public, 0); 716 } 717 if (delete_host && !c) 718 print_host(out, cp, public, 0); 719 } else if (hash_hosts) 720 print_host(out, cp, public, 0); 721 } else { 722 if (find_host || delete_host) { 723 c = (match_hostname(name, cp, 724 strlen(cp)) == 1); 725 if (find_host && c) { 726 printf("# Host %s found: " 727 "line %d type %s\n", name, 728 num, key_type(public)); 729 print_host(out, cp, public, hash_hosts); 730 } 731 if (delete_host && !c) 732 print_host(out, cp, public, 0); 733 } else if (hash_hosts) { 734 for (cp2 = strsep(&cp, ","); 735 cp2 != NULL && *cp2 != '\0'; 736 cp2 = strsep(&cp, ",")) { 737 if (strcspn(cp2, "*?!") != strlen(cp2)) 738 fprintf(stderr, "Warning: " 739 "ignoring host name with " 740 "metacharacters: %.64s\n", 741 cp2); 742 else 743 print_host(out, cp2, public, 1); 744 } 745 has_unhashed = 1; 746 } 747 } 748 key_free(public); 749 } 750 fclose(in); 751 752 if (invalid) { 753 fprintf(stderr, "%s is not a valid known_host file.\n", 754 identity_file); 755 if (inplace) { 756 fprintf(stderr, "Not replacing existing known_hosts " 757 "file because of errors\n"); 758 fclose(out); 759 unlink(tmp); 760 } 761 exit(1); 762 } 763 764 if (inplace) { 765 fclose(out); 766 767 /* Backup existing file */ 768 if (unlink(old) == -1 && errno != ENOENT) 769 fatal("unlink %.100s: %s", old, strerror(errno)); 770 if (link(identity_file, old) == -1) 771 fatal("link %.100s to %.100s: %s", identity_file, old, 772 strerror(errno)); 773 /* Move new one into place */ 774 if (rename(tmp, identity_file) == -1) { 775 error("rename\"%s\" to \"%s\": %s", tmp, identity_file, 776 strerror(errno)); 777 unlink(tmp); 778 unlink(old); 779 exit(1); 780 } 781 782 fprintf(stderr, "%s updated.\n", identity_file); 783 fprintf(stderr, "Original contents retained as %s\n", old); 784 if (has_unhashed) { 785 fprintf(stderr, "WARNING: %s contains unhashed " 786 "entries\n", old); 787 fprintf(stderr, "Delete this file to ensure privacy " 788 "of hostnames\n"); 789 } 790 } 791 792 exit(0); 793} 794 795/* 796 * Perform changing a passphrase. The argument is the passwd structure 797 * for the current user. 798 */ 799static void 800do_change_passphrase(struct passwd *pw) 801{ 802 char *comment; 803 char *old_passphrase, *passphrase1, *passphrase2; 804 struct stat st; 805 Key *private; 806 807 if (!have_identity) 808 ask_filename(pw, "Enter file in which the key is"); 809 if (stat(identity_file, &st) < 0) { 810 perror(identity_file); 811 exit(1); 812 } 813 /* Try to load the file with empty passphrase. */ 814 private = key_load_private(identity_file, "", &comment); 815 if (private == NULL) { 816 if (identity_passphrase) 817 old_passphrase = xstrdup(identity_passphrase); 818 else 819 old_passphrase = 820 read_passphrase("Enter old passphrase: ", 821 RP_ALLOW_STDIN); 822 private = key_load_private(identity_file, old_passphrase, 823 &comment); 824 memset(old_passphrase, 0, strlen(old_passphrase)); 825 xfree(old_passphrase); 826 if (private == NULL) { 827 printf("Bad passphrase.\n"); 828 exit(1); 829 } 830 } 831 printf("Key has comment '%s'\n", comment); 832 833 /* Ask the new passphrase (twice). */ 834 if (identity_new_passphrase) { 835 passphrase1 = xstrdup(identity_new_passphrase); 836 passphrase2 = NULL; 837 } else { 838 passphrase1 = 839 read_passphrase("Enter new passphrase (empty for no " 840 "passphrase): ", RP_ALLOW_STDIN); 841 passphrase2 = read_passphrase("Enter same passphrase again: ", 842 RP_ALLOW_STDIN); 843 844 /* Verify that they are the same. */ 845 if (strcmp(passphrase1, passphrase2) != 0) { 846 memset(passphrase1, 0, strlen(passphrase1)); 847 memset(passphrase2, 0, strlen(passphrase2)); 848 xfree(passphrase1); 849 xfree(passphrase2); 850 printf("Pass phrases do not match. Try again.\n"); 851 exit(1); 852 } 853 /* Destroy the other copy. */ 854 memset(passphrase2, 0, strlen(passphrase2)); 855 xfree(passphrase2); 856 } 857 858 /* Save the file using the new passphrase. */ 859 if (!key_save_private(private, identity_file, passphrase1, comment)) { 860 printf("Saving the key failed: %s.\n", identity_file); 861 memset(passphrase1, 0, strlen(passphrase1)); 862 xfree(passphrase1); 863 key_free(private); 864 xfree(comment); 865 exit(1); 866 } 867 /* Destroy the passphrase and the copy of the key in memory. */ 868 memset(passphrase1, 0, strlen(passphrase1)); 869 xfree(passphrase1); 870 key_free(private); /* Destroys contents */ 871 xfree(comment); 872 873 printf("Your identification has been saved with the new passphrase.\n"); 874 exit(0); 875} 876 877/* 878 * Print the SSHFP RR. 879 */ 880static int 881do_print_resource_record(struct passwd *pw, char *fname, char *hname) 882{ 883 Key *public; 884 char *comment = NULL; 885 struct stat st; 886 887 if (fname == NULL) 888 ask_filename(pw, "Enter file in which the key is"); 889 if (stat(fname, &st) < 0) { 890 if (errno == ENOENT) 891 return 0; 892 perror(fname); 893 exit(1); 894 } 895 public = key_load_public(fname, &comment); 896 if (public != NULL) { 897 export_dns_rr(hname, public, stdout, print_generic); 898 key_free(public); 899 xfree(comment); 900 return 1; 901 } 902 if (comment) 903 xfree(comment); 904 905 printf("failed to read v2 public key from %s.\n", fname); 906 exit(1); 907} 908 909/* 910 * Change the comment of a private key file. 911 */ 912static void 913do_change_comment(struct passwd *pw) 914{ 915 char new_comment[1024], *comment, *passphrase; 916 Key *private; 917 Key *public; 918 struct stat st; 919 FILE *f; 920 int fd; 921 922 if (!have_identity) 923 ask_filename(pw, "Enter file in which the key is"); 924 if (stat(identity_file, &st) < 0) { 925 perror(identity_file); 926 exit(1); 927 } 928 private = key_load_private(identity_file, "", &comment); 929 if (private == NULL) { 930 if (identity_passphrase) 931 passphrase = xstrdup(identity_passphrase); 932 else if (identity_new_passphrase) 933 passphrase = xstrdup(identity_new_passphrase); 934 else 935 passphrase = read_passphrase("Enter passphrase: ", 936 RP_ALLOW_STDIN); 937 /* Try to load using the passphrase. */ 938 private = key_load_private(identity_file, passphrase, &comment); 939 if (private == NULL) { 940 memset(passphrase, 0, strlen(passphrase)); 941 xfree(passphrase); 942 printf("Bad passphrase.\n"); 943 exit(1); 944 } 945 } else { 946 passphrase = xstrdup(""); 947 } 948 if (private->type != KEY_RSA1) { 949 fprintf(stderr, "Comments are only supported for RSA1 keys.\n"); 950 key_free(private); 951 exit(1); 952 } 953 printf("Key now has comment '%s'\n", comment); 954 955 if (identity_comment) { 956 strlcpy(new_comment, identity_comment, sizeof(new_comment)); 957 } else { 958 printf("Enter new comment: "); 959 fflush(stdout); 960 if (!fgets(new_comment, sizeof(new_comment), stdin)) { 961 memset(passphrase, 0, strlen(passphrase)); 962 key_free(private); 963 exit(1); 964 } 965 if (strchr(new_comment, '\n')) 966 *strchr(new_comment, '\n') = 0; 967 } 968 969 /* Save the file using the new passphrase. */ 970 if (!key_save_private(private, identity_file, passphrase, new_comment)) { 971 printf("Saving the key failed: %s.\n", identity_file); 972 memset(passphrase, 0, strlen(passphrase)); 973 xfree(passphrase); 974 key_free(private); 975 xfree(comment); 976 exit(1); 977 } 978 memset(passphrase, 0, strlen(passphrase)); 979 xfree(passphrase); 980 public = key_from_private(private); 981 key_free(private); 982 983 strlcat(identity_file, ".pub", sizeof(identity_file)); 984 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 985 if (fd == -1) { 986 printf("Could not save your public key in %s\n", identity_file); 987 exit(1); 988 } 989 f = fdopen(fd, "w"); 990 if (f == NULL) { 991 printf("fdopen %s failed", identity_file); 992 exit(1); 993 } 994 if (!key_write(public, f)) 995 fprintf(stderr, "write key failed"); 996 key_free(public); 997 fprintf(f, " %s\n", new_comment); 998 fclose(f); 999 1000 xfree(comment); 1001 1002 printf("The comment in your key file has been changed.\n"); 1003 exit(0); 1004} 1005 1006static void 1007usage(void) 1008{ 1009 fprintf(stderr, "Usage: %s [options]\n", __progname); 1010 fprintf(stderr, "Options:\n"); 1011 fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n"); 1012 fprintf(stderr, " -B Show bubblebabble digest of key file.\n"); 1013 fprintf(stderr, " -b bits Number of bits in the key to create.\n"); 1014 fprintf(stderr, " -C comment Provide new comment.\n"); 1015 fprintf(stderr, " -c Change comment in private and public key files.\n"); 1016#ifdef SMARTCARD 1017 fprintf(stderr, " -D reader Download public key from smartcard.\n"); 1018#endif /* SMARTCARD */ 1019 fprintf(stderr, " -e Convert OpenSSH to IETF SECSH key file.\n"); 1020 fprintf(stderr, " -F hostname Find hostname in known hosts file.\n"); 1021 fprintf(stderr, " -f filename Filename of the key file.\n"); 1022 fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n"); 1023 fprintf(stderr, " -g Use generic DNS resource record format.\n"); 1024 fprintf(stderr, " -H Hash names in known_hosts file.\n"); 1025 fprintf(stderr, " -i Convert IETF SECSH to OpenSSH key file.\n"); 1026 fprintf(stderr, " -l Show fingerprint of key file.\n"); 1027 fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n"); 1028 fprintf(stderr, " -N phrase Provide new passphrase.\n"); 1029 fprintf(stderr, " -P phrase Provide old passphrase.\n"); 1030 fprintf(stderr, " -p Change passphrase of private key file.\n"); 1031 fprintf(stderr, " -q Quiet.\n"); 1032 fprintf(stderr, " -R hostname Remove host from known_hosts file.\n"); 1033 fprintf(stderr, " -r hostname Print DNS resource record.\n"); 1034 fprintf(stderr, " -S start Start point (hex) for generating DH-GEX moduli.\n"); 1035 fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n"); 1036 fprintf(stderr, " -t type Specify type of key to create.\n"); 1037#ifdef SMARTCARD 1038 fprintf(stderr, " -U reader Upload private key to smartcard.\n"); 1039#endif /* SMARTCARD */ 1040 fprintf(stderr, " -v Verbose.\n"); 1041 fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); 1042 fprintf(stderr, " -y Read private key file and print public key.\n"); 1043 1044 exit(1); 1045} 1046 1047/* 1048 * Main program for key management. 1049 */ 1050int 1051main(int ac, char **av) 1052{ 1053 char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; 1054 char out_file[MAXPATHLEN], *reader_id = NULL; 1055 char *rr_hostname = NULL; 1056 Key *private, *public; 1057 struct passwd *pw; 1058 struct stat st; 1059 int opt, type, fd, download = 0; 1060 u_int32_t memory = 0, generator_wanted = 0, trials = 100; 1061 int do_gen_candidates = 0, do_screen_candidates = 0; 1062 int log_level = SYSLOG_LEVEL_INFO; 1063 BIGNUM *start = NULL; 1064 FILE *f; 1065 const char *errstr; 1066 1067 extern int optind; 1068 extern char *optarg; 1069 1070 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 1071 sanitise_stdfd(); 1072 1073 __progname = ssh_get_progname(av[0]); 1074 1075 SSLeay_add_all_algorithms(); 1076 log_init(av[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); 1077 1078 init_rng(); 1079 seed_rng(); 1080 1081 /* we need this for the home * directory. */ 1082 pw = getpwuid(getuid()); 1083 if (!pw) { 1084 printf("You don't exist, go away!\n"); 1085 exit(1); 1086 } 1087 if (gethostname(hostname, sizeof(hostname)) < 0) { 1088 perror("gethostname"); 1089 exit(1); 1090 } 1091 1092 while ((opt = getopt(ac, av, 1093 "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) { 1094 switch (opt) { 1095 case 'b': 1096 bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr); 1097 if (errstr) 1098 fatal("Bits has bad value %s (%s)", 1099 optarg, errstr); 1100 break; 1101 case 'F': 1102 find_host = 1; 1103 rr_hostname = optarg; 1104 break; 1105 case 'H': 1106 hash_hosts = 1; 1107 break; 1108 case 'R': 1109 delete_host = 1; 1110 rr_hostname = optarg; 1111 break; 1112 case 'l': 1113 print_fingerprint = 1; 1114 break; 1115 case 'B': 1116 print_bubblebabble = 1; 1117 break; 1118 case 'p': 1119 change_passphrase = 1; 1120 break; 1121 case 'c': 1122 change_comment = 1; 1123 break; 1124 case 'f': 1125 if (strlcpy(identity_file, optarg, sizeof(identity_file)) >= 1126 sizeof(identity_file)) 1127 fatal("Identity filename too long"); 1128 have_identity = 1; 1129 break; 1130 case 'g': 1131 print_generic = 1; 1132 break; 1133 case 'P': 1134 identity_passphrase = optarg; 1135 break; 1136 case 'N': 1137 identity_new_passphrase = optarg; 1138 break; 1139 case 'C': 1140 identity_comment = optarg; 1141 break; 1142 case 'q': 1143 quiet = 1; 1144 break; 1145 case 'e': 1146 case 'x': 1147 /* export key */ 1148 convert_to_ssh2 = 1; 1149 break; 1150 case 'i': 1151 case 'X': 1152 /* import key */ 1153 convert_from_ssh2 = 1; 1154 break; 1155 case 'y': 1156 print_public = 1; 1157 break; 1158 case 'd': 1159 key_type_name = "dsa"; 1160 break; 1161 case 't': 1162 key_type_name = optarg; 1163 break; 1164 case 'D': 1165 download = 1; 1166 /*FALLTHROUGH*/ 1167 case 'U': 1168 reader_id = optarg; 1169 break; 1170 case 'v': 1171 if (log_level == SYSLOG_LEVEL_INFO) 1172 log_level = SYSLOG_LEVEL_DEBUG1; 1173 else { 1174 if (log_level >= SYSLOG_LEVEL_DEBUG1 && 1175 log_level < SYSLOG_LEVEL_DEBUG3) 1176 log_level++; 1177 } 1178 break; 1179 case 'r': 1180 rr_hostname = optarg; 1181 break; 1182 case 'W': 1183 generator_wanted = (u_int32_t)strtonum(optarg, 1, 1184 UINT_MAX, &errstr); 1185 if (errstr) 1186 fatal("Desired generator has bad value: %s (%s)", 1187 optarg, errstr); 1188 break; 1189 case 'a': 1190 trials = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); 1191 if (errstr) 1192 fatal("Invalid number of trials: %s (%s)", 1193 optarg, errstr); 1194 break; 1195 case 'M': 1196 memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); 1197 if (errstr) { 1198 fatal("Memory limit is %s: %s", errstr, optarg); 1199 } 1200 break; 1201 case 'G': 1202 do_gen_candidates = 1; 1203 if (strlcpy(out_file, optarg, sizeof(out_file)) >= 1204 sizeof(out_file)) 1205 fatal("Output filename too long"); 1206 break; 1207 case 'T': 1208 do_screen_candidates = 1; 1209 if (strlcpy(out_file, optarg, sizeof(out_file)) >= 1210 sizeof(out_file)) 1211 fatal("Output filename too long"); 1212 break; 1213 case 'S': 1214 /* XXX - also compare length against bits */ 1215 if (BN_hex2bn(&start, optarg) == 0) 1216 fatal("Invalid start point."); 1217 break; 1218 case '?': 1219 default: 1220 usage(); 1221 } 1222 } 1223 1224 /* reinit */ 1225 log_init(av[0], log_level, SYSLOG_FACILITY_USER, 1); 1226 1227 if (optind < ac) { 1228 printf("Too many arguments.\n"); 1229 usage(); 1230 } 1231 if (change_passphrase && change_comment) { 1232 printf("Can only have one of -p and -c.\n"); 1233 usage(); 1234 } 1235 if (delete_host || hash_hosts || find_host) 1236 do_known_hosts(pw, rr_hostname); 1237 if (print_fingerprint || print_bubblebabble) 1238 do_fingerprint(pw); 1239 if (change_passphrase) 1240 do_change_passphrase(pw); 1241 if (change_comment) 1242 do_change_comment(pw); 1243 if (convert_to_ssh2) 1244 do_convert_to_ssh2(pw); 1245 if (convert_from_ssh2) 1246 do_convert_from_ssh2(pw); 1247 if (print_public) 1248 do_print_public(pw); 1249 if (rr_hostname != NULL) { 1250 unsigned int n = 0; 1251 1252 if (have_identity) { 1253 n = do_print_resource_record(pw, 1254 identity_file, rr_hostname); 1255 if (n == 0) { 1256 perror(identity_file); 1257 exit(1); 1258 } 1259 exit(0); 1260 } else { 1261 1262 n += do_print_resource_record(pw, 1263 _PATH_HOST_RSA_KEY_FILE, rr_hostname); 1264 n += do_print_resource_record(pw, 1265 _PATH_HOST_DSA_KEY_FILE, rr_hostname); 1266 1267 if (n == 0) 1268 fatal("no keys found."); 1269 exit(0); 1270 } 1271 } 1272 if (reader_id != NULL) { 1273#ifdef SMARTCARD 1274 if (download) 1275 do_download(pw, reader_id); 1276 else 1277 do_upload(pw, reader_id); 1278#else /* SMARTCARD */ 1279 fatal("no support for smartcards."); 1280#endif /* SMARTCARD */ 1281 } 1282 1283 if (do_gen_candidates) { 1284 FILE *out = fopen(out_file, "w"); 1285 1286 if (out == NULL) { 1287 error("Couldn't open modulus candidate file \"%s\": %s", 1288 out_file, strerror(errno)); 1289 return (1); 1290 } 1291 if (bits == 0) 1292 bits = DEFAULT_BITS; 1293 if (gen_candidates(out, memory, bits, start) != 0) 1294 fatal("modulus candidate generation failed"); 1295 1296 return (0); 1297 } 1298 1299 if (do_screen_candidates) { 1300 FILE *in; 1301 FILE *out = fopen(out_file, "w"); 1302 1303 if (have_identity && strcmp(identity_file, "-") != 0) { 1304 if ((in = fopen(identity_file, "r")) == NULL) { 1305 fatal("Couldn't open modulus candidate " 1306 "file \"%s\": %s", identity_file, 1307 strerror(errno)); 1308 } 1309 } else 1310 in = stdin; 1311 1312 if (out == NULL) { 1313 fatal("Couldn't open moduli file \"%s\": %s", 1314 out_file, strerror(errno)); 1315 } 1316 if (prime_test(in, out, trials, generator_wanted) != 0) 1317 fatal("modulus screening failed"); 1318 return (0); 1319 } 1320 1321 arc4random_stir(); 1322 1323 if (key_type_name == NULL) 1324 key_type_name = "rsa"; 1325 1326 type = key_type_from_name(key_type_name); 1327 if (type == KEY_UNSPEC) { 1328 fprintf(stderr, "unknown key type %s\n", key_type_name); 1329 exit(1); 1330 } 1331 if (bits == 0) 1332 bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS; 1333 if (type == KEY_DSA && bits != 1024) 1334 fatal("DSA keys must be 1024 bits"); 1335 if (!quiet) 1336 printf("Generating public/private %s key pair.\n", key_type_name); 1337 private = key_generate(type, bits); 1338 if (private == NULL) { 1339 fprintf(stderr, "key_generate failed"); 1340 exit(1); 1341 } 1342 public = key_from_private(private); 1343 1344 if (!have_identity) 1345 ask_filename(pw, "Enter file in which to save the key"); 1346 1347 /* Create ~/.ssh directory if it doesn't already exist. */ 1348 snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, _PATH_SSH_USER_DIR); 1349 if (strstr(identity_file, dotsshdir) != NULL && 1350 stat(dotsshdir, &st) < 0) { 1351 if (mkdir(dotsshdir, 0700) < 0) 1352 error("Could not create directory '%s'.", dotsshdir); 1353 else if (!quiet) 1354 printf("Created directory '%s'.\n", dotsshdir); 1355 } 1356 /* If the file already exists, ask the user to confirm. */ 1357 if (stat(identity_file, &st) >= 0) { 1358 char yesno[3]; 1359 printf("%s already exists.\n", identity_file); 1360 printf("Overwrite (y/n)? "); 1361 fflush(stdout); 1362 if (fgets(yesno, sizeof(yesno), stdin) == NULL) 1363 exit(1); 1364 if (yesno[0] != 'y' && yesno[0] != 'Y') 1365 exit(1); 1366 } 1367 /* Ask for a passphrase (twice). */ 1368 if (identity_passphrase) 1369 passphrase1 = xstrdup(identity_passphrase); 1370 else if (identity_new_passphrase) 1371 passphrase1 = xstrdup(identity_new_passphrase); 1372 else { 1373passphrase_again: 1374 passphrase1 = 1375 read_passphrase("Enter passphrase (empty for no " 1376 "passphrase): ", RP_ALLOW_STDIN); 1377 passphrase2 = read_passphrase("Enter same passphrase again: ", 1378 RP_ALLOW_STDIN); 1379 if (strcmp(passphrase1, passphrase2) != 0) { 1380 /* 1381 * The passphrases do not match. Clear them and 1382 * retry. 1383 */ 1384 memset(passphrase1, 0, strlen(passphrase1)); 1385 memset(passphrase2, 0, strlen(passphrase2)); 1386 xfree(passphrase1); 1387 xfree(passphrase2); 1388 printf("Passphrases do not match. Try again.\n"); 1389 goto passphrase_again; 1390 } 1391 /* Clear the other copy of the passphrase. */ 1392 memset(passphrase2, 0, strlen(passphrase2)); 1393 xfree(passphrase2); 1394 } 1395 1396 if (identity_comment) { 1397 strlcpy(comment, identity_comment, sizeof(comment)); 1398 } else { 1399 /* Create default commend field for the passphrase. */ 1400 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); 1401 } 1402 1403 /* Save the key with the given passphrase and comment. */ 1404 if (!key_save_private(private, identity_file, passphrase1, comment)) { 1405 printf("Saving the key failed: %s.\n", identity_file); 1406 memset(passphrase1, 0, strlen(passphrase1)); 1407 xfree(passphrase1); 1408 exit(1); 1409 } 1410 /* Clear the passphrase. */ 1411 memset(passphrase1, 0, strlen(passphrase1)); 1412 xfree(passphrase1); 1413 1414 /* Clear the private key and the random number generator. */ 1415 key_free(private); 1416 arc4random_stir(); 1417 1418 if (!quiet) 1419 printf("Your identification has been saved in %s.\n", identity_file); 1420 1421 strlcat(identity_file, ".pub", sizeof(identity_file)); 1422 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 1423 if (fd == -1) { 1424 printf("Could not save your public key in %s\n", identity_file); 1425 exit(1); 1426 } 1427 f = fdopen(fd, "w"); 1428 if (f == NULL) { 1429 printf("fdopen %s failed", identity_file); 1430 exit(1); 1431 } 1432 if (!key_write(public, f)) 1433 fprintf(stderr, "write key failed"); 1434 fprintf(f, " %s\n", comment); 1435 fclose(f); 1436 1437 if (!quiet) { 1438 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); 1439 printf("Your public key has been saved in %s.\n", 1440 identity_file); 1441 printf("The key fingerprint is:\n"); 1442 printf("%s %s\n", fp, comment); 1443 xfree(fp); 1444 } 1445 1446 key_free(public); 1447 exit(0); 1448} 1449