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