[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.413 and 1.418

version 1.413, 2020/06/26 05:02:03 version 1.418, 2020/08/27 01:08:45
Line 127 
Line 127 
 static char *certflags_src_addr = NULL;  static char *certflags_src_addr = NULL;
   
 /* Arbitrary extensions specified by user */  /* Arbitrary extensions specified by user */
 struct cert_userext {  struct cert_ext {
         char *key;          char *key;
         char *val;          char *val;
         int crit;          int crit;
 };  };
 static struct cert_userext *cert_userext;  static struct cert_ext *cert_ext;
 static size_t ncert_userext;  static size_t ncert_ext;
   
 /* Conversion to/from various formats */  /* Conversion to/from various formats */
 enum {  enum {
Line 573 
Line 573 
   
         /* try the key */          /* try the key */
         if (sshkey_sign(key, &sig, &slen, data, sizeof(data),          if (sshkey_sign(key, &sig, &slen, data, sizeof(data),
             NULL, NULL, 0) != 0 ||              NULL, NULL, NULL, 0) != 0 ||
             sshkey_verify(key, sig, slen, data, sizeof(data),              sshkey_verify(key, sig, slen, data, sizeof(data),
             NULL, 0, NULL) != 0) {              NULL, 0, NULL) != 0) {
                 sshkey_free(key);                  sshkey_free(key);
Line 1579 
Line 1579 
 }  }
   
 static void  static void
 add_flag_option(struct sshbuf *c, const char *name)  cert_ext_add(const char *key, const char *value, int iscrit)
 {  {
         int r;          cert_ext = xreallocarray(cert_ext, ncert_ext + 1, sizeof(*cert_ext));
           cert_ext[ncert_ext].key = xstrdup(key);
         debug3("%s: %s", __func__, name);          cert_ext[ncert_ext].val = value == NULL ? NULL : xstrdup(value);
         if ((r = sshbuf_put_cstring(c, name)) != 0 ||          cert_ext[ncert_ext].crit = iscrit;
             (r = sshbuf_put_string(c, NULL, 0)) != 0)          ncert_ext++;
                 fatal("%s: buffer error: %s", __func__, ssh_err(r));  
 }  }
   
 static void  /* qsort(3) comparison function for certificate extensions */
 add_string_option(struct sshbuf *c, const char *name, const char *value)  static int
   cert_ext_cmp(const void *_a, const void *_b)
 {  {
         struct sshbuf *b;          const struct cert_ext *a = (const struct cert_ext *)_a;
           const struct cert_ext *b = (const struct cert_ext *)_b;
         int r;          int r;
   
         debug3("%s: %s=%s", __func__, name, value);          if (a->crit != b->crit)
         if ((b = sshbuf_new()) == NULL)                  return (a->crit < b->crit) ? -1 : 1;
                 fatal("%s: sshbuf_new failed", __func__);          if ((r = strcmp(a->key, b->key)) != 0)
         if ((r = sshbuf_put_cstring(b, value)) != 0 ||                  return r;
             (r = sshbuf_put_cstring(c, name)) != 0 ||          if ((a->val == NULL) != (b->val == NULL))
             (r = sshbuf_put_stringb(c, b)) != 0)                  return (a->val == NULL) ? -1 : 1;
                 fatal("%s: buffer error: %s", __func__, ssh_err(r));          if (a->val != NULL && (r = strcmp(a->val, b->val)) != 0)
                   return r;
         sshbuf_free(b);          return 0;
 }  }
   
 #define OPTIONS_CRITICAL        1  #define OPTIONS_CRITICAL        1
Line 1611 
Line 1612 
 static void  static void
 prepare_options_buf(struct sshbuf *c, int which)  prepare_options_buf(struct sshbuf *c, int which)
 {  {
           struct sshbuf *b;
         size_t i;          size_t i;
           int r;
           const struct cert_ext *ext;
   
           if ((b = sshbuf_new()) == NULL)
                   fatal("%s: sshbuf_new failed", __func__);
         sshbuf_reset(c);          sshbuf_reset(c);
         if ((which & OPTIONS_CRITICAL) != 0 &&          for (i = 0; i < ncert_ext; i++) {
             certflags_command != NULL)                  ext = &cert_ext[i];
                 add_string_option(c, "force-command", certflags_command);                  if ((ext->crit && (which & OPTIONS_EXTENSIONS)) ||
         if ((which & OPTIONS_EXTENSIONS) != 0 &&                      (!ext->crit && (which & OPTIONS_CRITICAL)))
             (certflags_flags & CERTOPT_X_FWD) != 0)  
                 add_flag_option(c, "permit-X11-forwarding");  
         if ((which & OPTIONS_EXTENSIONS) != 0 &&  
             (certflags_flags & CERTOPT_AGENT_FWD) != 0)  
                 add_flag_option(c, "permit-agent-forwarding");  
         if ((which & OPTIONS_EXTENSIONS) != 0 &&  
             (certflags_flags & CERTOPT_PORT_FWD) != 0)  
                 add_flag_option(c, "permit-port-forwarding");  
         if ((which & OPTIONS_EXTENSIONS) != 0 &&  
             (certflags_flags & CERTOPT_PTY) != 0)  
                 add_flag_option(c, "permit-pty");  
         if ((which & OPTIONS_EXTENSIONS) != 0 &&  
             (certflags_flags & CERTOPT_USER_RC) != 0)  
                 add_flag_option(c, "permit-user-rc");  
         if ((which & OPTIONS_EXTENSIONS) != 0 &&  
             (certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0)  
                 add_flag_option(c, "no-touch-required");  
         if ((which & OPTIONS_CRITICAL) != 0 &&  
             certflags_src_addr != NULL)  
                 add_string_option(c, "source-address", certflags_src_addr);  
         for (i = 0; i < ncert_userext; i++) {  
                 if ((cert_userext[i].crit && (which & OPTIONS_EXTENSIONS)) ||  
                     (!cert_userext[i].crit && (which & OPTIONS_CRITICAL)))  
                         continue;                          continue;
                 if (cert_userext[i].val == NULL)                  if (ext->val == NULL) {
                         add_flag_option(c, cert_userext[i].key);                          /* flag option */
                 else {                          debug3("%s: %s", __func__, ext->key);
                         add_string_option(c, cert_userext[i].key,                          if ((r = sshbuf_put_cstring(c, ext->key)) != 0 ||
                             cert_userext[i].val);                              (r = sshbuf_put_string(c, NULL, 0)) != 0)
                                   fatal("%s: buffer: %s", __func__, ssh_err(r));
                   } else {
                           /* key/value option */
                           debug3("%s: %s=%s", __func__, ext->key, ext->val);
                           sshbuf_reset(b);
                           if ((r = sshbuf_put_cstring(c, ext->key)) != 0 ||
                               (r = sshbuf_put_cstring(b, ext->val)) != 0 ||
                               (r = sshbuf_put_stringb(c, b)) != 0)
                                   fatal("%s: buffer: %s", __func__, ssh_err(r));
                 }                  }
         }          }
           sshbuf_free(b);
 }  }
   
   static void
   finalise_cert_exts(void)
   {
           /* critical options */
           if (certflags_command != NULL)
                   cert_ext_add("force-command", certflags_command, 1);
           if (certflags_src_addr != NULL)
                   cert_ext_add("source-address", certflags_src_addr, 1);
           /* extensions */
           if ((certflags_flags & CERTOPT_X_FWD) != 0)
                   cert_ext_add("permit-X11-forwarding", NULL, 0);
           if ((certflags_flags & CERTOPT_AGENT_FWD) != 0)
                   cert_ext_add("permit-agent-forwarding", NULL, 0);
           if ((certflags_flags & CERTOPT_PORT_FWD) != 0)
                   cert_ext_add("permit-port-forwarding", NULL, 0);
           if ((certflags_flags & CERTOPT_PTY) != 0)
                   cert_ext_add("permit-pty", NULL, 0);
           if ((certflags_flags & CERTOPT_USER_RC) != 0)
                   cert_ext_add("permit-user-rc", NULL, 0);
           if ((certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0)
                   cert_ext_add("no-touch-required", NULL, 0);
           /* order lexically by key */
           if (ncert_ext > 0)
                   qsort(cert_ext, ncert_ext, sizeof(*cert_ext), cert_ext_cmp);
   }
   
 static struct sshkey *  static struct sshkey *
 load_pkcs11_key(char *path)  load_pkcs11_key(char *path)
 {  {
Line 1686 
Line 1705 
 static int  static int
 agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp,  agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp,
     const u_char *data, size_t datalen,      const u_char *data, size_t datalen,
     const char *alg, const char *provider, u_int compat, void *ctx)      const char *alg, const char *provider, const char *pin,
       u_int compat, void *ctx)
 {  {
         int *agent_fdp = (int *)ctx;          int *agent_fdp = (int *)ctx;
   
Line 1703 
Line 1723 
         u_int n;          u_int n;
         struct sshkey *ca, *public;          struct sshkey *ca, *public;
         char valid[64], *otmp, *tmp, *cp, *out, *comment;          char valid[64], *otmp, *tmp, *cp, *out, *comment;
         char *ca_fp = NULL, **plist = NULL;          char *ca_fp = NULL, **plist = NULL, *pin = NULL;
         struct ssh_identitylist *agent_ids;          struct ssh_identitylist *agent_ids;
         size_t j;          size_t j;
         struct notifier_ctx *notifier = NULL;          struct notifier_ctx *notifier = NULL;
Line 1744 
Line 1764 
         } else {          } else {
                 /* CA key is assumed to be a private key on the filesystem */                  /* CA key is assumed to be a private key on the filesystem */
                 ca = load_identity(tmp, NULL);                  ca = load_identity(tmp, NULL);
                   if (sshkey_is_sk(ca) &&
                       (ca->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
                           if ((pin = read_passphrase("Enter PIN for CA key: ",
                               RP_ALLOW_STDIN)) == NULL)
                                   fatal("%s: couldn't read PIN", __func__);
                   }
         }          }
         free(tmp);          free(tmp);
   
Line 1758 
Line 1784 
         }          }
         ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT);          ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT);
   
           finalise_cert_exts();
         for (i = 0; i < argc; i++) {          for (i = 0; i < argc; i++) {
                 /* Split list of principals */                  /* Split list of principals */
                 n = 0;                  n = 0;
Line 1802 
Line 1829 
   
                 if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) {                  if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) {
                         if ((r = sshkey_certify_custom(public, ca,                          if ((r = sshkey_certify_custom(public, ca,
                             key_type_name, sk_provider, agent_signer,                              key_type_name, sk_provider, NULL, agent_signer,
                             &agent_fd)) != 0)                              &agent_fd)) != 0)
                                 fatal("Couldn't certify key %s via agent: %s",                                  fatal("Couldn't certify key %s via agent: %s",
                                     tmp, ssh_err(r));                                      tmp, ssh_err(r));
Line 1814 
Line 1841 
                                     sshkey_type(ca), ca_fp);                                      sshkey_type(ca), ca_fp);
                         }                          }
                         r = sshkey_certify(public, ca, key_type_name,                          r = sshkey_certify(public, ca, key_type_name,
                             sk_provider);                              sk_provider, pin);
                         notify_complete(notifier);                          notify_complete(notifier);
                         if (r != 0)                          if (r != 0)
                                 fatal("Couldn't certify key %s: %s",                                  fatal("Couldn't certify key %s: %s",
Line 1848 
Line 1875 
                 if (cert_serial_autoinc)                  if (cert_serial_autoinc)
                         cert_serial++;                          cert_serial++;
         }          }
           if (pin != NULL)
                   freezero(pin, strlen(pin));
         free(ca_fp);          free(ca_fp);
 #ifdef ENABLE_PKCS11  #ifdef ENABLE_PKCS11
         pkcs11_terminate();          pkcs11_terminate();
Line 1972 
Line 2001 
                 val = xstrdup(strchr(opt, ':') + 1);                  val = xstrdup(strchr(opt, ':') + 1);
                 if ((cp = strchr(val, '=')) != NULL)                  if ((cp = strchr(val, '=')) != NULL)
                         *cp++ = '\0';                          *cp++ = '\0';
                 cert_userext = xreallocarray(cert_userext, ncert_userext + 1,                  cert_ext_add(val, cp, iscrit);
                     sizeof(*cert_userext));                  free(val);
                 cert_userext[ncert_userext].key = val;  
                 cert_userext[ncert_userext].val = cp == NULL ?  
                     NULL : xstrdup(cp);  
                 cert_userext[ncert_userext].crit = iscrit;  
                 ncert_userext++;  
         } else          } else
                 fatal("Unsupported certificate option \"%s\"", opt);                  fatal("Unsupported certificate option \"%s\"", opt);
 }  }
Line 1986 
Line 2010 
 static void  static void
 show_options(struct sshbuf *optbuf, int in_critical)  show_options(struct sshbuf *optbuf, int in_critical)
 {  {
         char *name, *arg;          char *name, *arg, *hex;
         struct sshbuf *options, *option = NULL;          struct sshbuf *options, *option = NULL;
         int r;          int r;
   
Line 2015 
Line 2039 
                                     __func__, ssh_err(r));                                      __func__, ssh_err(r));
                         printf(" %s\n", arg);                          printf(" %s\n", arg);
                         free(arg);                          free(arg);
                 } else {                  } else if (sshbuf_len(option) > 0) {
                         printf(" UNKNOWN OPTION (len %zu)\n",                          hex = sshbuf_dtob16(option);
                             sshbuf_len(option));                          printf(" UNKNOWN OPTION: %s (len %zu)\n",
                               hex, sshbuf_len(option));
                         sshbuf_reset(option);                          sshbuf_reset(option);
                 }                          free(hex);
                   } else
                           printf(" UNKNOWN FLAG OPTION\n");
                 free(name);                  free(name);
                 if (sshbuf_len(option) != 0)                  if (sshbuf_len(option) != 0)
                         fatal("Option corrupt: extra data at end");                          fatal("Option corrupt: extra data at end");
Line 2486 
Line 2513 
         struct sshbuf *sigbuf = NULL, *abuf = NULL;          struct sshbuf *sigbuf = NULL, *abuf = NULL;
         int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno;          int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno;
         char *wfile = NULL, *asig = NULL, *fp = NULL;          char *wfile = NULL, *asig = NULL, *fp = NULL;
           char *pin = NULL, *prompt = NULL;
   
         if (!quiet) {          if (!quiet) {
                 if (fd == STDIN_FILENO)                  if (fd == STDIN_FILENO)
Line 2493 
Line 2521 
                 else                  else
                         fprintf(stderr, "Signing file %s\n", filename);                          fprintf(stderr, "Signing file %s\n", filename);
         }          }
         if (signer == NULL && sshkey_is_sk(signkey) &&          if (signer == NULL && sshkey_is_sk(signkey)) {
             (signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {                  if ((signkey->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
                 if ((fp = sshkey_fingerprint(signkey, fingerprint_hash,                          xasprintf(&prompt, "Enter PIN for %s key: ",
                     SSH_FP_DEFAULT)) == NULL)                              sshkey_type(signkey));
                         fatal("%s: sshkey_fingerprint failed", __func__);                          if ((pin = read_passphrase(prompt,
                 fprintf(stderr, "Confirm user presence for key %s %s\n",                              RP_ALLOW_STDIN)) == NULL)
                     sshkey_type(signkey), fp);                                  fatal("%s: couldn't read PIN", __func__);
                 free(fp);                  }
                   if ((signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
                           if ((fp = sshkey_fingerprint(signkey, fingerprint_hash,
                               SSH_FP_DEFAULT)) == NULL)
                                   fatal("%s: fingerprint failed", __func__);
                           fprintf(stderr, "Confirm user presence for key %s %s\n",
                               sshkey_type(signkey), fp);
                           free(fp);
                   }
         }          }
         if ((r = sshsig_sign_fd(signkey, NULL, sk_provider, fd, sig_namespace,          if ((r = sshsig_sign_fd(signkey, NULL, sk_provider, pin,
             &sigbuf, signer, signer_ctx)) != 0) {              fd, sig_namespace, &sigbuf, signer, signer_ctx)) != 0) {
                 error("Signing %s failed: %s", filename, ssh_err(r));                  error("Signing %s failed: %s", filename, ssh_err(r));
                 goto out;                  goto out;
         }          }
Line 2551 
Line 2587 
         r = 0;          r = 0;
  out:   out:
         free(wfile);          free(wfile);
           free(prompt);
         free(asig);          free(asig);
           if (pin != NULL)
                   freezero(pin, strlen(pin));
         sshbuf_free(abuf);          sshbuf_free(abuf);
         sshbuf_free(sigbuf);          sshbuf_free(sigbuf);
         if (wfd != -1)          if (wfd != -1)
Line 2923 
Line 2962 
         if (skprovider == NULL)          if (skprovider == NULL)
                 fatal("Cannot download keys without provider");                  fatal("Cannot download keys without provider");
   
         for (i = 0; i < 2; i++) {          pin = read_passphrase("Enter PIN for authenticator: ", RP_ALLOW_STDIN);
                 if (i == 1) {          if (!quiet) {
                         pin = read_passphrase("Enter PIN for authenticator: ",                  printf("You may need to touch your authenticator "
                             RP_ALLOW_STDIN);                      "to authorize key download.\n");
                 }  
                 if ((r = sshsk_load_resident(skprovider, device, pin,  
                     &keys, &nkeys)) != 0) {  
                         if (i == 0 && r == SSH_ERR_KEY_WRONG_PASSPHRASE)  
                                 continue;  
                         if (pin != NULL)  
                                 freezero(pin, strlen(pin));  
                         error("Unable to load resident keys: %s", ssh_err(r));  
                         return -1;  
                 }  
         }          }
           if ((r = sshsk_load_resident(skprovider, device, pin,
               &keys, &nkeys)) != 0) {
                   if (pin != NULL)
                           freezero(pin, strlen(pin));
                   error("Unable to load resident keys: %s", ssh_err(r));
                   return -1;
           }
         if (nkeys == 0)          if (nkeys == 0)
                 logit("No keys to download");                  logit("No keys to download");
         if (pin != NULL)          if (pin != NULL)
Line 3013 
Line 3049 
 usage(void)  usage(void)
 {  {
         fprintf(stderr,          fprintf(stderr,
             "usage: ssh-keygen [-q] [-b bits] [-C comment] [-f output_keyfile] [-m format]\n"              "usage: ssh-keygen [-q] [-a rounds] [-b bits] [-C comment] [-f output_keyfile]\n"
               "                  [-m format] [-N new_passphrase] [-O option]\n"
             "                  [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n"              "                  [-t dsa | ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa]\n"
             "                  [-N new_passphrase] [-O option] [-w provider]\n"              "                  [-w provider]\n"
             "       ssh-keygen -p [-f keyfile] [-m format] [-N new_passphrase]\n"              "       ssh-keygen -p [-a rounds] [-f keyfile] [-m format] [-N new_passphrase]\n"
             "                   [-P old_passphrase]\n"              "                   [-P old_passphrase]\n"
             "       ssh-keygen -i [-f input_keyfile] [-m key_format]\n"              "       ssh-keygen -i [-f input_keyfile] [-m key_format]\n"
             "       ssh-keygen -e [-f input_keyfile] [-m key_format]\n"              "       ssh-keygen -e [-f input_keyfile] [-m key_format]\n"
             "       ssh-keygen -y [-f input_keyfile]\n"              "       ssh-keygen -y [-f input_keyfile]\n"
             "       ssh-keygen -c [-C comment] [-f keyfile] [-P passphrase]\n"              "       ssh-keygen -c [-a rounds] [-C comment] [-f keyfile] [-P passphrase]\n"
             "       ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"              "       ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"
             "       ssh-keygen -B [-f input_keyfile]\n");              "       ssh-keygen -B [-f input_keyfile]\n");
 #ifdef ENABLE_PKCS11  #ifdef ENABLE_PKCS11
Line 3031 
Line 3068 
         fprintf(stderr,          fprintf(stderr,
             "       ssh-keygen -F hostname [-lv] [-f known_hosts_file]\n"              "       ssh-keygen -F hostname [-lv] [-f known_hosts_file]\n"
             "       ssh-keygen -H [-f known_hosts_file]\n"              "       ssh-keygen -H [-f known_hosts_file]\n"
             "       ssh-keygen -K [-w provider]\n"              "       ssh-keygen -K [-a rounds] [-w provider]\n"
             "       ssh-keygen -R hostname [-f known_hosts_file]\n"              "       ssh-keygen -R hostname [-f known_hosts_file]\n"
             "       ssh-keygen -r hostname [-g] [-f input_keyfile]\n"              "       ssh-keygen -r hostname [-g] [-f input_keyfile]\n"
 #ifdef WITH_OPENSSL  #ifdef WITH_OPENSSL
Line 3042 
Line 3079 
             "                  [-n principals] [-O option] [-V validity_interval]\n"              "                  [-n principals] [-O option] [-V validity_interval]\n"
             "                  [-z serial_number] file ...\n"              "                  [-z serial_number] file ...\n"
             "       ssh-keygen -L [-f input_keyfile]\n"              "       ssh-keygen -L [-f input_keyfile]\n"
             "       ssh-keygen -A [-f prefix_path]\n"              "       ssh-keygen -A [-a rounds] [-f prefix_path]\n"
             "       ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"              "       ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
             "                  file ...\n"              "                  file ...\n"
             "       ssh-keygen -Q [-l] -f krl_file [file ...]\n"              "       ssh-keygen -Q [-l] -f krl_file [file ...]\n"
Line 3510 
Line 3547 
                 for (i = 0; i < nopts; i++) {                  for (i = 0; i < nopts; i++) {
                         if (strcasecmp(opts[i], "no-touch-required") == 0) {                          if (strcasecmp(opts[i], "no-touch-required") == 0) {
                                 sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;                                  sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
                           } else if (strcasecmp(opts[i], "verify-required") == 0) {
                                   sk_flags |= SSH_SK_USER_VERIFICATION_REQD;
                         } else if (strcasecmp(opts[i], "resident") == 0) {                          } else if (strcasecmp(opts[i], "resident") == 0) {
                                 sk_flags |= SSH_SK_RESIDENT_KEY;                                  sk_flags |= SSH_SK_RESIDENT_KEY;
                         } else if (strncasecmp(opts[i], "device=", 7) == 0) {                          } else if (strncasecmp(opts[i], "device=", 7) == 0) {
Line 3542 
Line 3581 
                         printf("You may need to touch your authenticator "                          printf("You may need to touch your authenticator "
                             "to authorize key generation.\n");                              "to authorize key generation.\n");
                 }                  }
                 passphrase = NULL;  
                 if ((attest = sshbuf_new()) == NULL)                  if ((attest = sshbuf_new()) == NULL)
                         fatal("sshbuf_new failed");                          fatal("sshbuf_new failed");
                   if ((sk_flags &
                       (SSH_SK_USER_VERIFICATION_REQD|SSH_SK_RESIDENT_KEY))) {
                           passphrase = read_passphrase("Enter PIN for "
                               "authenticator: ", RP_ALLOW_STDIN);
                   } else {
                           passphrase = NULL;
                   }
                 for (i = 0 ; ; i++) {                  for (i = 0 ; ; i++) {
                         fflush(stdout);                          fflush(stdout);
                         r = sshsk_enroll(type, sk_provider, sk_device,                          r = sshsk_enroll(type, sk_provider, sk_device,
Line 3555 
Line 3600 
                                 break;                                  break;
                         if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)                          if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
                                 fatal("Key enrollment failed: %s", ssh_err(r));                                  fatal("Key enrollment failed: %s", ssh_err(r));
                         else if (i > 0)                          else if (passphrase != NULL) {
                                 error("PIN incorrect");                                  error("PIN incorrect");
                         if (passphrase != NULL) {  
                                 freezero(passphrase, strlen(passphrase));                                  freezero(passphrase, strlen(passphrase));
                                 passphrase = NULL;                                  passphrase = NULL;
                         }                          }
Line 3565 
Line 3609 
                                 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.413  
changed lines
  Added in v.1.418