1 /* $OpenBSD: ssh-keygen.c,v 1.185 2010/03/15 19:40:02 stevesk 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 #include "openbsd-compat/openssl-compat.h" 25 26 #include <errno.h> 27 #include <fcntl.h> 28 #include <netdb.h> 29 #ifdef HAVE_PATHS_H 30 # include <paths.h> 31 #endif 32 #include <pwd.h> 33 #include <stdarg.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <unistd.h> 38 39 #include "xmalloc.h" 40 #include "key.h" 41 #include "rsa.h" 42 #include "authfile.h" 43 #include "uuencode.h" 44 #include "buffer.h" 45 #include "pathnames.h" 46 #include "log.h" 47 #include "misc.h" 48 #include "match.h" 49 #include "hostfile.h" 50 #include "dns.h" 51 #include "ssh2.h" 52 53 #ifdef ENABLE_PKCS11 54 #include "ssh-pkcs11.h" 55 #endif 56 57 /* Number of bits in the RSA/DSA key. This value can be set on the command line. */ 58 #define DEFAULT_BITS 2048 59 #define DEFAULT_BITS_DSA 1024 60 u_int32_t bits = 0; 61 62 /* 63 * Flag indicating that we just want to change the passphrase. This can be 64 * set on the command line. 65 */ 66 int change_passphrase = 0; 67 68 /* 69 * Flag indicating that we just want to change the comment. This can be set 70 * on the command line. 71 */ 72 int change_comment = 0; 73 74 int quiet = 0; 75 76 int log_level = SYSLOG_LEVEL_INFO; 77 78 /* Flag indicating that we want to hash a known_hosts file */ 79 int hash_hosts = 0; 80 /* Flag indicating that we want lookup a host in known_hosts file */ 81 int find_host = 0; 82 /* Flag indicating that we want to delete a host from a known_hosts file */ 83 int delete_host = 0; 84 85 /* Flag indicating that we want to show the contents of a certificate */ 86 int show_cert = 0; 87 88 /* Flag indicating that we just want to see the key fingerprint */ 89 int print_fingerprint = 0; 90 int print_bubblebabble = 0; 91 92 /* The identity file name, given on the command line or entered by the user. */ 93 char identity_file[1024]; 94 int have_identity = 0; 95 96 /* This is set to the passphrase if given on the command line. */ 97 char *identity_passphrase = NULL; 98 99 /* This is set to the new passphrase if given on the command line. */ 100 char *identity_new_passphrase = NULL; 101 102 /* This is set to the new comment if given on the command line. */ 103 char *identity_comment = NULL; 104 105 /* Path to CA key when certifying keys. */ 106 char *ca_key_path = NULL; 107 108 /* Key type when certifying */ 109 u_int cert_key_type = SSH2_CERT_TYPE_USER; 110 111 /* "key ID" of signed key */ 112 char *cert_key_id = NULL; 113 114 /* Comma-separated list of principal names for certifying keys */ 115 char *cert_principals = NULL; 116 117 /* Validity period for certificates */ 118 u_int64_t cert_valid_from = 0; 119 u_int64_t cert_valid_to = ~0ULL; 120 121 /* Certificate constraints */ 122 #define CONSTRAINT_X_FWD (1) 123 #define CONSTRAINT_AGENT_FWD (1<<1) 124 #define CONSTRAINT_PORT_FWD (1<<2) 125 #define CONSTRAINT_PTY (1<<3) 126 #define CONSTRAINT_USER_RC (1<<4) 127 #define CONSTRAINT_DEFAULT (CONSTRAINT_X_FWD|CONSTRAINT_AGENT_FWD| \ 128 CONSTRAINT_PORT_FWD|CONSTRAINT_PTY| \ 129 CONSTRAINT_USER_RC) 130 u_int32_t constraint_flags = CONSTRAINT_DEFAULT; 131 char *constraint_command = NULL; 132 char *constraint_src_addr = NULL; 133 134 /* Dump public key file in format used by real and the original SSH 2 */ 135 int convert_to_ssh2 = 0; 136 int convert_from_ssh2 = 0; 137 int print_public = 0; 138 int print_generic = 0; 139 140 char *key_type_name = NULL; 141 142 /* argv0 */ 143 extern char *__progname; 144 145 char hostname[MAXHOSTNAMELEN]; 146 147 /* moduli.c */ 148 int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); 149 int prime_test(FILE *, FILE *, u_int32_t, u_int32_t); 150 151 static void 152 ask_filename(struct passwd *pw, const char *prompt) 153 { 154 char buf[1024]; 155 char *name = NULL; 156 157 if (key_type_name == NULL) 158 name = _PATH_SSH_CLIENT_ID_RSA; 159 else { 160 switch (key_type_from_name(key_type_name)) { 161 case KEY_RSA1: 162 name = _PATH_SSH_CLIENT_IDENTITY; 163 break; 164 case KEY_DSA: 165 name = _PATH_SSH_CLIENT_ID_DSA; 166 break; 167 case KEY_RSA: 168 name = _PATH_SSH_CLIENT_ID_RSA; 169 break; 170 default: 171 fprintf(stderr, "bad key type\n"); 172 exit(1); 173 break; 174 } 175 } 176 snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name); 177 fprintf(stderr, "%s (%s): ", prompt, identity_file); 178 if (fgets(buf, sizeof(buf), stdin) == NULL) 179 exit(1); 180 buf[strcspn(buf, "\n")] = '\0'; 181 if (strcmp(buf, "") != 0) 182 strlcpy(identity_file, buf, sizeof(identity_file)); 183 have_identity = 1; 184 } 185 186 static Key * 187 load_identity(char *filename) 188 { 189 char *pass; 190 Key *prv; 191 192 prv = key_load_private(filename, "", NULL); 193 if (prv == NULL) { 194 if (identity_passphrase) 195 pass = xstrdup(identity_passphrase); 196 else 197 pass = read_passphrase("Enter passphrase: ", 198 RP_ALLOW_STDIN); 199 prv = key_load_private(filename, pass, NULL); 200 memset(pass, 0, strlen(pass)); 201 xfree(pass); 202 } 203 return prv; 204 } 205 206 #define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" 207 #define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----" 208 #define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----" 209 #define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb 210 211 static void 212 do_convert_to_ssh2(struct passwd *pw) 213 { 214 Key *k; 215 u_int len; 216 u_char *blob; 217 char comment[61]; 218 struct stat st; 219 220 if (!have_identity) 221 ask_filename(pw, "Enter file in which the key is"); 222 if (stat(identity_file, &st) < 0) { 223 perror(identity_file); 224 exit(1); 225 } 226 if ((k = key_load_public(identity_file, NULL)) == NULL) { 227 if ((k = load_identity(identity_file)) == NULL) { 228 fprintf(stderr, "load failed\n"); 229 exit(1); 230 } 231 } 232 if (k->type == KEY_RSA1) { 233 fprintf(stderr, "version 1 keys are not supported\n"); 234 exit(1); 235 } 236 if (key_to_blob(k, &blob, &len) <= 0) { 237 fprintf(stderr, "key_to_blob failed\n"); 238 exit(1); 239 } 240 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ 241 snprintf(comment, sizeof(comment), 242 "%u-bit %s, converted by %s@%s from OpenSSH", 243 key_size(k), key_type(k), 244 pw->pw_name, hostname); 245 246 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); 247 fprintf(stdout, "Comment: \"%s\"\n", comment); 248 dump_base64(stdout, blob, len); 249 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); 250 key_free(k); 251 xfree(blob); 252 exit(0); 253 } 254 255 static void 256 buffer_get_bignum_bits(Buffer *b, BIGNUM *value) 257 { 258 u_int bignum_bits = buffer_get_int(b); 259 u_int bytes = (bignum_bits + 7) / 8; 260 261 if (buffer_len(b) < bytes) 262 fatal("buffer_get_bignum_bits: input buffer too small: " 263 "need %d have %d", bytes, buffer_len(b)); 264 if (BN_bin2bn(buffer_ptr(b), bytes, value) == NULL) 265 fatal("buffer_get_bignum_bits: BN_bin2bn failed"); 266 buffer_consume(b, bytes); 267 } 268 269 static Key * 270 do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) 271 { 272 Buffer b; 273 Key *key = NULL; 274 char *type, *cipher; 275 u_char *sig, data[] = "abcde12345"; 276 int magic, rlen, ktype, i1, i2, i3, i4; 277 u_int slen; 278 u_long e; 279 280 buffer_init(&b); 281 buffer_append(&b, blob, blen); 282 283 magic = buffer_get_int(&b); 284 if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { 285 error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC); 286 buffer_free(&b); 287 return NULL; 288 } 289 i1 = buffer_get_int(&b); 290 type = buffer_get_string(&b, NULL); 291 cipher = buffer_get_string(&b, NULL); 292 i2 = buffer_get_int(&b); 293 i3 = buffer_get_int(&b); 294 i4 = buffer_get_int(&b); 295 debug("ignore (%d %d %d %d)", i1, i2, i3, i4); 296 if (strcmp(cipher, "none") != 0) { 297 error("unsupported cipher %s", cipher); 298 xfree(cipher); 299 buffer_free(&b); 300 xfree(type); 301 return NULL; 302 } 303 xfree(cipher); 304 305 if (strstr(type, "dsa")) { 306 ktype = KEY_DSA; 307 } else if (strstr(type, "rsa")) { 308 ktype = KEY_RSA; 309 } else { 310 buffer_free(&b); 311 xfree(type); 312 return NULL; 313 } 314 key = key_new_private(ktype); 315 xfree(type); 316 317 switch (key->type) { 318 case KEY_DSA: 319 buffer_get_bignum_bits(&b, key->dsa->p); 320 buffer_get_bignum_bits(&b, key->dsa->g); 321 buffer_get_bignum_bits(&b, key->dsa->q); 322 buffer_get_bignum_bits(&b, key->dsa->pub_key); 323 buffer_get_bignum_bits(&b, key->dsa->priv_key); 324 break; 325 case KEY_RSA: 326 e = buffer_get_char(&b); 327 debug("e %lx", e); 328 if (e < 30) { 329 e <<= 8; 330 e += buffer_get_char(&b); 331 debug("e %lx", e); 332 e <<= 8; 333 e += buffer_get_char(&b); 334 debug("e %lx", e); 335 } 336 if (!BN_set_word(key->rsa->e, e)) { 337 buffer_free(&b); 338 key_free(key); 339 return NULL; 340 } 341 buffer_get_bignum_bits(&b, key->rsa->d); 342 buffer_get_bignum_bits(&b, key->rsa->n); 343 buffer_get_bignum_bits(&b, key->rsa->iqmp); 344 buffer_get_bignum_bits(&b, key->rsa->q); 345 buffer_get_bignum_bits(&b, key->rsa->p); 346 rsa_generate_additional_parameters(key->rsa); 347 break; 348 } 349 rlen = buffer_len(&b); 350 if (rlen != 0) 351 error("do_convert_private_ssh2_from_blob: " 352 "remaining bytes in key blob %d", rlen); 353 buffer_free(&b); 354 355 /* try the key */ 356 key_sign(key, &sig, &slen, data, sizeof(data)); 357 key_verify(key, sig, slen, data, sizeof(data)); 358 xfree(sig); 359 return key; 360 } 361 362 static int 363 get_line(FILE *fp, char *line, size_t len) 364 { 365 int c; 366 size_t pos = 0; 367 368 line[0] = '\0'; 369 while ((c = fgetc(fp)) != EOF) { 370 if (pos >= len - 1) { 371 fprintf(stderr, "input line too long.\n"); 372 exit(1); 373 } 374 switch (c) { 375 case '\r': 376 c = fgetc(fp); 377 if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) { 378 fprintf(stderr, "unget: %s\n", strerror(errno)); 379 exit(1); 380 } 381 return pos; 382 case '\n': 383 return pos; 384 } 385 line[pos++] = c; 386 line[pos] = '\0'; 387 } 388 /* We reached EOF */ 389 return -1; 390 } 391 392 static void 393 do_convert_from_ssh2(struct passwd *pw) 394 { 395 Key *k; 396 int blen; 397 u_int len; 398 char line[1024]; 399 u_char blob[8096]; 400 char encoded[8096]; 401 struct stat st; 402 int escaped = 0, private = 0, ok; 403 FILE *fp; 404 405 if (!have_identity) 406 ask_filename(pw, "Enter file in which the key is"); 407 if (stat(identity_file, &st) < 0) { 408 perror(identity_file); 409 exit(1); 410 } 411 fp = fopen(identity_file, "r"); 412 if (fp == NULL) { 413 perror(identity_file); 414 exit(1); 415 } 416 encoded[0] = '\0'; 417 while ((blen = get_line(fp, line, sizeof(line))) != -1) { 418 if (line[blen - 1] == '\\') 419 escaped++; 420 if (strncmp(line, "----", 4) == 0 || 421 strstr(line, ": ") != NULL) { 422 if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL) 423 private = 1; 424 if (strstr(line, " END ") != NULL) { 425 break; 426 } 427 /* fprintf(stderr, "ignore: %s", line); */ 428 continue; 429 } 430 if (escaped) { 431 escaped--; 432 /* fprintf(stderr, "escaped: %s", line); */ 433 continue; 434 } 435 strlcat(encoded, line, sizeof(encoded)); 436 } 437 len = strlen(encoded); 438 if (((len % 4) == 3) && 439 (encoded[len-1] == '=') && 440 (encoded[len-2] == '=') && 441 (encoded[len-3] == '=')) 442 encoded[len-3] = '\0'; 443 blen = uudecode(encoded, blob, sizeof(blob)); 444 if (blen < 0) { 445 fprintf(stderr, "uudecode failed.\n"); 446 exit(1); 447 } 448 k = private ? 449 do_convert_private_ssh2_from_blob(blob, blen) : 450 key_from_blob(blob, blen); 451 if (k == NULL) { 452 fprintf(stderr, "decode blob failed.\n"); 453 exit(1); 454 } 455 ok = private ? 456 (k->type == KEY_DSA ? 457 PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) : 458 PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) : 459 key_write(k, stdout); 460 if (!ok) { 461 fprintf(stderr, "key write failed\n"); 462 exit(1); 463 } 464 key_free(k); 465 if (!private) 466 fprintf(stdout, "\n"); 467 fclose(fp); 468 exit(0); 469 } 470 471 static void 472 do_print_public(struct passwd *pw) 473 { 474 Key *prv; 475 struct stat st; 476 477 if (!have_identity) 478 ask_filename(pw, "Enter file in which the key is"); 479 if (stat(identity_file, &st) < 0) { 480 perror(identity_file); 481 exit(1); 482 } 483 prv = load_identity(identity_file); 484 if (prv == NULL) { 485 fprintf(stderr, "load failed\n"); 486 exit(1); 487 } 488 if (!key_write(prv, stdout)) 489 fprintf(stderr, "key_write failed"); 490 key_free(prv); 491 fprintf(stdout, "\n"); 492 exit(0); 493 } 494 495 static void 496 do_download(struct passwd *pw, char *pkcs11provider) 497 { 498 #ifdef ENABLE_PKCS11 499 Key **keys = NULL; 500 int i, nkeys; 501 502 pkcs11_init(0); 503 nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); 504 if (nkeys <= 0) 505 fatal("cannot read public key from pkcs11"); 506 for (i = 0; i < nkeys; i++) { 507 key_write(keys[i], stdout); 508 key_free(keys[i]); 509 fprintf(stdout, "\n"); 510 } 511 xfree(keys); 512 pkcs11_terminate(); 513 exit(0); 514 #else 515 fatal("no pkcs11 support"); 516 #endif /* ENABLE_PKCS11 */ 517 } 518 519 static void 520 do_fingerprint(struct passwd *pw) 521 { 522 FILE *f; 523 Key *public; 524 char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; 525 int i, skip = 0, num = 0, invalid = 1; 526 enum fp_rep rep; 527 enum fp_type fptype; 528 struct stat st; 529 530 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; 531 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; 532 533 if (!have_identity) 534 ask_filename(pw, "Enter file in which the key is"); 535 if (stat(identity_file, &st) < 0) { 536 perror(identity_file); 537 exit(1); 538 } 539 public = key_load_public(identity_file, &comment); 540 if (public != NULL) { 541 fp = key_fingerprint(public, fptype, rep); 542 ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); 543 printf("%u %s %s (%s)\n", key_size(public), fp, comment, 544 key_type(public)); 545 if (log_level >= SYSLOG_LEVEL_VERBOSE) 546 printf("%s\n", ra); 547 key_free(public); 548 xfree(comment); 549 xfree(ra); 550 xfree(fp); 551 exit(0); 552 } 553 if (comment) { 554 xfree(comment); 555 comment = NULL; 556 } 557 558 f = fopen(identity_file, "r"); 559 if (f != NULL) { 560 while (fgets(line, sizeof(line), f)) { 561 if ((cp = strchr(line, '\n')) == NULL) { 562 error("line %d too long: %.40s...", 563 num + 1, line); 564 skip = 1; 565 continue; 566 } 567 num++; 568 if (skip) { 569 skip = 0; 570 continue; 571 } 572 *cp = '\0'; 573 574 /* Skip leading whitespace, empty and comment lines. */ 575 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 576 ; 577 if (!*cp || *cp == '\n' || *cp == '#') 578 continue; 579 i = strtol(cp, &ep, 10); 580 if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) { 581 int quoted = 0; 582 comment = cp; 583 for (; *cp && (quoted || (*cp != ' ' && 584 *cp != '\t')); cp++) { 585 if (*cp == '\\' && cp[1] == '"') 586 cp++; /* Skip both */ 587 else if (*cp == '"') 588 quoted = !quoted; 589 } 590 if (!*cp) 591 continue; 592 *cp++ = '\0'; 593 } 594 ep = cp; 595 public = key_new(KEY_RSA1); 596 if (key_read(public, &cp) != 1) { 597 cp = ep; 598 key_free(public); 599 public = key_new(KEY_UNSPEC); 600 if (key_read(public, &cp) != 1) { 601 key_free(public); 602 continue; 603 } 604 } 605 comment = *cp ? cp : comment; 606 fp = key_fingerprint(public, fptype, rep); 607 ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); 608 printf("%u %s %s (%s)\n", key_size(public), fp, 609 comment ? comment : "no comment", key_type(public)); 610 if (log_level >= SYSLOG_LEVEL_VERBOSE) 611 printf("%s\n", ra); 612 xfree(ra); 613 xfree(fp); 614 key_free(public); 615 invalid = 0; 616 } 617 fclose(f); 618 } 619 if (invalid) { 620 printf("%s is not a public key file.\n", identity_file); 621 exit(1); 622 } 623 exit(0); 624 } 625 626 static void 627 printhost(FILE *f, const char *name, Key *public, int ca, int hash) 628 { 629 if (print_fingerprint) { 630 enum fp_rep rep; 631 enum fp_type fptype; 632 char *fp, *ra; 633 634 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; 635 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; 636 fp = key_fingerprint(public, fptype, rep); 637 ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); 638 printf("%u %s %s (%s)\n", key_size(public), fp, name, 639 key_type(public)); 640 if (log_level >= SYSLOG_LEVEL_VERBOSE) 641 printf("%s\n", ra); 642 xfree(ra); 643 xfree(fp); 644 } else { 645 if (hash && (name = host_hash(name, NULL, 0)) == NULL) 646 fatal("hash_host failed"); 647 fprintf(f, "%s%s%s ", ca ? CA_MARKER : "", ca ? " " : "", name); 648 if (!key_write(public, f)) 649 fatal("key_write failed"); 650 fprintf(f, "\n"); 651 } 652 } 653 654 static void 655 do_known_hosts(struct passwd *pw, const char *name) 656 { 657 FILE *in, *out = stdout; 658 Key *pub; 659 char *cp, *cp2, *kp, *kp2; 660 char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; 661 int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; 662 int ca; 663 664 if (!have_identity) { 665 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); 666 if (strlcpy(identity_file, cp, sizeof(identity_file)) >= 667 sizeof(identity_file)) 668 fatal("Specified known hosts path too long"); 669 xfree(cp); 670 have_identity = 1; 671 } 672 if ((in = fopen(identity_file, "r")) == NULL) 673 fatal("fopen: %s", strerror(errno)); 674 675 /* 676 * Find hosts goes to stdout, hash and deletions happen in-place 677 * A corner case is ssh-keygen -HF foo, which should go to stdout 678 */ 679 if (!find_host && (hash_hosts || delete_host)) { 680 if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) || 681 strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) || 682 strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) || 683 strlcat(old, ".old", sizeof(old)) >= sizeof(old)) 684 fatal("known_hosts path too long"); 685 umask(077); 686 if ((c = mkstemp(tmp)) == -1) 687 fatal("mkstemp: %s", strerror(errno)); 688 if ((out = fdopen(c, "w")) == NULL) { 689 c = errno; 690 unlink(tmp); 691 fatal("fdopen: %s", strerror(c)); 692 } 693 inplace = 1; 694 } 695 696 while (fgets(line, sizeof(line), in)) { 697 if ((cp = strchr(line, '\n')) == NULL) { 698 error("line %d too long: %.40s...", num + 1, line); 699 skip = 1; 700 invalid = 1; 701 continue; 702 } 703 num++; 704 if (skip) { 705 skip = 0; 706 continue; 707 } 708 *cp = '\0'; 709 710 /* Skip leading whitespace, empty and comment lines. */ 711 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 712 ; 713 if (!*cp || *cp == '\n' || *cp == '#') { 714 if (inplace) 715 fprintf(out, "%s\n", cp); 716 continue; 717 } 718 /* Check whether this is a CA key */ 719 if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 && 720 (cp[sizeof(CA_MARKER) - 1] == ' ' || 721 cp[sizeof(CA_MARKER) - 1] == '\t')) { 722 ca = 1; 723 cp += sizeof(CA_MARKER); 724 } else 725 ca = 0; 726 727 /* Find the end of the host name portion. */ 728 for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++) 729 ; 730 731 if (*kp == '\0' || *(kp + 1) == '\0') { 732 error("line %d missing key: %.40s...", 733 num, line); 734 invalid = 1; 735 continue; 736 } 737 *kp++ = '\0'; 738 kp2 = kp; 739 740 pub = key_new(KEY_RSA1); 741 if (key_read(pub, &kp) != 1) { 742 kp = kp2; 743 key_free(pub); 744 pub = key_new(KEY_UNSPEC); 745 if (key_read(pub, &kp) != 1) { 746 error("line %d invalid key: %.40s...", 747 num, line); 748 key_free(pub); 749 invalid = 1; 750 continue; 751 } 752 } 753 754 if (*cp == HASH_DELIM) { 755 if (find_host || delete_host) { 756 cp2 = host_hash(name, cp, strlen(cp)); 757 if (cp2 == NULL) { 758 error("line %d: invalid hashed " 759 "name: %.64s...", num, line); 760 invalid = 1; 761 continue; 762 } 763 c = (strcmp(cp2, cp) == 0); 764 if (find_host && c) { 765 printf("# Host %s found: " 766 "line %d type %s%s\n", name, 767 num, key_type(pub), 768 ca ? " (CA key)" : ""); 769 printhost(out, cp, pub, ca, 0); 770 } 771 if (delete_host && !c && !ca) 772 printhost(out, cp, pub, ca, 0); 773 } else if (hash_hosts) 774 printhost(out, cp, pub, ca, 0); 775 } else { 776 if (find_host || delete_host) { 777 c = (match_hostname(name, cp, 778 strlen(cp)) == 1); 779 if (find_host && c) { 780 printf("# Host %s found: " 781 "line %d type %s%s\n", name, 782 num, key_type(pub), 783 ca ? " (CA key)" : ""); 784 printhost(out, name, pub, 785 ca, hash_hosts && !ca); 786 } 787 if (delete_host && !c && !ca) 788 printhost(out, cp, pub, ca, 0); 789 } else if (hash_hosts) { 790 for (cp2 = strsep(&cp, ","); 791 cp2 != NULL && *cp2 != '\0'; 792 cp2 = strsep(&cp, ",")) { 793 if (ca) { 794 fprintf(stderr, "Warning: " 795 "ignoring CA key for host: " 796 "%.64s\n", cp2); 797 printhost(out, cp2, pub, ca, 0); 798 } else if (strcspn(cp2, "*?!") != 799 strlen(cp2)) { 800 fprintf(stderr, "Warning: " 801 "ignoring host name with " 802 "metacharacters: %.64s\n", 803 cp2); 804 printhost(out, cp2, pub, ca, 0); 805 } else 806 printhost(out, cp2, pub, ca, 1); 807 } 808 has_unhashed = 1; 809 } 810 } 811 key_free(pub); 812 } 813 fclose(in); 814 815 if (invalid) { 816 fprintf(stderr, "%s is not a valid known_hosts file.\n", 817 identity_file); 818 if (inplace) { 819 fprintf(stderr, "Not replacing existing known_hosts " 820 "file because of errors\n"); 821 fclose(out); 822 unlink(tmp); 823 } 824 exit(1); 825 } 826 827 if (inplace) { 828 fclose(out); 829 830 /* Backup existing file */ 831 if (unlink(old) == -1 && errno != ENOENT) 832 fatal("unlink %.100s: %s", old, strerror(errno)); 833 if (link(identity_file, old) == -1) 834 fatal("link %.100s to %.100s: %s", identity_file, old, 835 strerror(errno)); 836 /* Move new one into place */ 837 if (rename(tmp, identity_file) == -1) { 838 error("rename\"%s\" to \"%s\": %s", tmp, identity_file, 839 strerror(errno)); 840 unlink(tmp); 841 unlink(old); 842 exit(1); 843 } 844 845 fprintf(stderr, "%s updated.\n", identity_file); 846 fprintf(stderr, "Original contents retained as %s\n", old); 847 if (has_unhashed) { 848 fprintf(stderr, "WARNING: %s contains unhashed " 849 "entries\n", old); 850 fprintf(stderr, "Delete this file to ensure privacy " 851 "of hostnames\n"); 852 } 853 } 854 855 exit(0); 856 } 857 858 /* 859 * Perform changing a passphrase. The argument is the passwd structure 860 * for the current user. 861 */ 862 static void 863 do_change_passphrase(struct passwd *pw) 864 { 865 char *comment; 866 char *old_passphrase, *passphrase1, *passphrase2; 867 struct stat st; 868 Key *private; 869 870 if (!have_identity) 871 ask_filename(pw, "Enter file in which the key is"); 872 if (stat(identity_file, &st) < 0) { 873 perror(identity_file); 874 exit(1); 875 } 876 /* Try to load the file with empty passphrase. */ 877 private = key_load_private(identity_file, "", &comment); 878 if (private == NULL) { 879 if (identity_passphrase) 880 old_passphrase = xstrdup(identity_passphrase); 881 else 882 old_passphrase = 883 read_passphrase("Enter old passphrase: ", 884 RP_ALLOW_STDIN); 885 private = key_load_private(identity_file, old_passphrase, 886 &comment); 887 memset(old_passphrase, 0, strlen(old_passphrase)); 888 xfree(old_passphrase); 889 if (private == NULL) { 890 printf("Bad passphrase.\n"); 891 exit(1); 892 } 893 } 894 printf("Key has comment '%s'\n", comment); 895 896 /* Ask the new passphrase (twice). */ 897 if (identity_new_passphrase) { 898 passphrase1 = xstrdup(identity_new_passphrase); 899 passphrase2 = NULL; 900 } else { 901 passphrase1 = 902 read_passphrase("Enter new passphrase (empty for no " 903 "passphrase): ", RP_ALLOW_STDIN); 904 passphrase2 = read_passphrase("Enter same passphrase again: ", 905 RP_ALLOW_STDIN); 906 907 /* Verify that they are the same. */ 908 if (strcmp(passphrase1, passphrase2) != 0) { 909 memset(passphrase1, 0, strlen(passphrase1)); 910 memset(passphrase2, 0, strlen(passphrase2)); 911 xfree(passphrase1); 912 xfree(passphrase2); 913 printf("Pass phrases do not match. Try again.\n"); 914 exit(1); 915 } 916 /* Destroy the other copy. */ 917 memset(passphrase2, 0, strlen(passphrase2)); 918 xfree(passphrase2); 919 } 920 921 /* Save the file using the new passphrase. */ 922 if (!key_save_private(private, identity_file, passphrase1, comment)) { 923 printf("Saving the key failed: %s.\n", identity_file); 924 memset(passphrase1, 0, strlen(passphrase1)); 925 xfree(passphrase1); 926 key_free(private); 927 xfree(comment); 928 exit(1); 929 } 930 /* Destroy the passphrase and the copy of the key in memory. */ 931 memset(passphrase1, 0, strlen(passphrase1)); 932 xfree(passphrase1); 933 key_free(private); /* Destroys contents */ 934 xfree(comment); 935 936 printf("Your identification has been saved with the new passphrase.\n"); 937 exit(0); 938 } 939 940 /* 941 * Print the SSHFP RR. 942 */ 943 static int 944 do_print_resource_record(struct passwd *pw, char *fname, char *hname) 945 { 946 Key *public; 947 char *comment = NULL; 948 struct stat st; 949 950 if (fname == NULL) 951 ask_filename(pw, "Enter file in which the key is"); 952 if (stat(fname, &st) < 0) { 953 if (errno == ENOENT) 954 return 0; 955 perror(fname); 956 exit(1); 957 } 958 public = key_load_public(fname, &comment); 959 if (public != NULL) { 960 export_dns_rr(hname, public, stdout, print_generic); 961 key_free(public); 962 xfree(comment); 963 return 1; 964 } 965 if (comment) 966 xfree(comment); 967 968 printf("failed to read v2 public key from %s.\n", fname); 969 exit(1); 970 } 971 972 /* 973 * Change the comment of a private key file. 974 */ 975 static void 976 do_change_comment(struct passwd *pw) 977 { 978 char new_comment[1024], *comment, *passphrase; 979 Key *private; 980 Key *public; 981 struct stat st; 982 FILE *f; 983 int fd; 984 985 if (!have_identity) 986 ask_filename(pw, "Enter file in which the key is"); 987 if (stat(identity_file, &st) < 0) { 988 perror(identity_file); 989 exit(1); 990 } 991 private = key_load_private(identity_file, "", &comment); 992 if (private == NULL) { 993 if (identity_passphrase) 994 passphrase = xstrdup(identity_passphrase); 995 else if (identity_new_passphrase) 996 passphrase = xstrdup(identity_new_passphrase); 997 else 998 passphrase = read_passphrase("Enter passphrase: ", 999 RP_ALLOW_STDIN); 1000 /* Try to load using the passphrase. */ 1001 private = key_load_private(identity_file, passphrase, &comment); 1002 if (private == NULL) { 1003 memset(passphrase, 0, strlen(passphrase)); 1004 xfree(passphrase); 1005 printf("Bad passphrase.\n"); 1006 exit(1); 1007 } 1008 } else { 1009 passphrase = xstrdup(""); 1010 } 1011 if (private->type != KEY_RSA1) { 1012 fprintf(stderr, "Comments are only supported for RSA1 keys.\n"); 1013 key_free(private); 1014 exit(1); 1015 } 1016 printf("Key now has comment '%s'\n", comment); 1017 1018 if (identity_comment) { 1019 strlcpy(new_comment, identity_comment, sizeof(new_comment)); 1020 } else { 1021 printf("Enter new comment: "); 1022 fflush(stdout); 1023 if (!fgets(new_comment, sizeof(new_comment), stdin)) { 1024 memset(passphrase, 0, strlen(passphrase)); 1025 key_free(private); 1026 exit(1); 1027 } 1028 new_comment[strcspn(new_comment, "\n")] = '\0'; 1029 } 1030 1031 /* Save the file using the new passphrase. */ 1032 if (!key_save_private(private, identity_file, passphrase, new_comment)) { 1033 printf("Saving the key failed: %s.\n", identity_file); 1034 memset(passphrase, 0, strlen(passphrase)); 1035 xfree(passphrase); 1036 key_free(private); 1037 xfree(comment); 1038 exit(1); 1039 } 1040 memset(passphrase, 0, strlen(passphrase)); 1041 xfree(passphrase); 1042 public = key_from_private(private); 1043 key_free(private); 1044 1045 strlcat(identity_file, ".pub", sizeof(identity_file)); 1046 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 1047 if (fd == -1) { 1048 printf("Could not save your public key in %s\n", identity_file); 1049 exit(1); 1050 } 1051 f = fdopen(fd, "w"); 1052 if (f == NULL) { 1053 printf("fdopen %s failed\n", identity_file); 1054 exit(1); 1055 } 1056 if (!key_write(public, f)) 1057 fprintf(stderr, "write key failed\n"); 1058 key_free(public); 1059 fprintf(f, " %s\n", new_comment); 1060 fclose(f); 1061 1062 xfree(comment); 1063 1064 printf("The comment in your key file has been changed.\n"); 1065 exit(0); 1066 } 1067 1068 static const char * 1069 fmt_validity(u_int64_t valid_from, u_int64_t valid_to) 1070 { 1071 char from[32], to[32]; 1072 static char ret[64]; 1073 time_t tt; 1074 struct tm *tm; 1075 1076 *from = *to = '\0'; 1077 if (valid_from == 0 && valid_to == 0xffffffffffffffffULL) 1078 return "forever"; 1079 1080 if (valid_from != 0) { 1081 /* XXX revisit INT_MAX in 2038 :) */ 1082 tt = valid_from > INT_MAX ? INT_MAX : valid_from; 1083 tm = localtime(&tt); 1084 strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm); 1085 } 1086 if (valid_to != 0xffffffffffffffffULL) { 1087 /* XXX revisit INT_MAX in 2038 :) */ 1088 tt = valid_to > INT_MAX ? INT_MAX : valid_to; 1089 tm = localtime(&tt); 1090 strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm); 1091 } 1092 1093 if (valid_from == 0) { 1094 snprintf(ret, sizeof(ret), "before %s", to); 1095 return ret; 1096 } 1097 if (valid_to == 0xffffffffffffffffULL) { 1098 snprintf(ret, sizeof(ret), "after %s", from); 1099 return ret; 1100 } 1101 1102 snprintf(ret, sizeof(ret), "from %s to %s", from, to); 1103 return ret; 1104 } 1105 1106 static void 1107 add_flag_constraint(Buffer *c, const char *name) 1108 { 1109 debug3("%s: %s", __func__, name); 1110 buffer_put_cstring(c, name); 1111 buffer_put_string(c, NULL, 0); 1112 } 1113 1114 static void 1115 add_string_constraint(Buffer *c, const char *name, const char *value) 1116 { 1117 Buffer b; 1118 1119 debug3("%s: %s=%s", __func__, name, value); 1120 buffer_init(&b); 1121 buffer_put_cstring(&b, value); 1122 1123 buffer_put_cstring(c, name); 1124 buffer_put_string(c, buffer_ptr(&b), buffer_len(&b)); 1125 1126 buffer_free(&b); 1127 } 1128 1129 static void 1130 prepare_constraint_buf(Buffer *c) 1131 { 1132 1133 buffer_clear(c); 1134 if ((constraint_flags & CONSTRAINT_X_FWD) != 0) 1135 add_flag_constraint(c, "permit-X11-forwarding"); 1136 if ((constraint_flags & CONSTRAINT_AGENT_FWD) != 0) 1137 add_flag_constraint(c, "permit-agent-forwarding"); 1138 if ((constraint_flags & CONSTRAINT_PORT_FWD) != 0) 1139 add_flag_constraint(c, "permit-port-forwarding"); 1140 if ((constraint_flags & CONSTRAINT_PTY) != 0) 1141 add_flag_constraint(c, "permit-pty"); 1142 if ((constraint_flags & CONSTRAINT_USER_RC) != 0) 1143 add_flag_constraint(c, "permit-user-rc"); 1144 if (constraint_command != NULL) 1145 add_string_constraint(c, "force-command", constraint_command); 1146 if (constraint_src_addr != NULL) 1147 add_string_constraint(c, "source-address", constraint_src_addr); 1148 } 1149 1150 static void 1151 do_ca_sign(struct passwd *pw, int argc, char **argv) 1152 { 1153 int i, fd; 1154 u_int n; 1155 Key *ca, *public; 1156 char *otmp, *tmp, *cp, *out, *comment, **plist = NULL; 1157 FILE *f; 1158 1159 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); 1160 if ((ca = load_identity(tmp)) == NULL) 1161 fatal("Couldn't load CA key \"%s\"", tmp); 1162 xfree(tmp); 1163 1164 for (i = 0; i < argc; i++) { 1165 /* Split list of principals */ 1166 n = 0; 1167 if (cert_principals != NULL) { 1168 otmp = tmp = xstrdup(cert_principals); 1169 plist = NULL; 1170 for (; (cp = strsep(&tmp, ",")) != NULL; n++) { 1171 plist = xrealloc(plist, n + 1, sizeof(*plist)); 1172 if (*(plist[n] = xstrdup(cp)) == '\0') 1173 fatal("Empty principal name"); 1174 } 1175 xfree(otmp); 1176 } 1177 1178 tmp = tilde_expand_filename(argv[i], pw->pw_uid); 1179 if ((public = key_load_public(tmp, &comment)) == NULL) 1180 fatal("%s: unable to open \"%s\"", __func__, tmp); 1181 if (public->type != KEY_RSA && public->type != KEY_DSA) 1182 fatal("%s: key \"%s\" type %s cannot be certified", 1183 __func__, tmp, key_type(public)); 1184 1185 /* Prepare certificate to sign */ 1186 if (key_to_certified(public) != 0) 1187 fatal("Could not upgrade key %s to certificate", tmp); 1188 public->cert->type = cert_key_type; 1189 public->cert->key_id = xstrdup(cert_key_id); 1190 public->cert->nprincipals = n; 1191 public->cert->principals = plist; 1192 public->cert->valid_after = cert_valid_from; 1193 public->cert->valid_before = cert_valid_to; 1194 prepare_constraint_buf(&public->cert->constraints); 1195 public->cert->signature_key = key_from_private(ca); 1196 1197 if (key_certify(public, ca) != 0) 1198 fatal("Couldn't not certify key %s", tmp); 1199 1200 if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0) 1201 *cp = '\0'; 1202 xasprintf(&out, "%s-cert.pub", tmp); 1203 xfree(tmp); 1204 1205 if ((fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) 1206 fatal("Could not open \"%s\" for writing: %s", out, 1207 strerror(errno)); 1208 if ((f = fdopen(fd, "w")) == NULL) 1209 fatal("%s: fdopen: %s", __func__, strerror(errno)); 1210 if (!key_write(public, f)) 1211 fatal("Could not write certified key to %s", out); 1212 fprintf(f, " %s\n", comment); 1213 fclose(f); 1214 1215 if (!quiet) 1216 logit("Signed %s key %s: id \"%s\"%s%s valid %s", 1217 cert_key_type == SSH2_CERT_TYPE_USER?"user":"host", 1218 out, cert_key_id, 1219 cert_principals != NULL ? " for " : "", 1220 cert_principals != NULL ? cert_principals : "", 1221 fmt_validity(cert_valid_from, cert_valid_to)); 1222 1223 key_free(public); 1224 xfree(out); 1225 } 1226 exit(0); 1227 } 1228 1229 static u_int64_t 1230 parse_relative_time(const char *s, time_t now) 1231 { 1232 int64_t mul, secs; 1233 1234 mul = *s == '-' ? -1 : 1; 1235 1236 if ((secs = convtime(s + 1)) == -1) 1237 fatal("Invalid relative certificate time %s", s); 1238 if (mul == -1 && secs > now) 1239 fatal("Certificate time %s cannot be represented", s); 1240 return now + (u_int64_t)(secs * mul); 1241 } 1242 1243 static u_int64_t 1244 parse_absolute_time(const char *s) 1245 { 1246 struct tm tm; 1247 time_t tt; 1248 char buf[32], *fmt; 1249 1250 /* 1251 * POSIX strptime says "The application shall ensure that there 1252 * is white-space or other non-alphanumeric characters between 1253 * any two conversion specifications" so arrange things this way. 1254 */ 1255 switch (strlen(s)) { 1256 case 8: 1257 fmt = "%Y-%m-%d"; 1258 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6); 1259 break; 1260 case 14: 1261 fmt = "%Y-%m-%dT%H:%M:%S"; 1262 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s", 1263 s, s + 4, s + 6, s + 8, s + 10, s + 12); 1264 break; 1265 default: 1266 fatal("Invalid certificate time format %s", s); 1267 } 1268 1269 bzero(&tm, sizeof(tm)); 1270 if (strptime(buf, fmt, &tm) == NULL) 1271 fatal("Invalid certificate time %s", s); 1272 if ((tt = mktime(&tm)) < 0) 1273 fatal("Certificate time %s cannot be represented", s); 1274 return (u_int64_t)tt; 1275 } 1276 1277 static void 1278 parse_cert_times(char *timespec) 1279 { 1280 char *from, *to; 1281 time_t now = time(NULL); 1282 int64_t secs; 1283 1284 /* +timespec relative to now */ 1285 if (*timespec == '+' && strchr(timespec, ':') == NULL) { 1286 if ((secs = convtime(timespec + 1)) == -1) 1287 fatal("Invalid relative certificate life %s", timespec); 1288 cert_valid_to = now + secs; 1289 /* 1290 * Backdate certificate one minute to avoid problems on hosts 1291 * with poorly-synchronised clocks. 1292 */ 1293 cert_valid_from = ((now - 59)/ 60) * 60; 1294 return; 1295 } 1296 1297 /* 1298 * from:to, where 1299 * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS 1300 * to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS 1301 */ 1302 from = xstrdup(timespec); 1303 to = strchr(from, ':'); 1304 if (to == NULL || from == to || *(to + 1) == '\0') 1305 fatal("Invalid certificate life specification %s", timespec); 1306 *to++ = '\0'; 1307 1308 if (*from == '-' || *from == '+') 1309 cert_valid_from = parse_relative_time(from, now); 1310 else 1311 cert_valid_from = parse_absolute_time(from); 1312 1313 if (*to == '-' || *to == '+') 1314 cert_valid_to = parse_relative_time(to, cert_valid_from); 1315 else 1316 cert_valid_to = parse_absolute_time(to); 1317 1318 if (cert_valid_to <= cert_valid_from) 1319 fatal("Empty certificate validity interval"); 1320 xfree(from); 1321 } 1322 1323 static void 1324 add_cert_constraint(char *opt) 1325 { 1326 char *val; 1327 1328 if (strcmp(opt, "clear") == 0) 1329 constraint_flags = 0; 1330 else if (strcasecmp(opt, "no-x11-forwarding") == 0) 1331 constraint_flags &= ~CONSTRAINT_X_FWD; 1332 else if (strcasecmp(opt, "permit-x11-forwarding") == 0) 1333 constraint_flags |= CONSTRAINT_X_FWD; 1334 else if (strcasecmp(opt, "no-agent-forwarding") == 0) 1335 constraint_flags &= ~CONSTRAINT_AGENT_FWD; 1336 else if (strcasecmp(opt, "permit-agent-forwarding") == 0) 1337 constraint_flags |= CONSTRAINT_AGENT_FWD; 1338 else if (strcasecmp(opt, "no-port-forwarding") == 0) 1339 constraint_flags &= ~CONSTRAINT_PORT_FWD; 1340 else if (strcasecmp(opt, "permit-port-forwarding") == 0) 1341 constraint_flags |= CONSTRAINT_PORT_FWD; 1342 else if (strcasecmp(opt, "no-pty") == 0) 1343 constraint_flags &= ~CONSTRAINT_PTY; 1344 else if (strcasecmp(opt, "permit-pty") == 0) 1345 constraint_flags |= CONSTRAINT_PTY; 1346 else if (strcasecmp(opt, "no-user-rc") == 0) 1347 constraint_flags &= ~CONSTRAINT_USER_RC; 1348 else if (strcasecmp(opt, "permit-user-rc") == 0) 1349 constraint_flags |= CONSTRAINT_USER_RC; 1350 else if (strncasecmp(opt, "force-command=", 14) == 0) { 1351 val = opt + 14; 1352 if (*val == '\0') 1353 fatal("Empty force-command constraint"); 1354 if (constraint_command != NULL) 1355 fatal("force-command already specified"); 1356 constraint_command = xstrdup(val); 1357 } else if (strncasecmp(opt, "source-address=", 15) == 0) { 1358 val = opt + 15; 1359 if (*val == '\0') 1360 fatal("Empty source-address constraint"); 1361 if (constraint_src_addr != NULL) 1362 fatal("source-address already specified"); 1363 if (addr_match_cidr_list(NULL, val) != 0) 1364 fatal("Invalid source-address list"); 1365 constraint_src_addr = xstrdup(val); 1366 } else 1367 fatal("Unsupported certificate constraint \"%s\"", opt); 1368 } 1369 1370 static void 1371 do_show_cert(struct passwd *pw) 1372 { 1373 Key *key; 1374 struct stat st; 1375 char *key_fp, *ca_fp; 1376 Buffer constraints, constraint; 1377 u_char *name, *data; 1378 u_int i, dlen; 1379 1380 if (!have_identity) 1381 ask_filename(pw, "Enter file in which the key is"); 1382 if (stat(identity_file, &st) < 0) { 1383 perror(identity_file); 1384 exit(1); 1385 } 1386 if ((key = key_load_public(identity_file, NULL)) == NULL) 1387 fatal("%s is not a public key", identity_file); 1388 if (!key_is_cert(key)) 1389 fatal("%s is not a certificate", identity_file); 1390 1391 key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); 1392 ca_fp = key_fingerprint(key->cert->signature_key, 1393 SSH_FP_MD5, SSH_FP_HEX); 1394 1395 printf("%s:\n", identity_file); 1396 printf(" %s %s certificate %s\n", key_type(key), 1397 key_cert_type(key), key_fp); 1398 printf(" Signed by %s CA %s\n", 1399 key_type(key->cert->signature_key), ca_fp); 1400 printf(" Key ID \"%s\"\n", key->cert->key_id); 1401 printf(" Valid: %s\n", 1402 fmt_validity(key->cert->valid_after, key->cert->valid_before)); 1403 printf(" Principals: "); 1404 if (key->cert->nprincipals == 0) 1405 printf("(none)\n"); 1406 else { 1407 for (i = 0; i < key->cert->nprincipals; i++) 1408 printf("\n %s", 1409 key->cert->principals[i]); 1410 printf("\n"); 1411 } 1412 printf(" Constraints: "); 1413 if (buffer_len(&key->cert->constraints) == 0) 1414 printf("(none)\n"); 1415 else { 1416 printf("\n"); 1417 buffer_init(&constraints); 1418 buffer_append(&constraints, 1419 buffer_ptr(&key->cert->constraints), 1420 buffer_len(&key->cert->constraints)); 1421 buffer_init(&constraint); 1422 while (buffer_len(&constraints) != 0) { 1423 name = buffer_get_string(&constraints, NULL); 1424 data = buffer_get_string_ptr(&constraints, &dlen); 1425 buffer_append(&constraint, data, dlen); 1426 printf(" %s", name); 1427 if (strcmp(name, "permit-X11-forwarding") == 0 || 1428 strcmp(name, "permit-agent-forwarding") == 0 || 1429 strcmp(name, "permit-port-forwarding") == 0 || 1430 strcmp(name, "permit-pty") == 0 || 1431 strcmp(name, "permit-user-rc") == 0) 1432 printf("\n"); 1433 else if (strcmp(name, "force-command") == 0 || 1434 strcmp(name, "source-address") == 0) { 1435 data = buffer_get_string(&constraint, NULL); 1436 printf(" %s\n", data); 1437 xfree(data); 1438 } else { 1439 printf(" UNKNOWN CONSTRAINT (len %u)\n", 1440 buffer_len(&constraint)); 1441 buffer_clear(&constraint); 1442 } 1443 xfree(name); 1444 if (buffer_len(&constraint) != 0) 1445 fatal("Constraint corrupt: extra data at end"); 1446 } 1447 buffer_free(&constraint); 1448 buffer_free(&constraints); 1449 } 1450 1451 exit(0); 1452 } 1453 1454 static void 1455 usage(void) 1456 { 1457 fprintf(stderr, "usage: %s [options]\n", __progname); 1458 fprintf(stderr, "Options:\n"); 1459 fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n"); 1460 fprintf(stderr, " -B Show bubblebabble digest of key file.\n"); 1461 fprintf(stderr, " -b bits Number of bits in the key to create.\n"); 1462 fprintf(stderr, " -C comment Provide new comment.\n"); 1463 fprintf(stderr, " -c Change comment in private and public key files.\n"); 1464 #ifdef ENABLE_PKCS11 1465 fprintf(stderr, " -D pkcs11 Download public key from pkcs11 token.\n"); 1466 #endif 1467 fprintf(stderr, " -e Convert OpenSSH to RFC 4716 key file.\n"); 1468 fprintf(stderr, " -F hostname Find hostname in known hosts file.\n"); 1469 fprintf(stderr, " -f filename Filename of the key file.\n"); 1470 fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n"); 1471 fprintf(stderr, " -g Use generic DNS resource record format.\n"); 1472 fprintf(stderr, " -H Hash names in known_hosts file.\n"); 1473 fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n"); 1474 fprintf(stderr, " -I key_id Key identifier to include in certificate.\n"); 1475 fprintf(stderr, " -i Convert RFC 4716 to OpenSSH key file.\n"); 1476 fprintf(stderr, " -L Print the contents of a certificate.\n"); 1477 fprintf(stderr, " -l Show fingerprint of key file.\n"); 1478 fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n"); 1479 fprintf(stderr, " -n name,... User/host principal names to include in certificate\n"); 1480 fprintf(stderr, " -N phrase Provide new passphrase.\n"); 1481 fprintf(stderr, " -O cnstr Specify a certificate constraint.\n"); 1482 fprintf(stderr, " -P phrase Provide old passphrase.\n"); 1483 fprintf(stderr, " -p Change passphrase of private key file.\n"); 1484 fprintf(stderr, " -q Quiet.\n"); 1485 fprintf(stderr, " -R hostname Remove host from known_hosts file.\n"); 1486 fprintf(stderr, " -r hostname Print DNS resource record.\n"); 1487 fprintf(stderr, " -s ca_key Certify keys with CA key.\n"); 1488 fprintf(stderr, " -S start Start point (hex) for generating DH-GEX moduli.\n"); 1489 fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n"); 1490 fprintf(stderr, " -t type Specify type of key to create.\n"); 1491 fprintf(stderr, " -V from:to Specify certificate validity interval.\n"); 1492 fprintf(stderr, " -v Verbose.\n"); 1493 fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n"); 1494 fprintf(stderr, " -y Read private key file and print public key.\n"); 1495 1496 exit(1); 1497 } 1498 1499 /* 1500 * Main program for key management. 1501 */ 1502 int 1503 main(int argc, char **argv) 1504 { 1505 char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; 1506 char out_file[MAXPATHLEN], *pkcs11provider = NULL; 1507 char *rr_hostname = NULL; 1508 Key *private, *public; 1509 struct passwd *pw; 1510 struct stat st; 1511 int opt, type, fd; 1512 u_int32_t memory = 0, generator_wanted = 0, trials = 100; 1513 int do_gen_candidates = 0, do_screen_candidates = 0; 1514 BIGNUM *start = NULL; 1515 FILE *f; 1516 const char *errstr; 1517 1518 extern int optind; 1519 extern char *optarg; 1520 1521 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 1522 sanitise_stdfd(); 1523 1524 __progname = ssh_get_progname(argv[0]); 1525 1526 SSLeay_add_all_algorithms(); 1527 log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); 1528 1529 init_rng(); 1530 seed_rng(); 1531 1532 /* we need this for the home * directory. */ 1533 pw = getpwuid(getuid()); 1534 if (!pw) { 1535 printf("You don't exist, go away!\n"); 1536 exit(1); 1537 } 1538 if (gethostname(hostname, sizeof(hostname)) < 0) { 1539 perror("gethostname"); 1540 exit(1); 1541 } 1542 1543 while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:N:n:" 1544 "O:C:r:g:R:T:G:M:S:s:a:V:W:")) != -1) { 1545 switch (opt) { 1546 case 'b': 1547 bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr); 1548 if (errstr) 1549 fatal("Bits has bad value %s (%s)", 1550 optarg, errstr); 1551 break; 1552 case 'F': 1553 find_host = 1; 1554 rr_hostname = optarg; 1555 break; 1556 case 'H': 1557 hash_hosts = 1; 1558 break; 1559 case 'I': 1560 cert_key_id = optarg; 1561 break; 1562 case 'R': 1563 delete_host = 1; 1564 rr_hostname = optarg; 1565 break; 1566 case 'L': 1567 show_cert = 1; 1568 break; 1569 case 'l': 1570 print_fingerprint = 1; 1571 break; 1572 case 'B': 1573 print_bubblebabble = 1; 1574 break; 1575 case 'n': 1576 cert_principals = optarg; 1577 break; 1578 case 'p': 1579 change_passphrase = 1; 1580 break; 1581 case 'c': 1582 change_comment = 1; 1583 break; 1584 case 'f': 1585 if (strlcpy(identity_file, optarg, sizeof(identity_file)) >= 1586 sizeof(identity_file)) 1587 fatal("Identity filename too long"); 1588 have_identity = 1; 1589 break; 1590 case 'g': 1591 print_generic = 1; 1592 break; 1593 case 'P': 1594 identity_passphrase = optarg; 1595 break; 1596 case 'N': 1597 identity_new_passphrase = optarg; 1598 break; 1599 case 'O': 1600 add_cert_constraint(optarg); 1601 break; 1602 case 'C': 1603 identity_comment = optarg; 1604 break; 1605 case 'q': 1606 quiet = 1; 1607 break; 1608 case 'e': 1609 case 'x': 1610 /* export key */ 1611 convert_to_ssh2 = 1; 1612 break; 1613 case 'h': 1614 cert_key_type = SSH2_CERT_TYPE_HOST; 1615 constraint_flags = 0; 1616 break; 1617 case 'i': 1618 case 'X': 1619 /* import key */ 1620 convert_from_ssh2 = 1; 1621 break; 1622 case 'y': 1623 print_public = 1; 1624 break; 1625 case 'd': 1626 key_type_name = "dsa"; 1627 break; 1628 case 's': 1629 ca_key_path = optarg; 1630 break; 1631 case 't': 1632 key_type_name = optarg; 1633 break; 1634 case 'D': 1635 pkcs11provider = optarg; 1636 break; 1637 case 'v': 1638 if (log_level == SYSLOG_LEVEL_INFO) 1639 log_level = SYSLOG_LEVEL_DEBUG1; 1640 else { 1641 if (log_level >= SYSLOG_LEVEL_DEBUG1 && 1642 log_level < SYSLOG_LEVEL_DEBUG3) 1643 log_level++; 1644 } 1645 break; 1646 case 'r': 1647 rr_hostname = optarg; 1648 break; 1649 case 'W': 1650 generator_wanted = (u_int32_t)strtonum(optarg, 1, 1651 UINT_MAX, &errstr); 1652 if (errstr) 1653 fatal("Desired generator has bad value: %s (%s)", 1654 optarg, errstr); 1655 break; 1656 case 'a': 1657 trials = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); 1658 if (errstr) 1659 fatal("Invalid number of trials: %s (%s)", 1660 optarg, errstr); 1661 break; 1662 case 'M': 1663 memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); 1664 if (errstr) { 1665 fatal("Memory limit is %s: %s", errstr, optarg); 1666 } 1667 break; 1668 case 'G': 1669 do_gen_candidates = 1; 1670 if (strlcpy(out_file, optarg, sizeof(out_file)) >= 1671 sizeof(out_file)) 1672 fatal("Output filename too long"); 1673 break; 1674 case 'T': 1675 do_screen_candidates = 1; 1676 if (strlcpy(out_file, optarg, sizeof(out_file)) >= 1677 sizeof(out_file)) 1678 fatal("Output filename too long"); 1679 break; 1680 case 'S': 1681 /* XXX - also compare length against bits */ 1682 if (BN_hex2bn(&start, optarg) == 0) 1683 fatal("Invalid start point."); 1684 break; 1685 case 'V': 1686 parse_cert_times(optarg); 1687 break; 1688 case '?': 1689 default: 1690 usage(); 1691 } 1692 } 1693 1694 /* reinit */ 1695 log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1); 1696 1697 argv += optind; 1698 argc -= optind; 1699 1700 if (ca_key_path != NULL) { 1701 if (argc < 1) { 1702 printf("Too few arguments.\n"); 1703 usage(); 1704 } 1705 } else if (argc > 0) { 1706 printf("Too many arguments.\n"); 1707 usage(); 1708 } 1709 if (change_passphrase && change_comment) { 1710 printf("Can only have one of -p and -c.\n"); 1711 usage(); 1712 } 1713 if (print_fingerprint && (delete_host || hash_hosts)) { 1714 printf("Cannot use -l with -D or -R.\n"); 1715 usage(); 1716 } 1717 if (ca_key_path != NULL) { 1718 if (cert_key_id == NULL) 1719 fatal("Must specify key id (-I) when certifying"); 1720 do_ca_sign(pw, argc, argv); 1721 } 1722 if (show_cert) 1723 do_show_cert(pw); 1724 if (delete_host || hash_hosts || find_host) 1725 do_known_hosts(pw, rr_hostname); 1726 if (print_fingerprint || print_bubblebabble) 1727 do_fingerprint(pw); 1728 if (change_passphrase) 1729 do_change_passphrase(pw); 1730 if (change_comment) 1731 do_change_comment(pw); 1732 if (convert_to_ssh2) 1733 do_convert_to_ssh2(pw); 1734 if (convert_from_ssh2) 1735 do_convert_from_ssh2(pw); 1736 if (print_public) 1737 do_print_public(pw); 1738 if (rr_hostname != NULL) { 1739 unsigned int n = 0; 1740 1741 if (have_identity) { 1742 n = do_print_resource_record(pw, 1743 identity_file, rr_hostname); 1744 if (n == 0) { 1745 perror(identity_file); 1746 exit(1); 1747 } 1748 exit(0); 1749 } else { 1750 1751 n += do_print_resource_record(pw, 1752 _PATH_HOST_RSA_KEY_FILE, rr_hostname); 1753 n += do_print_resource_record(pw, 1754 _PATH_HOST_DSA_KEY_FILE, rr_hostname); 1755 1756 if (n == 0) 1757 fatal("no keys found."); 1758 exit(0); 1759 } 1760 } 1761 if (pkcs11provider != NULL) 1762 do_download(pw, pkcs11provider); 1763 1764 if (do_gen_candidates) { 1765 FILE *out = fopen(out_file, "w"); 1766 1767 if (out == NULL) { 1768 error("Couldn't open modulus candidate file \"%s\": %s", 1769 out_file, strerror(errno)); 1770 return (1); 1771 } 1772 if (bits == 0) 1773 bits = DEFAULT_BITS; 1774 if (gen_candidates(out, memory, bits, start) != 0) 1775 fatal("modulus candidate generation failed"); 1776 1777 return (0); 1778 } 1779 1780 if (do_screen_candidates) { 1781 FILE *in; 1782 FILE *out = fopen(out_file, "w"); 1783 1784 if (have_identity && strcmp(identity_file, "-") != 0) { 1785 if ((in = fopen(identity_file, "r")) == NULL) { 1786 fatal("Couldn't open modulus candidate " 1787 "file \"%s\": %s", identity_file, 1788 strerror(errno)); 1789 } 1790 } else 1791 in = stdin; 1792 1793 if (out == NULL) { 1794 fatal("Couldn't open moduli file \"%s\": %s", 1795 out_file, strerror(errno)); 1796 } 1797 if (prime_test(in, out, trials, generator_wanted) != 0) 1798 fatal("modulus screening failed"); 1799 return (0); 1800 } 1801 1802 arc4random_stir(); 1803 1804 if (key_type_name == NULL) 1805 key_type_name = "rsa"; 1806 1807 type = key_type_from_name(key_type_name); 1808 if (type == KEY_UNSPEC) { 1809 fprintf(stderr, "unknown key type %s\n", key_type_name); 1810 exit(1); 1811 } 1812 if (bits == 0) 1813 bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS; 1814 if (type == KEY_DSA && bits != 1024) 1815 fatal("DSA keys must be 1024 bits"); 1816 if (!quiet) 1817 printf("Generating public/private %s key pair.\n", key_type_name); 1818 private = key_generate(type, bits); 1819 if (private == NULL) { 1820 fprintf(stderr, "key_generate failed\n"); 1821 exit(1); 1822 } 1823 public = key_from_private(private); 1824 1825 if (!have_identity) 1826 ask_filename(pw, "Enter file in which to save the key"); 1827 1828 /* Create ~/.ssh directory if it doesn't already exist. */ 1829 snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, _PATH_SSH_USER_DIR); 1830 if (strstr(identity_file, dotsshdir) != NULL && 1831 stat(dotsshdir, &st) < 0) { 1832 if (mkdir(dotsshdir, 0700) < 0) 1833 error("Could not create directory '%s'.", dotsshdir); 1834 else if (!quiet) 1835 printf("Created directory '%s'.\n", dotsshdir); 1836 } 1837 /* If the file already exists, ask the user to confirm. */ 1838 if (stat(identity_file, &st) >= 0) { 1839 char yesno[3]; 1840 printf("%s already exists.\n", identity_file); 1841 printf("Overwrite (y/n)? "); 1842 fflush(stdout); 1843 if (fgets(yesno, sizeof(yesno), stdin) == NULL) 1844 exit(1); 1845 if (yesno[0] != 'y' && yesno[0] != 'Y') 1846 exit(1); 1847 } 1848 /* Ask for a passphrase (twice). */ 1849 if (identity_passphrase) 1850 passphrase1 = xstrdup(identity_passphrase); 1851 else if (identity_new_passphrase) 1852 passphrase1 = xstrdup(identity_new_passphrase); 1853 else { 1854 passphrase_again: 1855 passphrase1 = 1856 read_passphrase("Enter passphrase (empty for no " 1857 "passphrase): ", RP_ALLOW_STDIN); 1858 passphrase2 = read_passphrase("Enter same passphrase again: ", 1859 RP_ALLOW_STDIN); 1860 if (strcmp(passphrase1, passphrase2) != 0) { 1861 /* 1862 * The passphrases do not match. Clear them and 1863 * retry. 1864 */ 1865 memset(passphrase1, 0, strlen(passphrase1)); 1866 memset(passphrase2, 0, strlen(passphrase2)); 1867 xfree(passphrase1); 1868 xfree(passphrase2); 1869 printf("Passphrases do not match. Try again.\n"); 1870 goto passphrase_again; 1871 } 1872 /* Clear the other copy of the passphrase. */ 1873 memset(passphrase2, 0, strlen(passphrase2)); 1874 xfree(passphrase2); 1875 } 1876 1877 if (identity_comment) { 1878 strlcpy(comment, identity_comment, sizeof(comment)); 1879 } else { 1880 /* Create default comment field for the passphrase. */ 1881 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); 1882 } 1883 1884 /* Save the key with the given passphrase and comment. */ 1885 if (!key_save_private(private, identity_file, passphrase1, comment)) { 1886 printf("Saving the key failed: %s.\n", identity_file); 1887 memset(passphrase1, 0, strlen(passphrase1)); 1888 xfree(passphrase1); 1889 exit(1); 1890 } 1891 /* Clear the passphrase. */ 1892 memset(passphrase1, 0, strlen(passphrase1)); 1893 xfree(passphrase1); 1894 1895 /* Clear the private key and the random number generator. */ 1896 key_free(private); 1897 arc4random_stir(); 1898 1899 if (!quiet) 1900 printf("Your identification has been saved in %s.\n", identity_file); 1901 1902 strlcat(identity_file, ".pub", sizeof(identity_file)); 1903 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 1904 if (fd == -1) { 1905 printf("Could not save your public key in %s\n", identity_file); 1906 exit(1); 1907 } 1908 f = fdopen(fd, "w"); 1909 if (f == NULL) { 1910 printf("fdopen %s failed\n", identity_file); 1911 exit(1); 1912 } 1913 if (!key_write(public, f)) 1914 fprintf(stderr, "write key failed\n"); 1915 fprintf(f, " %s\n", comment); 1916 fclose(f); 1917 1918 if (!quiet) { 1919 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); 1920 char *ra = key_fingerprint(public, SSH_FP_MD5, 1921 SSH_FP_RANDOMART); 1922 printf("Your public key has been saved in %s.\n", 1923 identity_file); 1924 printf("The key fingerprint is:\n"); 1925 printf("%s %s\n", fp, comment); 1926 printf("The key's randomart image is:\n"); 1927 printf("%s\n", ra); 1928 xfree(ra); 1929 xfree(fp); 1930 } 1931 1932 key_free(public); 1933 exit(0); 1934 } 1935