1 /* $OpenBSD: ssh-keygen.c,v 1.474 2024/09/04 05:33:34 djm Exp $ */ 2 /* 3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5 * All rights reserved 6 * Identity and host key generation and maintenance. 7 * 8 * As far as I am concerned, the code I have written for this software 9 * can be used freely for any purpose. Any derived versions of this 10 * software must be clearly marked as such, and if the derived work is 11 * incompatible with the protocol description in the RFC file, it must be 12 * called by a name other than "ssh" or "Secure Shell". 13 */ 14 15 #include <sys/types.h> 16 #include <sys/socket.h> 17 #include <sys/stat.h> 18 19 #ifdef WITH_OPENSSL 20 #include <openssl/evp.h> 21 #include <openssl/pem.h> 22 #endif 23 24 #include <stdint.h> 25 #include <errno.h> 26 #include <fcntl.h> 27 #include <netdb.h> 28 #include <pwd.h> 29 #include <stdarg.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <unistd.h> 34 #include <limits.h> 35 #include <locale.h> 36 37 #include "xmalloc.h" 38 #include "sshkey.h" 39 #include "authfile.h" 40 #include "sshbuf.h" 41 #include "pathnames.h" 42 #include "log.h" 43 #include "misc.h" 44 #include "match.h" 45 #include "hostfile.h" 46 #include "dns.h" 47 #include "ssh.h" 48 #include "ssh2.h" 49 #include "ssherr.h" 50 #include "atomicio.h" 51 #include "krl.h" 52 #include "digest.h" 53 #include "utf8.h" 54 #include "authfd.h" 55 #include "sshsig.h" 56 #include "ssh-sk.h" 57 #include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */ 58 #include "cipher.h" 59 60 #ifdef ENABLE_PKCS11 61 #include "ssh-pkcs11.h" 62 #endif 63 64 #define DEFAULT_KEY_TYPE_NAME "ed25519" 65 66 /* 67 * Default number of bits in the RSA, DSA and ECDSA keys. These value can be 68 * overridden on the command line. 69 * 70 * These values, with the exception of DSA, provide security equivalent to at 71 * least 128 bits of security according to NIST Special Publication 800-57: 72 * Recommendation for Key Management Part 1 rev 4 section 5.6.1. 73 * For DSA it (and FIPS-186-4 section 4.2) specifies that the only size for 74 * which a 160bit hash is acceptable is 1kbit, and since ssh-dss specifies only 75 * SHA1 we limit the DSA key size 1k bits. 76 */ 77 #define DEFAULT_BITS 3072 78 #define DEFAULT_BITS_DSA 1024 79 #define DEFAULT_BITS_ECDSA 256 80 81 static int quiet = 0; 82 83 /* Flag indicating that we just want to see the key fingerprint */ 84 static int print_fingerprint = 0; 85 static int print_bubblebabble = 0; 86 87 /* Hash algorithm to use for fingerprints. */ 88 static int fingerprint_hash = SSH_FP_HASH_DEFAULT; 89 90 /* The identity file name, given on the command line or entered by the user. */ 91 static char identity_file[PATH_MAX]; 92 static int have_identity = 0; 93 94 /* This is set to the passphrase if given on the command line. */ 95 static char *identity_passphrase = NULL; 96 97 /* This is set to the new passphrase if given on the command line. */ 98 static char *identity_new_passphrase = NULL; 99 100 /* Key type when certifying */ 101 static u_int cert_key_type = SSH2_CERT_TYPE_USER; 102 103 /* "key ID" of signed key */ 104 static char *cert_key_id = NULL; 105 106 /* Comma-separated list of principal names for certifying keys */ 107 static char *cert_principals = NULL; 108 109 /* Validity period for certificates */ 110 static u_int64_t cert_valid_from = 0; 111 static u_int64_t cert_valid_to = ~0ULL; 112 113 /* Certificate options */ 114 #define CERTOPT_X_FWD (1) 115 #define CERTOPT_AGENT_FWD (1<<1) 116 #define CERTOPT_PORT_FWD (1<<2) 117 #define CERTOPT_PTY (1<<3) 118 #define CERTOPT_USER_RC (1<<4) 119 #define CERTOPT_NO_REQUIRE_USER_PRESENCE (1<<5) 120 #define CERTOPT_REQUIRE_VERIFY (1<<6) 121 #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \ 122 CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC) 123 static u_int32_t certflags_flags = CERTOPT_DEFAULT; 124 static char *certflags_command = NULL; 125 static char *certflags_src_addr = NULL; 126 127 /* Arbitrary extensions specified by user */ 128 struct cert_ext { 129 char *key; 130 char *val; 131 int crit; 132 }; 133 static struct cert_ext *cert_ext; 134 static size_t ncert_ext; 135 136 /* Conversion to/from various formats */ 137 enum { 138 FMT_RFC4716, 139 FMT_PKCS8, 140 FMT_PEM 141 } convert_format = FMT_RFC4716; 142 143 static char *key_type_name = NULL; 144 145 /* Load key from this PKCS#11 provider */ 146 static char *pkcs11provider = NULL; 147 148 /* FIDO/U2F provider to use */ 149 static char *sk_provider = NULL; 150 151 /* Format for writing private keys */ 152 static int private_key_format = SSHKEY_PRIVATE_OPENSSH; 153 154 /* Cipher for new-format private keys */ 155 static char *openssh_format_cipher = NULL; 156 157 /* Number of KDF rounds to derive new format keys. */ 158 static int rounds = 0; 159 160 /* argv0 */ 161 extern char *__progname; 162 163 static char hostname[NI_MAXHOST]; 164 165 #ifdef WITH_OPENSSL 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 #endif 171 172 static void 173 type_bits_valid(int type, const char *name, u_int32_t *bitsp) 174 { 175 if (type == KEY_UNSPEC) 176 fatal("unknown key type %s", key_type_name); 177 if (*bitsp == 0) { 178 #ifdef WITH_OPENSSL 179 int nid; 180 181 switch(type) { 182 case KEY_DSA: 183 *bitsp = DEFAULT_BITS_DSA; 184 break; 185 case KEY_ECDSA: 186 if (name != NULL && 187 (nid = sshkey_ecdsa_nid_from_name(name)) > 0) 188 *bitsp = sshkey_curve_nid_to_bits(nid); 189 if (*bitsp == 0) 190 *bitsp = DEFAULT_BITS_ECDSA; 191 break; 192 case KEY_RSA: 193 *bitsp = DEFAULT_BITS; 194 break; 195 } 196 #endif 197 } 198 #ifdef WITH_OPENSSL 199 switch (type) { 200 case KEY_DSA: 201 if (*bitsp != 1024) 202 fatal("Invalid DSA key length: must be 1024 bits"); 203 break; 204 case KEY_RSA: 205 if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE) 206 fatal("Invalid RSA key length: minimum is %d bits", 207 SSH_RSA_MINIMUM_MODULUS_SIZE); 208 else if (*bitsp > OPENSSL_RSA_MAX_MODULUS_BITS) 209 fatal("Invalid RSA key length: maximum is %d bits", 210 OPENSSL_RSA_MAX_MODULUS_BITS); 211 break; 212 case KEY_ECDSA: 213 if (sshkey_ecdsa_bits_to_nid(*bitsp) == -1) 214 fatal("Invalid ECDSA key length: valid lengths are " 215 "256, 384 or 521 bits"); 216 } 217 #endif 218 } 219 220 /* 221 * Checks whether a file exists and, if so, asks the user whether they wish 222 * to overwrite it. 223 * Returns nonzero if the file does not already exist or if the user agrees to 224 * overwrite, or zero otherwise. 225 */ 226 static int 227 confirm_overwrite(const char *filename) 228 { 229 char yesno[3]; 230 struct stat st; 231 232 if (stat(filename, &st) != 0) 233 return 1; 234 printf("%s already exists.\n", filename); 235 printf("Overwrite (y/n)? "); 236 fflush(stdout); 237 if (fgets(yesno, sizeof(yesno), stdin) == NULL) 238 return 0; 239 if (yesno[0] != 'y' && yesno[0] != 'Y') 240 return 0; 241 return 1; 242 } 243 244 static void 245 ask_filename(struct passwd *pw, const char *prompt) 246 { 247 char buf[1024]; 248 char *name = NULL; 249 250 if (key_type_name == NULL) 251 name = _PATH_SSH_CLIENT_ID_ED25519; 252 else { 253 switch (sshkey_type_from_shortname(key_type_name)) { 254 #ifdef WITH_DSA 255 case KEY_DSA_CERT: 256 case KEY_DSA: 257 name = _PATH_SSH_CLIENT_ID_DSA; 258 break; 259 #endif 260 case KEY_ECDSA_CERT: 261 case KEY_ECDSA: 262 name = _PATH_SSH_CLIENT_ID_ECDSA; 263 break; 264 case KEY_ECDSA_SK_CERT: 265 case KEY_ECDSA_SK: 266 name = _PATH_SSH_CLIENT_ID_ECDSA_SK; 267 break; 268 case KEY_RSA_CERT: 269 case KEY_RSA: 270 name = _PATH_SSH_CLIENT_ID_RSA; 271 break; 272 case KEY_ED25519: 273 case KEY_ED25519_CERT: 274 name = _PATH_SSH_CLIENT_ID_ED25519; 275 break; 276 case KEY_ED25519_SK: 277 case KEY_ED25519_SK_CERT: 278 name = _PATH_SSH_CLIENT_ID_ED25519_SK; 279 break; 280 case KEY_XMSS: 281 case KEY_XMSS_CERT: 282 name = _PATH_SSH_CLIENT_ID_XMSS; 283 break; 284 default: 285 fatal("bad key type"); 286 } 287 } 288 snprintf(identity_file, sizeof(identity_file), 289 "%s/%s", pw->pw_dir, name); 290 printf("%s (%s): ", prompt, identity_file); 291 fflush(stdout); 292 if (fgets(buf, sizeof(buf), stdin) == NULL) 293 exit(1); 294 buf[strcspn(buf, "\n")] = '\0'; 295 if (strcmp(buf, "") != 0) 296 strlcpy(identity_file, buf, sizeof(identity_file)); 297 have_identity = 1; 298 } 299 300 static struct sshkey * 301 load_identity(const char *filename, char **commentp) 302 { 303 char *pass; 304 struct sshkey *prv; 305 int r; 306 307 if (commentp != NULL) 308 *commentp = NULL; 309 if ((r = sshkey_load_private(filename, "", &prv, commentp)) == 0) 310 return prv; 311 if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) 312 fatal_r(r, "Load key \"%s\"", filename); 313 if (identity_passphrase) 314 pass = xstrdup(identity_passphrase); 315 else 316 pass = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN); 317 r = sshkey_load_private(filename, pass, &prv, commentp); 318 freezero(pass, strlen(pass)); 319 if (r != 0) 320 fatal_r(r, "Load key \"%s\"", filename); 321 return prv; 322 } 323 324 #define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----" 325 #define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----" 326 #define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----" 327 #define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb 328 329 #ifdef WITH_OPENSSL 330 static void 331 do_convert_to_ssh2(struct passwd *pw, struct sshkey *k) 332 { 333 struct sshbuf *b; 334 char comment[61], *b64; 335 int r; 336 337 if ((b = sshbuf_new()) == NULL) 338 fatal_f("sshbuf_new failed"); 339 if ((r = sshkey_putb(k, b)) != 0) 340 fatal_fr(r, "put key"); 341 if ((b64 = sshbuf_dtob64_string(b, 1)) == NULL) 342 fatal_f("sshbuf_dtob64_string failed"); 343 344 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ 345 snprintf(comment, sizeof(comment), 346 "%u-bit %s, converted by %s@%s from OpenSSH", 347 sshkey_size(k), sshkey_type(k), 348 pw->pw_name, hostname); 349 350 sshkey_free(k); 351 sshbuf_free(b); 352 353 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); 354 fprintf(stdout, "Comment: \"%s\"\n%s", comment, b64); 355 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); 356 free(b64); 357 exit(0); 358 } 359 360 static void 361 do_convert_to_pkcs8(struct sshkey *k) 362 { 363 switch (sshkey_type_plain(k->type)) { 364 case KEY_RSA: 365 if (!PEM_write_RSA_PUBKEY(stdout, 366 EVP_PKEY_get0_RSA(k->pkey))) 367 fatal("PEM_write_RSA_PUBKEY failed"); 368 break; 369 #ifdef WITH_DSA 370 case KEY_DSA: 371 if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) 372 fatal("PEM_write_DSA_PUBKEY failed"); 373 break; 374 #endif 375 case KEY_ECDSA: 376 if (!PEM_write_EC_PUBKEY(stdout, 377 EVP_PKEY_get0_EC_KEY(k->pkey))) 378 fatal("PEM_write_EC_PUBKEY failed"); 379 break; 380 default: 381 fatal_f("unsupported key type %s", sshkey_type(k)); 382 } 383 exit(0); 384 } 385 386 static void 387 do_convert_to_pem(struct sshkey *k) 388 { 389 switch (sshkey_type_plain(k->type)) { 390 case KEY_RSA: 391 if (!PEM_write_RSAPublicKey(stdout, 392 EVP_PKEY_get0_RSA(k->pkey))) 393 fatal("PEM_write_RSAPublicKey failed"); 394 break; 395 #ifdef WITH_DSA 396 case KEY_DSA: 397 if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) 398 fatal("PEM_write_DSA_PUBKEY failed"); 399 break; 400 #endif 401 case KEY_ECDSA: 402 if (!PEM_write_EC_PUBKEY(stdout, 403 EVP_PKEY_get0_EC_KEY(k->pkey))) 404 fatal("PEM_write_EC_PUBKEY failed"); 405 break; 406 default: 407 fatal_f("unsupported key type %s", sshkey_type(k)); 408 } 409 exit(0); 410 } 411 412 static void 413 do_convert_to(struct passwd *pw) 414 { 415 struct sshkey *k; 416 struct stat st; 417 int r; 418 419 if (!have_identity) 420 ask_filename(pw, "Enter file in which the key is"); 421 if (stat(identity_file, &st) == -1) 422 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 423 if ((r = sshkey_load_public(identity_file, &k, NULL)) != 0) 424 k = load_identity(identity_file, NULL); 425 switch (convert_format) { 426 case FMT_RFC4716: 427 do_convert_to_ssh2(pw, k); 428 break; 429 case FMT_PKCS8: 430 do_convert_to_pkcs8(k); 431 break; 432 case FMT_PEM: 433 do_convert_to_pem(k); 434 break; 435 default: 436 fatal_f("unknown key format %d", convert_format); 437 } 438 exit(0); 439 } 440 441 /* 442 * This is almost exactly the bignum1 encoding, but with 32 bit for length 443 * instead of 16. 444 */ 445 static void 446 buffer_get_bignum_bits(struct sshbuf *b, BIGNUM *value) 447 { 448 u_int bytes, bignum_bits; 449 int r; 450 451 if ((r = sshbuf_get_u32(b, &bignum_bits)) != 0) 452 fatal_fr(r, "parse"); 453 bytes = (bignum_bits + 7) / 8; 454 if (sshbuf_len(b) < bytes) 455 fatal_f("input buffer too small: need %d have %zu", 456 bytes, sshbuf_len(b)); 457 if (BN_bin2bn(sshbuf_ptr(b), bytes, value) == NULL) 458 fatal_f("BN_bin2bn failed"); 459 if ((r = sshbuf_consume(b, bytes)) != 0) 460 fatal_fr(r, "consume"); 461 } 462 463 static struct sshkey * 464 do_convert_private_ssh2(struct sshbuf *b) 465 { 466 struct sshkey *key = NULL; 467 char *type, *cipher; 468 const char *alg = NULL; 469 u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345"; 470 int r, rlen, ktype; 471 u_int magic, i1, i2, i3, i4; 472 size_t slen; 473 u_long e; 474 #ifdef WITH_DSA 475 BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL; 476 BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL; 477 #endif 478 BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; 479 BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; 480 BIGNUM *rsa_dmp1 = NULL, *rsa_dmq1 = NULL; 481 RSA *rsa = NULL; 482 483 if ((r = sshbuf_get_u32(b, &magic)) != 0) 484 fatal_fr(r, "parse magic"); 485 486 if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { 487 error("bad magic 0x%x != 0x%x", magic, 488 SSH_COM_PRIVATE_KEY_MAGIC); 489 return NULL; 490 } 491 if ((r = sshbuf_get_u32(b, &i1)) != 0 || 492 (r = sshbuf_get_cstring(b, &type, NULL)) != 0 || 493 (r = sshbuf_get_cstring(b, &cipher, NULL)) != 0 || 494 (r = sshbuf_get_u32(b, &i2)) != 0 || 495 (r = sshbuf_get_u32(b, &i3)) != 0 || 496 (r = sshbuf_get_u32(b, &i4)) != 0) 497 fatal_fr(r, "parse"); 498 debug("ignore (%d %d %d %d)", i1, i2, i3, i4); 499 if (strcmp(cipher, "none") != 0) { 500 error("unsupported cipher %s", cipher); 501 free(cipher); 502 free(type); 503 return NULL; 504 } 505 free(cipher); 506 507 if (strstr(type, "rsa")) { 508 ktype = KEY_RSA; 509 #ifdef WITH_DSA 510 } else if (strstr(type, "dsa")) { 511 ktype = KEY_DSA; 512 #endif 513 } else { 514 free(type); 515 return NULL; 516 } 517 if ((key = sshkey_new(ktype)) == NULL) 518 fatal("sshkey_new failed"); 519 free(type); 520 521 switch (key->type) { 522 #ifdef WITH_DSA 523 case KEY_DSA: 524 if ((dsa_p = BN_new()) == NULL || 525 (dsa_q = BN_new()) == NULL || 526 (dsa_g = BN_new()) == NULL || 527 (dsa_pub_key = BN_new()) == NULL || 528 (dsa_priv_key = BN_new()) == NULL) 529 fatal_f("BN_new"); 530 buffer_get_bignum_bits(b, dsa_p); 531 buffer_get_bignum_bits(b, dsa_g); 532 buffer_get_bignum_bits(b, dsa_q); 533 buffer_get_bignum_bits(b, dsa_pub_key); 534 buffer_get_bignum_bits(b, dsa_priv_key); 535 if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) 536 fatal_f("DSA_set0_pqg failed"); 537 dsa_p = dsa_q = dsa_g = NULL; /* transferred */ 538 if (!DSA_set0_key(key->dsa, dsa_pub_key, dsa_priv_key)) 539 fatal_f("DSA_set0_key failed"); 540 dsa_pub_key = dsa_priv_key = NULL; /* transferred */ 541 break; 542 #endif 543 case KEY_RSA: 544 if ((r = sshbuf_get_u8(b, &e1)) != 0 || 545 (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) || 546 (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0)) 547 fatal_fr(r, "parse RSA"); 548 e = e1; 549 debug("e %lx", e); 550 if (e < 30) { 551 e <<= 8; 552 e += e2; 553 debug("e %lx", e); 554 e <<= 8; 555 e += e3; 556 debug("e %lx", e); 557 } 558 if ((rsa_e = BN_new()) == NULL) 559 fatal_f("BN_new"); 560 if (!BN_set_word(rsa_e, e)) { 561 BN_clear_free(rsa_e); 562 sshkey_free(key); 563 return NULL; 564 } 565 if ((rsa_n = BN_new()) == NULL || 566 (rsa_d = BN_new()) == NULL || 567 (rsa_p = BN_new()) == NULL || 568 (rsa_q = BN_new()) == NULL || 569 (rsa_iqmp = BN_new()) == NULL) 570 fatal_f("BN_new"); 571 buffer_get_bignum_bits(b, rsa_d); 572 buffer_get_bignum_bits(b, rsa_n); 573 buffer_get_bignum_bits(b, rsa_iqmp); 574 buffer_get_bignum_bits(b, rsa_q); 575 buffer_get_bignum_bits(b, rsa_p); 576 if ((r = ssh_rsa_complete_crt_parameters(rsa_d, rsa_p, rsa_q, 577 rsa_iqmp, &rsa_dmp1, &rsa_dmq1)) != 0) 578 fatal_fr(r, "generate RSA CRT parameters"); 579 if ((key->pkey = EVP_PKEY_new()) == NULL) 580 fatal_f("EVP_PKEY_new failed"); 581 if ((rsa = RSA_new()) == NULL) 582 fatal_f("RSA_new failed"); 583 if (!RSA_set0_key(rsa, rsa_n, rsa_e, rsa_d)) 584 fatal_f("RSA_set0_key failed"); 585 rsa_n = rsa_e = rsa_d = NULL; /* transferred */ 586 if (!RSA_set0_factors(rsa, rsa_p, rsa_q)) 587 fatal_f("RSA_set0_factors failed"); 588 rsa_p = rsa_q = NULL; /* transferred */ 589 if (RSA_set0_crt_params(rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp) != 1) 590 fatal_f("RSA_set0_crt_params failed"); 591 rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; 592 if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) 593 fatal_f("EVP_PKEY_set1_RSA failed"); 594 RSA_free(rsa); 595 alg = "rsa-sha2-256"; 596 break; 597 } 598 rlen = sshbuf_len(b); 599 if (rlen != 0) 600 error_f("remaining bytes in key blob %d", rlen); 601 602 /* try the key */ 603 if ((r = sshkey_sign(key, &sig, &slen, data, sizeof(data), 604 alg, NULL, NULL, 0)) != 0) 605 error_fr(r, "signing with converted key failed"); 606 else if ((r = sshkey_verify(key, sig, slen, data, sizeof(data), 607 alg, 0, NULL)) != 0) 608 error_fr(r, "verification with converted key failed"); 609 if (r != 0) { 610 sshkey_free(key); 611 free(sig); 612 return NULL; 613 } 614 free(sig); 615 return key; 616 } 617 618 static int 619 get_line(FILE *fp, char *line, size_t len) 620 { 621 int c; 622 size_t pos = 0; 623 624 line[0] = '\0'; 625 while ((c = fgetc(fp)) != EOF) { 626 if (pos >= len - 1) 627 fatal("input line too long."); 628 switch (c) { 629 case '\r': 630 c = fgetc(fp); 631 if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) 632 fatal("unget: %s", strerror(errno)); 633 return pos; 634 case '\n': 635 return pos; 636 } 637 line[pos++] = c; 638 line[pos] = '\0'; 639 } 640 /* We reached EOF */ 641 return -1; 642 } 643 644 static void 645 do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private) 646 { 647 int r, blen, escaped = 0; 648 u_int len; 649 char line[1024]; 650 struct sshbuf *buf; 651 char encoded[8096]; 652 FILE *fp; 653 654 if ((buf = sshbuf_new()) == NULL) 655 fatal("sshbuf_new failed"); 656 if ((fp = fopen(identity_file, "r")) == NULL) 657 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 658 encoded[0] = '\0'; 659 while ((blen = get_line(fp, line, sizeof(line))) != -1) { 660 if (blen > 0 && line[blen - 1] == '\\') 661 escaped++; 662 if (strncmp(line, "----", 4) == 0 || 663 strstr(line, ": ") != NULL) { 664 if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL) 665 *private = 1; 666 if (strstr(line, " END ") != NULL) { 667 break; 668 } 669 /* fprintf(stderr, "ignore: %s", line); */ 670 continue; 671 } 672 if (escaped) { 673 escaped--; 674 /* fprintf(stderr, "escaped: %s", line); */ 675 continue; 676 } 677 strlcat(encoded, line, sizeof(encoded)); 678 } 679 len = strlen(encoded); 680 if (((len % 4) == 3) && 681 (encoded[len-1] == '=') && 682 (encoded[len-2] == '=') && 683 (encoded[len-3] == '=')) 684 encoded[len-3] = '\0'; 685 if ((r = sshbuf_b64tod(buf, encoded)) != 0) 686 fatal_fr(r, "base64 decode"); 687 if (*private) { 688 if ((*k = do_convert_private_ssh2(buf)) == NULL) 689 fatal_f("private key conversion failed"); 690 } else if ((r = sshkey_fromb(buf, k)) != 0) 691 fatal_fr(r, "parse key"); 692 sshbuf_free(buf); 693 fclose(fp); 694 } 695 696 static void 697 do_convert_from_pkcs8(struct sshkey **k, int *private) 698 { 699 EVP_PKEY *pubkey; 700 FILE *fp; 701 702 if ((fp = fopen(identity_file, "r")) == NULL) 703 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 704 if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) { 705 fatal_f("%s is not a recognised public key format", 706 identity_file); 707 } 708 fclose(fp); 709 switch (EVP_PKEY_base_id(pubkey)) { 710 case EVP_PKEY_RSA: 711 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) 712 fatal("sshkey_new failed"); 713 (*k)->type = KEY_RSA; 714 (*k)->pkey = pubkey; 715 pubkey = NULL; 716 break; 717 #ifdef WITH_DSA 718 case EVP_PKEY_DSA: 719 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) 720 fatal("sshkey_new failed"); 721 (*k)->type = KEY_DSA; 722 (*k)->dsa = EVP_PKEY_get1_DSA(pubkey); 723 break; 724 #endif 725 case EVP_PKEY_EC: 726 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) 727 fatal("sshkey_new failed"); 728 if (((*k)->ecdsa_nid = sshkey_ecdsa_fixup_group(pubkey)) == -1) 729 fatal("sshkey_ecdsa_fixup_group failed"); 730 (*k)->type = KEY_ECDSA; 731 (*k)->pkey = pubkey; 732 pubkey = NULL; 733 break; 734 default: 735 fatal_f("unsupported pubkey type %d", 736 EVP_PKEY_base_id(pubkey)); 737 } 738 EVP_PKEY_free(pubkey); 739 return; 740 } 741 742 static void 743 do_convert_from_pem(struct sshkey **k, int *private) 744 { 745 FILE *fp; 746 RSA *rsa; 747 748 if ((fp = fopen(identity_file, "r")) == NULL) 749 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 750 if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { 751 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) 752 fatal("sshkey_new failed"); 753 if (((*k)->pkey = EVP_PKEY_new()) == NULL) 754 fatal("EVP_PKEY_new failed"); 755 (*k)->type = KEY_RSA; 756 if (EVP_PKEY_set1_RSA((*k)->pkey, rsa) != 1) 757 fatal("EVP_PKEY_set1_RSA failed"); 758 RSA_free(rsa); 759 fclose(fp); 760 return; 761 } 762 fatal_f("unrecognised raw private key format"); 763 } 764 765 static void 766 do_convert_from(struct passwd *pw) 767 { 768 struct sshkey *k = NULL; 769 int r, private = 0, ok = 0; 770 struct stat st; 771 772 if (!have_identity) 773 ask_filename(pw, "Enter file in which the key is"); 774 if (stat(identity_file, &st) == -1) 775 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 776 777 switch (convert_format) { 778 case FMT_RFC4716: 779 do_convert_from_ssh2(pw, &k, &private); 780 break; 781 case FMT_PKCS8: 782 do_convert_from_pkcs8(&k, &private); 783 break; 784 case FMT_PEM: 785 do_convert_from_pem(&k, &private); 786 break; 787 default: 788 fatal_f("unknown key format %d", convert_format); 789 } 790 791 if (!private) { 792 if ((r = sshkey_write(k, stdout)) == 0) 793 ok = 1; 794 if (ok) 795 fprintf(stdout, "\n"); 796 } else { 797 switch (k->type) { 798 #ifdef WITH_DSA 799 case KEY_DSA: 800 ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, 801 NULL, 0, NULL, NULL); 802 break; 803 #endif 804 case KEY_ECDSA: 805 ok = PEM_write_ECPrivateKey(stdout, 806 EVP_PKEY_get0_EC_KEY(k->pkey), NULL, NULL, 0, 807 NULL, NULL); 808 break; 809 case KEY_RSA: 810 ok = PEM_write_RSAPrivateKey(stdout, 811 EVP_PKEY_get0_RSA(k->pkey), NULL, NULL, 0, 812 NULL, NULL); 813 break; 814 default: 815 fatal_f("unsupported key type %s", sshkey_type(k)); 816 } 817 } 818 819 if (!ok) 820 fatal("key write failed"); 821 sshkey_free(k); 822 exit(0); 823 } 824 #endif 825 826 static void 827 do_print_public(struct passwd *pw) 828 { 829 struct sshkey *prv; 830 struct stat st; 831 int r; 832 char *comment = NULL; 833 834 if (!have_identity) 835 ask_filename(pw, "Enter file in which the key is"); 836 if (stat(identity_file, &st) == -1) 837 fatal("%s: %s", identity_file, strerror(errno)); 838 prv = load_identity(identity_file, &comment); 839 if ((r = sshkey_write(prv, stdout)) != 0) 840 fatal_fr(r, "write key"); 841 if (comment != NULL && *comment != '\0') 842 fprintf(stdout, " %s", comment); 843 fprintf(stdout, "\n"); 844 if (sshkey_is_sk(prv)) { 845 debug("sk_application: \"%s\", sk_flags 0x%02x", 846 prv->sk_application, prv->sk_flags); 847 } 848 sshkey_free(prv); 849 free(comment); 850 exit(0); 851 } 852 853 static void 854 do_download(struct passwd *pw) 855 { 856 #ifdef ENABLE_PKCS11 857 struct sshkey **keys = NULL; 858 int i, nkeys; 859 enum sshkey_fp_rep rep; 860 int fptype; 861 char *fp, *ra, **comments = NULL; 862 863 fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; 864 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; 865 866 pkcs11_init(1); 867 nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys, &comments); 868 if (nkeys <= 0) 869 fatal("cannot read public key from pkcs11"); 870 for (i = 0; i < nkeys; i++) { 871 if (print_fingerprint) { 872 fp = sshkey_fingerprint(keys[i], fptype, rep); 873 ra = sshkey_fingerprint(keys[i], fingerprint_hash, 874 SSH_FP_RANDOMART); 875 if (fp == NULL || ra == NULL) 876 fatal_f("sshkey_fingerprint fail"); 877 printf("%u %s %s (PKCS11 key)\n", sshkey_size(keys[i]), 878 fp, sshkey_type(keys[i])); 879 if (log_level_get() >= SYSLOG_LEVEL_VERBOSE) 880 printf("%s\n", ra); 881 free(ra); 882 free(fp); 883 } else { 884 (void) sshkey_write(keys[i], stdout); /* XXX check */ 885 fprintf(stdout, "%s%s\n", 886 *(comments[i]) == '\0' ? "" : " ", comments[i]); 887 } 888 free(comments[i]); 889 sshkey_free(keys[i]); 890 } 891 free(comments); 892 free(keys); 893 pkcs11_terminate(); 894 exit(0); 895 #else 896 fatal("no pkcs11 support"); 897 #endif /* ENABLE_PKCS11 */ 898 } 899 900 static struct sshkey * 901 try_read_key(char **cpp) 902 { 903 struct sshkey *ret; 904 int r; 905 906 if ((ret = sshkey_new(KEY_UNSPEC)) == NULL) 907 fatal("sshkey_new failed"); 908 if ((r = sshkey_read(ret, cpp)) == 0) 909 return ret; 910 /* Not a key */ 911 sshkey_free(ret); 912 return NULL; 913 } 914 915 static void 916 fingerprint_one_key(const struct sshkey *public, const char *comment) 917 { 918 char *fp = NULL, *ra = NULL; 919 enum sshkey_fp_rep rep; 920 int fptype; 921 922 fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; 923 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; 924 fp = sshkey_fingerprint(public, fptype, rep); 925 ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); 926 if (fp == NULL || ra == NULL) 927 fatal_f("sshkey_fingerprint failed"); 928 mprintf("%u %s %s (%s)\n", sshkey_size(public), fp, 929 comment ? comment : "no comment", sshkey_type(public)); 930 if (log_level_get() >= SYSLOG_LEVEL_VERBOSE) 931 printf("%s\n", ra); 932 free(ra); 933 free(fp); 934 } 935 936 static void 937 fingerprint_private(const char *path) 938 { 939 struct stat st; 940 char *comment = NULL; 941 struct sshkey *privkey = NULL, *pubkey = NULL; 942 int r; 943 944 if (stat(identity_file, &st) == -1) 945 fatal("%s: %s", path, strerror(errno)); 946 if ((r = sshkey_load_public(path, &pubkey, &comment)) != 0) 947 debug_r(r, "load public \"%s\"", path); 948 if (pubkey == NULL || comment == NULL || *comment == '\0') { 949 free(comment); 950 if ((r = sshkey_load_private(path, NULL, 951 &privkey, &comment)) != 0) 952 debug_r(r, "load private \"%s\"", path); 953 } 954 if (pubkey == NULL && privkey == NULL) 955 fatal("%s is not a key file.", path); 956 957 fingerprint_one_key(pubkey == NULL ? privkey : pubkey, comment); 958 sshkey_free(pubkey); 959 sshkey_free(privkey); 960 free(comment); 961 } 962 963 static void 964 do_fingerprint(struct passwd *pw) 965 { 966 FILE *f; 967 struct sshkey *public = NULL; 968 char *comment = NULL, *cp, *ep, *line = NULL; 969 size_t linesize = 0; 970 int i, invalid = 1; 971 const char *path; 972 u_long lnum = 0; 973 974 if (!have_identity) 975 ask_filename(pw, "Enter file in which the key is"); 976 path = identity_file; 977 978 if (strcmp(identity_file, "-") == 0) { 979 f = stdin; 980 path = "(stdin)"; 981 } else if ((f = fopen(path, "r")) == NULL) 982 fatal("%s: %s: %s", __progname, path, strerror(errno)); 983 984 while (getline(&line, &linesize, f) != -1) { 985 lnum++; 986 cp = line; 987 cp[strcspn(cp, "\n")] = '\0'; 988 /* Trim leading space and comments */ 989 cp = line + strspn(line, " \t"); 990 if (*cp == '#' || *cp == '\0') 991 continue; 992 993 /* 994 * Input may be plain keys, private keys, authorized_keys 995 * or known_hosts. 996 */ 997 998 /* 999 * Try private keys first. Assume a key is private if 1000 * "SSH PRIVATE KEY" appears on the first line and we're 1001 * not reading from stdin (XXX support private keys on stdin). 1002 */ 1003 if (lnum == 1 && strcmp(identity_file, "-") != 0 && 1004 strstr(cp, "PRIVATE KEY") != NULL) { 1005 free(line); 1006 fclose(f); 1007 fingerprint_private(path); 1008 exit(0); 1009 } 1010 1011 /* 1012 * If it's not a private key, then this must be prepared to 1013 * accept a public key prefixed with a hostname or options. 1014 * Try a bare key first, otherwise skip the leading stuff. 1015 */ 1016 comment = NULL; 1017 if ((public = try_read_key(&cp)) == NULL) { 1018 i = strtol(cp, &ep, 10); 1019 if (i == 0 || ep == NULL || 1020 (*ep != ' ' && *ep != '\t')) { 1021 int quoted = 0; 1022 1023 comment = cp; 1024 for (; *cp && (quoted || (*cp != ' ' && 1025 *cp != '\t')); cp++) { 1026 if (*cp == '\\' && cp[1] == '"') 1027 cp++; /* Skip both */ 1028 else if (*cp == '"') 1029 quoted = !quoted; 1030 } 1031 if (!*cp) 1032 continue; 1033 *cp++ = '\0'; 1034 } 1035 } 1036 /* Retry after parsing leading hostname/key options */ 1037 if (public == NULL && (public = try_read_key(&cp)) == NULL) { 1038 debug("%s:%lu: not a public key", path, lnum); 1039 continue; 1040 } 1041 1042 /* Find trailing comment, if any */ 1043 for (; *cp == ' ' || *cp == '\t'; cp++) 1044 ; 1045 if (*cp != '\0' && *cp != '#') 1046 comment = cp; 1047 1048 fingerprint_one_key(public, comment); 1049 sshkey_free(public); 1050 invalid = 0; /* One good key in the file is sufficient */ 1051 } 1052 fclose(f); 1053 free(line); 1054 1055 if (invalid) 1056 fatal("%s is not a public key file.", path); 1057 exit(0); 1058 } 1059 1060 static void 1061 do_gen_all_hostkeys(struct passwd *pw) 1062 { 1063 struct { 1064 char *key_type; 1065 char *key_type_display; 1066 char *path; 1067 } key_types[] = { 1068 #ifdef WITH_OPENSSL 1069 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE }, 1070 { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE }, 1071 #endif /* WITH_OPENSSL */ 1072 { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE }, 1073 #ifdef WITH_XMSS 1074 { "xmss", "XMSS",_PATH_HOST_XMSS_KEY_FILE }, 1075 #endif /* WITH_XMSS */ 1076 { NULL, NULL, NULL } 1077 }; 1078 1079 u_int32_t bits = 0; 1080 int first = 0; 1081 struct stat st; 1082 struct sshkey *private, *public; 1083 char comment[1024], *prv_tmp, *pub_tmp, *prv_file, *pub_file; 1084 int i, type, fd, r; 1085 1086 for (i = 0; key_types[i].key_type; i++) { 1087 public = private = NULL; 1088 prv_tmp = pub_tmp = prv_file = pub_file = NULL; 1089 1090 xasprintf(&prv_file, "%s%s", 1091 identity_file, key_types[i].path); 1092 1093 /* Check whether private key exists and is not zero-length */ 1094 if (stat(prv_file, &st) == 0) { 1095 if (st.st_size != 0) 1096 goto next; 1097 } else if (errno != ENOENT) { 1098 error("Could not stat %s: %s", key_types[i].path, 1099 strerror(errno)); 1100 goto failnext; 1101 } 1102 1103 /* 1104 * Private key doesn't exist or is invalid; proceed with 1105 * key generation. 1106 */ 1107 xasprintf(&prv_tmp, "%s%s.XXXXXXXXXX", 1108 identity_file, key_types[i].path); 1109 xasprintf(&pub_tmp, "%s%s.pub.XXXXXXXXXX", 1110 identity_file, key_types[i].path); 1111 xasprintf(&pub_file, "%s%s.pub", 1112 identity_file, key_types[i].path); 1113 1114 if (first == 0) { 1115 first = 1; 1116 printf("%s: generating new host keys: ", __progname); 1117 } 1118 printf("%s ", key_types[i].key_type_display); 1119 fflush(stdout); 1120 type = sshkey_type_from_shortname(key_types[i].key_type); 1121 if ((fd = mkstemp(prv_tmp)) == -1) { 1122 error("Could not save your private key in %s: %s", 1123 prv_tmp, strerror(errno)); 1124 goto failnext; 1125 } 1126 (void)close(fd); /* just using mkstemp() to reserve a name */ 1127 bits = 0; 1128 type_bits_valid(type, NULL, &bits); 1129 if ((r = sshkey_generate(type, bits, &private)) != 0) { 1130 error_r(r, "sshkey_generate failed"); 1131 goto failnext; 1132 } 1133 if ((r = sshkey_from_private(private, &public)) != 0) 1134 fatal_fr(r, "sshkey_from_private"); 1135 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, 1136 hostname); 1137 if ((r = sshkey_save_private(private, prv_tmp, "", 1138 comment, private_key_format, openssh_format_cipher, 1139 rounds)) != 0) { 1140 error_r(r, "Saving key \"%s\" failed", prv_tmp); 1141 goto failnext; 1142 } 1143 if ((fd = mkstemp(pub_tmp)) == -1) { 1144 error("Could not save your public key in %s: %s", 1145 pub_tmp, strerror(errno)); 1146 goto failnext; 1147 } 1148 (void)fchmod(fd, 0644); 1149 (void)close(fd); 1150 if ((r = sshkey_save_public(public, pub_tmp, comment)) != 0) { 1151 error_r(r, "Unable to save public key to %s", 1152 identity_file); 1153 goto failnext; 1154 } 1155 1156 /* Rename temporary files to their permanent locations. */ 1157 if (rename(pub_tmp, pub_file) != 0) { 1158 error("Unable to move %s into position: %s", 1159 pub_file, strerror(errno)); 1160 goto failnext; 1161 } 1162 if (rename(prv_tmp, prv_file) != 0) { 1163 error("Unable to move %s into position: %s", 1164 key_types[i].path, strerror(errno)); 1165 failnext: 1166 first = 0; 1167 goto next; 1168 } 1169 next: 1170 sshkey_free(private); 1171 sshkey_free(public); 1172 free(prv_tmp); 1173 free(pub_tmp); 1174 free(prv_file); 1175 free(pub_file); 1176 } 1177 if (first != 0) 1178 printf("\n"); 1179 } 1180 1181 struct known_hosts_ctx { 1182 const char *host; /* Hostname searched for in find/delete case */ 1183 FILE *out; /* Output file, stdout for find_hosts case */ 1184 int has_unhashed; /* When hashing, original had unhashed hosts */ 1185 int found_key; /* For find/delete, host was found */ 1186 int invalid; /* File contained invalid items; don't delete */ 1187 int hash_hosts; /* Hash hostnames as we go */ 1188 int find_host; /* Search for specific hostname */ 1189 int delete_host; /* Delete host from known_hosts */ 1190 }; 1191 1192 static int 1193 known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx) 1194 { 1195 struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; 1196 char *hashed, *cp, *hosts, *ohosts; 1197 int has_wild = l->hosts && strcspn(l->hosts, "*?!") != strlen(l->hosts); 1198 int was_hashed = l->hosts && l->hosts[0] == HASH_DELIM; 1199 1200 switch (l->status) { 1201 case HKF_STATUS_OK: 1202 case HKF_STATUS_MATCHED: 1203 /* 1204 * Don't hash hosts already hashed, with wildcard 1205 * characters or a CA/revocation marker. 1206 */ 1207 if (was_hashed || has_wild || l->marker != MRK_NONE) { 1208 fprintf(ctx->out, "%s\n", l->line); 1209 if (has_wild && !ctx->find_host) { 1210 logit("%s:%lu: ignoring host name " 1211 "with wildcard: %.64s", l->path, 1212 l->linenum, l->hosts); 1213 } 1214 return 0; 1215 } 1216 /* 1217 * Split any comma-separated hostnames from the host list, 1218 * hash and store separately. 1219 */ 1220 ohosts = hosts = xstrdup(l->hosts); 1221 while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') { 1222 lowercase(cp); 1223 if ((hashed = host_hash(cp, NULL, 0)) == NULL) 1224 fatal("hash_host failed"); 1225 fprintf(ctx->out, "%s %s\n", hashed, l->rawkey); 1226 free(hashed); 1227 ctx->has_unhashed = 1; 1228 } 1229 free(ohosts); 1230 return 0; 1231 case HKF_STATUS_INVALID: 1232 /* Retain invalid lines, but mark file as invalid. */ 1233 ctx->invalid = 1; 1234 logit("%s:%lu: invalid line", l->path, l->linenum); 1235 /* FALLTHROUGH */ 1236 default: 1237 fprintf(ctx->out, "%s\n", l->line); 1238 return 0; 1239 } 1240 /* NOTREACHED */ 1241 return -1; 1242 } 1243 1244 static int 1245 known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx) 1246 { 1247 struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; 1248 enum sshkey_fp_rep rep; 1249 int fptype; 1250 char *fp = NULL, *ra = NULL; 1251 1252 fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; 1253 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; 1254 1255 if (l->status == HKF_STATUS_MATCHED) { 1256 if (ctx->delete_host) { 1257 if (l->marker != MRK_NONE) { 1258 /* Don't remove CA and revocation lines */ 1259 fprintf(ctx->out, "%s\n", l->line); 1260 } else { 1261 /* 1262 * Hostname matches and has no CA/revoke 1263 * marker, delete it by *not* writing the 1264 * line to ctx->out. 1265 */ 1266 ctx->found_key = 1; 1267 if (!quiet) 1268 printf("# Host %s found: line %lu\n", 1269 ctx->host, l->linenum); 1270 } 1271 return 0; 1272 } else if (ctx->find_host) { 1273 ctx->found_key = 1; 1274 if (!quiet) { 1275 printf("# Host %s found: line %lu %s\n", 1276 ctx->host, 1277 l->linenum, l->marker == MRK_CA ? "CA" : 1278 (l->marker == MRK_REVOKE ? "REVOKED" : "")); 1279 } 1280 if (ctx->hash_hosts) 1281 known_hosts_hash(l, ctx); 1282 else if (print_fingerprint) { 1283 fp = sshkey_fingerprint(l->key, fptype, rep); 1284 ra = sshkey_fingerprint(l->key, 1285 fingerprint_hash, SSH_FP_RANDOMART); 1286 if (fp == NULL || ra == NULL) 1287 fatal_f("sshkey_fingerprint failed"); 1288 mprintf("%s %s %s%s%s\n", ctx->host, 1289 sshkey_type(l->key), fp, 1290 l->comment[0] ? " " : "", 1291 l->comment); 1292 if (log_level_get() >= SYSLOG_LEVEL_VERBOSE) 1293 printf("%s\n", ra); 1294 free(ra); 1295 free(fp); 1296 } else 1297 fprintf(ctx->out, "%s\n", l->line); 1298 return 0; 1299 } 1300 } else if (ctx->delete_host) { 1301 /* Retain non-matching hosts when deleting */ 1302 if (l->status == HKF_STATUS_INVALID) { 1303 ctx->invalid = 1; 1304 logit("%s:%lu: invalid line", l->path, l->linenum); 1305 } 1306 fprintf(ctx->out, "%s\n", l->line); 1307 } 1308 return 0; 1309 } 1310 1311 static void 1312 do_known_hosts(struct passwd *pw, const char *name, int find_host, 1313 int delete_host, int hash_hosts) 1314 { 1315 char *cp, tmp[PATH_MAX], old[PATH_MAX]; 1316 int r, fd, oerrno, inplace = 0; 1317 struct known_hosts_ctx ctx; 1318 u_int foreach_options; 1319 struct stat sb; 1320 1321 if (!have_identity) { 1322 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); 1323 if (strlcpy(identity_file, cp, sizeof(identity_file)) >= 1324 sizeof(identity_file)) 1325 fatal("Specified known hosts path too long"); 1326 free(cp); 1327 have_identity = 1; 1328 } 1329 if (stat(identity_file, &sb) != 0) 1330 fatal("Cannot stat %s: %s", identity_file, strerror(errno)); 1331 1332 memset(&ctx, 0, sizeof(ctx)); 1333 ctx.out = stdout; 1334 ctx.host = name; 1335 ctx.hash_hosts = hash_hosts; 1336 ctx.find_host = find_host; 1337 ctx.delete_host = delete_host; 1338 1339 /* 1340 * Find hosts goes to stdout, hash and deletions happen in-place 1341 * A corner case is ssh-keygen -HF foo, which should go to stdout 1342 */ 1343 if (!find_host && (hash_hosts || delete_host)) { 1344 if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp) || 1345 strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp) || 1346 strlcpy(old, identity_file, sizeof(old)) >= sizeof(old) || 1347 strlcat(old, ".old", sizeof(old)) >= sizeof(old)) 1348 fatal("known_hosts path too long"); 1349 umask(077); 1350 if ((fd = mkstemp(tmp)) == -1) 1351 fatal("mkstemp: %s", strerror(errno)); 1352 if ((ctx.out = fdopen(fd, "w")) == NULL) { 1353 oerrno = errno; 1354 unlink(tmp); 1355 fatal("fdopen: %s", strerror(oerrno)); 1356 } 1357 (void)fchmod(fd, sb.st_mode & 0644); 1358 inplace = 1; 1359 } 1360 /* XXX support identity_file == "-" for stdin */ 1361 foreach_options = find_host ? HKF_WANT_MATCH : 0; 1362 foreach_options |= print_fingerprint ? HKF_WANT_PARSE_KEY : 0; 1363 if ((r = hostkeys_foreach(identity_file, (find_host || !hash_hosts) ? 1364 known_hosts_find_delete : known_hosts_hash, &ctx, name, NULL, 1365 foreach_options, 0)) != 0) { 1366 if (inplace) 1367 unlink(tmp); 1368 fatal_fr(r, "hostkeys_foreach"); 1369 } 1370 1371 if (inplace) 1372 fclose(ctx.out); 1373 1374 if (ctx.invalid) { 1375 error("%s is not a valid known_hosts file.", identity_file); 1376 if (inplace) { 1377 error("Not replacing existing known_hosts " 1378 "file because of errors"); 1379 unlink(tmp); 1380 } 1381 exit(1); 1382 } else if (delete_host && !ctx.found_key) { 1383 logit("Host %s not found in %s", name, identity_file); 1384 if (inplace) 1385 unlink(tmp); 1386 } else if (inplace) { 1387 /* Backup existing file */ 1388 if (unlink(old) == -1 && errno != ENOENT) 1389 fatal("unlink %.100s: %s", old, strerror(errno)); 1390 if (link(identity_file, old) == -1) 1391 fatal("link %.100s to %.100s: %s", identity_file, old, 1392 strerror(errno)); 1393 /* Move new one into place */ 1394 if (rename(tmp, identity_file) == -1) { 1395 error("rename\"%s\" to \"%s\": %s", tmp, identity_file, 1396 strerror(errno)); 1397 unlink(tmp); 1398 unlink(old); 1399 exit(1); 1400 } 1401 1402 printf("%s updated.\n", identity_file); 1403 printf("Original contents retained as %s\n", old); 1404 if (ctx.has_unhashed) { 1405 logit("WARNING: %s contains unhashed entries", old); 1406 logit("Delete this file to ensure privacy " 1407 "of hostnames"); 1408 } 1409 } 1410 1411 exit (find_host && !ctx.found_key); 1412 } 1413 1414 /* 1415 * Perform changing a passphrase. The argument is the passwd structure 1416 * for the current user. 1417 */ 1418 static void 1419 do_change_passphrase(struct passwd *pw) 1420 { 1421 char *comment; 1422 char *old_passphrase, *passphrase1, *passphrase2; 1423 struct stat st; 1424 struct sshkey *private; 1425 int r; 1426 1427 if (!have_identity) 1428 ask_filename(pw, "Enter file in which the key is"); 1429 if (stat(identity_file, &st) == -1) 1430 fatal("%s: %s", identity_file, strerror(errno)); 1431 /* Try to load the file with empty passphrase. */ 1432 r = sshkey_load_private(identity_file, "", &private, &comment); 1433 if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) { 1434 if (identity_passphrase) 1435 old_passphrase = xstrdup(identity_passphrase); 1436 else 1437 old_passphrase = 1438 read_passphrase("Enter old passphrase: ", 1439 RP_ALLOW_STDIN); 1440 r = sshkey_load_private(identity_file, old_passphrase, 1441 &private, &comment); 1442 freezero(old_passphrase, strlen(old_passphrase)); 1443 if (r != 0) 1444 goto badkey; 1445 } else if (r != 0) { 1446 badkey: 1447 fatal_r(r, "Failed to load key %s", identity_file); 1448 } 1449 if (comment) 1450 mprintf("Key has comment '%s'\n", comment); 1451 1452 /* Ask the new passphrase (twice). */ 1453 if (identity_new_passphrase) { 1454 passphrase1 = xstrdup(identity_new_passphrase); 1455 passphrase2 = NULL; 1456 } else { 1457 passphrase1 = 1458 read_passphrase("Enter new passphrase (empty for no " 1459 "passphrase): ", RP_ALLOW_STDIN); 1460 passphrase2 = read_passphrase("Enter same passphrase again: ", 1461 RP_ALLOW_STDIN); 1462 1463 /* Verify that they are the same. */ 1464 if (strcmp(passphrase1, passphrase2) != 0) { 1465 explicit_bzero(passphrase1, strlen(passphrase1)); 1466 explicit_bzero(passphrase2, strlen(passphrase2)); 1467 free(passphrase1); 1468 free(passphrase2); 1469 printf("Pass phrases do not match. Try again.\n"); 1470 exit(1); 1471 } 1472 /* Destroy the other copy. */ 1473 freezero(passphrase2, strlen(passphrase2)); 1474 } 1475 1476 /* Save the file using the new passphrase. */ 1477 if ((r = sshkey_save_private(private, identity_file, passphrase1, 1478 comment, private_key_format, openssh_format_cipher, rounds)) != 0) { 1479 error_r(r, "Saving key \"%s\" failed", identity_file); 1480 freezero(passphrase1, strlen(passphrase1)); 1481 sshkey_free(private); 1482 free(comment); 1483 exit(1); 1484 } 1485 /* Destroy the passphrase and the copy of the key in memory. */ 1486 freezero(passphrase1, strlen(passphrase1)); 1487 sshkey_free(private); /* Destroys contents */ 1488 free(comment); 1489 1490 printf("Your identification has been saved with the new passphrase.\n"); 1491 exit(0); 1492 } 1493 1494 /* 1495 * Print the SSHFP RR. 1496 */ 1497 static int 1498 do_print_resource_record(struct passwd *pw, char *fname, char *hname, 1499 int print_generic, char * const *opts, size_t nopts) 1500 { 1501 struct sshkey *public; 1502 char *comment = NULL; 1503 struct stat st; 1504 int r, hash = -1; 1505 size_t i; 1506 1507 for (i = 0; i < nopts; i++) { 1508 if (strncasecmp(opts[i], "hashalg=", 8) == 0) { 1509 if ((hash = ssh_digest_alg_by_name(opts[i] + 8)) == -1) 1510 fatal("Unsupported hash algorithm"); 1511 } else { 1512 error("Invalid option \"%s\"", opts[i]); 1513 return SSH_ERR_INVALID_ARGUMENT; 1514 } 1515 } 1516 if (fname == NULL) 1517 fatal_f("no filename"); 1518 if (stat(fname, &st) == -1) { 1519 if (errno == ENOENT) 1520 return 0; 1521 fatal("%s: %s", fname, strerror(errno)); 1522 } 1523 if ((r = sshkey_load_public(fname, &public, &comment)) != 0) 1524 fatal_r(r, "Failed to read v2 public key from \"%s\"", fname); 1525 export_dns_rr(hname, public, stdout, print_generic, hash); 1526 sshkey_free(public); 1527 free(comment); 1528 return 1; 1529 } 1530 1531 /* 1532 * Change the comment of a private key file. 1533 */ 1534 static void 1535 do_change_comment(struct passwd *pw, const char *identity_comment) 1536 { 1537 char new_comment[1024], *comment, *passphrase; 1538 struct sshkey *private; 1539 struct sshkey *public; 1540 struct stat st; 1541 int r; 1542 1543 if (!have_identity) 1544 ask_filename(pw, "Enter file in which the key is"); 1545 if (stat(identity_file, &st) == -1) 1546 fatal("%s: %s", identity_file, strerror(errno)); 1547 if ((r = sshkey_load_private(identity_file, "", 1548 &private, &comment)) == 0) 1549 passphrase = xstrdup(""); 1550 else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) 1551 fatal_r(r, "Cannot load private key \"%s\"", identity_file); 1552 else { 1553 if (identity_passphrase) 1554 passphrase = xstrdup(identity_passphrase); 1555 else if (identity_new_passphrase) 1556 passphrase = xstrdup(identity_new_passphrase); 1557 else 1558 passphrase = read_passphrase("Enter passphrase: ", 1559 RP_ALLOW_STDIN); 1560 /* Try to load using the passphrase. */ 1561 if ((r = sshkey_load_private(identity_file, passphrase, 1562 &private, &comment)) != 0) { 1563 freezero(passphrase, strlen(passphrase)); 1564 fatal_r(r, "Cannot load private key \"%s\"", 1565 identity_file); 1566 } 1567 } 1568 1569 if (private->type != KEY_ED25519 && private->type != KEY_XMSS && 1570 private_key_format != SSHKEY_PRIVATE_OPENSSH) { 1571 error("Comments are only supported for keys stored in " 1572 "the new format (-o)."); 1573 explicit_bzero(passphrase, strlen(passphrase)); 1574 sshkey_free(private); 1575 exit(1); 1576 } 1577 if (comment) 1578 printf("Old comment: %s\n", comment); 1579 else 1580 printf("No existing comment\n"); 1581 1582 if (identity_comment) { 1583 strlcpy(new_comment, identity_comment, sizeof(new_comment)); 1584 } else { 1585 printf("New comment: "); 1586 fflush(stdout); 1587 if (!fgets(new_comment, sizeof(new_comment), stdin)) { 1588 explicit_bzero(passphrase, strlen(passphrase)); 1589 sshkey_free(private); 1590 exit(1); 1591 } 1592 new_comment[strcspn(new_comment, "\n")] = '\0'; 1593 } 1594 if (comment != NULL && strcmp(comment, new_comment) == 0) { 1595 printf("No change to comment\n"); 1596 free(passphrase); 1597 sshkey_free(private); 1598 free(comment); 1599 exit(0); 1600 } 1601 1602 /* Save the file using the new passphrase. */ 1603 if ((r = sshkey_save_private(private, identity_file, passphrase, 1604 new_comment, private_key_format, openssh_format_cipher, 1605 rounds)) != 0) { 1606 error_r(r, "Saving key \"%s\" failed", identity_file); 1607 freezero(passphrase, strlen(passphrase)); 1608 sshkey_free(private); 1609 free(comment); 1610 exit(1); 1611 } 1612 freezero(passphrase, strlen(passphrase)); 1613 if ((r = sshkey_from_private(private, &public)) != 0) 1614 fatal_fr(r, "sshkey_from_private"); 1615 sshkey_free(private); 1616 1617 strlcat(identity_file, ".pub", sizeof(identity_file)); 1618 if ((r = sshkey_save_public(public, identity_file, new_comment)) != 0) 1619 fatal_r(r, "Unable to save public key to %s", identity_file); 1620 sshkey_free(public); 1621 free(comment); 1622 1623 if (strlen(new_comment) > 0) 1624 printf("Comment '%s' applied\n", new_comment); 1625 else 1626 printf("Comment removed\n"); 1627 1628 exit(0); 1629 } 1630 1631 static void 1632 cert_ext_add(const char *key, const char *value, int iscrit) 1633 { 1634 cert_ext = xreallocarray(cert_ext, ncert_ext + 1, sizeof(*cert_ext)); 1635 cert_ext[ncert_ext].key = xstrdup(key); 1636 cert_ext[ncert_ext].val = value == NULL ? NULL : xstrdup(value); 1637 cert_ext[ncert_ext].crit = iscrit; 1638 ncert_ext++; 1639 } 1640 1641 /* qsort(3) comparison function for certificate extensions */ 1642 static int 1643 cert_ext_cmp(const void *_a, const void *_b) 1644 { 1645 const struct cert_ext *a = (const struct cert_ext *)_a; 1646 const struct cert_ext *b = (const struct cert_ext *)_b; 1647 int r; 1648 1649 if (a->crit != b->crit) 1650 return (a->crit < b->crit) ? -1 : 1; 1651 if ((r = strcmp(a->key, b->key)) != 0) 1652 return r; 1653 if ((a->val == NULL) != (b->val == NULL)) 1654 return (a->val == NULL) ? -1 : 1; 1655 if (a->val != NULL && (r = strcmp(a->val, b->val)) != 0) 1656 return r; 1657 return 0; 1658 } 1659 1660 #define OPTIONS_CRITICAL 1 1661 #define OPTIONS_EXTENSIONS 2 1662 static void 1663 prepare_options_buf(struct sshbuf *c, int which) 1664 { 1665 struct sshbuf *b; 1666 size_t i; 1667 int r; 1668 const struct cert_ext *ext; 1669 1670 if ((b = sshbuf_new()) == NULL) 1671 fatal_f("sshbuf_new failed"); 1672 sshbuf_reset(c); 1673 for (i = 0; i < ncert_ext; i++) { 1674 ext = &cert_ext[i]; 1675 if ((ext->crit && (which & OPTIONS_EXTENSIONS)) || 1676 (!ext->crit && (which & OPTIONS_CRITICAL))) 1677 continue; 1678 if (ext->val == NULL) { 1679 /* flag option */ 1680 debug3_f("%s", ext->key); 1681 if ((r = sshbuf_put_cstring(c, ext->key)) != 0 || 1682 (r = sshbuf_put_string(c, NULL, 0)) != 0) 1683 fatal_fr(r, "prepare flag"); 1684 } else { 1685 /* key/value option */ 1686 debug3_f("%s=%s", ext->key, ext->val); 1687 sshbuf_reset(b); 1688 if ((r = sshbuf_put_cstring(c, ext->key)) != 0 || 1689 (r = sshbuf_put_cstring(b, ext->val)) != 0 || 1690 (r = sshbuf_put_stringb(c, b)) != 0) 1691 fatal_fr(r, "prepare k/v"); 1692 } 1693 } 1694 sshbuf_free(b); 1695 } 1696 1697 static void 1698 finalise_cert_exts(void) 1699 { 1700 /* critical options */ 1701 if (certflags_command != NULL) 1702 cert_ext_add("force-command", certflags_command, 1); 1703 if (certflags_src_addr != NULL) 1704 cert_ext_add("source-address", certflags_src_addr, 1); 1705 if ((certflags_flags & CERTOPT_REQUIRE_VERIFY) != 0) 1706 cert_ext_add("verify-required", NULL, 1); 1707 /* extensions */ 1708 if ((certflags_flags & CERTOPT_X_FWD) != 0) 1709 cert_ext_add("permit-X11-forwarding", NULL, 0); 1710 if ((certflags_flags & CERTOPT_AGENT_FWD) != 0) 1711 cert_ext_add("permit-agent-forwarding", NULL, 0); 1712 if ((certflags_flags & CERTOPT_PORT_FWD) != 0) 1713 cert_ext_add("permit-port-forwarding", NULL, 0); 1714 if ((certflags_flags & CERTOPT_PTY) != 0) 1715 cert_ext_add("permit-pty", NULL, 0); 1716 if ((certflags_flags & CERTOPT_USER_RC) != 0) 1717 cert_ext_add("permit-user-rc", NULL, 0); 1718 if ((certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0) 1719 cert_ext_add("no-touch-required", NULL, 0); 1720 /* order lexically by key */ 1721 if (ncert_ext > 0) 1722 qsort(cert_ext, ncert_ext, sizeof(*cert_ext), cert_ext_cmp); 1723 } 1724 1725 static struct sshkey * 1726 load_pkcs11_key(char *path) 1727 { 1728 #ifdef ENABLE_PKCS11 1729 struct sshkey **keys = NULL, *public, *private = NULL; 1730 int r, i, nkeys; 1731 1732 if ((r = sshkey_load_public(path, &public, NULL)) != 0) 1733 fatal_r(r, "Couldn't load CA public key \"%s\"", path); 1734 1735 nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, 1736 &keys, NULL); 1737 debug3_f("%d keys", nkeys); 1738 if (nkeys <= 0) 1739 fatal("cannot read public key from pkcs11"); 1740 for (i = 0; i < nkeys; i++) { 1741 if (sshkey_equal_public(public, keys[i])) { 1742 private = keys[i]; 1743 continue; 1744 } 1745 sshkey_free(keys[i]); 1746 } 1747 free(keys); 1748 sshkey_free(public); 1749 return private; 1750 #else 1751 fatal("no pkcs11 support"); 1752 #endif /* ENABLE_PKCS11 */ 1753 } 1754 1755 /* Signer for sshkey_certify_custom that uses the agent */ 1756 static int 1757 agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp, 1758 const u_char *data, size_t datalen, 1759 const char *alg, const char *provider, const char *pin, 1760 u_int compat, void *ctx) 1761 { 1762 int *agent_fdp = (int *)ctx; 1763 1764 return ssh_agent_sign(*agent_fdp, key, sigp, lenp, 1765 data, datalen, alg, compat); 1766 } 1767 1768 static void 1769 do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent, 1770 unsigned long long cert_serial, int cert_serial_autoinc, 1771 int argc, char **argv) 1772 { 1773 int r, i, found, agent_fd = -1; 1774 u_int n; 1775 struct sshkey *ca, *public; 1776 char valid[64], *otmp, *tmp, *cp, *out, *comment; 1777 char *ca_fp = NULL, **plist = NULL, *pin = NULL; 1778 struct ssh_identitylist *agent_ids; 1779 size_t j; 1780 struct notifier_ctx *notifier = NULL; 1781 1782 #ifdef ENABLE_PKCS11 1783 pkcs11_init(1); 1784 #endif 1785 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); 1786 if (pkcs11provider != NULL) { 1787 /* If a PKCS#11 token was specified then try to use it */ 1788 if ((ca = load_pkcs11_key(tmp)) == NULL) 1789 fatal("No PKCS#11 key matching %s found", ca_key_path); 1790 } else if (prefer_agent) { 1791 /* 1792 * Agent signature requested. Try to use agent after making 1793 * sure the public key specified is actually present in the 1794 * agent. 1795 */ 1796 if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0) 1797 fatal_r(r, "Cannot load CA public key %s", tmp); 1798 if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) 1799 fatal_r(r, "Cannot use public key for CA signature"); 1800 if ((r = ssh_fetch_identitylist(agent_fd, &agent_ids)) != 0) 1801 fatal_r(r, "Retrieve agent key list"); 1802 found = 0; 1803 for (j = 0; j < agent_ids->nkeys; j++) { 1804 if (sshkey_equal(ca, agent_ids->keys[j])) { 1805 found = 1; 1806 break; 1807 } 1808 } 1809 if (!found) 1810 fatal("CA key %s not found in agent", tmp); 1811 ssh_free_identitylist(agent_ids); 1812 ca->flags |= SSHKEY_FLAG_EXT; 1813 } else { 1814 /* CA key is assumed to be a private key on the filesystem */ 1815 ca = load_identity(tmp, NULL); 1816 if (sshkey_is_sk(ca) && 1817 (ca->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) { 1818 if ((pin = read_passphrase("Enter PIN for CA key: ", 1819 RP_ALLOW_STDIN)) == NULL) 1820 fatal_f("couldn't read PIN"); 1821 } 1822 } 1823 free(tmp); 1824 1825 if (key_type_name != NULL) { 1826 if (sshkey_type_from_shortname(key_type_name) != ca->type) { 1827 fatal("CA key type %s doesn't match specified %s", 1828 sshkey_ssh_name(ca), key_type_name); 1829 } 1830 } else if (ca->type == KEY_RSA) { 1831 /* Default to a good signature algorithm */ 1832 key_type_name = "rsa-sha2-512"; 1833 } 1834 ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT); 1835 1836 finalise_cert_exts(); 1837 for (i = 0; i < argc; i++) { 1838 /* Split list of principals */ 1839 n = 0; 1840 if (cert_principals != NULL) { 1841 otmp = tmp = xstrdup(cert_principals); 1842 plist = NULL; 1843 for (; (cp = strsep(&tmp, ",")) != NULL; n++) { 1844 plist = xreallocarray(plist, n + 1, sizeof(*plist)); 1845 if (*(plist[n] = xstrdup(cp)) == '\0') 1846 fatal("Empty principal name"); 1847 } 1848 free(otmp); 1849 } 1850 if (n > SSHKEY_CERT_MAX_PRINCIPALS) 1851 fatal("Too many certificate principals specified"); 1852 1853 tmp = tilde_expand_filename(argv[i], pw->pw_uid); 1854 if ((r = sshkey_load_public(tmp, &public, &comment)) != 0) 1855 fatal_r(r, "load pubkey \"%s\"", tmp); 1856 if (sshkey_is_cert(public)) 1857 fatal_f("key \"%s\" type %s cannot be certified", 1858 tmp, sshkey_type(public)); 1859 1860 /* Prepare certificate to sign */ 1861 if ((r = sshkey_to_certified(public)) != 0) 1862 fatal_r(r, "Could not upgrade key %s to certificate", tmp); 1863 public->cert->type = cert_key_type; 1864 public->cert->serial = (u_int64_t)cert_serial; 1865 public->cert->key_id = xstrdup(cert_key_id); 1866 public->cert->nprincipals = n; 1867 public->cert->principals = plist; 1868 public->cert->valid_after = cert_valid_from; 1869 public->cert->valid_before = cert_valid_to; 1870 prepare_options_buf(public->cert->critical, OPTIONS_CRITICAL); 1871 prepare_options_buf(public->cert->extensions, 1872 OPTIONS_EXTENSIONS); 1873 if ((r = sshkey_from_private(ca, 1874 &public->cert->signature_key)) != 0) 1875 fatal_r(r, "sshkey_from_private (ca key)"); 1876 1877 if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) { 1878 if ((r = sshkey_certify_custom(public, ca, 1879 key_type_name, sk_provider, NULL, agent_signer, 1880 &agent_fd)) != 0) 1881 fatal_r(r, "Couldn't certify %s via agent", tmp); 1882 } else { 1883 if (sshkey_is_sk(ca) && 1884 (ca->sk_flags & SSH_SK_USER_PRESENCE_REQD)) { 1885 notifier = notify_start(0, 1886 "Confirm user presence for key %s %s", 1887 sshkey_type(ca), ca_fp); 1888 } 1889 r = sshkey_certify(public, ca, key_type_name, 1890 sk_provider, pin); 1891 notify_complete(notifier, "User presence confirmed"); 1892 if (r != 0) 1893 fatal_r(r, "Couldn't certify key %s", tmp); 1894 } 1895 1896 if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0) 1897 *cp = '\0'; 1898 xasprintf(&out, "%s-cert.pub", tmp); 1899 free(tmp); 1900 1901 if ((r = sshkey_save_public(public, out, comment)) != 0) { 1902 fatal_r(r, "Unable to save public key to %s", 1903 identity_file); 1904 } 1905 1906 if (!quiet) { 1907 sshkey_format_cert_validity(public->cert, 1908 valid, sizeof(valid)); 1909 logit("Signed %s key %s: id \"%s\" serial %llu%s%s " 1910 "valid %s", sshkey_cert_type(public), 1911 out, public->cert->key_id, 1912 (unsigned long long)public->cert->serial, 1913 cert_principals != NULL ? " for " : "", 1914 cert_principals != NULL ? cert_principals : "", 1915 valid); 1916 } 1917 1918 sshkey_free(public); 1919 free(out); 1920 if (cert_serial_autoinc) 1921 cert_serial++; 1922 } 1923 if (pin != NULL) 1924 freezero(pin, strlen(pin)); 1925 free(ca_fp); 1926 #ifdef ENABLE_PKCS11 1927 pkcs11_terminate(); 1928 #endif 1929 exit(0); 1930 } 1931 1932 static u_int64_t 1933 parse_relative_time(const char *s, time_t now) 1934 { 1935 int64_t mul, secs; 1936 1937 mul = *s == '-' ? -1 : 1; 1938 1939 if ((secs = convtime(s + 1)) == -1) 1940 fatal("Invalid relative certificate time %s", s); 1941 if (mul == -1 && secs > now) 1942 fatal("Certificate time %s cannot be represented", s); 1943 return now + (u_int64_t)(secs * mul); 1944 } 1945 1946 static void 1947 parse_hex_u64(const char *s, uint64_t *up) 1948 { 1949 char *ep; 1950 unsigned long long ull; 1951 1952 errno = 0; 1953 ull = strtoull(s, &ep, 16); 1954 if (*s == '\0' || *ep != '\0') 1955 fatal("Invalid certificate time: not a number"); 1956 if (errno == ERANGE && ull == ULONG_MAX) 1957 fatal_fr(SSH_ERR_SYSTEM_ERROR, "Invalid certificate time"); 1958 *up = (uint64_t)ull; 1959 } 1960 1961 static void 1962 parse_cert_times(char *timespec) 1963 { 1964 char *from, *to; 1965 time_t now = time(NULL); 1966 int64_t secs; 1967 1968 /* +timespec relative to now */ 1969 if (*timespec == '+' && strchr(timespec, ':') == NULL) { 1970 if ((secs = convtime(timespec + 1)) == -1) 1971 fatal("Invalid relative certificate life %s", timespec); 1972 cert_valid_to = now + secs; 1973 /* 1974 * Backdate certificate one minute to avoid problems on hosts 1975 * with poorly-synchronised clocks. 1976 */ 1977 cert_valid_from = ((now - 59)/ 60) * 60; 1978 return; 1979 } 1980 1981 /* 1982 * from:to, where 1983 * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "always" 1984 * to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "forever" 1985 */ 1986 from = xstrdup(timespec); 1987 to = strchr(from, ':'); 1988 if (to == NULL || from == to || *(to + 1) == '\0') 1989 fatal("Invalid certificate life specification %s", timespec); 1990 *to++ = '\0'; 1991 1992 if (*from == '-' || *from == '+') 1993 cert_valid_from = parse_relative_time(from, now); 1994 else if (strcmp(from, "always") == 0) 1995 cert_valid_from = 0; 1996 else if (strncmp(from, "0x", 2) == 0) 1997 parse_hex_u64(from, &cert_valid_from); 1998 else if (parse_absolute_time(from, &cert_valid_from) != 0) 1999 fatal("Invalid from time \"%s\"", from); 2000 2001 if (*to == '-' || *to == '+') 2002 cert_valid_to = parse_relative_time(to, now); 2003 else if (strcmp(to, "forever") == 0) 2004 cert_valid_to = ~(u_int64_t)0; 2005 else if (strncmp(to, "0x", 2) == 0) 2006 parse_hex_u64(to, &cert_valid_to); 2007 else if (parse_absolute_time(to, &cert_valid_to) != 0) 2008 fatal("Invalid to time \"%s\"", to); 2009 2010 if (cert_valid_to <= cert_valid_from) 2011 fatal("Empty certificate validity interval"); 2012 free(from); 2013 } 2014 2015 static void 2016 add_cert_option(char *opt) 2017 { 2018 char *val, *cp; 2019 int iscrit = 0; 2020 2021 if (strcasecmp(opt, "clear") == 0) 2022 certflags_flags = 0; 2023 else if (strcasecmp(opt, "no-x11-forwarding") == 0) 2024 certflags_flags &= ~CERTOPT_X_FWD; 2025 else if (strcasecmp(opt, "permit-x11-forwarding") == 0) 2026 certflags_flags |= CERTOPT_X_FWD; 2027 else if (strcasecmp(opt, "no-agent-forwarding") == 0) 2028 certflags_flags &= ~CERTOPT_AGENT_FWD; 2029 else if (strcasecmp(opt, "permit-agent-forwarding") == 0) 2030 certflags_flags |= CERTOPT_AGENT_FWD; 2031 else if (strcasecmp(opt, "no-port-forwarding") == 0) 2032 certflags_flags &= ~CERTOPT_PORT_FWD; 2033 else if (strcasecmp(opt, "permit-port-forwarding") == 0) 2034 certflags_flags |= CERTOPT_PORT_FWD; 2035 else if (strcasecmp(opt, "no-pty") == 0) 2036 certflags_flags &= ~CERTOPT_PTY; 2037 else if (strcasecmp(opt, "permit-pty") == 0) 2038 certflags_flags |= CERTOPT_PTY; 2039 else if (strcasecmp(opt, "no-user-rc") == 0) 2040 certflags_flags &= ~CERTOPT_USER_RC; 2041 else if (strcasecmp(opt, "permit-user-rc") == 0) 2042 certflags_flags |= CERTOPT_USER_RC; 2043 else if (strcasecmp(opt, "touch-required") == 0) 2044 certflags_flags &= ~CERTOPT_NO_REQUIRE_USER_PRESENCE; 2045 else if (strcasecmp(opt, "no-touch-required") == 0) 2046 certflags_flags |= CERTOPT_NO_REQUIRE_USER_PRESENCE; 2047 else if (strcasecmp(opt, "no-verify-required") == 0) 2048 certflags_flags &= ~CERTOPT_REQUIRE_VERIFY; 2049 else if (strcasecmp(opt, "verify-required") == 0) 2050 certflags_flags |= CERTOPT_REQUIRE_VERIFY; 2051 else if (strncasecmp(opt, "force-command=", 14) == 0) { 2052 val = opt + 14; 2053 if (*val == '\0') 2054 fatal("Empty force-command option"); 2055 if (certflags_command != NULL) 2056 fatal("force-command already specified"); 2057 certflags_command = xstrdup(val); 2058 } else if (strncasecmp(opt, "source-address=", 15) == 0) { 2059 val = opt + 15; 2060 if (*val == '\0') 2061 fatal("Empty source-address option"); 2062 if (certflags_src_addr != NULL) 2063 fatal("source-address already specified"); 2064 if (addr_match_cidr_list(NULL, val) != 0) 2065 fatal("Invalid source-address list"); 2066 certflags_src_addr = xstrdup(val); 2067 } else if (strncasecmp(opt, "extension:", 10) == 0 || 2068 (iscrit = (strncasecmp(opt, "critical:", 9) == 0))) { 2069 val = xstrdup(strchr(opt, ':') + 1); 2070 if ((cp = strchr(val, '=')) != NULL) 2071 *cp++ = '\0'; 2072 cert_ext_add(val, cp, iscrit); 2073 free(val); 2074 } else 2075 fatal("Unsupported certificate option \"%s\"", opt); 2076 } 2077 2078 static void 2079 show_options(struct sshbuf *optbuf, int in_critical) 2080 { 2081 char *name, *arg, *hex; 2082 struct sshbuf *options, *option = NULL; 2083 int r; 2084 2085 if ((options = sshbuf_fromb(optbuf)) == NULL) 2086 fatal_f("sshbuf_fromb failed"); 2087 while (sshbuf_len(options) != 0) { 2088 sshbuf_free(option); 2089 option = NULL; 2090 if ((r = sshbuf_get_cstring(options, &name, NULL)) != 0 || 2091 (r = sshbuf_froms(options, &option)) != 0) 2092 fatal_fr(r, "parse option"); 2093 printf(" %s", name); 2094 if (!in_critical && 2095 (strcmp(name, "permit-X11-forwarding") == 0 || 2096 strcmp(name, "permit-agent-forwarding") == 0 || 2097 strcmp(name, "permit-port-forwarding") == 0 || 2098 strcmp(name, "permit-pty") == 0 || 2099 strcmp(name, "permit-user-rc") == 0 || 2100 strcmp(name, "no-touch-required") == 0)) { 2101 printf("\n"); 2102 } else if (in_critical && 2103 (strcmp(name, "force-command") == 0 || 2104 strcmp(name, "source-address") == 0)) { 2105 if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0) 2106 fatal_fr(r, "parse critical"); 2107 printf(" %s\n", arg); 2108 free(arg); 2109 } else if (in_critical && 2110 strcmp(name, "verify-required") == 0) { 2111 printf("\n"); 2112 } else if (sshbuf_len(option) > 0) { 2113 hex = sshbuf_dtob16(option); 2114 printf(" UNKNOWN OPTION: %s (len %zu)\n", 2115 hex, sshbuf_len(option)); 2116 sshbuf_reset(option); 2117 free(hex); 2118 } else 2119 printf(" UNKNOWN FLAG OPTION\n"); 2120 free(name); 2121 if (sshbuf_len(option) != 0) 2122 fatal("Option corrupt: extra data at end"); 2123 } 2124 sshbuf_free(option); 2125 sshbuf_free(options); 2126 } 2127 2128 static void 2129 print_cert(struct sshkey *key) 2130 { 2131 char valid[64], *key_fp, *ca_fp; 2132 u_int i; 2133 2134 key_fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT); 2135 ca_fp = sshkey_fingerprint(key->cert->signature_key, 2136 fingerprint_hash, SSH_FP_DEFAULT); 2137 if (key_fp == NULL || ca_fp == NULL) 2138 fatal_f("sshkey_fingerprint fail"); 2139 sshkey_format_cert_validity(key->cert, valid, sizeof(valid)); 2140 2141 printf(" Type: %s %s certificate\n", sshkey_ssh_name(key), 2142 sshkey_cert_type(key)); 2143 printf(" Public key: %s %s\n", sshkey_type(key), key_fp); 2144 printf(" Signing CA: %s %s (using %s)\n", 2145 sshkey_type(key->cert->signature_key), ca_fp, 2146 key->cert->signature_type); 2147 printf(" Key ID: \"%s\"\n", key->cert->key_id); 2148 printf(" Serial: %llu\n", (unsigned long long)key->cert->serial); 2149 printf(" Valid: %s\n", valid); 2150 printf(" Principals: "); 2151 if (key->cert->nprincipals == 0) 2152 printf("(none)\n"); 2153 else { 2154 for (i = 0; i < key->cert->nprincipals; i++) 2155 printf("\n %s", 2156 key->cert->principals[i]); 2157 printf("\n"); 2158 } 2159 printf(" Critical Options: "); 2160 if (sshbuf_len(key->cert->critical) == 0) 2161 printf("(none)\n"); 2162 else { 2163 printf("\n"); 2164 show_options(key->cert->critical, 1); 2165 } 2166 printf(" Extensions: "); 2167 if (sshbuf_len(key->cert->extensions) == 0) 2168 printf("(none)\n"); 2169 else { 2170 printf("\n"); 2171 show_options(key->cert->extensions, 0); 2172 } 2173 } 2174 2175 static void 2176 do_show_cert(struct passwd *pw) 2177 { 2178 struct sshkey *key = NULL; 2179 struct stat st; 2180 int r, is_stdin = 0, ok = 0; 2181 FILE *f; 2182 char *cp, *line = NULL; 2183 const char *path; 2184 size_t linesize = 0; 2185 u_long lnum = 0; 2186 2187 if (!have_identity) 2188 ask_filename(pw, "Enter file in which the key is"); 2189 if (strcmp(identity_file, "-") != 0 && stat(identity_file, &st) == -1) 2190 fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); 2191 2192 path = identity_file; 2193 if (strcmp(path, "-") == 0) { 2194 f = stdin; 2195 path = "(stdin)"; 2196 is_stdin = 1; 2197 } else if ((f = fopen(identity_file, "r")) == NULL) 2198 fatal("fopen %s: %s", identity_file, strerror(errno)); 2199 2200 while (getline(&line, &linesize, f) != -1) { 2201 lnum++; 2202 sshkey_free(key); 2203 key = NULL; 2204 /* Trim leading space and comments */ 2205 cp = line + strspn(line, " \t"); 2206 if (*cp == '#' || *cp == '\0') 2207 continue; 2208 if ((key = sshkey_new(KEY_UNSPEC)) == NULL) 2209 fatal("sshkey_new"); 2210 if ((r = sshkey_read(key, &cp)) != 0) { 2211 error_r(r, "%s:%lu: invalid key", path, lnum); 2212 continue; 2213 } 2214 if (!sshkey_is_cert(key)) { 2215 error("%s:%lu is not a certificate", path, lnum); 2216 continue; 2217 } 2218 ok = 1; 2219 if (!is_stdin && lnum == 1) 2220 printf("%s:\n", path); 2221 else 2222 printf("%s:%lu:\n", path, lnum); 2223 print_cert(key); 2224 } 2225 free(line); 2226 sshkey_free(key); 2227 fclose(f); 2228 exit(ok ? 0 : 1); 2229 } 2230 2231 static void 2232 load_krl(const char *path, struct ssh_krl **krlp) 2233 { 2234 struct sshbuf *krlbuf; 2235 int r; 2236 2237 if ((r = sshbuf_load_file(path, &krlbuf)) != 0) 2238 fatal_r(r, "Unable to load KRL %s", path); 2239 /* XXX check sigs */ 2240 if ((r = ssh_krl_from_blob(krlbuf, krlp)) != 0 || 2241 *krlp == NULL) 2242 fatal_r(r, "Invalid KRL file %s", path); 2243 sshbuf_free(krlbuf); 2244 } 2245 2246 static void 2247 hash_to_blob(const char *cp, u_char **blobp, size_t *lenp, 2248 const char *file, u_long lnum) 2249 { 2250 char *tmp; 2251 size_t tlen; 2252 struct sshbuf *b; 2253 int r; 2254 2255 if (strncmp(cp, "SHA256:", 7) != 0) 2256 fatal("%s:%lu: unsupported hash algorithm", file, lnum); 2257 cp += 7; 2258 2259 /* 2260 * OpenSSH base64 hashes omit trailing '=' 2261 * characters; put them back for decode. 2262 */ 2263 if ((tlen = strlen(cp)) >= SIZE_MAX - 5) 2264 fatal_f("hash too long: %zu bytes", tlen); 2265 tmp = xmalloc(tlen + 4 + 1); 2266 strlcpy(tmp, cp, tlen + 1); 2267 while ((tlen % 4) != 0) { 2268 tmp[tlen++] = '='; 2269 tmp[tlen] = '\0'; 2270 } 2271 if ((b = sshbuf_new()) == NULL) 2272 fatal_f("sshbuf_new failed"); 2273 if ((r = sshbuf_b64tod(b, tmp)) != 0) 2274 fatal_r(r, "%s:%lu: decode hash failed", file, lnum); 2275 free(tmp); 2276 *lenp = sshbuf_len(b); 2277 *blobp = xmalloc(*lenp); 2278 memcpy(*blobp, sshbuf_ptr(b), *lenp); 2279 sshbuf_free(b); 2280 } 2281 2282 static void 2283 update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, 2284 const struct sshkey *ca, struct ssh_krl *krl) 2285 { 2286 struct sshkey *key = NULL; 2287 u_long lnum = 0; 2288 char *path, *cp, *ep, *line = NULL; 2289 u_char *blob = NULL; 2290 size_t blen = 0, linesize = 0; 2291 unsigned long long serial, serial2; 2292 int i, was_explicit_key, was_sha1, was_sha256, was_hash, r; 2293 FILE *krl_spec; 2294 2295 path = tilde_expand_filename(file, pw->pw_uid); 2296 if (strcmp(path, "-") == 0) { 2297 krl_spec = stdin; 2298 free(path); 2299 path = xstrdup("(standard input)"); 2300 } else if ((krl_spec = fopen(path, "r")) == NULL) 2301 fatal("fopen %s: %s", path, strerror(errno)); 2302 2303 if (!quiet) 2304 printf("Revoking from %s\n", path); 2305 while (getline(&line, &linesize, krl_spec) != -1) { 2306 if (linesize >= INT_MAX) { 2307 fatal_f("%s contains unparsable line, len=%zu", 2308 path, linesize); 2309 } 2310 lnum++; 2311 was_explicit_key = was_sha1 = was_sha256 = was_hash = 0; 2312 cp = line + strspn(line, " \t"); 2313 /* Trim trailing space, comments and strip \n */ 2314 for (i = 0, r = -1; cp[i] != '\0'; i++) { 2315 if (cp[i] == '#' || cp[i] == '\n') { 2316 cp[i] = '\0'; 2317 break; 2318 } 2319 if (cp[i] == ' ' || cp[i] == '\t') { 2320 /* Remember the start of a span of whitespace */ 2321 if (r == -1) 2322 r = i; 2323 } else 2324 r = -1; 2325 } 2326 if (r != -1) 2327 cp[r] = '\0'; 2328 if (*cp == '\0') 2329 continue; 2330 if (strncasecmp(cp, "serial:", 7) == 0) { 2331 if (ca == NULL && !wild_ca) { 2332 fatal("revoking certificates by serial number " 2333 "requires specification of a CA key"); 2334 } 2335 cp += 7; 2336 cp = cp + strspn(cp, " \t"); 2337 errno = 0; 2338 serial = strtoull(cp, &ep, 0); 2339 if (*cp == '\0' || (*ep != '\0' && *ep != '-')) 2340 fatal("%s:%lu: invalid serial \"%s\"", 2341 path, lnum, cp); 2342 if (errno == ERANGE && serial == ULLONG_MAX) 2343 fatal("%s:%lu: serial out of range", 2344 path, lnum); 2345 serial2 = serial; 2346 if (*ep == '-') { 2347 cp = ep + 1; 2348 errno = 0; 2349 serial2 = strtoull(cp, &ep, 0); 2350 if (*cp == '\0' || *ep != '\0') 2351 fatal("%s:%lu: invalid serial \"%s\"", 2352 path, lnum, cp); 2353 if (errno == ERANGE && serial2 == ULLONG_MAX) 2354 fatal("%s:%lu: serial out of range", 2355 path, lnum); 2356 if (serial2 <= serial) 2357 fatal("%s:%lu: invalid serial range " 2358 "%llu:%llu", path, lnum, 2359 (unsigned long long)serial, 2360 (unsigned long long)serial2); 2361 } 2362 if (ssh_krl_revoke_cert_by_serial_range(krl, 2363 ca, serial, serial2) != 0) { 2364 fatal_f("revoke serial failed"); 2365 } 2366 } else if (strncasecmp(cp, "id:", 3) == 0) { 2367 if (ca == NULL && !wild_ca) { 2368 fatal("revoking certificates by key ID " 2369 "requires specification of a CA key"); 2370 } 2371 cp += 3; 2372 cp = cp + strspn(cp, " \t"); 2373 if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0) 2374 fatal_f("revoke key ID failed"); 2375 } else if (strncasecmp(cp, "hash:", 5) == 0) { 2376 cp += 5; 2377 cp = cp + strspn(cp, " \t"); 2378 hash_to_blob(cp, &blob, &blen, file, lnum); 2379 r = ssh_krl_revoke_key_sha256(krl, blob, blen); 2380 if (r != 0) 2381 fatal_fr(r, "revoke key failed"); 2382 } else { 2383 if (strncasecmp(cp, "key:", 4) == 0) { 2384 cp += 4; 2385 cp = cp + strspn(cp, " \t"); 2386 was_explicit_key = 1; 2387 } else if (strncasecmp(cp, "sha1:", 5) == 0) { 2388 cp += 5; 2389 cp = cp + strspn(cp, " \t"); 2390 was_sha1 = 1; 2391 } else if (strncasecmp(cp, "sha256:", 7) == 0) { 2392 cp += 7; 2393 cp = cp + strspn(cp, " \t"); 2394 was_sha256 = 1; 2395 /* 2396 * Just try to process the line as a key. 2397 * Parsing will fail if it isn't. 2398 */ 2399 } 2400 if ((key = sshkey_new(KEY_UNSPEC)) == NULL) 2401 fatal("sshkey_new"); 2402 if ((r = sshkey_read(key, &cp)) != 0) 2403 fatal_r(r, "%s:%lu: invalid key", path, lnum); 2404 if (was_explicit_key) 2405 r = ssh_krl_revoke_key_explicit(krl, key); 2406 else if (was_sha1) { 2407 if (sshkey_fingerprint_raw(key, 2408 SSH_DIGEST_SHA1, &blob, &blen) != 0) { 2409 fatal("%s:%lu: fingerprint failed", 2410 file, lnum); 2411 } 2412 r = ssh_krl_revoke_key_sha1(krl, blob, blen); 2413 } else if (was_sha256) { 2414 if (sshkey_fingerprint_raw(key, 2415 SSH_DIGEST_SHA256, &blob, &blen) != 0) { 2416 fatal("%s:%lu: fingerprint failed", 2417 file, lnum); 2418 } 2419 r = ssh_krl_revoke_key_sha256(krl, blob, blen); 2420 } else 2421 r = ssh_krl_revoke_key(krl, key); 2422 if (r != 0) 2423 fatal_fr(r, "revoke key failed"); 2424 freezero(blob, blen); 2425 blob = NULL; 2426 blen = 0; 2427 sshkey_free(key); 2428 } 2429 } 2430 if (strcmp(path, "-") != 0) 2431 fclose(krl_spec); 2432 free(line); 2433 free(path); 2434 } 2435 2436 static void 2437 do_gen_krl(struct passwd *pw, int updating, const char *ca_key_path, 2438 unsigned long long krl_version, const char *krl_comment, 2439 int argc, char **argv) 2440 { 2441 struct ssh_krl *krl; 2442 struct stat sb; 2443 struct sshkey *ca = NULL; 2444 int i, r, wild_ca = 0; 2445 char *tmp; 2446 struct sshbuf *kbuf; 2447 2448 if (*identity_file == '\0') 2449 fatal("KRL generation requires an output file"); 2450 if (stat(identity_file, &sb) == -1) { 2451 if (errno != ENOENT) 2452 fatal("Cannot access KRL \"%s\": %s", 2453 identity_file, strerror(errno)); 2454 if (updating) 2455 fatal("KRL \"%s\" does not exist", identity_file); 2456 } 2457 if (ca_key_path != NULL) { 2458 if (strcasecmp(ca_key_path, "none") == 0) 2459 wild_ca = 1; 2460 else { 2461 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); 2462 if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0) 2463 fatal_r(r, "Cannot load CA public key %s", tmp); 2464 free(tmp); 2465 } 2466 } 2467 2468 if (updating) 2469 load_krl(identity_file, &krl); 2470 else if ((krl = ssh_krl_init()) == NULL) 2471 fatal("couldn't create KRL"); 2472 2473 if (krl_version != 0) 2474 ssh_krl_set_version(krl, krl_version); 2475 if (krl_comment != NULL) 2476 ssh_krl_set_comment(krl, krl_comment); 2477 2478 for (i = 0; i < argc; i++) 2479 update_krl_from_file(pw, argv[i], wild_ca, ca, krl); 2480 2481 if ((kbuf = sshbuf_new()) == NULL) 2482 fatal("sshbuf_new failed"); 2483 if (ssh_krl_to_blob(krl, kbuf) != 0) 2484 fatal("Couldn't generate KRL"); 2485 if ((r = sshbuf_write_file(identity_file, kbuf)) != 0) 2486 fatal("write %s: %s", identity_file, strerror(errno)); 2487 sshbuf_free(kbuf); 2488 ssh_krl_free(krl); 2489 sshkey_free(ca); 2490 } 2491 2492 static void 2493 do_check_krl(struct passwd *pw, int print_krl, int argc, char **argv) 2494 { 2495 int i, r, ret = 0; 2496 char *comment; 2497 struct ssh_krl *krl; 2498 struct sshkey *k; 2499 2500 if (*identity_file == '\0') 2501 fatal("KRL checking requires an input file"); 2502 load_krl(identity_file, &krl); 2503 if (print_krl) 2504 krl_dump(krl, stdout); 2505 for (i = 0; i < argc; i++) { 2506 if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0) 2507 fatal_r(r, "Cannot load public key %s", argv[i]); 2508 r = ssh_krl_check_key(krl, k); 2509 printf("%s%s%s%s: %s\n", argv[i], 2510 *comment ? " (" : "", comment, *comment ? ")" : "", 2511 r == 0 ? "ok" : "REVOKED"); 2512 if (r != 0) 2513 ret = 1; 2514 sshkey_free(k); 2515 free(comment); 2516 } 2517 ssh_krl_free(krl); 2518 exit(ret); 2519 } 2520 2521 static struct sshkey * 2522 load_sign_key(const char *keypath, const struct sshkey *pubkey) 2523 { 2524 size_t i, slen, plen = strlen(keypath); 2525 char *privpath = xstrdup(keypath); 2526 static const char * const suffixes[] = { "-cert.pub", ".pub", NULL }; 2527 struct sshkey *ret = NULL, *privkey = NULL; 2528 int r, waspub = 0; 2529 struct stat st; 2530 2531 /* 2532 * If passed a public key filename, then try to locate the corresponding 2533 * private key. This lets us specify certificates on the command-line 2534 * and have ssh-keygen find the appropriate private key. 2535 */ 2536 for (i = 0; suffixes[i]; i++) { 2537 slen = strlen(suffixes[i]); 2538 if (plen <= slen || 2539 strcmp(privpath + plen - slen, suffixes[i]) != 0) 2540 continue; 2541 privpath[plen - slen] = '\0'; 2542 debug_f("%s looks like a public key, using private key " 2543 "path %s instead", keypath, privpath); 2544 waspub = 1; 2545 } 2546 if (waspub && stat(privpath, &st) != 0 && errno == ENOENT) 2547 fatal("No private key found for public key \"%s\"", keypath); 2548 if ((r = sshkey_load_private(privpath, "", &privkey, NULL)) != 0 && 2549 (r != SSH_ERR_KEY_WRONG_PASSPHRASE)) { 2550 debug_fr(r, "load private key \"%s\"", privpath); 2551 fatal("No private key found for \"%s\"", privpath); 2552 } else if (privkey == NULL) 2553 privkey = load_identity(privpath, NULL); 2554 2555 if (!sshkey_equal_public(pubkey, privkey)) { 2556 error("Public key %s doesn't match private %s", 2557 keypath, privpath); 2558 goto done; 2559 } 2560 if (sshkey_is_cert(pubkey) && !sshkey_is_cert(privkey)) { 2561 /* 2562 * Graft the certificate onto the private key to make 2563 * it capable of signing. 2564 */ 2565 if ((r = sshkey_to_certified(privkey)) != 0) { 2566 error_fr(r, "sshkey_to_certified"); 2567 goto done; 2568 } 2569 if ((r = sshkey_cert_copy(pubkey, privkey)) != 0) { 2570 error_fr(r, "sshkey_cert_copy"); 2571 goto done; 2572 } 2573 } 2574 /* success */ 2575 ret = privkey; 2576 privkey = NULL; 2577 done: 2578 sshkey_free(privkey); 2579 free(privpath); 2580 return ret; 2581 } 2582 2583 static int 2584 sign_one(struct sshkey *signkey, const char *filename, int fd, 2585 const char *sig_namespace, const char *hashalg, sshsig_signer *signer, 2586 void *signer_ctx) 2587 { 2588 struct sshbuf *sigbuf = NULL, *abuf = NULL; 2589 int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno; 2590 char *wfile = NULL, *asig = NULL, *fp = NULL; 2591 char *pin = NULL, *prompt = NULL; 2592 2593 if (!quiet) { 2594 if (fd == STDIN_FILENO) 2595 fprintf(stderr, "Signing data on standard input\n"); 2596 else 2597 fprintf(stderr, "Signing file %s\n", filename); 2598 } 2599 if (signer == NULL && sshkey_is_sk(signkey)) { 2600 if ((signkey->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) { 2601 xasprintf(&prompt, "Enter PIN for %s key: ", 2602 sshkey_type(signkey)); 2603 if ((pin = read_passphrase(prompt, 2604 RP_ALLOW_STDIN)) == NULL) 2605 fatal_f("couldn't read PIN"); 2606 } 2607 if ((signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) { 2608 if ((fp = sshkey_fingerprint(signkey, fingerprint_hash, 2609 SSH_FP_DEFAULT)) == NULL) 2610 fatal_f("fingerprint failed"); 2611 fprintf(stderr, "Confirm user presence for key %s %s\n", 2612 sshkey_type(signkey), fp); 2613 free(fp); 2614 } 2615 } 2616 if ((r = sshsig_sign_fd(signkey, hashalg, sk_provider, pin, 2617 fd, sig_namespace, &sigbuf, signer, signer_ctx)) != 0) { 2618 error_r(r, "Signing %s failed", filename); 2619 goto out; 2620 } 2621 if ((r = sshsig_armor(sigbuf, &abuf)) != 0) { 2622 error_fr(r, "sshsig_armor"); 2623 goto out; 2624 } 2625 if ((asig = sshbuf_dup_string(abuf)) == NULL) { 2626 error_f("buffer error"); 2627 r = SSH_ERR_ALLOC_FAIL; 2628 goto out; 2629 } 2630 2631 if (fd == STDIN_FILENO) { 2632 fputs(asig, stdout); 2633 fflush(stdout); 2634 } else { 2635 xasprintf(&wfile, "%s.sig", filename); 2636 if (confirm_overwrite(wfile)) { 2637 if ((wfd = open(wfile, O_WRONLY|O_CREAT|O_TRUNC, 2638 0666)) == -1) { 2639 oerrno = errno; 2640 error("Cannot open %s: %s", 2641 wfile, strerror(errno)); 2642 errno = oerrno; 2643 r = SSH_ERR_SYSTEM_ERROR; 2644 goto out; 2645 } 2646 if (atomicio(vwrite, wfd, asig, 2647 strlen(asig)) != strlen(asig)) { 2648 oerrno = errno; 2649 error("Cannot write to %s: %s", 2650 wfile, strerror(errno)); 2651 errno = oerrno; 2652 r = SSH_ERR_SYSTEM_ERROR; 2653 goto out; 2654 } 2655 if (!quiet) { 2656 fprintf(stderr, "Write signature to %s\n", 2657 wfile); 2658 } 2659 } 2660 } 2661 /* success */ 2662 r = 0; 2663 out: 2664 free(wfile); 2665 free(prompt); 2666 free(asig); 2667 if (pin != NULL) 2668 freezero(pin, strlen(pin)); 2669 sshbuf_free(abuf); 2670 sshbuf_free(sigbuf); 2671 if (wfd != -1) 2672 close(wfd); 2673 return r; 2674 } 2675 2676 static int 2677 sig_process_opts(char * const *opts, size_t nopts, char **hashalgp, 2678 uint64_t *verify_timep, int *print_pubkey) 2679 { 2680 size_t i; 2681 time_t now; 2682 2683 if (verify_timep != NULL) 2684 *verify_timep = 0; 2685 if (print_pubkey != NULL) 2686 *print_pubkey = 0; 2687 if (hashalgp != NULL) 2688 *hashalgp = NULL; 2689 for (i = 0; i < nopts; i++) { 2690 if (hashalgp != NULL && 2691 strncasecmp(opts[i], "hashalg=", 8) == 0) { 2692 *hashalgp = xstrdup(opts[i] + 8); 2693 } else if (verify_timep && 2694 strncasecmp(opts[i], "verify-time=", 12) == 0) { 2695 if (parse_absolute_time(opts[i] + 12, 2696 verify_timep) != 0 || *verify_timep == 0) { 2697 error("Invalid \"verify-time\" option"); 2698 return SSH_ERR_INVALID_ARGUMENT; 2699 } 2700 } else if (print_pubkey && 2701 strcasecmp(opts[i], "print-pubkey") == 0) { 2702 *print_pubkey = 1; 2703 } else { 2704 error("Invalid option \"%s\"", opts[i]); 2705 return SSH_ERR_INVALID_ARGUMENT; 2706 } 2707 } 2708 if (verify_timep && *verify_timep == 0) { 2709 if ((now = time(NULL)) < 0) { 2710 error("Time is before epoch"); 2711 return SSH_ERR_INVALID_ARGUMENT; 2712 } 2713 *verify_timep = (uint64_t)now; 2714 } 2715 return 0; 2716 } 2717 2718 2719 static int 2720 sig_sign(const char *keypath, const char *sig_namespace, int require_agent, 2721 int argc, char **argv, char * const *opts, size_t nopts) 2722 { 2723 int i, fd = -1, r, ret = -1; 2724 int agent_fd = -1; 2725 struct sshkey *pubkey = NULL, *privkey = NULL, *signkey = NULL; 2726 sshsig_signer *signer = NULL; 2727 char *hashalg = NULL; 2728 2729 /* Check file arguments. */ 2730 for (i = 0; i < argc; i++) { 2731 if (strcmp(argv[i], "-") != 0) 2732 continue; 2733 if (i > 0 || argc > 1) 2734 fatal("Cannot sign mix of paths and standard input"); 2735 } 2736 2737 if (sig_process_opts(opts, nopts, &hashalg, NULL, NULL) != 0) 2738 goto done; /* error already logged */ 2739 2740 if ((r = sshkey_load_public(keypath, &pubkey, NULL)) != 0) { 2741 error_r(r, "Couldn't load public key %s", keypath); 2742 goto done; 2743 } 2744 2745 if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) { 2746 if (require_agent) 2747 fatal("Couldn't get agent socket"); 2748 debug_r(r, "Couldn't get agent socket"); 2749 } else { 2750 if ((r = ssh_agent_has_key(agent_fd, pubkey)) == 0) 2751 signer = agent_signer; 2752 else { 2753 if (require_agent) 2754 fatal("Couldn't find key in agent"); 2755 debug_r(r, "Couldn't find key in agent"); 2756 } 2757 } 2758 2759 if (signer == NULL) { 2760 /* Not using agent - try to load private key */ 2761 if ((privkey = load_sign_key(keypath, pubkey)) == NULL) 2762 goto done; 2763 signkey = privkey; 2764 } else { 2765 /* Will use key in agent */ 2766 signkey = pubkey; 2767 } 2768 2769 if (argc == 0) { 2770 if ((r = sign_one(signkey, "(stdin)", STDIN_FILENO, 2771 sig_namespace, hashalg, signer, &agent_fd)) != 0) 2772 goto done; 2773 } else { 2774 for (i = 0; i < argc; i++) { 2775 if (strcmp(argv[i], "-") == 0) 2776 fd = STDIN_FILENO; 2777 else if ((fd = open(argv[i], O_RDONLY)) == -1) { 2778 error("Cannot open %s for signing: %s", 2779 argv[i], strerror(errno)); 2780 goto done; 2781 } 2782 if ((r = sign_one(signkey, argv[i], fd, sig_namespace, 2783 hashalg, signer, &agent_fd)) != 0) 2784 goto done; 2785 if (fd != STDIN_FILENO) 2786 close(fd); 2787 fd = -1; 2788 } 2789 } 2790 2791 ret = 0; 2792 done: 2793 if (fd != -1 && fd != STDIN_FILENO) 2794 close(fd); 2795 sshkey_free(pubkey); 2796 sshkey_free(privkey); 2797 free(hashalg); 2798 return ret; 2799 } 2800 2801 static int 2802 sig_verify(const char *signature, const char *sig_namespace, 2803 const char *principal, const char *allowed_keys, const char *revoked_keys, 2804 char * const *opts, size_t nopts) 2805 { 2806 int r, ret = -1; 2807 int print_pubkey = 0; 2808 struct sshbuf *sigbuf = NULL, *abuf = NULL; 2809 struct sshkey *sign_key = NULL; 2810 char *fp = NULL; 2811 struct sshkey_sig_details *sig_details = NULL; 2812 uint64_t verify_time = 0; 2813 2814 if (sig_process_opts(opts, nopts, NULL, &verify_time, 2815 &print_pubkey) != 0) 2816 goto done; /* error already logged */ 2817 2818 memset(&sig_details, 0, sizeof(sig_details)); 2819 if ((r = sshbuf_load_file(signature, &abuf)) != 0) { 2820 error_r(r, "Couldn't read signature file"); 2821 goto done; 2822 } 2823 2824 if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) { 2825 error_fr(r, "sshsig_armor"); 2826 goto done; 2827 } 2828 if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace, 2829 &sign_key, &sig_details)) != 0) 2830 goto done; /* sshsig_verify() prints error */ 2831 2832 if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash, 2833 SSH_FP_DEFAULT)) == NULL) 2834 fatal_f("sshkey_fingerprint failed"); 2835 debug("Valid (unverified) signature from key %s", fp); 2836 if (sig_details != NULL) { 2837 debug2_f("signature details: counter = %u, flags = 0x%02x", 2838 sig_details->sk_counter, sig_details->sk_flags); 2839 } 2840 free(fp); 2841 fp = NULL; 2842 2843 if (revoked_keys != NULL) { 2844 if ((r = sshkey_check_revoked(sign_key, revoked_keys)) != 0) { 2845 debug3_fr(r, "sshkey_check_revoked"); 2846 goto done; 2847 } 2848 } 2849 2850 if (allowed_keys != NULL && (r = sshsig_check_allowed_keys(allowed_keys, 2851 sign_key, principal, sig_namespace, verify_time)) != 0) { 2852 debug3_fr(r, "sshsig_check_allowed_keys"); 2853 goto done; 2854 } 2855 /* success */ 2856 ret = 0; 2857 done: 2858 if (!quiet) { 2859 if (ret == 0) { 2860 if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash, 2861 SSH_FP_DEFAULT)) == NULL) 2862 fatal_f("sshkey_fingerprint failed"); 2863 if (principal == NULL) { 2864 printf("Good \"%s\" signature with %s key %s\n", 2865 sig_namespace, sshkey_type(sign_key), fp); 2866 2867 } else { 2868 printf("Good \"%s\" signature for %s with %s key %s\n", 2869 sig_namespace, principal, 2870 sshkey_type(sign_key), fp); 2871 } 2872 } else { 2873 printf("Could not verify signature.\n"); 2874 } 2875 } 2876 /* Print the signature key if requested */ 2877 if (ret == 0 && print_pubkey && sign_key != NULL) { 2878 if ((r = sshkey_write(sign_key, stdout)) == 0) 2879 fputc('\n', stdout); 2880 else { 2881 error_r(r, "Could not print public key.\n"); 2882 ret = -1; 2883 } 2884 } 2885 sshbuf_free(sigbuf); 2886 sshbuf_free(abuf); 2887 sshkey_free(sign_key); 2888 sshkey_sig_details_free(sig_details); 2889 free(fp); 2890 return ret; 2891 } 2892 2893 static int 2894 sig_find_principals(const char *signature, const char *allowed_keys, 2895 char * const *opts, size_t nopts) 2896 { 2897 int r, ret = -1; 2898 struct sshbuf *sigbuf = NULL, *abuf = NULL; 2899 struct sshkey *sign_key = NULL; 2900 char *principals = NULL, *cp, *tmp; 2901 uint64_t verify_time = 0; 2902 2903 if (sig_process_opts(opts, nopts, NULL, &verify_time, NULL) != 0) 2904 goto done; /* error already logged */ 2905 2906 if ((r = sshbuf_load_file(signature, &abuf)) != 0) { 2907 error_r(r, "Couldn't read signature file"); 2908 goto done; 2909 } 2910 if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) { 2911 error_fr(r, "sshsig_armor"); 2912 goto done; 2913 } 2914 if ((r = sshsig_get_pubkey(sigbuf, &sign_key)) != 0) { 2915 error_fr(r, "sshsig_get_pubkey"); 2916 goto done; 2917 } 2918 if ((r = sshsig_find_principals(allowed_keys, sign_key, 2919 verify_time, &principals)) != 0) { 2920 if (r != SSH_ERR_KEY_NOT_FOUND) 2921 error_fr(r, "sshsig_find_principal"); 2922 goto done; 2923 } 2924 ret = 0; 2925 done: 2926 if (ret == 0 ) { 2927 /* Emit matching principals one per line */ 2928 tmp = principals; 2929 while ((cp = strsep(&tmp, ",")) != NULL && *cp != '\0') 2930 puts(cp); 2931 } else { 2932 fprintf(stderr, "No principal matched.\n"); 2933 } 2934 sshbuf_free(sigbuf); 2935 sshbuf_free(abuf); 2936 sshkey_free(sign_key); 2937 free(principals); 2938 return ret; 2939 } 2940 2941 static int 2942 sig_match_principals(const char *allowed_keys, char *principal, 2943 char * const *opts, size_t nopts) 2944 { 2945 int r; 2946 char **principals = NULL; 2947 size_t i, nprincipals = 0; 2948 2949 if ((r = sig_process_opts(opts, nopts, NULL, NULL, NULL)) != 0) 2950 return r; /* error already logged */ 2951 2952 if ((r = sshsig_match_principals(allowed_keys, principal, 2953 &principals, &nprincipals)) != 0) { 2954 debug_f("match: %s", ssh_err(r)); 2955 fprintf(stderr, "No principal matched.\n"); 2956 return r; 2957 } 2958 for (i = 0; i < nprincipals; i++) { 2959 printf("%s\n", principals[i]); 2960 free(principals[i]); 2961 } 2962 free(principals); 2963 2964 return 0; 2965 } 2966 2967 static void 2968 do_moduli_gen(const char *out_file, char **opts, size_t nopts) 2969 { 2970 #ifdef WITH_OPENSSL 2971 /* Moduli generation/screening */ 2972 u_int32_t memory = 0; 2973 BIGNUM *start = NULL; 2974 int moduli_bits = 0; 2975 FILE *out; 2976 size_t i; 2977 const char *errstr; 2978 2979 /* Parse options */ 2980 for (i = 0; i < nopts; i++) { 2981 if (strncmp(opts[i], "memory=", 7) == 0) { 2982 memory = (u_int32_t)strtonum(opts[i]+7, 1, 2983 UINT_MAX, &errstr); 2984 if (errstr) { 2985 fatal("Memory limit is %s: %s", 2986 errstr, opts[i]+7); 2987 } 2988 } else if (strncmp(opts[i], "start=", 6) == 0) { 2989 /* XXX - also compare length against bits */ 2990 if (BN_hex2bn(&start, opts[i]+6) == 0) 2991 fatal("Invalid start point."); 2992 } else if (strncmp(opts[i], "bits=", 5) == 0) { 2993 moduli_bits = (int)strtonum(opts[i]+5, 1, 2994 INT_MAX, &errstr); 2995 if (errstr) { 2996 fatal("Invalid number: %s (%s)", 2997 opts[i]+12, errstr); 2998 } 2999 } else { 3000 fatal("Option \"%s\" is unsupported for moduli " 3001 "generation", opts[i]); 3002 } 3003 } 3004 3005 if ((out = fopen(out_file, "w")) == NULL) { 3006 fatal("Couldn't open modulus candidate file \"%s\": %s", 3007 out_file, strerror(errno)); 3008 } 3009 setvbuf(out, NULL, _IOLBF, 0); 3010 3011 if (moduli_bits == 0) 3012 moduli_bits = DEFAULT_BITS; 3013 if (gen_candidates(out, memory, moduli_bits, start) != 0) 3014 fatal("modulus candidate generation failed"); 3015 #else /* WITH_OPENSSL */ 3016 fatal("Moduli generation is not supported"); 3017 #endif /* WITH_OPENSSL */ 3018 } 3019 3020 static void 3021 do_moduli_screen(const char *out_file, char **opts, size_t nopts) 3022 { 3023 #ifdef WITH_OPENSSL 3024 /* Moduli generation/screening */ 3025 char *checkpoint = NULL; 3026 u_int32_t generator_wanted = 0; 3027 unsigned long start_lineno = 0, lines_to_process = 0; 3028 int prime_tests = 0; 3029 FILE *out, *in = stdin; 3030 size_t i; 3031 const char *errstr; 3032 3033 /* Parse options */ 3034 for (i = 0; i < nopts; i++) { 3035 if (strncmp(opts[i], "lines=", 6) == 0) { 3036 lines_to_process = strtoul(opts[i]+6, NULL, 10); 3037 } else if (strncmp(opts[i], "start-line=", 11) == 0) { 3038 start_lineno = strtoul(opts[i]+11, NULL, 10); 3039 } else if (strncmp(opts[i], "checkpoint=", 11) == 0) { 3040 free(checkpoint); 3041 checkpoint = xstrdup(opts[i]+11); 3042 } else if (strncmp(opts[i], "generator=", 10) == 0) { 3043 generator_wanted = (u_int32_t)strtonum( 3044 opts[i]+10, 1, UINT_MAX, &errstr); 3045 if (errstr != NULL) { 3046 fatal("Generator invalid: %s (%s)", 3047 opts[i]+10, errstr); 3048 } 3049 } else if (strncmp(opts[i], "prime-tests=", 12) == 0) { 3050 prime_tests = (int)strtonum(opts[i]+12, 1, 3051 INT_MAX, &errstr); 3052 if (errstr) { 3053 fatal("Invalid number: %s (%s)", 3054 opts[i]+12, errstr); 3055 } 3056 } else { 3057 fatal("Option \"%s\" is unsupported for moduli " 3058 "screening", opts[i]); 3059 } 3060 } 3061 3062 if (have_identity && strcmp(identity_file, "-") != 0) { 3063 if ((in = fopen(identity_file, "r")) == NULL) { 3064 fatal("Couldn't open modulus candidate " 3065 "file \"%s\": %s", identity_file, 3066 strerror(errno)); 3067 } 3068 } 3069 3070 if ((out = fopen(out_file, "a")) == NULL) { 3071 fatal("Couldn't open moduli file \"%s\": %s", 3072 out_file, strerror(errno)); 3073 } 3074 setvbuf(out, NULL, _IOLBF, 0); 3075 if (prime_test(in, out, prime_tests == 0 ? 100 : prime_tests, 3076 generator_wanted, checkpoint, 3077 start_lineno, lines_to_process) != 0) 3078 fatal("modulus screening failed"); 3079 if (in != stdin) 3080 (void)fclose(in); 3081 free(checkpoint); 3082 #else /* WITH_OPENSSL */ 3083 fatal("Moduli screening is not supported"); 3084 #endif /* WITH_OPENSSL */ 3085 } 3086 3087 /* Read and confirm a passphrase */ 3088 static char * 3089 read_check_passphrase(const char *prompt1, const char *prompt2, 3090 const char *retry_prompt) 3091 { 3092 char *passphrase1, *passphrase2; 3093 3094 for (;;) { 3095 passphrase1 = read_passphrase(prompt1, RP_ALLOW_STDIN); 3096 passphrase2 = read_passphrase(prompt2, RP_ALLOW_STDIN); 3097 if (strcmp(passphrase1, passphrase2) == 0) { 3098 freezero(passphrase2, strlen(passphrase2)); 3099 return passphrase1; 3100 } 3101 /* The passphrases do not match. Clear them and retry. */ 3102 freezero(passphrase1, strlen(passphrase1)); 3103 freezero(passphrase2, strlen(passphrase2)); 3104 fputs(retry_prompt, stdout); 3105 fputc('\n', stdout); 3106 fflush(stdout); 3107 } 3108 /* NOTREACHED */ 3109 return NULL; 3110 } 3111 3112 static char * 3113 private_key_passphrase(void) 3114 { 3115 if (identity_passphrase) 3116 return xstrdup(identity_passphrase); 3117 if (identity_new_passphrase) 3118 return xstrdup(identity_new_passphrase); 3119 3120 return read_check_passphrase( 3121 "Enter passphrase (empty for no passphrase): ", 3122 "Enter same passphrase again: ", 3123 "Passphrases do not match. Try again."); 3124 } 3125 3126 static char * 3127 sk_suffix(const char *application, const uint8_t *user, size_t userlen) 3128 { 3129 char *ret, *cp; 3130 size_t slen, i; 3131 3132 /* Trim off URL-like preamble */ 3133 if (strncmp(application, "ssh://", 6) == 0) 3134 ret = xstrdup(application + 6); 3135 else if (strncmp(application, "ssh:", 4) == 0) 3136 ret = xstrdup(application + 4); 3137 else 3138 ret = xstrdup(application); 3139 3140 /* Count trailing zeros in user */ 3141 for (i = 0; i < userlen; i++) { 3142 if (user[userlen - i - 1] != 0) 3143 break; 3144 } 3145 if (i >= userlen) 3146 return ret; /* user-id was default all-zeros */ 3147 3148 /* Append user-id, escaping non-UTF-8 characters */ 3149 slen = userlen - i; 3150 if (asmprintf(&cp, INT_MAX, NULL, "%.*s", (int)slen, user) == -1) 3151 fatal_f("asmprintf failed"); 3152 /* Don't emit a user-id that contains path or control characters */ 3153 if (strchr(cp, '/') != NULL || strstr(cp, "..") != NULL || 3154 strchr(cp, '\\') != NULL) { 3155 free(cp); 3156 cp = tohex(user, slen); 3157 } 3158 xextendf(&ret, "_", "%s", cp); 3159 free(cp); 3160 return ret; 3161 } 3162 3163 static int 3164 do_download_sk(const char *skprovider, const char *device) 3165 { 3166 struct sshsk_resident_key **srks; 3167 size_t nsrks, i; 3168 int r, ret = -1; 3169 char *fp, *pin = NULL, *pass = NULL, *path, *pubpath; 3170 const char *ext; 3171 struct sshkey *key; 3172 3173 if (skprovider == NULL) 3174 fatal("Cannot download keys without provider"); 3175 3176 pin = read_passphrase("Enter PIN for authenticator: ", RP_ALLOW_STDIN); 3177 if (!quiet) { 3178 printf("You may need to touch your authenticator " 3179 "to authorize key download.\n"); 3180 } 3181 if ((r = sshsk_load_resident(skprovider, device, pin, 0, 3182 &srks, &nsrks)) != 0) { 3183 if (pin != NULL) 3184 freezero(pin, strlen(pin)); 3185 error_r(r, "Unable to load resident keys"); 3186 return -1; 3187 } 3188 if (nsrks == 0) 3189 logit("No keys to download"); 3190 if (pin != NULL) 3191 freezero(pin, strlen(pin)); 3192 3193 for (i = 0; i < nsrks; i++) { 3194 key = srks[i]->key; 3195 if (key->type != KEY_ECDSA_SK && key->type != KEY_ED25519_SK) { 3196 error("Unsupported key type %s (%d)", 3197 sshkey_type(key), key->type); 3198 continue; 3199 } 3200 if ((fp = sshkey_fingerprint(key, fingerprint_hash, 3201 SSH_FP_DEFAULT)) == NULL) 3202 fatal_f("sshkey_fingerprint failed"); 3203 debug_f("key %zu: %s %s %s (flags 0x%02x)", i, 3204 sshkey_type(key), fp, key->sk_application, key->sk_flags); 3205 ext = sk_suffix(key->sk_application, 3206 srks[i]->user_id, srks[i]->user_id_len); 3207 xasprintf(&path, "id_%s_rk%s%s", 3208 key->type == KEY_ECDSA_SK ? "ecdsa_sk" : "ed25519_sk", 3209 *ext == '\0' ? "" : "_", ext); 3210 3211 /* If the file already exists, ask the user to confirm. */ 3212 if (!confirm_overwrite(path)) { 3213 free(path); 3214 break; 3215 } 3216 3217 /* Save the key with the application string as the comment */ 3218 if (pass == NULL) 3219 pass = private_key_passphrase(); 3220 if ((r = sshkey_save_private(key, path, pass, 3221 key->sk_application, private_key_format, 3222 openssh_format_cipher, rounds)) != 0) { 3223 error_r(r, "Saving key \"%s\" failed", path); 3224 free(path); 3225 break; 3226 } 3227 if (!quiet) { 3228 printf("Saved %s key%s%s to %s\n", sshkey_type(key), 3229 *ext != '\0' ? " " : "", 3230 *ext != '\0' ? key->sk_application : "", 3231 path); 3232 } 3233 3234 /* Save public key too */ 3235 xasprintf(&pubpath, "%s.pub", path); 3236 free(path); 3237 if ((r = sshkey_save_public(key, pubpath, 3238 key->sk_application)) != 0) { 3239 error_r(r, "Saving public key \"%s\" failed", pubpath); 3240 free(pubpath); 3241 break; 3242 } 3243 free(pubpath); 3244 } 3245 3246 if (i >= nsrks) 3247 ret = 0; /* success */ 3248 if (pass != NULL) 3249 freezero(pass, strlen(pass)); 3250 sshsk_free_resident_keys(srks, nsrks); 3251 return ret; 3252 } 3253 3254 static void 3255 save_attestation(struct sshbuf *attest, const char *path) 3256 { 3257 mode_t omask; 3258 int r; 3259 3260 if (path == NULL) 3261 return; /* nothing to do */ 3262 if (attest == NULL || sshbuf_len(attest) == 0) 3263 fatal("Enrollment did not return attestation data"); 3264 omask = umask(077); 3265 r = sshbuf_write_file(path, attest); 3266 umask(omask); 3267 if (r != 0) 3268 fatal_r(r, "Unable to write attestation data \"%s\"", path); 3269 if (!quiet) 3270 printf("Your FIDO attestation certificate has been saved in " 3271 "%s\n", path); 3272 } 3273 3274 static int 3275 confirm_sk_overwrite(const char *application, const char *user) 3276 { 3277 char yesno[3]; 3278 3279 printf("A resident key scoped to '%s' with user id '%s' already " 3280 "exists.\n", application == NULL ? "ssh:" : application, 3281 user == NULL ? "null" : user); 3282 printf("Overwrite key in token (y/n)? "); 3283 fflush(stdout); 3284 if (fgets(yesno, sizeof(yesno), stdin) == NULL) 3285 return 0; 3286 if (yesno[0] != 'y' && yesno[0] != 'Y') 3287 return 0; 3288 return 1; 3289 } 3290 3291 static void 3292 usage(void) 3293 { 3294 fprintf(stderr, 3295 "usage: ssh-keygen [-q] [-a rounds] [-b bits] [-C comment] [-f output_keyfile]\n" 3296 " [-m format] [-N new_passphrase] [-O option]\n" 3297 " [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n" 3298 " [-w provider] [-Z cipher]\n" 3299 " ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase]\n" 3300 " [-P old_passphrase] [-Z cipher]\n" 3301 #ifdef WITH_OPENSSL 3302 " ssh-keygen -i [-f input_keyfile] [-m key_format]\n" 3303 " ssh-keygen -e [-f input_keyfile] [-m key_format]\n" 3304 #endif 3305 " ssh-keygen -y [-f input_keyfile]\n" 3306 " ssh-keygen -c [-a rounds] [-C comment] [-f keyfile] [-P passphrase]\n" 3307 " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n" 3308 " ssh-keygen -B [-f input_keyfile]\n"); 3309 #ifdef ENABLE_PKCS11 3310 fprintf(stderr, 3311 " ssh-keygen -D pkcs11\n"); 3312 #endif 3313 fprintf(stderr, 3314 " ssh-keygen -F hostname [-lv] [-f known_hosts_file]\n" 3315 " ssh-keygen -H [-f known_hosts_file]\n" 3316 " ssh-keygen -K [-a rounds] [-w provider]\n" 3317 " ssh-keygen -R hostname [-f known_hosts_file]\n" 3318 " ssh-keygen -r hostname [-g] [-f input_keyfile]\n" 3319 #ifdef WITH_OPENSSL 3320 " ssh-keygen -M generate [-O option] output_file\n" 3321 " ssh-keygen -M screen [-f input_file] [-O option] output_file\n" 3322 #endif 3323 " ssh-keygen -I certificate_identity -s ca_key [-hU] [-D pkcs11_provider]\n" 3324 " [-n principals] [-O option] [-V validity_interval]\n" 3325 " [-z serial_number] file ...\n" 3326 " ssh-keygen -L [-f input_keyfile]\n" 3327 " ssh-keygen -A [-a rounds] [-f prefix_path]\n" 3328 " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n" 3329 " file ...\n" 3330 " ssh-keygen -Q [-l] -f krl_file [file ...]\n" 3331 " ssh-keygen -Y find-principals -s signature_file -f allowed_signers_file\n" 3332 " ssh-keygen -Y match-principals -I signer_identity -f allowed_signers_file\n" 3333 " ssh-keygen -Y check-novalidate -n namespace -s signature_file\n" 3334 " ssh-keygen -Y sign -f key_file -n namespace file [-O option] ...\n" 3335 " ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n" 3336 " -n namespace -s signature_file [-r krl_file] [-O option]\n"); 3337 exit(1); 3338 } 3339 3340 /* 3341 * Main program for key management. 3342 */ 3343 int 3344 main(int argc, char **argv) 3345 { 3346 char comment[1024], *passphrase = NULL; 3347 char *rr_hostname = NULL, *ep, *fp, *ra; 3348 struct sshkey *private, *public; 3349 struct passwd *pw; 3350 int r, opt, type; 3351 int change_passphrase = 0, change_comment = 0, show_cert = 0; 3352 int find_host = 0, delete_host = 0, hash_hosts = 0; 3353 int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; 3354 int prefer_agent = 0, convert_to = 0, convert_from = 0; 3355 int print_public = 0, print_generic = 0, cert_serial_autoinc = 0; 3356 int do_gen_candidates = 0, do_screen_candidates = 0, download_sk = 0; 3357 unsigned long long cert_serial = 0; 3358 char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL; 3359 char *sk_application = NULL, *sk_device = NULL, *sk_user = NULL; 3360 char *sk_attestation_path = NULL; 3361 struct sshbuf *challenge = NULL, *attest = NULL; 3362 size_t i, nopts = 0; 3363 u_int32_t bits = 0; 3364 uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD; 3365 const char *errstr; 3366 int log_level = SYSLOG_LEVEL_INFO; 3367 char *sign_op = NULL; 3368 3369 extern int optind; 3370 extern char *optarg; 3371 3372 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 3373 sanitise_stdfd(); 3374 3375 #ifdef WITH_OPENSSL 3376 OpenSSL_add_all_algorithms(); 3377 #endif 3378 log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); 3379 3380 setlocale(LC_CTYPE, ""); 3381 3382 /* we need this for the home * directory. */ 3383 pw = getpwuid(getuid()); 3384 if (!pw) 3385 fatal("No user exists for uid %lu", (u_long)getuid()); 3386 pw = pwcopy(pw); 3387 if (gethostname(hostname, sizeof(hostname)) == -1) 3388 fatal("gethostname: %s", strerror(errno)); 3389 3390 sk_provider = getenv("SSH_SK_PROVIDER"); 3391 3392 /* Remaining characters: dGjJSTWx */ 3393 while ((opt = getopt(argc, argv, "ABHKLQUXceghiklopquvy" 3394 "C:D:E:F:I:M:N:O:P:R:V:Y:Z:" 3395 "a:b:f:g:m:n:r:s:t:w:z:")) != -1) { 3396 switch (opt) { 3397 case 'A': 3398 gen_all_hostkeys = 1; 3399 break; 3400 case 'b': 3401 bits = (u_int32_t)strtonum(optarg, 1, UINT32_MAX, 3402 &errstr); 3403 if (errstr) 3404 fatal("Bits has bad value %s (%s)", 3405 optarg, errstr); 3406 break; 3407 case 'E': 3408 fingerprint_hash = ssh_digest_alg_by_name(optarg); 3409 if (fingerprint_hash == -1) 3410 fatal("Invalid hash algorithm \"%s\"", optarg); 3411 break; 3412 case 'F': 3413 find_host = 1; 3414 rr_hostname = optarg; 3415 break; 3416 case 'H': 3417 hash_hosts = 1; 3418 break; 3419 case 'I': 3420 cert_key_id = optarg; 3421 break; 3422 case 'R': 3423 delete_host = 1; 3424 rr_hostname = optarg; 3425 break; 3426 case 'L': 3427 show_cert = 1; 3428 break; 3429 case 'l': 3430 print_fingerprint = 1; 3431 break; 3432 case 'B': 3433 print_bubblebabble = 1; 3434 break; 3435 case 'm': 3436 if (strcasecmp(optarg, "RFC4716") == 0 || 3437 strcasecmp(optarg, "ssh2") == 0) { 3438 convert_format = FMT_RFC4716; 3439 break; 3440 } 3441 if (strcasecmp(optarg, "PKCS8") == 0) { 3442 convert_format = FMT_PKCS8; 3443 private_key_format = SSHKEY_PRIVATE_PKCS8; 3444 break; 3445 } 3446 if (strcasecmp(optarg, "PEM") == 0) { 3447 convert_format = FMT_PEM; 3448 private_key_format = SSHKEY_PRIVATE_PEM; 3449 break; 3450 } 3451 fatal("Unsupported conversion format \"%s\"", optarg); 3452 case 'n': 3453 cert_principals = optarg; 3454 break; 3455 case 'o': 3456 /* no-op; new format is already the default */ 3457 break; 3458 case 'p': 3459 change_passphrase = 1; 3460 break; 3461 case 'c': 3462 change_comment = 1; 3463 break; 3464 case 'f': 3465 if (strlcpy(identity_file, optarg, 3466 sizeof(identity_file)) >= sizeof(identity_file)) 3467 fatal("Identity filename too long"); 3468 have_identity = 1; 3469 break; 3470 case 'g': 3471 print_generic = 1; 3472 break; 3473 case 'K': 3474 download_sk = 1; 3475 break; 3476 case 'P': 3477 identity_passphrase = optarg; 3478 break; 3479 case 'N': 3480 identity_new_passphrase = optarg; 3481 break; 3482 case 'Q': 3483 check_krl = 1; 3484 break; 3485 case 'O': 3486 opts = xrecallocarray(opts, nopts, nopts + 1, 3487 sizeof(*opts)); 3488 opts[nopts++] = xstrdup(optarg); 3489 break; 3490 case 'Z': 3491 openssh_format_cipher = optarg; 3492 if (cipher_by_name(openssh_format_cipher) == NULL) 3493 fatal("Invalid OpenSSH-format cipher '%s'", 3494 openssh_format_cipher); 3495 break; 3496 case 'C': 3497 identity_comment = optarg; 3498 break; 3499 case 'q': 3500 quiet = 1; 3501 break; 3502 case 'e': 3503 /* export key */ 3504 convert_to = 1; 3505 break; 3506 case 'h': 3507 cert_key_type = SSH2_CERT_TYPE_HOST; 3508 certflags_flags = 0; 3509 break; 3510 case 'k': 3511 gen_krl = 1; 3512 break; 3513 case 'i': 3514 case 'X': 3515 /* import key */ 3516 convert_from = 1; 3517 break; 3518 case 'y': 3519 print_public = 1; 3520 break; 3521 case 's': 3522 ca_key_path = optarg; 3523 break; 3524 case 't': 3525 key_type_name = optarg; 3526 break; 3527 case 'D': 3528 pkcs11provider = optarg; 3529 break; 3530 case 'U': 3531 prefer_agent = 1; 3532 break; 3533 case 'u': 3534 update_krl = 1; 3535 break; 3536 case 'v': 3537 if (log_level == SYSLOG_LEVEL_INFO) 3538 log_level = SYSLOG_LEVEL_DEBUG1; 3539 else { 3540 if (log_level >= SYSLOG_LEVEL_DEBUG1 && 3541 log_level < SYSLOG_LEVEL_DEBUG3) 3542 log_level++; 3543 } 3544 break; 3545 case 'r': 3546 rr_hostname = optarg; 3547 break; 3548 case 'a': 3549 rounds = (int)strtonum(optarg, 1, INT_MAX, &errstr); 3550 if (errstr) 3551 fatal("Invalid number: %s (%s)", 3552 optarg, errstr); 3553 break; 3554 case 'V': 3555 parse_cert_times(optarg); 3556 break; 3557 case 'Y': 3558 sign_op = optarg; 3559 break; 3560 case 'w': 3561 sk_provider = optarg; 3562 break; 3563 case 'z': 3564 errno = 0; 3565 if (*optarg == '+') { 3566 cert_serial_autoinc = 1; 3567 optarg++; 3568 } 3569 cert_serial = strtoull(optarg, &ep, 10); 3570 if (*optarg < '0' || *optarg > '9' || *ep != '\0' || 3571 (errno == ERANGE && cert_serial == ULLONG_MAX)) 3572 fatal("Invalid serial number \"%s\"", optarg); 3573 break; 3574 case 'M': 3575 if (strcmp(optarg, "generate") == 0) 3576 do_gen_candidates = 1; 3577 else if (strcmp(optarg, "screen") == 0) 3578 do_screen_candidates = 1; 3579 else 3580 fatal("Unsupported moduli option %s", optarg); 3581 break; 3582 default: 3583 usage(); 3584 } 3585 } 3586 3587 if (sk_provider == NULL) 3588 sk_provider = "internal"; 3589 3590 /* reinit */ 3591 log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1); 3592 3593 argv += optind; 3594 argc -= optind; 3595 3596 if (sign_op != NULL) { 3597 if (strncmp(sign_op, "find-principals", 15) == 0) { 3598 if (ca_key_path == NULL) { 3599 error("Too few arguments for find-principals:" 3600 "missing signature file"); 3601 exit(1); 3602 } 3603 if (!have_identity) { 3604 error("Too few arguments for find-principals:" 3605 "missing allowed keys file"); 3606 exit(1); 3607 } 3608 return sig_find_principals(ca_key_path, identity_file, 3609 opts, nopts); 3610 } else if (strncmp(sign_op, "match-principals", 16) == 0) { 3611 if (!have_identity) { 3612 error("Too few arguments for match-principals:" 3613 "missing allowed keys file"); 3614 exit(1); 3615 } 3616 if (cert_key_id == NULL) { 3617 error("Too few arguments for match-principals: " 3618 "missing principal ID"); 3619 exit(1); 3620 } 3621 return sig_match_principals(identity_file, cert_key_id, 3622 opts, nopts); 3623 } else if (strncmp(sign_op, "sign", 4) == 0) { 3624 /* NB. cert_principals is actually namespace, via -n */ 3625 if (cert_principals == NULL || 3626 *cert_principals == '\0') { 3627 error("Too few arguments for sign: " 3628 "missing namespace"); 3629 exit(1); 3630 } 3631 if (!have_identity) { 3632 error("Too few arguments for sign: " 3633 "missing key"); 3634 exit(1); 3635 } 3636 return sig_sign(identity_file, cert_principals, 3637 prefer_agent, argc, argv, opts, nopts); 3638 } else if (strncmp(sign_op, "check-novalidate", 16) == 0) { 3639 /* NB. cert_principals is actually namespace, via -n */ 3640 if (cert_principals == NULL || 3641 *cert_principals == '\0') { 3642 error("Too few arguments for check-novalidate: " 3643 "missing namespace"); 3644 exit(1); 3645 } 3646 if (ca_key_path == NULL) { 3647 error("Too few arguments for check-novalidate: " 3648 "missing signature file"); 3649 exit(1); 3650 } 3651 return sig_verify(ca_key_path, cert_principals, 3652 NULL, NULL, NULL, opts, nopts); 3653 } else if (strncmp(sign_op, "verify", 6) == 0) { 3654 /* NB. cert_principals is actually namespace, via -n */ 3655 if (cert_principals == NULL || 3656 *cert_principals == '\0') { 3657 error("Too few arguments for verify: " 3658 "missing namespace"); 3659 exit(1); 3660 } 3661 if (ca_key_path == NULL) { 3662 error("Too few arguments for verify: " 3663 "missing signature file"); 3664 exit(1); 3665 } 3666 if (!have_identity) { 3667 error("Too few arguments for sign: " 3668 "missing allowed keys file"); 3669 exit(1); 3670 } 3671 if (cert_key_id == NULL) { 3672 error("Too few arguments for verify: " 3673 "missing principal identity"); 3674 exit(1); 3675 } 3676 return sig_verify(ca_key_path, cert_principals, 3677 cert_key_id, identity_file, rr_hostname, 3678 opts, nopts); 3679 } 3680 error("Unsupported operation for -Y: \"%s\"", sign_op); 3681 usage(); 3682 /* NOTREACHED */ 3683 } 3684 3685 if (ca_key_path != NULL) { 3686 if (argc < 1 && !gen_krl) { 3687 error("Too few arguments."); 3688 usage(); 3689 } 3690 } else if (argc > 0 && !gen_krl && !check_krl && 3691 !do_gen_candidates && !do_screen_candidates) { 3692 error("Too many arguments."); 3693 usage(); 3694 } 3695 if (change_passphrase && change_comment) { 3696 error("Can only have one of -p and -c."); 3697 usage(); 3698 } 3699 if (print_fingerprint && (delete_host || hash_hosts)) { 3700 error("Cannot use -l with -H or -R."); 3701 usage(); 3702 } 3703 if (gen_krl) { 3704 do_gen_krl(pw, update_krl, ca_key_path, 3705 cert_serial, identity_comment, argc, argv); 3706 return (0); 3707 } 3708 if (check_krl) { 3709 do_check_krl(pw, print_fingerprint, argc, argv); 3710 return (0); 3711 } 3712 if (ca_key_path != NULL) { 3713 if (cert_key_id == NULL) 3714 fatal("Must specify key id (-I) when certifying"); 3715 for (i = 0; i < nopts; i++) 3716 add_cert_option(opts[i]); 3717 do_ca_sign(pw, ca_key_path, prefer_agent, 3718 cert_serial, cert_serial_autoinc, argc, argv); 3719 } 3720 if (show_cert) 3721 do_show_cert(pw); 3722 if (delete_host || hash_hosts || find_host) { 3723 do_known_hosts(pw, rr_hostname, find_host, 3724 delete_host, hash_hosts); 3725 } 3726 if (pkcs11provider != NULL) 3727 do_download(pw); 3728 if (download_sk) { 3729 for (i = 0; i < nopts; i++) { 3730 if (strncasecmp(opts[i], "device=", 7) == 0) { 3731 sk_device = xstrdup(opts[i] + 7); 3732 } else { 3733 fatal("Option \"%s\" is unsupported for " 3734 "FIDO authenticator download", opts[i]); 3735 } 3736 } 3737 return do_download_sk(sk_provider, sk_device); 3738 } 3739 if (print_fingerprint || print_bubblebabble) 3740 do_fingerprint(pw); 3741 if (change_passphrase) 3742 do_change_passphrase(pw); 3743 if (change_comment) 3744 do_change_comment(pw, identity_comment); 3745 #ifdef WITH_OPENSSL 3746 if (convert_to) 3747 do_convert_to(pw); 3748 if (convert_from) 3749 do_convert_from(pw); 3750 #else /* WITH_OPENSSL */ 3751 if (convert_to || convert_from) 3752 fatal("key conversion disabled at compile time"); 3753 #endif /* WITH_OPENSSL */ 3754 if (print_public) 3755 do_print_public(pw); 3756 if (rr_hostname != NULL) { 3757 unsigned int n = 0; 3758 3759 if (have_identity) { 3760 n = do_print_resource_record(pw, identity_file, 3761 rr_hostname, print_generic, opts, nopts); 3762 if (n == 0) 3763 fatal("%s: %s", identity_file, strerror(errno)); 3764 exit(0); 3765 } else { 3766 3767 n += do_print_resource_record(pw, 3768 _PATH_HOST_RSA_KEY_FILE, rr_hostname, 3769 print_generic, opts, nopts); 3770 #ifdef WITH_DSA 3771 n += do_print_resource_record(pw, 3772 _PATH_HOST_DSA_KEY_FILE, rr_hostname, 3773 print_generic, opts, nopts); 3774 #endif 3775 n += do_print_resource_record(pw, 3776 _PATH_HOST_ECDSA_KEY_FILE, rr_hostname, 3777 print_generic, opts, nopts); 3778 n += do_print_resource_record(pw, 3779 _PATH_HOST_ED25519_KEY_FILE, rr_hostname, 3780 print_generic, opts, nopts); 3781 n += do_print_resource_record(pw, 3782 _PATH_HOST_XMSS_KEY_FILE, rr_hostname, 3783 print_generic, opts, nopts); 3784 if (n == 0) 3785 fatal("no keys found."); 3786 exit(0); 3787 } 3788 } 3789 3790 if (do_gen_candidates || do_screen_candidates) { 3791 if (argc <= 0) 3792 fatal("No output file specified"); 3793 else if (argc > 1) 3794 fatal("Too many output files specified"); 3795 } 3796 if (do_gen_candidates) { 3797 do_moduli_gen(argv[0], opts, nopts); 3798 return 0; 3799 } 3800 if (do_screen_candidates) { 3801 do_moduli_screen(argv[0], opts, nopts); 3802 return 0; 3803 } 3804 3805 if (gen_all_hostkeys) { 3806 do_gen_all_hostkeys(pw); 3807 return (0); 3808 } 3809 3810 if (key_type_name == NULL) 3811 key_type_name = DEFAULT_KEY_TYPE_NAME; 3812 3813 type = sshkey_type_from_shortname(key_type_name); 3814 type_bits_valid(type, key_type_name, &bits); 3815 3816 if (!quiet) 3817 printf("Generating public/private %s key pair.\n", 3818 key_type_name); 3819 switch (type) { 3820 case KEY_ECDSA_SK: 3821 case KEY_ED25519_SK: 3822 for (i = 0; i < nopts; i++) { 3823 if (strcasecmp(opts[i], "no-touch-required") == 0) { 3824 sk_flags &= ~SSH_SK_USER_PRESENCE_REQD; 3825 } else if (strcasecmp(opts[i], "verify-required") == 0) { 3826 sk_flags |= SSH_SK_USER_VERIFICATION_REQD; 3827 } else if (strcasecmp(opts[i], "resident") == 0) { 3828 sk_flags |= SSH_SK_RESIDENT_KEY; 3829 } else if (strncasecmp(opts[i], "device=", 7) == 0) { 3830 sk_device = xstrdup(opts[i] + 7); 3831 } else if (strncasecmp(opts[i], "user=", 5) == 0) { 3832 sk_user = xstrdup(opts[i] + 5); 3833 } else if (strncasecmp(opts[i], "challenge=", 10) == 0) { 3834 if ((r = sshbuf_load_file(opts[i] + 10, 3835 &challenge)) != 0) { 3836 fatal_r(r, "Unable to load FIDO " 3837 "enrollment challenge \"%s\"", 3838 opts[i] + 10); 3839 } 3840 } else if (strncasecmp(opts[i], 3841 "write-attestation=", 18) == 0) { 3842 sk_attestation_path = opts[i] + 18; 3843 } else if (strncasecmp(opts[i], 3844 "application=", 12) == 0) { 3845 sk_application = xstrdup(opts[i] + 12); 3846 if (strncmp(sk_application, "ssh:", 4) != 0) { 3847 fatal("FIDO application string must " 3848 "begin with \"ssh:\""); 3849 } 3850 } else { 3851 fatal("Option \"%s\" is unsupported for " 3852 "FIDO authenticator enrollment", opts[i]); 3853 } 3854 } 3855 if ((attest = sshbuf_new()) == NULL) 3856 fatal("sshbuf_new failed"); 3857 r = 0; 3858 for (i = 0 ;;) { 3859 if (!quiet) { 3860 printf("You may need to touch your " 3861 "authenticator%s to authorize key " 3862 "generation.\n", 3863 r == 0 ? "" : " again"); 3864 } 3865 fflush(stdout); 3866 r = sshsk_enroll(type, sk_provider, sk_device, 3867 sk_application == NULL ? "ssh:" : sk_application, 3868 sk_user, sk_flags, passphrase, challenge, 3869 &private, attest); 3870 if (r == 0) 3871 break; 3872 if (r == SSH_ERR_KEY_BAD_PERMISSIONS && 3873 (sk_flags & SSH_SK_RESIDENT_KEY) != 0 && 3874 (sk_flags & SSH_SK_FORCE_OPERATION) == 0 && 3875 confirm_sk_overwrite(sk_application, sk_user)) { 3876 sk_flags |= SSH_SK_FORCE_OPERATION; 3877 continue; 3878 } 3879 if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) 3880 fatal_r(r, "Key enrollment failed"); 3881 else if (passphrase != NULL) { 3882 error("PIN incorrect"); 3883 freezero(passphrase, strlen(passphrase)); 3884 passphrase = NULL; 3885 } 3886 if (++i >= 3) 3887 fatal("Too many incorrect PINs"); 3888 passphrase = read_passphrase("Enter PIN for " 3889 "authenticator: ", RP_ALLOW_STDIN); 3890 } 3891 if (passphrase != NULL) { 3892 freezero(passphrase, strlen(passphrase)); 3893 passphrase = NULL; 3894 } 3895 break; 3896 default: 3897 if ((r = sshkey_generate(type, bits, &private)) != 0) 3898 fatal("sshkey_generate failed"); 3899 break; 3900 } 3901 if ((r = sshkey_from_private(private, &public)) != 0) 3902 fatal_r(r, "sshkey_from_private"); 3903 3904 if (!have_identity) 3905 ask_filename(pw, "Enter file in which to save the key"); 3906 3907 /* Create ~/.ssh directory if it doesn't already exist. */ 3908 hostfile_create_user_ssh_dir(identity_file, !quiet); 3909 3910 /* If the file already exists, ask the user to confirm. */ 3911 if (!confirm_overwrite(identity_file)) 3912 exit(1); 3913 3914 /* Determine the passphrase for the private key */ 3915 passphrase = private_key_passphrase(); 3916 if (identity_comment) { 3917 strlcpy(comment, identity_comment, sizeof(comment)); 3918 } else { 3919 /* Create default comment field for the passphrase. */ 3920 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); 3921 } 3922 3923 /* Save the key with the given passphrase and comment. */ 3924 if ((r = sshkey_save_private(private, identity_file, passphrase, 3925 comment, private_key_format, openssh_format_cipher, rounds)) != 0) { 3926 error_r(r, "Saving key \"%s\" failed", identity_file); 3927 freezero(passphrase, strlen(passphrase)); 3928 exit(1); 3929 } 3930 freezero(passphrase, strlen(passphrase)); 3931 sshkey_free(private); 3932 3933 if (!quiet) { 3934 printf("Your identification has been saved in %s\n", 3935 identity_file); 3936 } 3937 3938 strlcat(identity_file, ".pub", sizeof(identity_file)); 3939 if ((r = sshkey_save_public(public, identity_file, comment)) != 0) 3940 fatal_r(r, "Unable to save public key to %s", identity_file); 3941 3942 if (!quiet) { 3943 fp = sshkey_fingerprint(public, fingerprint_hash, 3944 SSH_FP_DEFAULT); 3945 ra = sshkey_fingerprint(public, fingerprint_hash, 3946 SSH_FP_RANDOMART); 3947 if (fp == NULL || ra == NULL) 3948 fatal("sshkey_fingerprint failed"); 3949 printf("Your public key has been saved in %s\n", 3950 identity_file); 3951 printf("The key fingerprint is:\n"); 3952 printf("%s %s\n", fp, comment); 3953 printf("The key's randomart image is:\n"); 3954 printf("%s\n", ra); 3955 free(ra); 3956 free(fp); 3957 } 3958 3959 if (sk_attestation_path != NULL) 3960 save_attestation(attest, sk_attestation_path); 3961 3962 sshbuf_free(attest); 3963 sshkey_free(public); 3964 3965 exit(0); 3966 } 3967