[BACK]Return to ssh-keygen.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/ssh-keygen.c between version 1.453 and 1.472

version 1.453, 2022/05/31 14:05:12 version 1.472, 2024/01/11 01:45:36
Line 61 
Line 61 
 #include "ssh-pkcs11.h"  #include "ssh-pkcs11.h"
 #endif  #endif
   
 #ifdef WITH_OPENSSL  #define DEFAULT_KEY_TYPE_NAME "ed25519"
 # define DEFAULT_KEY_TYPE_NAME "rsa"  
 #else  
 # define DEFAULT_KEY_TYPE_NAME "ed25519"  
 #endif  
   
 /*  /*
  * Default number of bits in the RSA, DSA and ECDSA keys.  These value can be   * Default number of bits in the RSA, DSA and ECDSA keys.  These value can be
Line 252 
Line 248 
         char *name = NULL;          char *name = NULL;
   
         if (key_type_name == NULL)          if (key_type_name == NULL)
                 name = _PATH_SSH_CLIENT_ID_RSA;                  name = _PATH_SSH_CLIENT_ID_ED25519;
         else {          else {
                 switch (sshkey_type_from_name(key_type_name)) {                  switch (sshkey_type_from_name(key_type_name)) {
   #ifdef WITH_DSA
                 case KEY_DSA_CERT:                  case KEY_DSA_CERT:
                 case KEY_DSA:                  case KEY_DSA:
                         name = _PATH_SSH_CLIENT_ID_DSA;                          name = _PATH_SSH_CLIENT_ID_DSA;
                         break;                          break;
   #endif
                 case KEY_ECDSA_CERT:                  case KEY_ECDSA_CERT:
                 case KEY_ECDSA:                  case KEY_ECDSA:
                         name = _PATH_SSH_CLIENT_ID_ECDSA;                          name = _PATH_SSH_CLIENT_ID_ECDSA;
Line 367 
Line 365 
                 if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))                  if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))
                         fatal("PEM_write_RSA_PUBKEY failed");                          fatal("PEM_write_RSA_PUBKEY failed");
                 break;                  break;
   #ifdef WITH_DSA
         case KEY_DSA:          case KEY_DSA:
                 if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))                  if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
                         fatal("PEM_write_DSA_PUBKEY failed");                          fatal("PEM_write_DSA_PUBKEY failed");
                 break;                  break;
   #endif
         case KEY_ECDSA:          case KEY_ECDSA:
                 if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))                  if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
                         fatal("PEM_write_EC_PUBKEY failed");                          fatal("PEM_write_EC_PUBKEY failed");
Line 389 
Line 389 
                 if (!PEM_write_RSAPublicKey(stdout, k->rsa))                  if (!PEM_write_RSAPublicKey(stdout, k->rsa))
                         fatal("PEM_write_RSAPublicKey failed");                          fatal("PEM_write_RSAPublicKey failed");
                 break;                  break;
   #ifdef WITH_DSA
         case KEY_DSA:          case KEY_DSA:
                 if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))                  if (!PEM_write_DSA_PUBKEY(stdout, k->dsa))
                         fatal("PEM_write_DSA_PUBKEY failed");                          fatal("PEM_write_DSA_PUBKEY failed");
                 break;                  break;
   #endif
         case KEY_ECDSA:          case KEY_ECDSA:
                 if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))                  if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa))
                         fatal("PEM_write_EC_PUBKEY failed");                          fatal("PEM_write_EC_PUBKEY failed");
Line 459 
Line 461 
 {  {
         struct sshkey *key = NULL;          struct sshkey *key = NULL;
         char *type, *cipher;          char *type, *cipher;
           const char *alg = NULL;
         u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345";          u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345";
         int r, rlen, ktype;          int r, rlen, ktype;
         u_int magic, i1, i2, i3, i4;          u_int magic, i1, i2, i3, i4;
         size_t slen;          size_t slen;
         u_long e;          u_long e;
   #ifdef WITH_DSA
         BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;          BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
         BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;          BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
   #endif
         BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;          BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
         BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;          BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;
   
Line 493 
Line 498 
         }          }
         free(cipher);          free(cipher);
   
         if (strstr(type, "dsa")) {          if (strstr(type, "rsa")) {
                 ktype = KEY_DSA;  
         } else if (strstr(type, "rsa")) {  
                 ktype = KEY_RSA;                  ktype = KEY_RSA;
   #ifdef WITH_DSA
           } else if (strstr(type, "dsa")) {
                   ktype = KEY_DSA;
   #endif
         } else {          } else {
                 free(type);                  free(type);
                 return NULL;                  return NULL;
Line 506 
Line 513 
         free(type);          free(type);
   
         switch (key->type) {          switch (key->type) {
   #ifdef WITH_DSA
         case KEY_DSA:          case KEY_DSA:
                 if ((dsa_p = BN_new()) == NULL ||                  if ((dsa_p = BN_new()) == NULL ||
                     (dsa_q = BN_new()) == NULL ||                      (dsa_q = BN_new()) == NULL ||
Line 525 
Line 533 
                         fatal_f("DSA_set0_key failed");                          fatal_f("DSA_set0_key failed");
                 dsa_pub_key = dsa_priv_key = NULL; /* transferred */                  dsa_pub_key = dsa_priv_key = NULL; /* transferred */
                 break;                  break;
   #endif
         case KEY_RSA:          case KEY_RSA:
                 if ((r = sshbuf_get_u8(b, &e1)) != 0 ||                  if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
                     (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) ||                      (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) ||
Line 567 
Line 576 
                 if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)                  if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)
                         fatal_fr(r, "generate RSA parameters");                          fatal_fr(r, "generate RSA parameters");
                 BN_clear_free(rsa_iqmp);                  BN_clear_free(rsa_iqmp);
                   alg = "rsa-sha2-256";
                 break;                  break;
         }          }
         rlen = sshbuf_len(b);          rlen = sshbuf_len(b);
Line 574 
Line 584 
                 error_f("remaining bytes in key blob %d", rlen);                  error_f("remaining bytes in key blob %d", rlen);
   
         /* try the key */          /* try the key */
         if (sshkey_sign(key, &sig, &slen, data, sizeof(data),          if ((r = sshkey_sign(key, &sig, &slen, data, sizeof(data),
             NULL, NULL, NULL, 0) != 0 ||              alg, NULL, NULL, 0)) != 0)
             sshkey_verify(key, sig, slen, data, sizeof(data),                  error_fr(r, "signing with converted key failed");
             NULL, 0, NULL) != 0) {          else if ((r = sshkey_verify(key, sig, slen, data, sizeof(data),
               alg, 0, NULL)) != 0)
                   error_fr(r, "verification with converted key failed");
           if (r != 0) {
                 sshkey_free(key);                  sshkey_free(key);
                 free(sig);                  free(sig);
                 return NULL;                  return NULL;
Line 684 
Line 697 
                 (*k)->type = KEY_RSA;                  (*k)->type = KEY_RSA;
                 (*k)->rsa = EVP_PKEY_get1_RSA(pubkey);                  (*k)->rsa = EVP_PKEY_get1_RSA(pubkey);
                 break;                  break;
   #ifdef WITH_DSA
         case EVP_PKEY_DSA:          case EVP_PKEY_DSA:
                 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)                  if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
                         fatal("sshkey_new failed");                          fatal("sshkey_new failed");
                 (*k)->type = KEY_DSA;                  (*k)->type = KEY_DSA;
                 (*k)->dsa = EVP_PKEY_get1_DSA(pubkey);                  (*k)->dsa = EVP_PKEY_get1_DSA(pubkey);
                 break;                  break;
   #endif
         case EVP_PKEY_EC:          case EVP_PKEY_EC:
                 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)                  if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
                         fatal("sshkey_new failed");                          fatal("sshkey_new failed");
Line 757 
Line 772 
                         fprintf(stdout, "\n");                          fprintf(stdout, "\n");
         } else {          } else {
                 switch (k->type) {                  switch (k->type) {
   #ifdef WITH_DSA
                 case KEY_DSA:                  case KEY_DSA:
                         ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,                          ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL,
                             NULL, 0, NULL, NULL);                              NULL, 0, NULL, NULL);
                         break;                          break;
   #endif
                 case KEY_ECDSA:                  case KEY_ECDSA:
                         ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL,                          ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL,
                             NULL, 0, NULL, NULL);                              NULL, 0, NULL, NULL);
Line 971 
Line 988 
                  * accept a public key prefixed with a hostname or options.                   * accept a public key prefixed with a hostname or options.
                  * Try a bare key first, otherwise skip the leading stuff.                   * Try a bare key first, otherwise skip the leading stuff.
                  */                   */
                   comment = NULL;
                 if ((public = try_read_key(&cp)) == NULL) {                  if ((public = try_read_key(&cp)) == NULL) {
                         i = strtol(cp, &ep, 10);                          i = strtol(cp, &ep, 10);
                         if (i == 0 || ep == NULL ||                          if (i == 0 || ep == NULL ||
Line 1024 
Line 1042 
         } key_types[] = {          } key_types[] = {
 #ifdef WITH_OPENSSL  #ifdef WITH_OPENSSL
                 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },                  { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
                 { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE },  
                 { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE },                  { "ecdsa", "ECDSA",_PATH_HOST_ECDSA_KEY_FILE },
 #endif /* WITH_OPENSSL */  #endif /* WITH_OPENSSL */
                 { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE },                  { "ed25519", "ED25519",_PATH_HOST_ED25519_KEY_FILE },
Line 1159 
Line 1176 
         case HKF_STATUS_OK:          case HKF_STATUS_OK:
         case HKF_STATUS_MATCHED:          case HKF_STATUS_MATCHED:
                 /*                  /*
                  * Don't hash hosts already already hashed, with wildcard                   * Don't hash hosts already hashed, with wildcard
                  * characters or a CA/revocation marker.                   * characters or a CA/revocation marker.
                  */                   */
                 if (was_hashed || has_wild || l->marker != MRK_NONE) {                  if (was_hashed || has_wild || l->marker != MRK_NONE) {
Line 1312 
Line 1329 
                         unlink(tmp);                          unlink(tmp);
                         fatal("fdopen: %s", strerror(oerrno));                          fatal("fdopen: %s", strerror(oerrno));
                 }                  }
                 fchmod(fd, sb.st_mode & 0644);                  (void)fchmod(fd, sb.st_mode & 0644);
                 inplace = 1;                  inplace = 1;
         }          }
         /* XXX support identity_file == "-" for stdin */          /* XXX support identity_file == "-" for stdin */
Line 1454 
Line 1471 
  */   */
 static int  static int
 do_print_resource_record(struct passwd *pw, char *fname, char *hname,  do_print_resource_record(struct passwd *pw, char *fname, char *hname,
     int print_generic)      int print_generic, char * const *opts, size_t nopts)
 {  {
         struct sshkey *public;          struct sshkey *public;
         char *comment = NULL;          char *comment = NULL;
         struct stat st;          struct stat st;
         int r;          int r, hash = -1;
           size_t i;
   
           for (i = 0; i < nopts; i++) {
                   if (strncasecmp(opts[i], "hashalg=", 8) == 0) {
                           if ((hash = ssh_digest_alg_by_name(opts[i] + 8)) == -1)
                                   fatal("Unsupported hash algorithm");
                   } else {
                           error("Invalid option \"%s\"", opts[i]);
                           return SSH_ERR_INVALID_ARGUMENT;
                   }
           }
         if (fname == NULL)          if (fname == NULL)
                 fatal_f("no filename");                  fatal_f("no filename");
         if (stat(fname, &st) == -1) {          if (stat(fname, &st) == -1) {
Line 1470 
Line 1497 
         }          }
         if ((r = sshkey_load_public(fname, &public, &comment)) != 0)          if ((r = sshkey_load_public(fname, &public, &comment)) != 0)
                 fatal_r(r, "Failed to read v2 public key from \"%s\"", fname);                  fatal_r(r, "Failed to read v2 public key from \"%s\"", fname);
         export_dns_rr(hname, public, stdout, print_generic);          export_dns_rr(hname, public, stdout, print_generic, hash);
         sshkey_free(public);          sshkey_free(public);
         free(comment);          free(comment);
         return 1;          return 1;
Line 1892 
Line 1919 
 }  }
   
 static void  static void
   parse_hex_u64(const char *s, uint64_t *up)
   {
           char *ep;
           unsigned long long ull;
   
           errno = 0;
           ull = strtoull(s, &ep, 16);
           if (*s == '\0' || *ep != '\0')
                   fatal("Invalid certificate time: not a number");
           if (errno == ERANGE && ull == ULONG_MAX)
                   fatal_fr(SSH_ERR_SYSTEM_ERROR, "Invalid certificate time");
           *up = (uint64_t)ull;
   }
   
   static void
 parse_cert_times(char *timespec)  parse_cert_times(char *timespec)
 {  {
         char *from, *to;          char *from, *to;
Line 1913 
Line 1955 
   
         /*          /*
          * from:to, where           * from:to, where
          * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "always"           * from := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "always"
          *   to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | "forever"           *   to := [+-]timespec | YYYYMMDD | YYYYMMDDHHMMSS | 0x... | "forever"
          */           */
         from = xstrdup(timespec);          from = xstrdup(timespec);
         to = strchr(from, ':');          to = strchr(from, ':');
Line 1926 
Line 1968 
                 cert_valid_from = parse_relative_time(from, now);                  cert_valid_from = parse_relative_time(from, now);
         else if (strcmp(from, "always") == 0)          else if (strcmp(from, "always") == 0)
                 cert_valid_from = 0;                  cert_valid_from = 0;
           else if (strncmp(from, "0x", 2) == 0)
                   parse_hex_u64(from, &cert_valid_from);
         else if (parse_absolute_time(from, &cert_valid_from) != 0)          else if (parse_absolute_time(from, &cert_valid_from) != 0)
                 fatal("Invalid from time \"%s\"", from);                  fatal("Invalid from time \"%s\"", from);
   
Line 1933 
Line 1977 
                 cert_valid_to = parse_relative_time(to, now);                  cert_valid_to = parse_relative_time(to, now);
         else if (strcmp(to, "forever") == 0)          else if (strcmp(to, "forever") == 0)
                 cert_valid_to = ~(u_int64_t)0;                  cert_valid_to = ~(u_int64_t)0;
           else if (strncmp(to, "0x", 2) == 0)
                   parse_hex_u64(to, &cert_valid_to);
         else if (parse_absolute_time(to, &cert_valid_to) != 0)          else if (parse_absolute_time(to, &cert_valid_to) != 0)
                 fatal("Invalid to time \"%s\"", to);                  fatal("Invalid to time \"%s\"", to);
   
Line 2166 
Line 2212 
         if ((r = sshbuf_load_file(path, &krlbuf)) != 0)          if ((r = sshbuf_load_file(path, &krlbuf)) != 0)
                 fatal_r(r, "Unable to load KRL %s", path);                  fatal_r(r, "Unable to load KRL %s", path);
         /* XXX check sigs */          /* XXX check sigs */
         if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 ||          if ((r = ssh_krl_from_blob(krlbuf, krlp)) != 0 ||
             *krlp == NULL)              *krlp == NULL)
                 fatal_r(r, "Invalid KRL file %s", path);                  fatal_r(r, "Invalid KRL file %s", path);
         sshbuf_free(krlbuf);          sshbuf_free(krlbuf);
Line 2189 
Line 2235 
          * OpenSSH base64 hashes omit trailing '='           * OpenSSH base64 hashes omit trailing '='
          * characters; put them back for decode.           * characters; put them back for decode.
          */           */
         tlen = strlen(cp);          if ((tlen = strlen(cp)) >= SIZE_MAX - 5)
                   fatal_f("hash too long: %zu bytes", tlen);
         tmp = xmalloc(tlen + 4 + 1);          tmp = xmalloc(tlen + 4 + 1);
         strlcpy(tmp, cp, tlen + 1);          strlcpy(tmp, cp, tlen + 1);
         while ((tlen % 4) != 0) {          while ((tlen % 4) != 0) {
Line 2231 
Line 2278 
         if (!quiet)          if (!quiet)
                 printf("Revoking from %s\n", path);                  printf("Revoking from %s\n", path);
         while (getline(&line, &linesize, krl_spec) != -1) {          while (getline(&line, &linesize, krl_spec) != -1) {
                   if (linesize >= INT_MAX) {
                           fatal_f("%s contains unparsable line, len=%zu",
                               path, linesize);
                   }
                 lnum++;                  lnum++;
                 was_explicit_key = was_sha1 = was_sha256 = was_hash = 0;                  was_explicit_key = was_sha1 = was_sha256 = was_hash = 0;
                 cp = line + strspn(line, " \t");                  cp = line + strspn(line, " \t");
Line 2404 
Line 2455 
   
         if ((kbuf = sshbuf_new()) == NULL)          if ((kbuf = sshbuf_new()) == NULL)
                 fatal("sshbuf_new failed");                  fatal("sshbuf_new failed");
         if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0)          if (ssh_krl_to_blob(krl, kbuf) != 0)
                 fatal("Couldn't generate KRL");                  fatal("Couldn't generate KRL");
         if ((r = sshbuf_write_file(identity_file, kbuf)) != 0)          if ((r = sshbuf_write_file(identity_file, kbuf)) != 0)
                 fatal("write %s: %s", identity_file, strerror(errno));                  fatal("write %s: %s", identity_file, strerror(errno));
Line 2961 
Line 3012 
                 } else if (strncmp(opts[i], "start-line=", 11) == 0) {                  } else if (strncmp(opts[i], "start-line=", 11) == 0) {
                         start_lineno = strtoul(opts[i]+11, NULL, 10);                          start_lineno = strtoul(opts[i]+11, NULL, 10);
                 } else if (strncmp(opts[i], "checkpoint=", 11) == 0) {                  } else if (strncmp(opts[i], "checkpoint=", 11) == 0) {
                           free(checkpoint);
                         checkpoint = xstrdup(opts[i]+11);                          checkpoint = xstrdup(opts[i]+11);
                 } else if (strncmp(opts[i], "generator=", 10) == 0) {                  } else if (strncmp(opts[i], "generator=", 10) == 0) {
                         generator_wanted = (u_int32_t)strtonum(                          generator_wanted = (u_int32_t)strtonum(
Line 2999 
Line 3051 
             generator_wanted, checkpoint,              generator_wanted, checkpoint,
             start_lineno, lines_to_process) != 0)              start_lineno, lines_to_process) != 0)
                 fatal("modulus screening failed");                  fatal("modulus screening failed");
           if (in != stdin)
                   (void)fclose(in);
           free(checkpoint);
 #else /* WITH_OPENSSL */  #else /* WITH_OPENSSL */
         fatal("Moduli screening is not supported");          fatal("Moduli screening is not supported");
 #endif /* WITH_OPENSSL */  #endif /* WITH_OPENSSL */
 }  }
   
   /* Read and confirm a passphrase */
 static char *  static char *
 private_key_passphrase(void)  read_check_passphrase(const char *prompt1, const char *prompt2,
       const char *retry_prompt)
 {  {
         char *passphrase1, *passphrase2;          char *passphrase1, *passphrase2;
   
         /* Ask for a passphrase (twice). */          for (;;) {
         if (identity_passphrase)                  passphrase1 = read_passphrase(prompt1, RP_ALLOW_STDIN);
                 passphrase1 = xstrdup(identity_passphrase);                  passphrase2 = read_passphrase(prompt2, RP_ALLOW_STDIN);
         else if (identity_new_passphrase)                  if (strcmp(passphrase1, passphrase2) == 0) {
                 passphrase1 = xstrdup(identity_new_passphrase);  
         else {  
 passphrase_again:  
                 passphrase1 =  
                         read_passphrase("Enter passphrase (empty for no "  
                             "passphrase): ", RP_ALLOW_STDIN);  
                 passphrase2 = read_passphrase("Enter same passphrase again: ",  
                     RP_ALLOW_STDIN);  
                 if (strcmp(passphrase1, passphrase2) != 0) {  
                         /*  
                          * The passphrases do not match.  Clear them and  
                          * retry.  
                          */  
                         freezero(passphrase1, strlen(passphrase1));  
                         freezero(passphrase2, strlen(passphrase2));                          freezero(passphrase2, strlen(passphrase2));
                         printf("Passphrases do not match.  Try again.\n");                          return passphrase1;
                         goto passphrase_again;  
                 }                  }
                 /* Clear the other copy of the passphrase. */                  /* The passphrases do not match. Clear them and retry. */
                   freezero(passphrase1, strlen(passphrase1));
                 freezero(passphrase2, strlen(passphrase2));                  freezero(passphrase2, strlen(passphrase2));
                   fputs(retry_prompt, stdout);
                   fputc('\n', stdout);
                   fflush(stdout);
         }          }
         return passphrase1;          /* NOTREACHED */
           return NULL;
 }  }
   
 static char *  static char *
   private_key_passphrase(void)
   {
           if (identity_passphrase)
                   return xstrdup(identity_passphrase);
           if (identity_new_passphrase)
                   return xstrdup(identity_new_passphrase);
   
           return read_check_passphrase(
               "Enter passphrase (empty for no passphrase): ",
               "Enter same passphrase again: ",
               "Passphrases do not match.  Try again.");
   }
   
   static char *
 sk_suffix(const char *application, const uint8_t *user, size_t userlen)  sk_suffix(const char *application, const uint8_t *user, size_t userlen)
 {  {
         char *ret, *cp;          char *ret, *cp;
Line 3185 
Line 3246 
                     "%s\n", path);                      "%s\n", path);
 }  }
   
   static int
   confirm_sk_overwrite(const char *application, const char *user)
   {
           char yesno[3];
   
           printf("A resident key scoped to '%s' with user id '%s' already "
               "exists.\n", application == NULL ? "ssh:" : application,
               user == NULL ? "null" : user);
           printf("Overwrite key in token (y/n)? ");
           fflush(stdout);
           if (fgets(yesno, sizeof(yesno), stdin) == NULL)
                   return 0;
           if (yesno[0] != 'y' && yesno[0] != 'Y')
                   return 0;
           return 1;
   }
   
 static void  static void
 usage(void)  usage(void)
 {  {
Line 3240 
Line 3318 
 int  int
 main(int argc, char **argv)  main(int argc, char **argv)
 {  {
         char comment[1024], *passphrase;          char comment[1024], *passphrase = NULL;
         char *rr_hostname = NULL, *ep, *fp, *ra;          char *rr_hostname = NULL, *ep, *fp, *ra;
         struct sshkey *private, *public;          struct sshkey *private, *public;
         struct passwd *pw;          struct passwd *pw;
Line 3476 
Line 3554 
                         else                          else
                                 fatal("Unsupported moduli option %s", optarg);                                  fatal("Unsupported moduli option %s", optarg);
                         break;                          break;
                 case '?':  
                 default:                  default:
                         usage();                          usage();
                 }                  }
Line 3656 
Line 3733 
   
                 if (have_identity) {                  if (have_identity) {
                         n = do_print_resource_record(pw, identity_file,                          n = do_print_resource_record(pw, identity_file,
                             rr_hostname, print_generic);                              rr_hostname, print_generic, opts, nopts);
                         if (n == 0)                          if (n == 0)
                                 fatal("%s: %s", identity_file, strerror(errno));                                  fatal("%s: %s", identity_file, strerror(errno));
                         exit(0);                          exit(0);
Line 3664 
Line 3741 
   
                         n += do_print_resource_record(pw,                          n += do_print_resource_record(pw,
                             _PATH_HOST_RSA_KEY_FILE, rr_hostname,                              _PATH_HOST_RSA_KEY_FILE, rr_hostname,
                             print_generic);                              print_generic, opts, nopts);
   #ifdef WITH_DSA
                         n += do_print_resource_record(pw,                          n += do_print_resource_record(pw,
                             _PATH_HOST_DSA_KEY_FILE, rr_hostname,                              _PATH_HOST_DSA_KEY_FILE, rr_hostname,
                             print_generic);                              print_generic, opts, nopts);
   #endif
                         n += do_print_resource_record(pw,                          n += do_print_resource_record(pw,
                             _PATH_HOST_ECDSA_KEY_FILE, rr_hostname,                              _PATH_HOST_ECDSA_KEY_FILE, rr_hostname,
                             print_generic);                              print_generic, opts, nopts);
                         n += do_print_resource_record(pw,                          n += do_print_resource_record(pw,
                             _PATH_HOST_ED25519_KEY_FILE, rr_hostname,                              _PATH_HOST_ED25519_KEY_FILE, rr_hostname,
                             print_generic);                              print_generic, opts, nopts);
                         n += do_print_resource_record(pw,                          n += do_print_resource_record(pw,
                             _PATH_HOST_XMSS_KEY_FILE, rr_hostname,                              _PATH_HOST_XMSS_KEY_FILE, rr_hostname,
                             print_generic);                              print_generic, opts, nopts);
                         if (n == 0)                          if (n == 0)
                                 fatal("no keys found.");                                  fatal("no keys found.");
                         exit(0);                          exit(0);
Line 3748 
Line 3827 
                                     "FIDO authenticator enrollment", opts[i]);                                      "FIDO authenticator enrollment", opts[i]);
                         }                          }
                 }                  }
                 if (!quiet) {  
                         printf("You may need to touch your authenticator "  
                             "to authorize key generation.\n");  
                 }  
                 if ((attest = sshbuf_new()) == NULL)                  if ((attest = sshbuf_new()) == NULL)
                         fatal("sshbuf_new failed");                          fatal("sshbuf_new failed");
                 if ((sk_flags &                  r = 0;
                     (SSH_SK_USER_VERIFICATION_REQD|SSH_SK_RESIDENT_KEY))) {                  for (i = 0 ;;) {
                         passphrase = read_passphrase("Enter PIN for "                          if (!quiet) {
                             "authenticator: ", RP_ALLOW_STDIN);                                  printf("You may need to touch your "
                 } else {                                      "authenticator%s to authorize key "
                         passphrase = NULL;                                      "generation.\n",
                 }                                      r == 0 ? "" : " again");
                 for (i = 0 ; ; i++) {                          }
                         fflush(stdout);                          fflush(stdout);
                         r = sshsk_enroll(type, sk_provider, sk_device,                          r = sshsk_enroll(type, sk_provider, sk_device,
                             sk_application == NULL ? "ssh:" : sk_application,                              sk_application == NULL ? "ssh:" : sk_application,
Line 3769 
Line 3844 
                             &private, attest);                              &private, attest);
                         if (r == 0)                          if (r == 0)
                                 break;                                  break;
                           if (r == SSH_ERR_KEY_BAD_PERMISSIONS &&
                               (sk_flags & SSH_SK_RESIDENT_KEY) != 0 &&
                               (sk_flags & SSH_SK_FORCE_OPERATION) == 0 &&
                               confirm_sk_overwrite(sk_application, sk_user)) {
                                   sk_flags |= SSH_SK_FORCE_OPERATION;
                                   continue;
                           }
                         if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)                          if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
                                 fatal_r(r, "Key enrollment failed");                                  fatal_r(r, "Key enrollment failed");
                         else if (passphrase != NULL) {                          else if (passphrase != NULL) {
Line 3776 
Line 3858 
                                 freezero(passphrase, strlen(passphrase));                                  freezero(passphrase, strlen(passphrase));
                                 passphrase = NULL;                                  passphrase = NULL;
                         }                          }
                         if (i >= 3)                          if (++i >= 3)
                                 fatal("Too many incorrect PINs");                                  fatal("Too many incorrect PINs");
                         passphrase = read_passphrase("Enter PIN for "                          passphrase = read_passphrase("Enter PIN for "
                             "authenticator: ", RP_ALLOW_STDIN);                              "authenticator: ", RP_ALLOW_STDIN);
                         if (!quiet) {  
                                 printf("You may need to touch your "  
                                     "authenticator (again) to authorize "  
                                     "key generation.\n");  
                         }  
                 }                  }
                 if (passphrase != NULL) {                  if (passphrase != NULL) {
                         freezero(passphrase, strlen(passphrase));                          freezero(passphrase, strlen(passphrase));

Legend:
Removed from v.1.453  
changed lines
  Added in v.1.472