[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.445 and 1.456

version 1.445, 2022/01/05 04:50:11 version 1.456, 2022/07/20 03:29:14
Line 121 
Line 121 
 #define CERTOPT_PTY                             (1<<3)  #define CERTOPT_PTY                             (1<<3)
 #define CERTOPT_USER_RC                         (1<<4)  #define CERTOPT_USER_RC                         (1<<4)
 #define CERTOPT_NO_REQUIRE_USER_PRESENCE        (1<<5)  #define CERTOPT_NO_REQUIRE_USER_PRESENCE        (1<<5)
   #define CERTOPT_REQUIRE_VERIFY                  (1<<6)
 #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \  #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \
                          CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)                           CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC)
 static u_int32_t certflags_flags = CERTOPT_DEFAULT;  static u_int32_t certflags_flags = CERTOPT_DEFAULT;
Line 573 
Line 574 
                 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 ||              NULL, 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),
               NULL, 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 1023 
Line 1027 
         } 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 1649 
Line 1652 
                 cert_ext_add("force-command", certflags_command, 1);                  cert_ext_add("force-command", certflags_command, 1);
         if (certflags_src_addr != NULL)          if (certflags_src_addr != NULL)
                 cert_ext_add("source-address", certflags_src_addr, 1);                  cert_ext_add("source-address", certflags_src_addr, 1);
           if ((certflags_flags & CERTOPT_REQUIRE_VERIFY) != 0)
                   cert_ext_add("verify-required", NULL, 1);
         /* extensions */          /* extensions */
         if ((certflags_flags & CERTOPT_X_FWD) != 0)          if ((certflags_flags & CERTOPT_X_FWD) != 0)
                 cert_ext_add("permit-X11-forwarding", NULL, 0);                  cert_ext_add("permit-X11-forwarding", NULL, 0);
Line 1970 
Line 1975 
                 certflags_flags &= ~CERTOPT_NO_REQUIRE_USER_PRESENCE;                  certflags_flags &= ~CERTOPT_NO_REQUIRE_USER_PRESENCE;
         else if (strcasecmp(opt, "no-touch-required") == 0)          else if (strcasecmp(opt, "no-touch-required") == 0)
                 certflags_flags |= CERTOPT_NO_REQUIRE_USER_PRESENCE;                  certflags_flags |= CERTOPT_NO_REQUIRE_USER_PRESENCE;
           else if (strcasecmp(opt, "no-verify-required") == 0)
                   certflags_flags &= ~CERTOPT_REQUIRE_VERIFY;
           else if (strcasecmp(opt, "verify-required") == 0)
                   certflags_flags |= CERTOPT_REQUIRE_VERIFY;
         else if (strncasecmp(opt, "force-command=", 14) == 0) {          else if (strncasecmp(opt, "force-command=", 14) == 0) {
                 val = opt + 14;                  val = opt + 14;
                 if (*val == '\0')                  if (*val == '\0')
Line 2028 
Line 2037 
                                 fatal_fr(r, "parse critical");                                  fatal_fr(r, "parse critical");
                         printf(" %s\n", arg);                          printf(" %s\n", arg);
                         free(arg);                          free(arg);
                   } else if (in_critical &&
                       strcmp(name, "verify-required") == 0) {
                           printf("\n");
                 } else if (sshbuf_len(option) > 0) {                  } else if (sshbuf_len(option) > 0) {
                         hex = sshbuf_dtob16(option);                          hex = sshbuf_dtob16(option);
                         printf(" UNKNOWN OPTION: %s (len %zu)\n",                          printf(" UNKNOWN OPTION: %s (len %zu)\n",
Line 2437 
Line 2449 
 {  {
         size_t i, slen, plen = strlen(keypath);          size_t i, slen, plen = strlen(keypath);
         char *privpath = xstrdup(keypath);          char *privpath = xstrdup(keypath);
         const char *suffixes[] = { "-cert.pub", ".pub", NULL };          static const char * const suffixes[] = { "-cert.pub", ".pub", NULL };
         struct sshkey *ret = NULL, *privkey = NULL;          struct sshkey *ret = NULL, *privkey = NULL;
         int r;          int r, waspub = 0;
           struct stat st;
   
         /*          /*
          * If passed a public key filename, then try to locate the corresponding           * If passed a public key filename, then try to locate the corresponding
Line 2454 
Line 2467 
                 privpath[plen - slen] = '\0';                  privpath[plen - slen] = '\0';
                 debug_f("%s looks like a public key, using private key "                  debug_f("%s looks like a public key, using private key "
                     "path %s instead", keypath, privpath);                      "path %s instead", keypath, privpath);
                   waspub = 1;
         }          }
         if ((privkey = load_identity(privpath, NULL)) == NULL) {          if (waspub && stat(privpath, &st) != 0 && errno == ENOENT)
                 error("Couldn't load identity %s", keypath);                  fatal("No private key found for public key \"%s\"", keypath);
                 goto done;          if ((r = sshkey_load_private(privpath, "", &privkey, NULL)) != 0 &&
         }              (r != SSH_ERR_KEY_WRONG_PASSPHRASE)) {
                   debug_fr(r, "load private key \"%s\"", privpath);
                   fatal("No private key found for \"%s\"", privpath);
           } else if (privkey == NULL)
                   privkey = load_identity(privpath, NULL);
   
         if (!sshkey_equal_public(pubkey, privkey)) {          if (!sshkey_equal_public(pubkey, privkey)) {
                 error("Public key %s doesn't match private %s",                  error("Public key %s doesn't match private %s",
                     keypath, privpath);                      keypath, privpath);
Line 2624 
Line 2643 
   
   
 static int  static int
 sig_sign(const char *keypath, const char *sig_namespace, int argc, char **argv,  sig_sign(const char *keypath, const char *sig_namespace, int require_agent,
     char * const *opts, size_t nopts)      int argc, char **argv, char * const *opts, size_t nopts)
 {  {
         int i, fd = -1, r, ret = -1;          int i, fd = -1, r, ret = -1;
         int agent_fd = -1;          int agent_fd = -1;
Line 2649 
Line 2668 
                 goto done;                  goto done;
         }          }
   
         if ((r = ssh_get_authentication_socket(&agent_fd)) != 0)          if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
                   if (require_agent)
                           fatal("Couldn't get agent socket");
                 debug_r(r, "Couldn't get agent socket");                  debug_r(r, "Couldn't get agent socket");
         else {          } else {
                 if ((r = ssh_agent_has_key(agent_fd, pubkey)) == 0)                  if ((r = ssh_agent_has_key(agent_fd, pubkey)) == 0)
                         signer = agent_signer;                          signer = agent_signer;
                 else                  else {
                           if (require_agent)
                                   fatal("Couldn't find key in agent");
                         debug_r(r, "Couldn't find key in agent");                          debug_r(r, "Couldn't find key in agent");
                   }
         }          }
   
         if (signer == NULL) {          if (signer == NULL) {
Line 2982 
Line 3006 
 #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 3163 
Line 3193 
                     "%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;
           printf("Touch your authenticator to authorize key generation.\n");
           return 1;
   }
   
 static void  static void
 usage(void)  usage(void)
 {  {
Line 3497 
Line 3545 
                         return sig_match_principals(identity_file, cert_key_id,                          return sig_match_principals(identity_file, cert_key_id,
                             opts, nopts);                              opts, nopts);
                 } else if (strncmp(sign_op, "sign", 4) == 0) {                  } else if (strncmp(sign_op, "sign", 4) == 0) {
                           /* NB. cert_principals is actually namespace, via -n */
                         if (cert_principals == NULL ||                          if (cert_principals == NULL ||
                             *cert_principals == '\0') {                              *cert_principals == '\0') {
                                 error("Too few arguments for sign: "                                  error("Too few arguments for sign: "
Line 3509 
Line 3558 
                                 exit(1);                                  exit(1);
                         }                          }
                         return sig_sign(identity_file, cert_principals,                          return sig_sign(identity_file, cert_principals,
                             argc, argv, opts, nopts);                              prefer_agent, argc, argv, opts, nopts);
                 } else if (strncmp(sign_op, "check-novalidate", 16) == 0) {                  } else if (strncmp(sign_op, "check-novalidate", 16) == 0) {
                           /* NB. cert_principals is actually namespace, via -n */
                           if (cert_principals == NULL ||
                               *cert_principals == '\0') {
                                   error("Too few arguments for check-novalidate: "
                                       "missing namespace");
                                   exit(1);
                           }
                         if (ca_key_path == NULL) {                          if (ca_key_path == NULL) {
                                 error("Too few arguments for check-novalidate: "                                  error("Too few arguments for check-novalidate: "
                                     "missing signature file");                                      "missing signature file");
Line 3519 
Line 3575 
                         return sig_verify(ca_key_path, cert_principals,                          return sig_verify(ca_key_path, cert_principals,
                             NULL, NULL, NULL, opts, nopts);                              NULL, NULL, NULL, opts, nopts);
                 } else if (strncmp(sign_op, "verify", 6) == 0) {                  } else if (strncmp(sign_op, "verify", 6) == 0) {
                           /* NB. cert_principals is actually namespace, via -n */
                         if (cert_principals == NULL ||                          if (cert_principals == NULL ||
                             *cert_principals == '\0') {                              *cert_principals == '\0') {
                                 error("Too few arguments for verify: "                                  error("Too few arguments for verify: "
Line 3537 
Line 3594 
                         }                          }
                         if (cert_key_id == NULL) {                          if (cert_key_id == NULL) {
                                 error("Too few arguments for verify: "                                  error("Too few arguments for verify: "
                                     "missing principal ID");                                      "missing principal identity");
                                 exit(1);                                  exit(1);
                         }                          }
                         return sig_verify(ca_key_path, cert_principals,                          return sig_verify(ca_key_path, cert_principals,
Line 3738 
Line 3795 
                             &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) {

Legend:
Removed from v.1.445  
changed lines
  Added in v.1.456