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