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