1 /* $OpenBSD: ssh-keygen.c,v 1.249 2014/07/03 03:47:27 djm 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 "ssh.h" 52 #include "ssh2.h" 53 #include "ssh-pkcs11.h" 54 #include "atomicio.h" 55 #include "krl.h" 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 #define DEFAULT_BITS_ECDSA 256 61 u_int32_t bits = 0; 62 63 /* 64 * Flag indicating that we just want to change the passphrase. This can be 65 * set on the command line. 66 */ 67 int change_passphrase = 0; 68 69 /* 70 * Flag indicating that we just want to change the comment. This can be set 71 * on the command line. 72 */ 73 int change_comment = 0; 74 75 int quiet = 0; 76 77 int log_level = SYSLOG_LEVEL_INFO; 78 79 /* Flag indicating that we want to hash a known_hosts file */ 80 int hash_hosts = 0; 81 /* Flag indicating that we want lookup a host in known_hosts file */ 82 int find_host = 0; 83 /* Flag indicating that we want to delete a host from a known_hosts file */ 84 int delete_host = 0; 85 86 /* Flag indicating that we want to show the contents of a certificate */ 87 int show_cert = 0; 88 89 /* Flag indicating that we just want to see the key fingerprint */ 90 int print_fingerprint = 0; 91 int print_bubblebabble = 0; 92 93 /* The identity file name, given on the command line or entered by the user. */ 94 char identity_file[1024]; 95 int have_identity = 0; 96 97 /* This is set to the passphrase if given on the command line. */ 98 char *identity_passphrase = NULL; 99 100 /* This is set to the new passphrase if given on the command line. */ 101 char *identity_new_passphrase = NULL; 102 103 /* This is set to the new comment if given on the command line. */ 104 char *identity_comment = NULL; 105 106 /* Path to CA key when certifying keys. */ 107 char *ca_key_path = NULL; 108 109 /* Certificate serial number */ 110 unsigned long long cert_serial = 0; 111 112 /* Key type when certifying */ 113 u_int cert_key_type = SSH2_CERT_TYPE_USER; 114 115 /* "key ID" of signed key */ 116 char *cert_key_id = NULL; 117 118 /* Comma-separated list of principal names for certifying keys */ 119 char *cert_principals = NULL; 120 121 /* Validity period for certificates */ 122 u_int64_t cert_valid_from = 0; 123 u_int64_t cert_valid_to = ~0ULL; 124 125 /* Certificate options */ 126 #define CERTOPT_X_FWD (1) 127 #define CERTOPT_AGENT_FWD (1<<1) 128 #define CERTOPT_PORT_FWD (1<<2) 129 #define CERTOPT_PTY (1<<3) 130 #define CERTOPT_USER_RC (1<<4) 131 #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \ 132 CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC) 133 u_int32_t certflags_flags = CERTOPT_DEFAULT; 134 char *certflags_command = NULL; 135 char *certflags_src_addr = NULL; 136 137 /* Conversion to/from various formats */ 138 int convert_to = 0; 139 int convert_from = 0; 140 enum { 141 FMT_RFC4716, 142 FMT_PKCS8, 143 FMT_PEM 144 } convert_format = FMT_RFC4716; 145 int print_public = 0; 146 int print_generic = 0; 147 148 char *key_type_name = NULL; 149 150 /* Load key from this PKCS#11 provider */ 151 char *pkcs11provider = NULL; 152 153 /* Use new OpenSSH private key format when writing SSH2 keys instead of PEM */ 154 int use_new_format = 0; 155 156 /* Cipher for new-format private keys */ 157 char *new_format_cipher = NULL; 158 159 /* 160 * Number of KDF rounds to derive new format keys / 161 * number of primality trials when screening moduli. 162 */ 163 int rounds = 0; 164 165 /* argv0 */ 166 extern char *__progname; 167 168 char hostname[NI_MAXHOST]; 169 170 /* moduli.c */ 171 int gen_candidates(FILE *, u_int32_t, u_int32_t, BIGNUM *); 172 int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, 173 unsigned long); 174 175 static void 176 type_bits_valid(int type, u_int32_t *bitsp) 177 { 178 u_int maxbits; 179 180 if (type == KEY_UNSPEC) { 181 fprintf(stderr, "unknown key type %s\n", key_type_name); 182 exit(1); 183 } 184 if (*bitsp == 0) { 185 if (type == KEY_DSA) 186 *bitsp = DEFAULT_BITS_DSA; 187 else if (type == KEY_ECDSA) 188 *bitsp = DEFAULT_BITS_ECDSA; 189 else 190 *bitsp = DEFAULT_BITS; 191 } 192 maxbits = (type == KEY_DSA) ? 193 OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; 194 if (*bitsp > maxbits) { 195 fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); 196 exit(1); 197 } 198 #ifdef WITH_OPENSSL 199 if (type == KEY_DSA && *bitsp != 1024) 200 fatal("DSA keys must be 1024 bits"); 201 else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) 202 fatal("Key must at least be 768 bits"); 203 else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1) 204 fatal("Invalid ECDSA key length - valid lengths are " 205 "256, 384 or 521 bits"); 206 #endif 207 } 208 209 static void 210 ask_filename(struct passwd *pw, const char *prompt) 211 { 212 char buf[1024]; 213 char *name = NULL; 214 215 if (key_type_name == NULL) 216 name = _PATH_SSH_CLIENT_ID_RSA; 217 else { 218 switch (key_type_from_name(key_type_name)) { 219 case KEY_RSA1: 220 name = _PATH_SSH_CLIENT_IDENTITY; 221 break; 222 case KEY_DSA_CERT: 223 case KEY_DSA_CERT_V00: 224 case KEY_DSA: 225 name = _PATH_SSH_CLIENT_ID_DSA; 226 break; 227 #ifdef OPENSSL_HAS_ECC 228 case KEY_ECDSA_CERT: 229 case KEY_ECDSA: 230 name = _PATH_SSH_CLIENT_ID_ECDSA; 231 break; 232 #endif 233 case KEY_RSA_CERT: 234 case KEY_RSA_CERT_V00: 235 case KEY_RSA: 236 name = _PATH_SSH_CLIENT_ID_RSA; 237 break; 238 case KEY_ED25519: 239 case KEY_ED25519_CERT: 240 name = _PATH_SSH_CLIENT_ID_ED25519; 241 break; 242 default: 243 fprintf(stderr, "bad key type\n"); 244 exit(1); 245 break; 246 } 247 } 248 snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name); 249 fprintf(stderr, "%s (%s): ", prompt, identity_file); 250 if (fgets(buf, sizeof(buf), stdin) == NULL) 251 exit(1); 252 buf[strcspn(buf, "\n")] = '\0'; 253 if (strcmp(buf, "") != 0) 254 strlcpy(identity_file, buf, sizeof(identity_file)); 255 have_identity = 1; 256 } 257 258 static Key * 259 load_identity(char *filename) 260 { 261 char *pass; 262 Key *prv; 263 264 prv = key_load_private(filename, "", NULL); 265 if (prv == NULL) { 266 if (identity_passphrase) 267 pass = xstrdup(identity_passphrase); 268 else 269 pass = read_passphrase("Enter passphrase: ", 270 RP_ALLOW_STDIN); 271 prv = key_load_private(filename, pass, NULL); 272 explicit_bzero(pass, strlen(pass)); 273 free(pass); 274 } 275 return prv; 276 } 277 278 #define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" 279 #define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----" 280 #define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----" 281 #define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb 282 283 #ifdef WITH_OPENSSL 284 static void 285 do_convert_to_ssh2(struct passwd *pw, Key *k) 286 { 287 u_int len; 288 u_char *blob; 289 char comment[61]; 290 291 if (k->type == KEY_RSA1) { 292 fprintf(stderr, "version 1 keys are not supported\n"); 293 exit(1); 294 } 295 if (key_to_blob(k, &blob, &len) <= 0) { 296 fprintf(stderr, "key_to_blob failed\n"); 297 exit(1); 298 } 299 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ 300 snprintf(comment, sizeof(comment), 301 "%u-bit %s, converted by %s@%s from OpenSSH", 302 key_size(k), key_type(k), 303 pw->pw_name, hostname); 304 305 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); 306 fprintf(stdout, "Comment: \"%s\"\n", comment); 307 dump_base64(stdout, blob, len); 308 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); 309 key_free(k); 310 free(blob); 311 exit(0); 312 } 313 314 static void 315 do_convert_to_pkcs8(Key *k) 316 { 317 switch (key_type_plain(k->type)) { 318 case KEY_RSA1: 319 case KEY_RSA: 320 if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) 321 fatal("PEM_write_RSA_PUBKEY failed"); 322 break; 323 case KEY_DSA: 324 if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) 325 fatal("PEM_write_DSA_PUBKEY failed"); 326 break; 327 #ifdef OPENSSL_HAS_ECC 328 case KEY_ECDSA: 329 if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa)) 330 fatal("PEM_write_EC_PUBKEY failed"); 331 break; 332 #endif 333 default: 334 fatal("%s: unsupported key type %s", __func__, key_type(k)); 335 } 336 exit(0); 337 } 338 339 static void 340 do_convert_to_pem(Key *k) 341 { 342 switch (key_type_plain(k->type)) { 343 case KEY_RSA1: 344 case KEY_RSA: 345 if (!PEM_write_RSAPublicKey(stdout, k->rsa)) 346 fatal("PEM_write_RSAPublicKey failed"); 347 break; 348 #if notyet /* OpenSSH 0.9.8 lacks this function */ 349 case KEY_DSA: 350 if (!PEM_write_DSAPublicKey(stdout, k->dsa)) 351 fatal("PEM_write_DSAPublicKey failed"); 352 break; 353 #endif 354 /* XXX ECDSA? */ 355 default: 356 fatal("%s: unsupported key type %s", __func__, key_type(k)); 357 } 358 exit(0); 359 } 360 361 static void 362 do_convert_to(struct passwd *pw) 363 { 364 Key *k; 365 struct stat st; 366 367 if (!have_identity) 368 ask_filename(pw, "Enter file in which the key is"); 369 if (stat(identity_file, &st) < 0) 370 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 371 if ((k = key_load_public(identity_file, NULL)) == NULL) { 372 if ((k = load_identity(identity_file)) == NULL) { 373 fprintf(stderr, "load failed\n"); 374 exit(1); 375 } 376 } 377 378 switch (convert_format) { 379 case FMT_RFC4716: 380 do_convert_to_ssh2(pw, k); 381 break; 382 case FMT_PKCS8: 383 do_convert_to_pkcs8(k); 384 break; 385 case FMT_PEM: 386 do_convert_to_pem(k); 387 break; 388 default: 389 fatal("%s: unknown key format %d", __func__, convert_format); 390 } 391 exit(0); 392 } 393 394 static void 395 buffer_get_bignum_bits(Buffer *b, BIGNUM *value) 396 { 397 u_int bignum_bits = buffer_get_int(b); 398 u_int bytes = (bignum_bits + 7) / 8; 399 400 if (buffer_len(b) < bytes) 401 fatal("buffer_get_bignum_bits: input buffer too small: " 402 "need %d have %d", bytes, buffer_len(b)); 403 if (BN_bin2bn(buffer_ptr(b), bytes, value) == NULL) 404 fatal("buffer_get_bignum_bits: BN_bin2bn failed"); 405 buffer_consume(b, bytes); 406 } 407 408 static Key * 409 do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) 410 { 411 Buffer b; 412 Key *key = NULL; 413 char *type, *cipher; 414 u_char *sig = NULL, data[] = "abcde12345"; 415 int magic, rlen, ktype, i1, i2, i3, i4; 416 u_int slen; 417 u_long e; 418 419 buffer_init(&b); 420 buffer_append(&b, blob, blen); 421 422 magic = buffer_get_int(&b); 423 if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { 424 error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC); 425 buffer_free(&b); 426 return NULL; 427 } 428 i1 = buffer_get_int(&b); 429 type = buffer_get_string(&b, NULL); 430 cipher = buffer_get_string(&b, NULL); 431 i2 = buffer_get_int(&b); 432 i3 = buffer_get_int(&b); 433 i4 = buffer_get_int(&b); 434 debug("ignore (%d %d %d %d)", i1, i2, i3, i4); 435 if (strcmp(cipher, "none") != 0) { 436 error("unsupported cipher %s", cipher); 437 free(cipher); 438 buffer_free(&b); 439 free(type); 440 return NULL; 441 } 442 free(cipher); 443 444 if (strstr(type, "dsa")) { 445 ktype = KEY_DSA; 446 } else if (strstr(type, "rsa")) { 447 ktype = KEY_RSA; 448 } else { 449 buffer_free(&b); 450 free(type); 451 return NULL; 452 } 453 key = key_new_private(ktype); 454 free(type); 455 456 switch (key->type) { 457 case KEY_DSA: 458 buffer_get_bignum_bits(&b, key->dsa->p); 459 buffer_get_bignum_bits(&b, key->dsa->g); 460 buffer_get_bignum_bits(&b, key->dsa->q); 461 buffer_get_bignum_bits(&b, key->dsa->pub_key); 462 buffer_get_bignum_bits(&b, key->dsa->priv_key); 463 break; 464 case KEY_RSA: 465 e = buffer_get_char(&b); 466 debug("e %lx", e); 467 if (e < 30) { 468 e <<= 8; 469 e += buffer_get_char(&b); 470 debug("e %lx", e); 471 e <<= 8; 472 e += buffer_get_char(&b); 473 debug("e %lx", e); 474 } 475 if (!BN_set_word(key->rsa->e, e)) { 476 buffer_free(&b); 477 key_free(key); 478 return NULL; 479 } 480 buffer_get_bignum_bits(&b, key->rsa->d); 481 buffer_get_bignum_bits(&b, key->rsa->n); 482 buffer_get_bignum_bits(&b, key->rsa->iqmp); 483 buffer_get_bignum_bits(&b, key->rsa->q); 484 buffer_get_bignum_bits(&b, key->rsa->p); 485 if (rsa_generate_additional_parameters(key->rsa) != 0) 486 fatal("%s: rsa_generate_additional_parameters " 487 "error", __func__); 488 break; 489 } 490 rlen = buffer_len(&b); 491 if (rlen != 0) 492 error("do_convert_private_ssh2_from_blob: " 493 "remaining bytes in key blob %d", rlen); 494 buffer_free(&b); 495 496 /* try the key */ 497 key_sign(key, &sig, &slen, data, sizeof(data)); 498 key_verify(key, sig, slen, data, sizeof(data)); 499 free(sig); 500 return key; 501 } 502 503 static int 504 get_line(FILE *fp, char *line, size_t len) 505 { 506 int c; 507 size_t pos = 0; 508 509 line[0] = '\0'; 510 while ((c = fgetc(fp)) != EOF) { 511 if (pos >= len - 1) { 512 fprintf(stderr, "input line too long.\n"); 513 exit(1); 514 } 515 switch (c) { 516 case '\r': 517 c = fgetc(fp); 518 if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) { 519 fprintf(stderr, "unget: %s\n", strerror(errno)); 520 exit(1); 521 } 522 return pos; 523 case '\n': 524 return pos; 525 } 526 line[pos++] = c; 527 line[pos] = '\0'; 528 } 529 /* We reached EOF */ 530 return -1; 531 } 532 533 static void 534 do_convert_from_ssh2(struct passwd *pw, Key **k, int *private) 535 { 536 int blen; 537 u_int len; 538 char line[1024]; 539 u_char blob[8096]; 540 char encoded[8096]; 541 int escaped = 0; 542 FILE *fp; 543 544 if ((fp = fopen(identity_file, "r")) == NULL) 545 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 546 encoded[0] = '\0'; 547 while ((blen = get_line(fp, line, sizeof(line))) != -1) { 548 if (blen > 0 && line[blen - 1] == '\\') 549 escaped++; 550 if (strncmp(line, "----", 4) == 0 || 551 strstr(line, ": ") != NULL) { 552 if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL) 553 *private = 1; 554 if (strstr(line, " END ") != NULL) { 555 break; 556 } 557 /* fprintf(stderr, "ignore: %s", line); */ 558 continue; 559 } 560 if (escaped) { 561 escaped--; 562 /* fprintf(stderr, "escaped: %s", line); */ 563 continue; 564 } 565 strlcat(encoded, line, sizeof(encoded)); 566 } 567 len = strlen(encoded); 568 if (((len % 4) == 3) && 569 (encoded[len-1] == '=') && 570 (encoded[len-2] == '=') && 571 (encoded[len-3] == '=')) 572 encoded[len-3] = '\0'; 573 blen = uudecode(encoded, blob, sizeof(blob)); 574 if (blen < 0) { 575 fprintf(stderr, "uudecode failed.\n"); 576 exit(1); 577 } 578 *k = *private ? 579 do_convert_private_ssh2_from_blob(blob, blen) : 580 key_from_blob(blob, blen); 581 if (*k == NULL) { 582 fprintf(stderr, "decode blob failed.\n"); 583 exit(1); 584 } 585 fclose(fp); 586 } 587 588 static void 589 do_convert_from_pkcs8(Key **k, int *private) 590 { 591 EVP_PKEY *pubkey; 592 FILE *fp; 593 594 if ((fp = fopen(identity_file, "r")) == NULL) 595 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 596 if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) { 597 fatal("%s: %s is not a recognised public key format", __func__, 598 identity_file); 599 } 600 fclose(fp); 601 switch (EVP_PKEY_type(pubkey->type)) { 602 case EVP_PKEY_RSA: 603 *k = key_new(KEY_UNSPEC); 604 (*k)->type = KEY_RSA; 605 (*k)->rsa = EVP_PKEY_get1_RSA(pubkey); 606 break; 607 case EVP_PKEY_DSA: 608 *k = key_new(KEY_UNSPEC); 609 (*k)->type = KEY_DSA; 610 (*k)->dsa = EVP_PKEY_get1_DSA(pubkey); 611 break; 612 #ifdef OPENSSL_HAS_ECC 613 case EVP_PKEY_EC: 614 *k = key_new(KEY_UNSPEC); 615 (*k)->type = KEY_ECDSA; 616 (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey); 617 (*k)->ecdsa_nid = key_ecdsa_key_to_nid((*k)->ecdsa); 618 break; 619 #endif 620 default: 621 fatal("%s: unsupported pubkey type %d", __func__, 622 EVP_PKEY_type(pubkey->type)); 623 } 624 EVP_PKEY_free(pubkey); 625 return; 626 } 627 628 static void 629 do_convert_from_pem(Key **k, int *private) 630 { 631 FILE *fp; 632 RSA *rsa; 633 #ifdef notyet 634 DSA *dsa; 635 #endif 636 637 if ((fp = fopen(identity_file, "r")) == NULL) 638 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 639 if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { 640 *k = key_new(KEY_UNSPEC); 641 (*k)->type = KEY_RSA; 642 (*k)->rsa = rsa; 643 fclose(fp); 644 return; 645 } 646 #if notyet /* OpenSSH 0.9.8 lacks this function */ 647 rewind(fp); 648 if ((dsa = PEM_read_DSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { 649 *k = key_new(KEY_UNSPEC); 650 (*k)->type = KEY_DSA; 651 (*k)->dsa = dsa; 652 fclose(fp); 653 return; 654 } 655 /* XXX ECDSA */ 656 #endif 657 fatal("%s: unrecognised raw private key format", __func__); 658 } 659 660 static void 661 do_convert_from(struct passwd *pw) 662 { 663 Key *k = NULL; 664 int private = 0, ok = 0; 665 struct stat st; 666 667 if (!have_identity) 668 ask_filename(pw, "Enter file in which the key is"); 669 if (stat(identity_file, &st) < 0) 670 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 671 672 switch (convert_format) { 673 case FMT_RFC4716: 674 do_convert_from_ssh2(pw, &k, &private); 675 break; 676 case FMT_PKCS8: 677 do_convert_from_pkcs8(&k, &private); 678 break; 679 case FMT_PEM: 680 do_convert_from_pem(&k, &private); 681 break; 682 default: 683 fatal("%s: unknown key format %d", __func__, convert_format); 684 } 685 686 if (!private) 687 ok = key_write(k, stdout); 688 if (ok) 689 fprintf(stdout, "\n"); 690 else { 691 switch (k->type) { 692 case KEY_DSA: 693 ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, 694 NULL, 0, NULL, NULL); 695 break; 696 #ifdef OPENSSL_HAS_ECC 697 case KEY_ECDSA: 698 ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL, 699 NULL, 0, NULL, NULL); 700 break; 701 #endif 702 case KEY_RSA: 703 ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, 704 NULL, 0, NULL, NULL); 705 break; 706 default: 707 fatal("%s: unsupported key type %s", __func__, 708 key_type(k)); 709 } 710 } 711 712 if (!ok) { 713 fprintf(stderr, "key write failed\n"); 714 exit(1); 715 } 716 key_free(k); 717 exit(0); 718 } 719 #endif 720 721 static void 722 do_print_public(struct passwd *pw) 723 { 724 Key *prv; 725 struct stat st; 726 727 if (!have_identity) 728 ask_filename(pw, "Enter file in which the key is"); 729 if (stat(identity_file, &st) < 0) { 730 perror(identity_file); 731 exit(1); 732 } 733 prv = load_identity(identity_file); 734 if (prv == NULL) { 735 fprintf(stderr, "load failed\n"); 736 exit(1); 737 } 738 if (!key_write(prv, stdout)) 739 fprintf(stderr, "key_write failed"); 740 key_free(prv); 741 fprintf(stdout, "\n"); 742 exit(0); 743 } 744 745 static void 746 do_download(struct passwd *pw) 747 { 748 #ifdef ENABLE_PKCS11 749 Key **keys = NULL; 750 int i, nkeys; 751 enum fp_rep rep; 752 enum fp_type fptype; 753 char *fp, *ra; 754 755 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; 756 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; 757 758 pkcs11_init(0); 759 nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); 760 if (nkeys <= 0) 761 fatal("cannot read public key from pkcs11"); 762 for (i = 0; i < nkeys; i++) { 763 if (print_fingerprint) { 764 fp = key_fingerprint(keys[i], fptype, rep); 765 ra = key_fingerprint(keys[i], SSH_FP_MD5, 766 SSH_FP_RANDOMART); 767 printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), 768 fp, key_type(keys[i])); 769 if (log_level >= SYSLOG_LEVEL_VERBOSE) 770 printf("%s\n", ra); 771 free(ra); 772 free(fp); 773 } else { 774 key_write(keys[i], stdout); 775 fprintf(stdout, "\n"); 776 } 777 key_free(keys[i]); 778 } 779 free(keys); 780 pkcs11_terminate(); 781 exit(0); 782 #else 783 fatal("no pkcs11 support"); 784 #endif /* ENABLE_PKCS11 */ 785 } 786 787 static void 788 do_fingerprint(struct passwd *pw) 789 { 790 FILE *f; 791 Key *public; 792 char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; 793 int i, skip = 0, num = 0, invalid = 1; 794 enum fp_rep rep; 795 enum fp_type fptype; 796 struct stat st; 797 798 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; 799 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; 800 801 if (!have_identity) 802 ask_filename(pw, "Enter file in which the key is"); 803 if (stat(identity_file, &st) < 0) { 804 perror(identity_file); 805 exit(1); 806 } 807 public = key_load_public(identity_file, &comment); 808 if (public != NULL) { 809 fp = key_fingerprint(public, fptype, rep); 810 ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); 811 printf("%u %s %s (%s)\n", key_size(public), fp, comment, 812 key_type(public)); 813 if (log_level >= SYSLOG_LEVEL_VERBOSE) 814 printf("%s\n", ra); 815 key_free(public); 816 free(comment); 817 free(ra); 818 free(fp); 819 exit(0); 820 } 821 if (comment) { 822 free(comment); 823 comment = NULL; 824 } 825 826 if ((f = fopen(identity_file, "r")) == NULL) 827 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 828 829 while (fgets(line, sizeof(line), f)) { 830 if ((cp = strchr(line, '\n')) == NULL) { 831 error("line %d too long: %.40s...", 832 num + 1, line); 833 skip = 1; 834 continue; 835 } 836 num++; 837 if (skip) { 838 skip = 0; 839 continue; 840 } 841 *cp = '\0'; 842 843 /* Skip leading whitespace, empty and comment lines. */ 844 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 845 ; 846 if (!*cp || *cp == '\n' || *cp == '#') 847 continue; 848 i = strtol(cp, &ep, 10); 849 if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) { 850 int quoted = 0; 851 comment = cp; 852 for (; *cp && (quoted || (*cp != ' ' && 853 *cp != '\t')); cp++) { 854 if (*cp == '\\' && cp[1] == '"') 855 cp++; /* Skip both */ 856 else if (*cp == '"') 857 quoted = !quoted; 858 } 859 if (!*cp) 860 continue; 861 *cp++ = '\0'; 862 } 863 ep = cp; 864 public = key_new(KEY_RSA1); 865 if (key_read(public, &cp) != 1) { 866 cp = ep; 867 key_free(public); 868 public = key_new(KEY_UNSPEC); 869 if (key_read(public, &cp) != 1) { 870 key_free(public); 871 continue; 872 } 873 } 874 comment = *cp ? cp : comment; 875 fp = key_fingerprint(public, fptype, rep); 876 ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); 877 printf("%u %s %s (%s)\n", key_size(public), fp, 878 comment ? comment : "no comment", key_type(public)); 879 if (log_level >= SYSLOG_LEVEL_VERBOSE) 880 printf("%s\n", ra); 881 free(ra); 882 free(fp); 883 key_free(public); 884 invalid = 0; 885 } 886 fclose(f); 887 888 if (invalid) { 889 printf("%s is not a public key file.\n", identity_file); 890 exit(1); 891 } 892 exit(0); 893 } 894 895 static void 896 do_gen_all_hostkeys(struct passwd *pw) 897 { 898 struct { 899 char *key_type; 900 char *key_type_display; 901 char *path; 902 } key_types[] = { 903 { "rsa1", "RSA1", _PATH_HOST_KEY_FILE }, 904 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE }, 905 { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE }, 906 #ifdef OPENSSL_HAS_ECC 907 { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE }, 908 #endif 909 { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE }, 910 { NULL, NULL, NULL } 911 }; 912 913 int first = 0; 914 struct stat st; 915 Key *private, *public; 916 char comment[1024]; 917 int i, type, fd; 918 FILE *f; 919 920 for (i = 0; key_types[i].key_type; i++) { 921 if (stat(key_types[i].path, &st) == 0) 922 continue; 923 if (errno != ENOENT) { 924 printf("Could not stat %s: %s", key_types[i].path, 925 strerror(errno)); 926 first = 0; 927 continue; 928 } 929 930 if (first == 0) { 931 first = 1; 932 printf("%s: generating new host keys: ", __progname); 933 } 934 printf("%s ", key_types[i].key_type_display); 935 fflush(stdout); 936 type = key_type_from_name(key_types[i].key_type); 937 strlcpy(identity_file, key_types[i].path, sizeof(identity_file)); 938 bits = 0; 939 type_bits_valid(type, &bits); 940 private = key_generate(type, bits); 941 if (private == NULL) { 942 fprintf(stderr, "key_generate failed\n"); 943 first = 0; 944 continue; 945 } 946 public = key_from_private(private); 947 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, 948 hostname); 949 if (!key_save_private(private, identity_file, "", comment, 950 use_new_format, new_format_cipher, rounds)) { 951 printf("Saving the key failed: %s.\n", identity_file); 952 key_free(private); 953 key_free(public); 954 first = 0; 955 continue; 956 } 957 key_free(private); 958 strlcat(identity_file, ".pub", sizeof(identity_file)); 959 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 960 if (fd == -1) { 961 printf("Could not save your public key in %s\n", 962 identity_file); 963 key_free(public); 964 first = 0; 965 continue; 966 } 967 f = fdopen(fd, "w"); 968 if (f == NULL) { 969 printf("fdopen %s failed\n", identity_file); 970 key_free(public); 971 first = 0; 972 continue; 973 } 974 if (!key_write(public, f)) { 975 fprintf(stderr, "write key failed\n"); 976 key_free(public); 977 first = 0; 978 continue; 979 } 980 fprintf(f, " %s\n", comment); 981 fclose(f); 982 key_free(public); 983 984 } 985 if (first != 0) 986 printf("\n"); 987 } 988 989 static void 990 printhost(FILE *f, const char *name, Key *public, int ca, int revoked, int hash) 991 { 992 if (print_fingerprint) { 993 enum fp_rep rep; 994 enum fp_type fptype; 995 char *fp, *ra; 996 997 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; 998 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; 999 fp = key_fingerprint(public, fptype, rep); 1000 ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); 1001 printf("%u %s %s (%s)\n", key_size(public), fp, name, 1002 key_type(public)); 1003 if (log_level >= SYSLOG_LEVEL_VERBOSE) 1004 printf("%s\n", ra); 1005 free(ra); 1006 free(fp); 1007 } else { 1008 if (hash && (name = host_hash(name, NULL, 0)) == NULL) 1009 fatal("hash_host failed"); 1010 fprintf(f, "%s%s%s ", ca ? CA_MARKER " " : "", 1011 revoked ? REVOKE_MARKER " " : "" , name); 1012 if (!key_write(public, f)) 1013 fatal("key_write failed"); 1014 fprintf(f, "\n"); 1015 } 1016 } 1017 1018 static void 1019 do_known_hosts(struct passwd *pw, const char *name) 1020 { 1021 FILE *in, *out = stdout; 1022 Key *pub; 1023 char *cp, *cp2, *kp, *kp2; 1024 char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; 1025 int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; 1026 int ca, revoked; 1027 int found_key = 0; 1028 1029 if (!have_identity) { 1030 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); 1031 if (strlcpy(identity_file, cp, sizeof(identity_file)) >= 1032 sizeof(identity_file)) 1033 fatal("Specified known hosts path too long"); 1034 free(cp); 1035 have_identity = 1; 1036 } 1037 if ((in = fopen(identity_file, "r")) == NULL) 1038 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 1039 1040 /* XXX this code is a mess; refactor -djm */ 1041 /* 1042 * Find hosts goes to stdout, hash and deletions happen in-place 1043 * A corner case is ssh-keygen -HF foo, which should go to stdout 1044 */ 1045 if (!find_host && (hash_hosts || delete_host)) { 1046 if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) || 1047 strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) || 1048 strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) || 1049 strlcat(old, ".old", sizeof(old)) >= sizeof(old)) 1050 fatal("known_hosts path too long"); 1051 umask(077); 1052 if ((c = mkstemp(tmp)) == -1) 1053 fatal("mkstemp: %s", strerror(errno)); 1054 if ((out = fdopen(c, "w")) == NULL) { 1055 c = errno; 1056 unlink(tmp); 1057 fatal("fdopen: %s", strerror(c)); 1058 } 1059 inplace = 1; 1060 } 1061 1062 while (fgets(line, sizeof(line), in)) { 1063 if ((cp = strchr(line, '\n')) == NULL) { 1064 error("line %d too long: %.40s...", num + 1, line); 1065 skip = 1; 1066 invalid = 1; 1067 continue; 1068 } 1069 num++; 1070 if (skip) { 1071 skip = 0; 1072 continue; 1073 } 1074 *cp = '\0'; 1075 1076 /* Skip leading whitespace, empty and comment lines. */ 1077 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 1078 ; 1079 if (!*cp || *cp == '\n' || *cp == '#') { 1080 if (inplace) 1081 fprintf(out, "%s\n", cp); 1082 continue; 1083 } 1084 /* Check whether this is a CA key or revocation marker */ 1085 if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 && 1086 (cp[sizeof(CA_MARKER) - 1] == ' ' || 1087 cp[sizeof(CA_MARKER) - 1] == '\t')) { 1088 ca = 1; 1089 cp += sizeof(CA_MARKER); 1090 } else 1091 ca = 0; 1092 if (strncasecmp(cp, REVOKE_MARKER, 1093 sizeof(REVOKE_MARKER) - 1) == 0 && 1094 (cp[sizeof(REVOKE_MARKER) - 1] == ' ' || 1095 cp[sizeof(REVOKE_MARKER) - 1] == '\t')) { 1096 revoked = 1; 1097 cp += sizeof(REVOKE_MARKER); 1098 } else 1099 revoked = 0; 1100 1101 /* Find the end of the host name portion. */ 1102 for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++) 1103 ; 1104 1105 if (*kp == '\0' || *(kp + 1) == '\0') { 1106 error("line %d missing key: %.40s...", 1107 num, line); 1108 invalid = 1; 1109 continue; 1110 } 1111 *kp++ = '\0'; 1112 kp2 = kp; 1113 1114 pub = key_new(KEY_RSA1); 1115 if (key_read(pub, &kp) != 1) { 1116 kp = kp2; 1117 key_free(pub); 1118 pub = key_new(KEY_UNSPEC); 1119 if (key_read(pub, &kp) != 1) { 1120 error("line %d invalid key: %.40s...", 1121 num, line); 1122 key_free(pub); 1123 invalid = 1; 1124 continue; 1125 } 1126 } 1127 1128 if (*cp == HASH_DELIM) { 1129 if (find_host || delete_host) { 1130 cp2 = host_hash(name, cp, strlen(cp)); 1131 if (cp2 == NULL) { 1132 error("line %d: invalid hashed " 1133 "name: %.64s...", num, line); 1134 invalid = 1; 1135 continue; 1136 } 1137 c = (strcmp(cp2, cp) == 0); 1138 if (find_host && c) { 1139 if (!quiet) 1140 printf("# Host %s found: " 1141 "line %d type %s%s\n", name, 1142 num, key_type(pub), 1143 ca ? " (CA key)" : 1144 revoked? " (revoked)" : ""); 1145 printhost(out, cp, pub, ca, revoked, 0); 1146 found_key = 1; 1147 } 1148 if (delete_host) { 1149 if (!c || ca || revoked) { 1150 printhost(out, cp, pub, 1151 ca, revoked, 0); 1152 } else { 1153 printf("# Host %s found: " 1154 "line %d type %s\n", name, 1155 num, key_type(pub)); 1156 } 1157 } 1158 } else if (hash_hosts) 1159 printhost(out, cp, pub, ca, revoked, 0); 1160 } else { 1161 if (find_host || delete_host) { 1162 c = (match_hostname(name, cp, 1163 strlen(cp)) == 1); 1164 if (find_host && c) { 1165 if (!quiet) 1166 printf("# Host %s found: " 1167 "line %d type %s%s\n", name, 1168 num, key_type(pub), 1169 ca ? " (CA key)" : ""); 1170 printhost(out, name, pub, ca, revoked, 1171 hash_hosts && !(ca || revoked)); 1172 found_key = 1; 1173 } 1174 if (delete_host) { 1175 if (!c || ca || revoked) { 1176 printhost(out, cp, pub, 1177 ca, revoked, 0); 1178 } else { 1179 printf("# Host %s found: " 1180 "line %d type %s\n", name, 1181 num, key_type(pub)); 1182 } 1183 } 1184 } else if (hash_hosts && (ca || revoked)) { 1185 /* Don't hash CA and revoked keys' hostnames */ 1186 printhost(out, cp, pub, ca, revoked, 0); 1187 has_unhashed = 1; 1188 } else if (hash_hosts) { 1189 /* Hash each hostname separately */ 1190 for (cp2 = strsep(&cp, ","); 1191 cp2 != NULL && *cp2 != '\0'; 1192 cp2 = strsep(&cp, ",")) { 1193 if (strcspn(cp2, "*?!") != 1194 strlen(cp2)) { 1195 fprintf(stderr, "Warning: " 1196 "ignoring host name with " 1197 "metacharacters: %.64s\n", 1198 cp2); 1199 printhost(out, cp2, pub, ca, 1200 revoked, 0); 1201 has_unhashed = 1; 1202 } else { 1203 printhost(out, cp2, pub, ca, 1204 revoked, 1); 1205 } 1206 } 1207 } 1208 } 1209 key_free(pub); 1210 } 1211 fclose(in); 1212 1213 if (invalid) { 1214 fprintf(stderr, "%s is not a valid known_hosts file.\n", 1215 identity_file); 1216 if (inplace) { 1217 fprintf(stderr, "Not replacing existing known_hosts " 1218 "file because of errors\n"); 1219 fclose(out); 1220 unlink(tmp); 1221 } 1222 exit(1); 1223 } 1224 1225 if (inplace) { 1226 fclose(out); 1227 1228 /* Backup existing file */ 1229 if (unlink(old) == -1 && errno != ENOENT) 1230 fatal("unlink %.100s: %s", old, strerror(errno)); 1231 if (link(identity_file, old) == -1) 1232 fatal("link %.100s to %.100s: %s", identity_file, old, 1233 strerror(errno)); 1234 /* Move new one into place */ 1235 if (rename(tmp, identity_file) == -1) { 1236 error("rename\"%s\" to \"%s\": %s", tmp, identity_file, 1237 strerror(errno)); 1238 unlink(tmp); 1239 unlink(old); 1240 exit(1); 1241 } 1242 1243 fprintf(stderr, "%s updated.\n", identity_file); 1244 fprintf(stderr, "Original contents retained as %s\n", old); 1245 if (has_unhashed) { 1246 fprintf(stderr, "WARNING: %s contains unhashed " 1247 "entries\n", old); 1248 fprintf(stderr, "Delete this file to ensure privacy " 1249 "of hostnames\n"); 1250 } 1251 } 1252 1253 exit (find_host && !found_key); 1254 } 1255 1256 /* 1257 * Perform changing a passphrase. The argument is the passwd structure 1258 * for the current user. 1259 */ 1260 static void 1261 do_change_passphrase(struct passwd *pw) 1262 { 1263 char *comment; 1264 char *old_passphrase, *passphrase1, *passphrase2; 1265 struct stat st; 1266 Key *private; 1267 1268 if (!have_identity) 1269 ask_filename(pw, "Enter file in which the key is"); 1270 if (stat(identity_file, &st) < 0) { 1271 perror(identity_file); 1272 exit(1); 1273 } 1274 /* Try to load the file with empty passphrase. */ 1275 private = key_load_private(identity_file, "", &comment); 1276 if (private == NULL) { 1277 if (identity_passphrase) 1278 old_passphrase = xstrdup(identity_passphrase); 1279 else 1280 old_passphrase = 1281 read_passphrase("Enter old passphrase: ", 1282 RP_ALLOW_STDIN); 1283 private = key_load_private(identity_file, old_passphrase, 1284 &comment); 1285 explicit_bzero(old_passphrase, strlen(old_passphrase)); 1286 free(old_passphrase); 1287 if (private == NULL) { 1288 printf("Bad passphrase.\n"); 1289 exit(1); 1290 } 1291 } 1292 printf("Key has comment '%s'\n", comment); 1293 1294 /* Ask the new passphrase (twice). */ 1295 if (identity_new_passphrase) { 1296 passphrase1 = xstrdup(identity_new_passphrase); 1297 passphrase2 = NULL; 1298 } else { 1299 passphrase1 = 1300 read_passphrase("Enter new passphrase (empty for no " 1301 "passphrase): ", RP_ALLOW_STDIN); 1302 passphrase2 = read_passphrase("Enter same passphrase again: ", 1303 RP_ALLOW_STDIN); 1304 1305 /* Verify that they are the same. */ 1306 if (strcmp(passphrase1, passphrase2) != 0) { 1307 explicit_bzero(passphrase1, strlen(passphrase1)); 1308 explicit_bzero(passphrase2, strlen(passphrase2)); 1309 free(passphrase1); 1310 free(passphrase2); 1311 printf("Pass phrases do not match. Try again.\n"); 1312 exit(1); 1313 } 1314 /* Destroy the other copy. */ 1315 explicit_bzero(passphrase2, strlen(passphrase2)); 1316 free(passphrase2); 1317 } 1318 1319 /* Save the file using the new passphrase. */ 1320 if (!key_save_private(private, identity_file, passphrase1, comment, 1321 use_new_format, new_format_cipher, rounds)) { 1322 printf("Saving the key failed: %s.\n", identity_file); 1323 explicit_bzero(passphrase1, strlen(passphrase1)); 1324 free(passphrase1); 1325 key_free(private); 1326 free(comment); 1327 exit(1); 1328 } 1329 /* Destroy the passphrase and the copy of the key in memory. */ 1330 explicit_bzero(passphrase1, strlen(passphrase1)); 1331 free(passphrase1); 1332 key_free(private); /* Destroys contents */ 1333 free(comment); 1334 1335 printf("Your identification has been saved with the new passphrase.\n"); 1336 exit(0); 1337 } 1338 1339 /* 1340 * Print the SSHFP RR. 1341 */ 1342 static int 1343 do_print_resource_record(struct passwd *pw, char *fname, char *hname) 1344 { 1345 Key *public; 1346 char *comment = NULL; 1347 struct stat st; 1348 1349 if (fname == NULL) 1350 fatal("%s: no filename", __func__); 1351 if (stat(fname, &st) < 0) { 1352 if (errno == ENOENT) 1353 return 0; 1354 perror(fname); 1355 exit(1); 1356 } 1357 public = key_load_public(fname, &comment); 1358 if (public != NULL) { 1359 export_dns_rr(hname, public, stdout, print_generic); 1360 key_free(public); 1361 free(comment); 1362 return 1; 1363 } 1364 if (comment) 1365 free(comment); 1366 1367 printf("failed to read v2 public key from %s.\n", fname); 1368 exit(1); 1369 } 1370 1371 /* 1372 * Change the comment of a private key file. 1373 */ 1374 static void 1375 do_change_comment(struct passwd *pw) 1376 { 1377 char new_comment[1024], *comment, *passphrase; 1378 Key *private; 1379 Key *public; 1380 struct stat st; 1381 FILE *f; 1382 int fd; 1383 1384 if (!have_identity) 1385 ask_filename(pw, "Enter file in which the key is"); 1386 if (stat(identity_file, &st) < 0) { 1387 perror(identity_file); 1388 exit(1); 1389 } 1390 private = key_load_private(identity_file, "", &comment); 1391 if (private == NULL) { 1392 if (identity_passphrase) 1393 passphrase = xstrdup(identity_passphrase); 1394 else if (identity_new_passphrase) 1395 passphrase = xstrdup(identity_new_passphrase); 1396 else 1397 passphrase = read_passphrase("Enter passphrase: ", 1398 RP_ALLOW_STDIN); 1399 /* Try to load using the passphrase. */ 1400 private = key_load_private(identity_file, passphrase, &comment); 1401 if (private == NULL) { 1402 explicit_bzero(passphrase, strlen(passphrase)); 1403 free(passphrase); 1404 printf("Bad passphrase.\n"); 1405 exit(1); 1406 } 1407 } else { 1408 passphrase = xstrdup(""); 1409 } 1410 if (private->type != KEY_RSA1) { 1411 fprintf(stderr, "Comments are only supported for RSA1 keys.\n"); 1412 key_free(private); 1413 exit(1); 1414 } 1415 printf("Key now has comment '%s'\n", comment); 1416 1417 if (identity_comment) { 1418 strlcpy(new_comment, identity_comment, sizeof(new_comment)); 1419 } else { 1420 printf("Enter new comment: "); 1421 fflush(stdout); 1422 if (!fgets(new_comment, sizeof(new_comment), stdin)) { 1423 explicit_bzero(passphrase, strlen(passphrase)); 1424 key_free(private); 1425 exit(1); 1426 } 1427 new_comment[strcspn(new_comment, "\n")] = '\0'; 1428 } 1429 1430 /* Save the file using the new passphrase. */ 1431 if (!key_save_private(private, identity_file, passphrase, new_comment, 1432 use_new_format, new_format_cipher, rounds)) { 1433 printf("Saving the key failed: %s.\n", identity_file); 1434 explicit_bzero(passphrase, strlen(passphrase)); 1435 free(passphrase); 1436 key_free(private); 1437 free(comment); 1438 exit(1); 1439 } 1440 explicit_bzero(passphrase, strlen(passphrase)); 1441 free(passphrase); 1442 public = key_from_private(private); 1443 key_free(private); 1444 1445 strlcat(identity_file, ".pub", sizeof(identity_file)); 1446 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 1447 if (fd == -1) { 1448 printf("Could not save your public key in %s\n", identity_file); 1449 exit(1); 1450 } 1451 f = fdopen(fd, "w"); 1452 if (f == NULL) { 1453 printf("fdopen %s failed\n", identity_file); 1454 exit(1); 1455 } 1456 if (!key_write(public, f)) 1457 fprintf(stderr, "write key failed\n"); 1458 key_free(public); 1459 fprintf(f, " %s\n", new_comment); 1460 fclose(f); 1461 1462 free(comment); 1463 1464 printf("The comment in your key file has been changed.\n"); 1465 exit(0); 1466 } 1467 1468 static const char * 1469 fmt_validity(u_int64_t valid_from, u_int64_t valid_to) 1470 { 1471 char from[32], to[32]; 1472 static char ret[64]; 1473 time_t tt; 1474 struct tm *tm; 1475 1476 *from = *to = '\0'; 1477 if (valid_from == 0 && valid_to == 0xffffffffffffffffULL) 1478 return "forever"; 1479 1480 if (valid_from != 0) { 1481 /* XXX revisit INT_MAX in 2038 :) */ 1482 tt = valid_from > INT_MAX ? INT_MAX : valid_from; 1483 tm = localtime(&tt); 1484 strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm); 1485 } 1486 if (valid_to != 0xffffffffffffffffULL) { 1487 /* XXX revisit INT_MAX in 2038 :) */ 1488 tt = valid_to > INT_MAX ? INT_MAX : valid_to; 1489 tm = localtime(&tt); 1490 strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm); 1491 } 1492 1493 if (valid_from == 0) { 1494 snprintf(ret, sizeof(ret), "before %s", to); 1495 return ret; 1496 } 1497 if (valid_to == 0xffffffffffffffffULL) { 1498 snprintf(ret, sizeof(ret), "after %s", from); 1499 return ret; 1500 } 1501 1502 snprintf(ret, sizeof(ret), "from %s to %s", from, to); 1503 return ret; 1504 } 1505 1506 static void 1507 add_flag_option(Buffer *c, const char *name) 1508 { 1509 debug3("%s: %s", __func__, name); 1510 buffer_put_cstring(c, name); 1511 buffer_put_string(c, NULL, 0); 1512 } 1513 1514 static void 1515 add_string_option(Buffer *c, const char *name, const char *value) 1516 { 1517 Buffer b; 1518 1519 debug3("%s: %s=%s", __func__, name, value); 1520 buffer_init(&b); 1521 buffer_put_cstring(&b, value); 1522 1523 buffer_put_cstring(c, name); 1524 buffer_put_string(c, buffer_ptr(&b), buffer_len(&b)); 1525 1526 buffer_free(&b); 1527 } 1528 1529 #define OPTIONS_CRITICAL 1 1530 #define OPTIONS_EXTENSIONS 2 1531 static void 1532 prepare_options_buf(Buffer *c, int which) 1533 { 1534 buffer_clear(c); 1535 if ((which & OPTIONS_CRITICAL) != 0 && 1536 certflags_command != NULL) 1537 add_string_option(c, "force-command", certflags_command); 1538 if ((which & OPTIONS_EXTENSIONS) != 0 && 1539 (certflags_flags & CERTOPT_X_FWD) != 0) 1540 add_flag_option(c, "permit-X11-forwarding"); 1541 if ((which & OPTIONS_EXTENSIONS) != 0 && 1542 (certflags_flags & CERTOPT_AGENT_FWD) != 0) 1543 add_flag_option(c, "permit-agent-forwarding"); 1544 if ((which & OPTIONS_EXTENSIONS) != 0 && 1545 (certflags_flags & CERTOPT_PORT_FWD) != 0) 1546 add_flag_option(c, "permit-port-forwarding"); 1547 if ((which & OPTIONS_EXTENSIONS) != 0 && 1548 (certflags_flags & CERTOPT_PTY) != 0) 1549 add_flag_option(c, "permit-pty"); 1550 if ((which & OPTIONS_EXTENSIONS) != 0 && 1551 (certflags_flags & CERTOPT_USER_RC) != 0) 1552 add_flag_option(c, "permit-user-rc"); 1553 if ((which & OPTIONS_CRITICAL) != 0 && 1554 certflags_src_addr != NULL) 1555 add_string_option(c, "source-address", certflags_src_addr); 1556 } 1557 1558 static Key * 1559 load_pkcs11_key(char *path) 1560 { 1561 #ifdef ENABLE_PKCS11 1562 Key **keys = NULL, *public, *private = NULL; 1563 int i, nkeys; 1564 1565 if ((public = key_load_public(path, NULL)) == NULL) 1566 fatal("Couldn't load CA public key \"%s\"", path); 1567 1568 nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys); 1569 debug3("%s: %d keys", __func__, nkeys); 1570 if (nkeys <= 0) 1571 fatal("cannot read public key from pkcs11"); 1572 for (i = 0; i < nkeys; i++) { 1573 if (key_equal_public(public, keys[i])) { 1574 private = keys[i]; 1575 continue; 1576 } 1577 key_free(keys[i]); 1578 } 1579 free(keys); 1580 key_free(public); 1581 return private; 1582 #else 1583 fatal("no pkcs11 support"); 1584 #endif /* ENABLE_PKCS11 */ 1585 } 1586 1587 static void 1588 do_ca_sign(struct passwd *pw, int argc, char **argv) 1589 { 1590 int i, fd; 1591 u_int n; 1592 Key *ca, *public; 1593 char *otmp, *tmp, *cp, *out, *comment, **plist = NULL; 1594 FILE *f; 1595 int v00 = 0; /* legacy keys */ 1596 1597 if (key_type_name != NULL) { 1598 switch (key_type_from_name(key_type_name)) { 1599 case KEY_RSA_CERT_V00: 1600 case KEY_DSA_CERT_V00: 1601 v00 = 1; 1602 break; 1603 case KEY_UNSPEC: 1604 if (strcasecmp(key_type_name, "v00") == 0) { 1605 v00 = 1; 1606 break; 1607 } else if (strcasecmp(key_type_name, "v01") == 0) 1608 break; 1609 /* FALLTHROUGH */ 1610 default: 1611 fprintf(stderr, "unknown key type %s\n", key_type_name); 1612 exit(1); 1613 } 1614 } 1615 1616 #ifdef ENABLE_PKCS11 1617 pkcs11_init(1); 1618 #endif 1619 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); 1620 if (pkcs11provider != NULL) { 1621 if ((ca = load_pkcs11_key(tmp)) == NULL) 1622 fatal("No PKCS#11 key matching %s found", ca_key_path); 1623 } else if ((ca = load_identity(tmp)) == NULL) 1624 fatal("Couldn't load CA key \"%s\"", tmp); 1625 free(tmp); 1626 1627 for (i = 0; i < argc; i++) { 1628 /* Split list of principals */ 1629 n = 0; 1630 if (cert_principals != NULL) { 1631 otmp = tmp = xstrdup(cert_principals); 1632 plist = NULL; 1633 for (; (cp = strsep(&tmp, ",")) != NULL; n++) { 1634 plist = xrealloc(plist, n + 1, sizeof(*plist)); 1635 if (*(plist[n] = xstrdup(cp)) == '\0') 1636 fatal("Empty principal name"); 1637 } 1638 free(otmp); 1639 } 1640 1641 tmp = tilde_expand_filename(argv[i], pw->pw_uid); 1642 if ((public = key_load_public(tmp, &comment)) == NULL) 1643 fatal("%s: unable to open \"%s\"", __func__, tmp); 1644 if (public->type != KEY_RSA && public->type != KEY_DSA && 1645 public->type != KEY_ECDSA && public->type != KEY_ED25519) 1646 fatal("%s: key \"%s\" type %s cannot be certified", 1647 __func__, tmp, key_type(public)); 1648 1649 /* Prepare certificate to sign */ 1650 if (key_to_certified(public, v00) != 0) 1651 fatal("Could not upgrade key %s to certificate", tmp); 1652 public->cert->type = cert_key_type; 1653 public->cert->serial = (u_int64_t)cert_serial; 1654 public->cert->key_id = xstrdup(cert_key_id); 1655 public->cert->nprincipals = n; 1656 public->cert->principals = plist; 1657 public->cert->valid_after = cert_valid_from; 1658 public->cert->valid_before = cert_valid_to; 1659 if (v00) { 1660 prepare_options_buf(public->cert->critical, 1661 OPTIONS_CRITICAL|OPTIONS_EXTENSIONS); 1662 } else { 1663 prepare_options_buf(public->cert->critical, 1664 OPTIONS_CRITICAL); 1665 prepare_options_buf(public->cert->extensions, 1666 OPTIONS_EXTENSIONS); 1667 } 1668 public->cert->signature_key = key_from_private(ca); 1669 1670 if (key_certify(public, ca) != 0) 1671 fatal("Couldn't not certify key %s", tmp); 1672 1673 if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0) 1674 *cp = '\0'; 1675 xasprintf(&out, "%s-cert.pub", tmp); 1676 free(tmp); 1677 1678 if ((fd = open(out, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) 1679 fatal("Could not open \"%s\" for writing: %s", out, 1680 strerror(errno)); 1681 if ((f = fdopen(fd, "w")) == NULL) 1682 fatal("%s: fdopen: %s", __func__, strerror(errno)); 1683 if (!key_write(public, f)) 1684 fatal("Could not write certified key to %s", out); 1685 fprintf(f, " %s\n", comment); 1686 fclose(f); 1687 1688 if (!quiet) { 1689 logit("Signed %s key %s: id \"%s\" serial %llu%s%s " 1690 "valid %s", key_cert_type(public), 1691 out, public->cert->key_id, 1692 (unsigned long long)public->cert->serial, 1693 cert_principals != NULL ? " for " : "", 1694 cert_principals != NULL ? cert_principals : "", 1695 fmt_validity(cert_valid_from, cert_valid_to)); 1696 } 1697 1698 key_free(public); 1699 free(out); 1700 } 1701 #ifdef ENABLE_PKCS11 1702 pkcs11_terminate(); 1703 #endif 1704 exit(0); 1705 } 1706 1707 static u_int64_t 1708 parse_relative_time(const char *s, time_t now) 1709 { 1710 int64_t mul, secs; 1711 1712 mul = *s == '-' ? -1 : 1; 1713 1714 if ((secs = convtime(s + 1)) == -1) 1715 fatal("Invalid relative certificate time %s", s); 1716 if (mul == -1 && secs > now) 1717 fatal("Certificate time %s cannot be represented", s); 1718 return now + (u_int64_t)(secs * mul); 1719 } 1720 1721 static u_int64_t 1722 parse_absolute_time(const char *s) 1723 { 1724 struct tm tm; 1725 time_t tt; 1726 char buf[32], *fmt; 1727 1728 /* 1729 * POSIX strptime says "The application shall ensure that there 1730 * is white-space or other non-alphanumeric characters between 1731 * any two conversion specifications" so arrange things this way. 1732 */ 1733 switch (strlen(s)) { 1734 case 8: 1735 fmt = "%Y-%m-%d"; 1736 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6); 1737 break; 1738 case 14: 1739 fmt = "%Y-%m-%dT%H:%M:%S"; 1740 snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s", 1741 s, s + 4, s + 6, s + 8, s + 10, s + 12); 1742 break; 1743 default: 1744 fatal("Invalid certificate time format %s", s); 1745 } 1746 1747 memset(&tm, 0, sizeof(tm)); 1748 if (strptime(buf, fmt, &tm) == NULL) 1749 fatal("Invalid certificate time %s", s); 1750 if ((tt = mktime(&tm)) < 0) 1751 fatal("Certificate time %s cannot be represented", s); 1752 return (u_int64_t)tt; 1753 } 1754 1755 static void 1756 parse_cert_times(char *timespec) 1757 { 1758 char *from, *to; 1759 time_t now = time(NULL); 1760 int64_t secs; 1761 1762 /* +timespec relative to now */ 1763 if (*timespec == '+' && strchr(timespec, ':') == NULL) { 1764 if ((secs = convtime(timespec + 1)) == -1) 1765 fatal("Invalid relative certificate life %s", timespec); 1766 cert_valid_to = now + secs; 1767 /* 1768 * Backdate certificate one minute to avoid problems on hosts 1769 * with poorly-synchronised clocks. 1770 */ 1771 cert_valid_from = ((now - 59)/ 60) * 60; 1772 return; 1773 } 1774 1775 /* 1776 * from:to, where 1777 * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS 1778 * to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS 1779 */ 1780 from = xstrdup(timespec); 1781 to = strchr(from, ':'); 1782 if (to == NULL || from == to || *(to + 1) == '\0') 1783 fatal("Invalid certificate life specification %s", timespec); 1784 *to++ = '\0'; 1785 1786 if (*from == '-' || *from == '+') 1787 cert_valid_from = parse_relative_time(from, now); 1788 else 1789 cert_valid_from = parse_absolute_time(from); 1790 1791 if (*to == '-' || *to == '+') 1792 cert_valid_to = parse_relative_time(to, now); 1793 else 1794 cert_valid_to = parse_absolute_time(to); 1795 1796 if (cert_valid_to <= cert_valid_from) 1797 fatal("Empty certificate validity interval"); 1798 free(from); 1799 } 1800 1801 static void 1802 add_cert_option(char *opt) 1803 { 1804 char *val; 1805 1806 if (strcasecmp(opt, "clear") == 0) 1807 certflags_flags = 0; 1808 else if (strcasecmp(opt, "no-x11-forwarding") == 0) 1809 certflags_flags &= ~CERTOPT_X_FWD; 1810 else if (strcasecmp(opt, "permit-x11-forwarding") == 0) 1811 certflags_flags |= CERTOPT_X_FWD; 1812 else if (strcasecmp(opt, "no-agent-forwarding") == 0) 1813 certflags_flags &= ~CERTOPT_AGENT_FWD; 1814 else if (strcasecmp(opt, "permit-agent-forwarding") == 0) 1815 certflags_flags |= CERTOPT_AGENT_FWD; 1816 else if (strcasecmp(opt, "no-port-forwarding") == 0) 1817 certflags_flags &= ~CERTOPT_PORT_FWD; 1818 else if (strcasecmp(opt, "permit-port-forwarding") == 0) 1819 certflags_flags |= CERTOPT_PORT_FWD; 1820 else if (strcasecmp(opt, "no-pty") == 0) 1821 certflags_flags &= ~CERTOPT_PTY; 1822 else if (strcasecmp(opt, "permit-pty") == 0) 1823 certflags_flags |= CERTOPT_PTY; 1824 else if (strcasecmp(opt, "no-user-rc") == 0) 1825 certflags_flags &= ~CERTOPT_USER_RC; 1826 else if (strcasecmp(opt, "permit-user-rc") == 0) 1827 certflags_flags |= CERTOPT_USER_RC; 1828 else if (strncasecmp(opt, "force-command=", 14) == 0) { 1829 val = opt + 14; 1830 if (*val == '\0') 1831 fatal("Empty force-command option"); 1832 if (certflags_command != NULL) 1833 fatal("force-command already specified"); 1834 certflags_command = xstrdup(val); 1835 } else if (strncasecmp(opt, "source-address=", 15) == 0) { 1836 val = opt + 15; 1837 if (*val == '\0') 1838 fatal("Empty source-address option"); 1839 if (certflags_src_addr != NULL) 1840 fatal("source-address already specified"); 1841 if (addr_match_cidr_list(NULL, val) != 0) 1842 fatal("Invalid source-address list"); 1843 certflags_src_addr = xstrdup(val); 1844 } else 1845 fatal("Unsupported certificate option \"%s\"", opt); 1846 } 1847 1848 static void 1849 show_options(const Buffer *optbuf, int v00, int in_critical) 1850 { 1851 char *name, *arg; 1852 const u_char *data; 1853 u_int dlen; 1854 Buffer options, option; 1855 1856 buffer_init(&options); 1857 buffer_append(&options, buffer_ptr(optbuf), buffer_len(optbuf)); 1858 1859 buffer_init(&option); 1860 while (buffer_len(&options) != 0) { 1861 name = buffer_get_string(&options, NULL); 1862 data = buffer_get_string_ptr(&options, &dlen); 1863 buffer_append(&option, data, dlen); 1864 printf(" %s", name); 1865 if ((v00 || !in_critical) && 1866 (strcmp(name, "permit-X11-forwarding") == 0 || 1867 strcmp(name, "permit-agent-forwarding") == 0 || 1868 strcmp(name, "permit-port-forwarding") == 0 || 1869 strcmp(name, "permit-pty") == 0 || 1870 strcmp(name, "permit-user-rc") == 0)) 1871 printf("\n"); 1872 else if ((v00 || in_critical) && 1873 (strcmp(name, "force-command") == 0 || 1874 strcmp(name, "source-address") == 0)) { 1875 arg = buffer_get_cstring(&option, NULL); 1876 printf(" %s\n", arg); 1877 free(arg); 1878 } else { 1879 printf(" UNKNOWN OPTION (len %u)\n", 1880 buffer_len(&option)); 1881 buffer_clear(&option); 1882 } 1883 free(name); 1884 if (buffer_len(&option) != 0) 1885 fatal("Option corrupt: extra data at end"); 1886 } 1887 buffer_free(&option); 1888 buffer_free(&options); 1889 } 1890 1891 static void 1892 do_show_cert(struct passwd *pw) 1893 { 1894 Key *key; 1895 struct stat st; 1896 char *key_fp, *ca_fp; 1897 u_int i, v00; 1898 1899 if (!have_identity) 1900 ask_filename(pw, "Enter file in which the key is"); 1901 if (stat(identity_file, &st) < 0) 1902 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 1903 if ((key = key_load_public(identity_file, NULL)) == NULL) 1904 fatal("%s is not a public key", identity_file); 1905 if (!key_is_cert(key)) 1906 fatal("%s is not a certificate", identity_file); 1907 v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00; 1908 1909 key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); 1910 ca_fp = key_fingerprint(key->cert->signature_key, 1911 SSH_FP_MD5, SSH_FP_HEX); 1912 1913 printf("%s:\n", identity_file); 1914 printf(" Type: %s %s certificate\n", key_ssh_name(key), 1915 key_cert_type(key)); 1916 printf(" Public key: %s %s\n", key_type(key), key_fp); 1917 printf(" Signing CA: %s %s\n", 1918 key_type(key->cert->signature_key), ca_fp); 1919 printf(" Key ID: \"%s\"\n", key->cert->key_id); 1920 if (!v00) { 1921 printf(" Serial: %llu\n", 1922 (unsigned long long)key->cert->serial); 1923 } 1924 printf(" Valid: %s\n", 1925 fmt_validity(key->cert->valid_after, key->cert->valid_before)); 1926 printf(" Principals: "); 1927 if (key->cert->nprincipals == 0) 1928 printf("(none)\n"); 1929 else { 1930 for (i = 0; i < key->cert->nprincipals; i++) 1931 printf("\n %s", 1932 key->cert->principals[i]); 1933 printf("\n"); 1934 } 1935 printf(" Critical Options: "); 1936 if (buffer_len(key->cert->critical) == 0) 1937 printf("(none)\n"); 1938 else { 1939 printf("\n"); 1940 show_options(key->cert->critical, v00, 1); 1941 } 1942 if (!v00) { 1943 printf(" Extensions: "); 1944 if (buffer_len(key->cert->extensions) == 0) 1945 printf("(none)\n"); 1946 else { 1947 printf("\n"); 1948 show_options(key->cert->extensions, v00, 0); 1949 } 1950 } 1951 exit(0); 1952 } 1953 1954 #ifdef WITH_OPENSSL 1955 static void 1956 load_krl(const char *path, struct ssh_krl **krlp) 1957 { 1958 Buffer krlbuf; 1959 int fd; 1960 1961 buffer_init(&krlbuf); 1962 if ((fd = open(path, O_RDONLY)) == -1) 1963 fatal("open %s: %s", path, strerror(errno)); 1964 if (!key_load_file(fd, path, &krlbuf)) 1965 fatal("Unable to load KRL"); 1966 close(fd); 1967 /* XXX check sigs */ 1968 if (ssh_krl_from_blob(&krlbuf, krlp, NULL, 0) != 0 || 1969 *krlp == NULL) 1970 fatal("Invalid KRL file"); 1971 buffer_free(&krlbuf); 1972 } 1973 1974 static void 1975 update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, 1976 struct ssh_krl *krl) 1977 { 1978 Key *key = NULL; 1979 u_long lnum = 0; 1980 char *path, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES]; 1981 unsigned long long serial, serial2; 1982 int i, was_explicit_key, was_sha1, r; 1983 FILE *krl_spec; 1984 1985 path = tilde_expand_filename(file, pw->pw_uid); 1986 if (strcmp(path, "-") == 0) { 1987 krl_spec = stdin; 1988 free(path); 1989 path = xstrdup("(standard input)"); 1990 } else if ((krl_spec = fopen(path, "r")) == NULL) 1991 fatal("fopen %s: %s", path, strerror(errno)); 1992 1993 if (!quiet) 1994 printf("Revoking from %s\n", path); 1995 while (read_keyfile_line(krl_spec, path, line, sizeof(line), 1996 &lnum) == 0) { 1997 was_explicit_key = was_sha1 = 0; 1998 cp = line + strspn(line, " \t"); 1999 /* Trim trailing space, comments and strip \n */ 2000 for (i = 0, r = -1; cp[i] != '\0'; i++) { 2001 if (cp[i] == '#' || cp[i] == '\n') { 2002 cp[i] = '\0'; 2003 break; 2004 } 2005 if (cp[i] == ' ' || cp[i] == '\t') { 2006 /* Remember the start of a span of whitespace */ 2007 if (r == -1) 2008 r = i; 2009 } else 2010 r = -1; 2011 } 2012 if (r != -1) 2013 cp[r] = '\0'; 2014 if (*cp == '\0') 2015 continue; 2016 if (strncasecmp(cp, "serial:", 7) == 0) { 2017 if (ca == NULL) { 2018 fatal("revoking certificates by serial number " 2019 "requires specification of a CA key"); 2020 } 2021 cp += 7; 2022 cp = cp + strspn(cp, " \t"); 2023 errno = 0; 2024 serial = strtoull(cp, &ep, 0); 2025 if (*cp == '\0' || (*ep != '\0' && *ep != '-')) 2026 fatal("%s:%lu: invalid serial \"%s\"", 2027 path, lnum, cp); 2028 if (errno == ERANGE && serial == ULLONG_MAX) 2029 fatal("%s:%lu: serial out of range", 2030 path, lnum); 2031 serial2 = serial; 2032 if (*ep == '-') { 2033 cp = ep + 1; 2034 errno = 0; 2035 serial2 = strtoull(cp, &ep, 0); 2036 if (*cp == '\0' || *ep != '\0') 2037 fatal("%s:%lu: invalid serial \"%s\"", 2038 path, lnum, cp); 2039 if (errno == ERANGE && serial2 == ULLONG_MAX) 2040 fatal("%s:%lu: serial out of range", 2041 path, lnum); 2042 if (serial2 <= serial) 2043 fatal("%s:%lu: invalid serial range " 2044 "%llu:%llu", path, lnum, 2045 (unsigned long long)serial, 2046 (unsigned long long)serial2); 2047 } 2048 if (ssh_krl_revoke_cert_by_serial_range(krl, 2049 ca, serial, serial2) != 0) { 2050 fatal("%s: revoke serial failed", 2051 __func__); 2052 } 2053 } else if (strncasecmp(cp, "id:", 3) == 0) { 2054 if (ca == NULL) { 2055 fatal("revoking certificates by key ID " 2056 "requires specification of a CA key"); 2057 } 2058 cp += 3; 2059 cp = cp + strspn(cp, " \t"); 2060 if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0) 2061 fatal("%s: revoke key ID failed", __func__); 2062 } else { 2063 if (strncasecmp(cp, "key:", 4) == 0) { 2064 cp += 4; 2065 cp = cp + strspn(cp, " \t"); 2066 was_explicit_key = 1; 2067 } else if (strncasecmp(cp, "sha1:", 5) == 0) { 2068 cp += 5; 2069 cp = cp + strspn(cp, " \t"); 2070 was_sha1 = 1; 2071 } else { 2072 /* 2073 * Just try to process the line as a key. 2074 * Parsing will fail if it isn't. 2075 */ 2076 } 2077 if ((key = key_new(KEY_UNSPEC)) == NULL) 2078 fatal("key_new"); 2079 if (key_read(key, &cp) != 1) 2080 fatal("%s:%lu: invalid key", path, lnum); 2081 if (was_explicit_key) 2082 r = ssh_krl_revoke_key_explicit(krl, key); 2083 else if (was_sha1) 2084 r = ssh_krl_revoke_key_sha1(krl, key); 2085 else 2086 r = ssh_krl_revoke_key(krl, key); 2087 if (r != 0) 2088 fatal("%s: revoke key failed", __func__); 2089 key_free(key); 2090 } 2091 } 2092 if (strcmp(path, "-") != 0) 2093 fclose(krl_spec); 2094 free(path); 2095 } 2096 2097 static void 2098 do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) 2099 { 2100 struct ssh_krl *krl; 2101 struct stat sb; 2102 Key *ca = NULL; 2103 int fd, i; 2104 char *tmp; 2105 Buffer kbuf; 2106 2107 if (*identity_file == '\0') 2108 fatal("KRL generation requires an output file"); 2109 if (stat(identity_file, &sb) == -1) { 2110 if (errno != ENOENT) 2111 fatal("Cannot access KRL \"%s\": %s", 2112 identity_file, strerror(errno)); 2113 if (updating) 2114 fatal("KRL \"%s\" does not exist", identity_file); 2115 } 2116 if (ca_key_path != NULL) { 2117 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); 2118 if ((ca = key_load_public(tmp, NULL)) == NULL) 2119 fatal("Cannot load CA public key %s", tmp); 2120 free(tmp); 2121 } 2122 2123 if (updating) 2124 load_krl(identity_file, &krl); 2125 else if ((krl = ssh_krl_init()) == NULL) 2126 fatal("couldn't create KRL"); 2127 2128 if (cert_serial != 0) 2129 ssh_krl_set_version(krl, cert_serial); 2130 if (identity_comment != NULL) 2131 ssh_krl_set_comment(krl, identity_comment); 2132 2133 for (i = 0; i < argc; i++) 2134 update_krl_from_file(pw, argv[i], ca, krl); 2135 2136 buffer_init(&kbuf); 2137 if (ssh_krl_to_blob(krl, &kbuf, NULL, 0) != 0) 2138 fatal("Couldn't generate KRL"); 2139 if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) 2140 fatal("open %s: %s", identity_file, strerror(errno)); 2141 if (atomicio(vwrite, fd, buffer_ptr(&kbuf), buffer_len(&kbuf)) != 2142 buffer_len(&kbuf)) 2143 fatal("write %s: %s", identity_file, strerror(errno)); 2144 close(fd); 2145 buffer_free(&kbuf); 2146 ssh_krl_free(krl); 2147 if (ca != NULL) 2148 key_free(ca); 2149 } 2150 2151 static void 2152 do_check_krl(struct passwd *pw, int argc, char **argv) 2153 { 2154 int i, r, ret = 0; 2155 char *comment; 2156 struct ssh_krl *krl; 2157 Key *k; 2158 2159 if (*identity_file == '\0') 2160 fatal("KRL checking requires an input file"); 2161 load_krl(identity_file, &krl); 2162 for (i = 0; i < argc; i++) { 2163 if ((k = key_load_public(argv[i], &comment)) == NULL) 2164 fatal("Cannot load public key %s", argv[i]); 2165 r = ssh_krl_check_key(krl, k); 2166 printf("%s%s%s%s: %s\n", argv[i], 2167 *comment ? " (" : "", comment, *comment ? ")" : "", 2168 r == 0 ? "ok" : "REVOKED"); 2169 if (r != 0) 2170 ret = 1; 2171 key_free(k); 2172 free(comment); 2173 } 2174 ssh_krl_free(krl); 2175 exit(ret); 2176 } 2177 #endif 2178 2179 static void 2180 usage(void) 2181 { 2182 fprintf(stderr, 2183 "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1]\n" 2184 " [-N new_passphrase] [-C comment] [-f output_keyfile]\n" 2185 " ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]\n" 2186 " ssh-keygen -i [-m key_format] [-f input_keyfile]\n" 2187 " ssh-keygen -e [-m key_format] [-f input_keyfile]\n" 2188 " ssh-keygen -y [-f input_keyfile]\n" 2189 " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n" 2190 " ssh-keygen -l [-f input_keyfile]\n" 2191 " ssh-keygen -B [-f input_keyfile]\n"); 2192 #ifdef ENABLE_PKCS11 2193 fprintf(stderr, 2194 " ssh-keygen -D pkcs11\n"); 2195 #endif 2196 fprintf(stderr, 2197 " ssh-keygen -F hostname [-f known_hosts_file] [-l]\n" 2198 " ssh-keygen -H [-f known_hosts_file]\n" 2199 " ssh-keygen -R hostname [-f known_hosts_file]\n" 2200 " ssh-keygen -r hostname [-f input_keyfile] [-g]\n" 2201 " ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]\n" 2202 " ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n" 2203 " [-j start_line] [-K checkpt] [-W generator]\n" 2204 " ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals]\n" 2205 " [-O option] [-V validity_interval] [-z serial_number] file ...\n" 2206 " ssh-keygen -L [-f input_keyfile]\n" 2207 " ssh-keygen -A\n" 2208 " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n" 2209 " file ...\n" 2210 " ssh-keygen -Q -f krl_file file ...\n"); 2211 exit(1); 2212 } 2213 2214 /* 2215 * Main program for key management. 2216 */ 2217 int 2218 main(int argc, char **argv) 2219 { 2220 char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; 2221 char *checkpoint = NULL; 2222 char out_file[MAXPATHLEN], *ep, *rr_hostname = NULL; 2223 Key *private, *public; 2224 struct passwd *pw; 2225 struct stat st; 2226 int opt, type, fd; 2227 u_int32_t memory = 0, generator_wanted = 0; 2228 int do_gen_candidates = 0, do_screen_candidates = 0; 2229 int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; 2230 unsigned long start_lineno = 0, lines_to_process = 0; 2231 BIGNUM *start = NULL; 2232 FILE *f; 2233 const char *errstr; 2234 2235 extern int optind; 2236 extern char *optarg; 2237 2238 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 2239 sanitise_stdfd(); 2240 2241 __progname = ssh_get_progname(argv[0]); 2242 2243 OpenSSL_add_all_algorithms(); 2244 log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); 2245 2246 seed_rng(); 2247 2248 /* we need this for the home * directory. */ 2249 pw = getpwuid(getuid()); 2250 if (!pw) { 2251 printf("No user exists for uid %lu\n", (u_long)getuid()); 2252 exit(1); 2253 } 2254 if (gethostname(hostname, sizeof(hostname)) < 0) { 2255 perror("gethostname"); 2256 exit(1); 2257 } 2258 2259 /* Remaining characters: EUYdw */ 2260 while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" 2261 "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:a:b:f:g:j:m:n:r:s:t:z:")) != -1) { 2262 switch (opt) { 2263 case 'A': 2264 gen_all_hostkeys = 1; 2265 break; 2266 case 'b': 2267 bits = (u_int32_t)strtonum(optarg, 256, 32768, &errstr); 2268 if (errstr) 2269 fatal("Bits has bad value %s (%s)", 2270 optarg, errstr); 2271 break; 2272 case 'F': 2273 find_host = 1; 2274 rr_hostname = optarg; 2275 break; 2276 case 'H': 2277 hash_hosts = 1; 2278 break; 2279 case 'I': 2280 cert_key_id = optarg; 2281 break; 2282 case 'J': 2283 lines_to_process = strtoul(optarg, NULL, 10); 2284 break; 2285 case 'j': 2286 start_lineno = strtoul(optarg, NULL, 10); 2287 break; 2288 case 'R': 2289 delete_host = 1; 2290 rr_hostname = optarg; 2291 break; 2292 case 'L': 2293 show_cert = 1; 2294 break; 2295 case 'l': 2296 print_fingerprint = 1; 2297 break; 2298 case 'B': 2299 print_bubblebabble = 1; 2300 break; 2301 case 'm': 2302 if (strcasecmp(optarg, "RFC4716") == 0 || 2303 strcasecmp(optarg, "ssh2") == 0) { 2304 convert_format = FMT_RFC4716; 2305 break; 2306 } 2307 if (strcasecmp(optarg, "PKCS8") == 0) { 2308 convert_format = FMT_PKCS8; 2309 break; 2310 } 2311 if (strcasecmp(optarg, "PEM") == 0) { 2312 convert_format = FMT_PEM; 2313 break; 2314 } 2315 fatal("Unsupported conversion format \"%s\"", optarg); 2316 case 'n': 2317 cert_principals = optarg; 2318 break; 2319 case 'o': 2320 use_new_format = 1; 2321 break; 2322 case 'p': 2323 change_passphrase = 1; 2324 break; 2325 case 'c': 2326 change_comment = 1; 2327 break; 2328 case 'f': 2329 if (strlcpy(identity_file, optarg, sizeof(identity_file)) >= 2330 sizeof(identity_file)) 2331 fatal("Identity filename too long"); 2332 have_identity = 1; 2333 break; 2334 case 'g': 2335 print_generic = 1; 2336 break; 2337 case 'P': 2338 identity_passphrase = optarg; 2339 break; 2340 case 'N': 2341 identity_new_passphrase = optarg; 2342 break; 2343 case 'Q': 2344 check_krl = 1; 2345 break; 2346 case 'O': 2347 add_cert_option(optarg); 2348 break; 2349 case 'Z': 2350 new_format_cipher = optarg; 2351 break; 2352 case 'C': 2353 identity_comment = optarg; 2354 break; 2355 case 'q': 2356 quiet = 1; 2357 break; 2358 case 'e': 2359 case 'x': 2360 /* export key */ 2361 convert_to = 1; 2362 break; 2363 case 'h': 2364 cert_key_type = SSH2_CERT_TYPE_HOST; 2365 certflags_flags = 0; 2366 break; 2367 case 'k': 2368 gen_krl = 1; 2369 break; 2370 case 'i': 2371 case 'X': 2372 /* import key */ 2373 convert_from = 1; 2374 break; 2375 case 'y': 2376 print_public = 1; 2377 break; 2378 case 's': 2379 ca_key_path = optarg; 2380 break; 2381 case 't': 2382 key_type_name = optarg; 2383 break; 2384 case 'D': 2385 pkcs11provider = optarg; 2386 break; 2387 case 'u': 2388 update_krl = 1; 2389 break; 2390 case 'v': 2391 if (log_level == SYSLOG_LEVEL_INFO) 2392 log_level = SYSLOG_LEVEL_DEBUG1; 2393 else { 2394 if (log_level >= SYSLOG_LEVEL_DEBUG1 && 2395 log_level < SYSLOG_LEVEL_DEBUG3) 2396 log_level++; 2397 } 2398 break; 2399 case 'r': 2400 rr_hostname = optarg; 2401 break; 2402 case 'W': 2403 generator_wanted = (u_int32_t)strtonum(optarg, 1, 2404 UINT_MAX, &errstr); 2405 if (errstr) 2406 fatal("Desired generator has bad value: %s (%s)", 2407 optarg, errstr); 2408 break; 2409 case 'a': 2410 rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr); 2411 if (errstr) 2412 fatal("Invalid number: %s (%s)", 2413 optarg, errstr); 2414 break; 2415 case 'M': 2416 memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); 2417 if (errstr) 2418 fatal("Memory limit is %s: %s", errstr, optarg); 2419 break; 2420 case 'G': 2421 do_gen_candidates = 1; 2422 if (strlcpy(out_file, optarg, sizeof(out_file)) >= 2423 sizeof(out_file)) 2424 fatal("Output filename too long"); 2425 break; 2426 case 'T': 2427 do_screen_candidates = 1; 2428 if (strlcpy(out_file, optarg, sizeof(out_file)) >= 2429 sizeof(out_file)) 2430 fatal("Output filename too long"); 2431 break; 2432 case 'K': 2433 if (strlen(optarg) >= MAXPATHLEN) 2434 fatal("Checkpoint filename too long"); 2435 checkpoint = xstrdup(optarg); 2436 break; 2437 case 'S': 2438 /* XXX - also compare length against bits */ 2439 if (BN_hex2bn(&start, optarg) == 0) 2440 fatal("Invalid start point."); 2441 break; 2442 case 'V': 2443 parse_cert_times(optarg); 2444 break; 2445 case 'z': 2446 errno = 0; 2447 cert_serial = strtoull(optarg, &ep, 10); 2448 if (*optarg < '0' || *optarg > '9' || *ep != '\0' || 2449 (errno == ERANGE && cert_serial == ULLONG_MAX)) 2450 fatal("Invalid serial number \"%s\"", optarg); 2451 break; 2452 case '?': 2453 default: 2454 usage(); 2455 } 2456 } 2457 2458 /* reinit */ 2459 log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1); 2460 2461 argv += optind; 2462 argc -= optind; 2463 2464 if (ca_key_path != NULL) { 2465 if (argc < 1 && !gen_krl) { 2466 printf("Too few arguments.\n"); 2467 usage(); 2468 } 2469 } else if (argc > 0 && !gen_krl && !check_krl) { 2470 printf("Too many arguments.\n"); 2471 usage(); 2472 } 2473 if (change_passphrase && change_comment) { 2474 printf("Can only have one of -p and -c.\n"); 2475 usage(); 2476 } 2477 if (print_fingerprint && (delete_host || hash_hosts)) { 2478 printf("Cannot use -l with -H or -R.\n"); 2479 usage(); 2480 } 2481 #ifdef WITH_OPENSSL 2482 if (gen_krl) { 2483 do_gen_krl(pw, update_krl, argc, argv); 2484 return (0); 2485 } 2486 if (check_krl) { 2487 do_check_krl(pw, argc, argv); 2488 return (0); 2489 } 2490 #endif 2491 if (ca_key_path != NULL) { 2492 if (cert_key_id == NULL) 2493 fatal("Must specify key id (-I) when certifying"); 2494 do_ca_sign(pw, argc, argv); 2495 } 2496 if (show_cert) 2497 do_show_cert(pw); 2498 if (delete_host || hash_hosts || find_host) 2499 do_known_hosts(pw, rr_hostname); 2500 if (pkcs11provider != NULL) 2501 do_download(pw); 2502 if (print_fingerprint || print_bubblebabble) 2503 do_fingerprint(pw); 2504 if (change_passphrase) 2505 do_change_passphrase(pw); 2506 if (change_comment) 2507 do_change_comment(pw); 2508 #ifdef WITH_OPENSSL 2509 if (convert_to) 2510 do_convert_to(pw); 2511 if (convert_from) 2512 do_convert_from(pw); 2513 #endif 2514 if (print_public) 2515 do_print_public(pw); 2516 if (rr_hostname != NULL) { 2517 unsigned int n = 0; 2518 2519 if (have_identity) { 2520 n = do_print_resource_record(pw, 2521 identity_file, rr_hostname); 2522 if (n == 0) { 2523 perror(identity_file); 2524 exit(1); 2525 } 2526 exit(0); 2527 } else { 2528 2529 n += do_print_resource_record(pw, 2530 _PATH_HOST_RSA_KEY_FILE, rr_hostname); 2531 n += do_print_resource_record(pw, 2532 _PATH_HOST_DSA_KEY_FILE, rr_hostname); 2533 n += do_print_resource_record(pw, 2534 _PATH_HOST_ECDSA_KEY_FILE, rr_hostname); 2535 n += do_print_resource_record(pw, 2536 _PATH_HOST_ED25519_KEY_FILE, rr_hostname); 2537 if (n == 0) 2538 fatal("no keys found."); 2539 exit(0); 2540 } 2541 } 2542 2543 if (do_gen_candidates) { 2544 FILE *out = fopen(out_file, "w"); 2545 2546 if (out == NULL) { 2547 error("Couldn't open modulus candidate file \"%s\": %s", 2548 out_file, strerror(errno)); 2549 return (1); 2550 } 2551 if (bits == 0) 2552 bits = DEFAULT_BITS; 2553 if (gen_candidates(out, memory, bits, start) != 0) 2554 fatal("modulus candidate generation failed"); 2555 2556 return (0); 2557 } 2558 2559 if (do_screen_candidates) { 2560 FILE *in; 2561 FILE *out = fopen(out_file, "a"); 2562 2563 if (have_identity && strcmp(identity_file, "-") != 0) { 2564 if ((in = fopen(identity_file, "r")) == NULL) { 2565 fatal("Couldn't open modulus candidate " 2566 "file \"%s\": %s", identity_file, 2567 strerror(errno)); 2568 } 2569 } else 2570 in = stdin; 2571 2572 if (out == NULL) { 2573 fatal("Couldn't open moduli file \"%s\": %s", 2574 out_file, strerror(errno)); 2575 } 2576 if (prime_test(in, out, rounds == 0 ? 100 : rounds, 2577 generator_wanted, checkpoint, 2578 start_lineno, lines_to_process) != 0) 2579 fatal("modulus screening failed"); 2580 return (0); 2581 } 2582 2583 if (gen_all_hostkeys) { 2584 do_gen_all_hostkeys(pw); 2585 return (0); 2586 } 2587 2588 if (key_type_name == NULL) 2589 key_type_name = "rsa"; 2590 2591 type = key_type_from_name(key_type_name); 2592 type_bits_valid(type, &bits); 2593 2594 if (!quiet) 2595 printf("Generating public/private %s key pair.\n", key_type_name); 2596 private = key_generate(type, bits); 2597 if (private == NULL) { 2598 fprintf(stderr, "key_generate failed\n"); 2599 exit(1); 2600 } 2601 public = key_from_private(private); 2602 2603 if (!have_identity) 2604 ask_filename(pw, "Enter file in which to save the key"); 2605 2606 /* Create ~/.ssh directory if it doesn't already exist. */ 2607 snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", 2608 pw->pw_dir, _PATH_SSH_USER_DIR); 2609 if (strstr(identity_file, dotsshdir) != NULL) { 2610 if (stat(dotsshdir, &st) < 0) { 2611 if (errno != ENOENT) { 2612 error("Could not stat %s: %s", dotsshdir, 2613 strerror(errno)); 2614 } else if (mkdir(dotsshdir, 0700) < 0) { 2615 error("Could not create directory '%s': %s", 2616 dotsshdir, strerror(errno)); 2617 } else if (!quiet) 2618 printf("Created directory '%s'.\n", dotsshdir); 2619 } 2620 } 2621 /* If the file already exists, ask the user to confirm. */ 2622 if (stat(identity_file, &st) >= 0) { 2623 char yesno[3]; 2624 printf("%s already exists.\n", identity_file); 2625 printf("Overwrite (y/n)? "); 2626 fflush(stdout); 2627 if (fgets(yesno, sizeof(yesno), stdin) == NULL) 2628 exit(1); 2629 if (yesno[0] != 'y' && yesno[0] != 'Y') 2630 exit(1); 2631 } 2632 /* Ask for a passphrase (twice). */ 2633 if (identity_passphrase) 2634 passphrase1 = xstrdup(identity_passphrase); 2635 else if (identity_new_passphrase) 2636 passphrase1 = xstrdup(identity_new_passphrase); 2637 else { 2638 passphrase_again: 2639 passphrase1 = 2640 read_passphrase("Enter passphrase (empty for no " 2641 "passphrase): ", RP_ALLOW_STDIN); 2642 passphrase2 = read_passphrase("Enter same passphrase again: ", 2643 RP_ALLOW_STDIN); 2644 if (strcmp(passphrase1, passphrase2) != 0) { 2645 /* 2646 * The passphrases do not match. Clear them and 2647 * retry. 2648 */ 2649 explicit_bzero(passphrase1, strlen(passphrase1)); 2650 explicit_bzero(passphrase2, strlen(passphrase2)); 2651 free(passphrase1); 2652 free(passphrase2); 2653 printf("Passphrases do not match. Try again.\n"); 2654 goto passphrase_again; 2655 } 2656 /* Clear the other copy of the passphrase. */ 2657 explicit_bzero(passphrase2, strlen(passphrase2)); 2658 free(passphrase2); 2659 } 2660 2661 if (identity_comment) { 2662 strlcpy(comment, identity_comment, sizeof(comment)); 2663 } else { 2664 /* Create default comment field for the passphrase. */ 2665 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); 2666 } 2667 2668 /* Save the key with the given passphrase and comment. */ 2669 if (!key_save_private(private, identity_file, passphrase1, comment, 2670 use_new_format, new_format_cipher, rounds)) { 2671 printf("Saving the key failed: %s.\n", identity_file); 2672 explicit_bzero(passphrase1, strlen(passphrase1)); 2673 free(passphrase1); 2674 exit(1); 2675 } 2676 /* Clear the passphrase. */ 2677 explicit_bzero(passphrase1, strlen(passphrase1)); 2678 free(passphrase1); 2679 2680 /* Clear the private key and the random number generator. */ 2681 key_free(private); 2682 2683 if (!quiet) 2684 printf("Your identification has been saved in %s.\n", identity_file); 2685 2686 strlcat(identity_file, ".pub", sizeof(identity_file)); 2687 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 2688 if (fd == -1) { 2689 printf("Could not save your public key in %s\n", identity_file); 2690 exit(1); 2691 } 2692 f = fdopen(fd, "w"); 2693 if (f == NULL) { 2694 printf("fdopen %s failed\n", identity_file); 2695 exit(1); 2696 } 2697 if (!key_write(public, f)) 2698 fprintf(stderr, "write key failed\n"); 2699 fprintf(f, " %s\n", comment); 2700 fclose(f); 2701 2702 if (!quiet) { 2703 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); 2704 char *ra = key_fingerprint(public, SSH_FP_MD5, 2705 SSH_FP_RANDOMART); 2706 printf("Your public key has been saved in %s.\n", 2707 identity_file); 2708 printf("The key fingerprint is:\n"); 2709 printf("%s %s\n", fp, comment); 2710 printf("The key's randomart image is:\n"); 2711 printf("%s\n", ra); 2712 free(ra); 2713 free(fp); 2714 } 2715 2716 key_free(public); 2717 exit(0); 2718 } 2719