[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.380 and 1.381

version 1.380, 2019/12/30 09:49:52 version 1.381, 2020/01/02 22:40:09
Line 2853 
Line 2853 
 #endif /* WITH_OPENSSL */  #endif /* WITH_OPENSSL */
 }  }
   
   static char *
   private_key_passphrase(void)
   {
           char *passphrase1, *passphrase2;
   
           /* Ask for a passphrase (twice). */
           if (identity_passphrase)
                   passphrase1 = xstrdup(identity_passphrase);
           else if (identity_new_passphrase)
                   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));
                           printf("Passphrases do not match.  Try again.\n");
                           goto passphrase_again;
                   }
                   /* Clear the other copy of the passphrase. */
                   freezero(passphrase2, strlen(passphrase2));
           }
           return passphrase1;
   }
   
   static const char *
   skip_ssh_url_preamble(const char *s)
   {
           if (strncmp(s, "ssh://", 6) == 0)
                   return s + 6;
           else if (strncmp(s, "ssh:", 4) == 0)
                   return s + 4;
           return s;
   }
   
   static int
   do_download_sk(const char *skprovider)
   {
           struct sshkey **keys;
           size_t nkeys, i;
           int r, ok = -1;
           char *fp, *pin, *pass = NULL, *path, *pubpath;
           const char *ext;
   
           if (skprovider == NULL)
                   fatal("Cannot download keys without provider");
   
           pin = read_passphrase("Enter PIN for security key: ", RP_ALLOW_STDIN);
           if ((r = sshsk_load_resident(skprovider, pin, &keys, &nkeys)) != 0) {
                   freezero(pin, strlen(pin));
                   error("Unable to load resident keys: %s", ssh_err(r));
                   return -1;
           }
           if (nkeys == 0)
                   logit("No keys to download");
           freezero(pin, strlen(pin));
   
           for (i = 0; i < nkeys; i++) {
                   if (keys[i]->type != KEY_ECDSA_SK &&
                       keys[i]->type != KEY_ED25519_SK) {
                           error("Unsupported key type %s (%d)",
                               sshkey_type(keys[i]), keys[i]->type);
                           continue;
                   }
                   if ((fp = sshkey_fingerprint(keys[i],
                       fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
                           fatal("%s: sshkey_fingerprint failed", __func__);
                   debug("%s: key %zu: %s %s %s (flags 0x%02x)", __func__, i,
                       sshkey_type(keys[i]), fp, keys[i]->sk_application,
                       keys[i]->sk_flags);
                   ext = skip_ssh_url_preamble(keys[i]->sk_application);
                   xasprintf(&path, "id_%s_rk%s%s",
                       keys[i]->type == KEY_ECDSA_SK ? "ecdsa_sk" : "ed25519_sk",
                       *ext == '\0' ? "" : "_", ext);
   
                   /* If the file already exists, ask the user to confirm. */
                   if (!confirm_overwrite(path)) {
                           free(path);
                           break;
                   }
   
                   /* Save the key with the application string as the comment */
                   if (pass == NULL)
                           pass = private_key_passphrase();
                   if ((r = sshkey_save_private(keys[i], path, pass,
                       keys[i]->sk_application, private_key_format,
                       openssh_format_cipher, rounds)) != 0) {
                           error("Saving key \"%s\" failed: %s",
                               path, ssh_err(r));
                           free(path);
                           break;
                   }
                   if (!quiet) {
                           printf("Saved %s key%s%s to %s\n",
                               sshkey_type(keys[i]),
                               *ext != '\0' ? " " : "",
                               *ext != '\0' ? keys[i]->sk_application : "",
                               path);
                   }
   
                   /* Save public key too */
                   xasprintf(&pubpath, "%s.pub", path);
                   free(path);
                   if ((r = sshkey_save_public(keys[i], pubpath,
                       keys[i]->sk_application)) != 0) {
                           free(pubpath);
                           error("Saving public key \"%s\" failed: %s",
                               pubpath, ssh_err(r));
                           break;
                   }
                   free(pubpath);
           }
   
           if (i >= nkeys)
                   ok = 0; /* success */
           if (pass != NULL)
                   freezero(pass, strlen(pass));
           for (i = 0; i < nkeys; i++)
                   sshkey_free(keys[i]);
           free(keys);
           return ok ? 0 : -1;
   }
   
 static void  static void
 usage(void)  usage(void)
 {  {
Line 2873 
Line 3004 
             "       ssh-keygen -D pkcs11\n");              "       ssh-keygen -D pkcs11\n");
 #endif  #endif
         fprintf(stderr,          fprintf(stderr,
               "       ssh-keygen -K path [-w sk_provider]\n");
           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 -R hostname [-f known_hosts_file]\n"              "       ssh-keygen -R hostname [-f known_hosts_file]\n"
Line 2902 
Line 3035 
 int  int
 main(int argc, char **argv)  main(int argc, char **argv)
 {  {
         char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2;          char dotsshdir[PATH_MAX], comment[1024], *passphrase;
         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;
         struct stat st;          struct stat st;
         int r, opt, type, fd;          int r, opt, type;
         int change_passphrase = 0, change_comment = 0, show_cert = 0;          int change_passphrase = 0, change_comment = 0, show_cert = 0;
         int find_host = 0, delete_host = 0, hash_hosts = 0;          int find_host = 0, delete_host = 0, hash_hosts = 0;
         int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;          int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
         int prefer_agent = 0, convert_to = 0, convert_from = 0;          int prefer_agent = 0, convert_to = 0, convert_from = 0;
         int print_public = 0, print_generic = 0, cert_serial_autoinc = 0;          int print_public = 0, print_generic = 0, cert_serial_autoinc = 0;
         int do_gen_candidates = 0, do_screen_candidates = 0;          int do_gen_candidates = 0, do_screen_candidates = 0, download_sk = 0;
         unsigned long long cert_serial = 0;          unsigned long long cert_serial = 0;
         char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL;          char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL;
         size_t i, nopts = 0;          size_t i, nopts = 0;
         u_int32_t bits = 0;          u_int32_t bits = 0;
         uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD;          uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD;
         FILE *f;  
         const char *errstr;          const char *errstr;
         int log_level = SYSLOG_LEVEL_INFO;          int log_level = SYSLOG_LEVEL_INFO;
         char *sign_op = NULL;          char *sign_op = NULL;
Line 2946 
Line 3078 
   
         sk_provider = getenv("SSH_SK_PROVIDER");          sk_provider = getenv("SSH_SK_PROVIDER");
   
         /* Remaining characters: dGjJKSTWx */          /* Remaining characters: dGjJSTWx */
         while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvy"          while ((opt = getopt(argc, argv, "ABHKLQUXceghiklopquvy"
             "C:D:E:F:I:M:N:O:P:R:V:Y:Z:"              "C:D:E:F:I:M:N:O:P:R:V:Y:Z:"
             "a:b:f:g:m:n:r:s:t:w:z:")) != -1) {              "a:b:f:g:m:n:r:s:t:w:z:")) != -1) {
                 switch (opt) {                  switch (opt) {
Line 3027 
Line 3159 
                 case 'g':                  case 'g':
                         print_generic = 1;                          print_generic = 1;
                         break;                          break;
                   case 'K':
                           download_sk = 1;
                           break;
                 case 'P':                  case 'P':
                         identity_passphrase = optarg;                          identity_passphrase = optarg;
                         break;                          break;
Line 3240 
Line 3375 
         }          }
         if (pkcs11provider != NULL)          if (pkcs11provider != NULL)
                 do_download(pw);                  do_download(pw);
           if (download_sk)
                   return do_download_sk(sk_provider);
         if (print_fingerprint || print_bubblebabble)          if (print_fingerprint || print_bubblebabble)
                 do_fingerprint(pw);                  do_fingerprint(pw);
         if (change_passphrase)          if (change_passphrase)
Line 3335 
Line 3472 
                         printf("You may need to touch your security key "                          printf("You may need to touch your security key "
                             "to authorize key generation.\n");                              "to authorize key generation.\n");
                 }                  }
                 passphrase1 = NULL;                  passphrase = NULL;
                 for (i = 0 ; i < 3; i++) {                  for (i = 0 ; i < 3; i++) {
                         if (!quiet) {                          if (!quiet) {
                                 printf("You may need to touch your security "                                  printf("You may need to touch your security "
Line 3344 
Line 3481 
                         fflush(stdout);                          fflush(stdout);
                         r = sshsk_enroll(type, sk_provider,                          r = sshsk_enroll(type, sk_provider,
                             cert_key_id == NULL ? "ssh:" : cert_key_id,                              cert_key_id == NULL ? "ssh:" : cert_key_id,
                             sk_flags, passphrase1, NULL, &private, NULL);                              sk_flags, passphrase, NULL, &private, NULL);
                         if (r == 0)                          if (r == 0)
                                 break;                                  break;
                         if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)                          if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
                                 exit(1); /* error message already printed */                                  exit(1); /* error message already printed */
                         if (passphrase1 != NULL)                          if (passphrase != NULL)
                                 freezero(passphrase1, strlen(passphrase1));                                  freezero(passphrase, strlen(passphrase));
                         passphrase1 = read_passphrase("Enter PIN for security "                          passphrase = read_passphrase("Enter PIN for security "
                             "key: ", RP_ALLOW_STDIN);                              "key: ", RP_ALLOW_STDIN);
                 }                  }
                 if (passphrase1 != NULL)                  if (passphrase != NULL)
                         freezero(passphrase1, strlen(passphrase1));                          freezero(passphrase, strlen(passphrase));
                 if (i > 3)                  if (i > 3)
                         fatal("Too many incorrect PINs");                          fatal("Too many incorrect PINs");
                 break;                  break;
Line 3388 
Line 3525 
         /* If the file already exists, ask the user to confirm. */          /* If the file already exists, ask the user to confirm. */
         if (!confirm_overwrite(identity_file))          if (!confirm_overwrite(identity_file))
                 exit(1);                  exit(1);
         /* Ask for a passphrase (twice). */  
         if (identity_passphrase)  
                 passphrase1 = xstrdup(identity_passphrase);  
         else if (identity_new_passphrase)  
                 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.  
                          */  
                         explicit_bzero(passphrase1, strlen(passphrase1));  
                         explicit_bzero(passphrase2, strlen(passphrase2));  
                         free(passphrase1);  
                         free(passphrase2);  
                         printf("Passphrases do not match.  Try again.\n");  
                         goto passphrase_again;  
                 }  
                 /* Clear the other copy of the passphrase. */  
                 explicit_bzero(passphrase2, strlen(passphrase2));  
                 free(passphrase2);  
         }  
   
           /* Determine the passphrase for the private key */
           passphrase = private_key_passphrase();
         if (identity_comment) {          if (identity_comment) {
                 strlcpy(comment, identity_comment, sizeof(comment));                  strlcpy(comment, identity_comment, sizeof(comment));
         } else {          } else {
Line 3425 
Line 3536 
         }          }
   
         /* Save the key with the given passphrase and comment. */          /* Save the key with the given passphrase and comment. */
         if ((r = sshkey_save_private(private, identity_file, passphrase1,          if ((r = sshkey_save_private(private, identity_file, passphrase,
             comment, private_key_format, openssh_format_cipher, rounds)) != 0) {              comment, private_key_format, openssh_format_cipher, rounds)) != 0) {
                 error("Saving key \"%s\" failed: %s",                  error("Saving key \"%s\" failed: %s",
                     identity_file, ssh_err(r));                      identity_file, ssh_err(r));
                 explicit_bzero(passphrase1, strlen(passphrase1));                  freezero(passphrase, strlen(passphrase));
                 free(passphrase1);  
                 exit(1);                  exit(1);
         }          }
         /* Clear the passphrase. */          freezero(passphrase, strlen(passphrase));
         explicit_bzero(passphrase1, strlen(passphrase1));  
         free(passphrase1);  
   
         /* Clear the private key and the random number generator. */  
         sshkey_free(private);          sshkey_free(private);
   
         if (!quiet)          if (!quiet) {
                 printf("Your identification has been saved in %s.\n", identity_file);                  printf("Your identification has been saved in %s.\n",
                       identity_file);
           }
   
         strlcat(identity_file, ".pub", sizeof(identity_file));          strlcat(identity_file, ".pub", sizeof(identity_file));
         if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)          if ((r = sshkey_save_public(public, identity_file, comment)) != 0) {
                 fatal("Unable to save public key to %s: %s",                  fatal("Unable to save public key to %s: %s",
                     identity_file, strerror(errno));                      identity_file, strerror(errno));
         if ((f = fdopen(fd, "w")) == NULL)          }
                 fatal("fdopen %s failed: %s", identity_file, strerror(errno));  
         if ((r = sshkey_write(public, f)) != 0)  
                 error("write key failed: %s", ssh_err(r));  
         fprintf(f, " %s\n", comment);  
         if (ferror(f) || fclose(f) != 0)  
                 fatal("write public failed: %s", strerror(errno));  
   
         if (!quiet) {          if (!quiet) {
                 fp = sshkey_fingerprint(public, fingerprint_hash,                  fp = sshkey_fingerprint(public, fingerprint_hash,

Legend:
Removed from v.1.380  
changed lines
  Added in v.1.381